順を追っていくと流れが理解できるようになっています。
項目1~3は徐々に機能を拡張しています。項目4が最終段階です。
まずは1~3を理解した後、項目4を作成し最後の挑戦課題に取り組んでみてください。
マップ上をキャラクタが移動できる
map_move.py
2次元リストで作ったマップ上をプレイヤーが移動できます。
# Pygame Zero: マップ上をキャラクタが移動できる
import pgzrun
# キャラクタチップサイズ
CSIZE = 64 # 64px X 64px
# 画面サイズ
WIDTH = CSIZE * 5 # 320px
HEIGHT = CSIZE * 5 # 320px
TITLE = "マップ上をキャラクタが移動できる"
# マップデータ
map = [
[0, 0, 0, 0, 0],
[0, 1, 1, 0, 0],
[0, 1, 1, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 0, 0, 1],
]
# プレイヤーを生成
px = py = 0 # プレイヤーのマップ上座標を設定
player = Actor("kero")
player.topleft = px * CSIZE, py * CSIZE # マップ上の座標を描画座標に変換してプレイヤーを描画
# 移動先位置を現在の位置に設定(初期状態)
xnext = px
ynext = py
# 描画関数
def draw_map():
# 壁を描画
for y in range(5):
for x in range(5):
if map[y][x] == 1:
screen.blit("kabe", (x*CSIZE, y*CSIZE))
else:
screen.blit("no_kabe", (x*CSIZE, y*CSIZE))
# プレイヤーを描画
player.draw()
# フレーム処理
def update():
draw_map() # マップを描画
# キーボードが押された時の処理
def on_key_down(key):
global px, py, xnext, ynext
# キー入力をチェック
if key == keys.A:
xnext -= 1 # 左
elif key == keys.D:
xnext += 1 # 右
elif key == keys.W:
ynext -= 1 # 上
elif key == keys.S:
ynext += 1 # 下
# プレイヤーを移動先に描画
player.left = xnext * CSIZE
player.top = ynext * CSIZE
# ゲームスタート
pgzrun.go()
マップ外は移動不可
マップの外は移動できないようにしました。
map_move_check.py
# Pygame Zero: マップ外は移動不可
import pgzrun
# キャラクタチップサイズ
CSIZE = 64 # 64px X 64px
# 画面サイズ
WIDTH = CSIZE * 5 # 320px
HEIGHT = CSIZE * 5 # 320px
TITLE = "マップ外は移動不可"
# マップデータ
map = [
[0, 0, 0, 0, 0],
[0, 1, 1, 0, 0],
[0, 1, 1, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 0, 0, 1],
]
# プレイヤーを生成
px = py = 0 # プレイヤーのマップ上座標を設定
player = Actor("kero")
player.topleft = px * CSIZE, py * CSIZE # マップ上の座標を描画座標に変換してプレイヤーを描画
# 移動先位置を現在の位置に設定(初期状態)
xnext = px
ynext = py
# 描画関数
def draw_map():
# 壁を描画
for y in range(5):
for x in range(5):
if map[y][x] == 1:
screen.blit("kabe", (x*CSIZE, y*CSIZE))
else:
screen.blit("no_kabe", (x*CSIZE, y*CSIZE))
# プレイヤーを描画
player.draw()
# フレーム処理
def update():
draw_map() # マップを描画
# キーボードが押された時の処理
def on_key_down(key):
global px, py, xnext, ynext
# キー入力をチェック
if key == keys.A:
xnext -= 1 # 左
elif key == keys.D:
xnext += 1 # 右
elif key == keys.W:
ynext -= 1 # 上
elif key == keys.S:
ynext += 1 # 下
# 移動先が壁かどうかチェック
if check_kabe(): # 壁である
xnext = px
ynext = py
else: # 壁でない
px = xnext
py = ynext
# プレイヤーを移動先に描画
player.left = xnext * CSIZE
player.top = ynext * CSIZE
# 移動先が壁かどうかのチェック関数
def check_kabe():
if xnext < 0 or xnext >= 5 or ynext < 0 or ynext >= 5: # マップ外も壁と判定
return True
return False # 移動可能
# ゲームスタート
pgzrun.go()
壁以外の部分は移動可能
壁以外の通路は移動できるようにしました。
map_move_check_kabe.py
# Pygame Zero: 壁以外の部分は移動可能
import pgzrun
# キャラクタチップサイズ
CSIZE = 64 # 64px X 64px
# 画面サイズ
WIDTH = CSIZE * 5 # 320px
HEIGHT = CSIZE * 5 # 320px
TITLE = "壁以外の部分は移動可能"
# マップデータ
map = [
[0, 0, 0, 0, 0],
[0, 1, 1, 0, 0],
[0, 1, 1, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 0, 0, 1],
]
# プレイヤーを生成
px = py = 0 # プレイヤーのマップ上座標を設定
player = Actor("kero")
player.topleft = px * CSIZE, py * CSIZE # マップ上の座標を描画座標に変換してプレイヤーを描画
# 移動先位置を現在の位置に設定(初期状態)
xnext = px
ynext = py
# 描画関数
def draw_map():
# 壁を描画
for y in range(5):
for x in range(5):
if map[y][x] == 1:
screen.blit("kabe", (x*CSIZE, y*CSIZE))
else:
screen.blit("no_kabe", (x*CSIZE, y*CSIZE))
# プレイヤーを描画
player.draw()
# フレーム処理
def update():
draw_map() # マップを描画
# キーボードが押された時の処理
def on_key_down(key):
global px, py, xnext, ynext
# キー入力をチェック
if key == keys.A:
xnext -= 1 # 左
elif key == keys.D:
xnext += 1 # 右
elif key == keys.W:
ynext -= 1 # 上
elif key == keys.S:
ynext += 1 # 下
# 移動先が壁かどうかチェック
if check_kabe(): # 壁である
xnext = px
ynext = py
else: # 壁でない
px = xnext
py = ynext
# プレイヤーを移動先に描画
player.left = xnext * CSIZE
player.top = ynext * CSIZE
# 移動先が壁かどうかのチェック関数
def check_kabe():
if xnext < 0 or xnext >= 5 or ynext < 0 or ynext >= 5: # マップ外も壁と判定
return True
elif map[ynext][xnext] == 1: # 壁
return True
return False # 移動可能
# ゲームスタート
pgzrun.go()
ゴールするだけのゲーム
前述のmap_move_check_kabe.pyを元にゴールするだけのゲームを作りました。
map_simple_game.py
# Pygame Zero: ゴールするだけのゲーム
import pgzrun
# キャラクタチップサイズ
CSIZE = 64 # 64px X 64px
# 画面サイズ
WIDTH = CSIZE * 5 # 320px
HEIGHT = CSIZE * 5 # 320px
TITLE = "ゴールするだけのゲーム"
# ゲームの状態
GAME = 0 # ゲーム中
GAMECLEAR = 1 # ゲームクリア
status = GAME
# マップデータ
map = [
[0, 1, 0, 1, 1],
[0, 1, 0, 0, 0],
[0, 1, 0, 1, 0],
[0, 0, 0, 1, 0],
[1, 1, 1, 1, 0],
]
# プレイヤーを生成
px = py = 0 # プレイヤーのマップ上座標を設定
player = Actor("kero")
player.topleft = px * CSIZE, py * CSIZE # マップ上の座標を描画座標に変換してプレイヤーを描画
# ゴールを生成
gx = gy = 4 # ゴールのマップ上座標を設定
goal = Actor("goal")
goal.topleft = gx * CSIZE, gy * CSIZE # マップ上の座標を描画座標に変換してゴールを描画
# 移動先位置を現在の位置に設定(初期状態)
xnext = px
ynext = py
# 描画関数
def draw_map():
# 壁を描画
for y in range(5):
for x in range(5):
if map[y][x] == 1:
screen.blit("kabe", (x*CSIZE, y*CSIZE))
else:
screen.blit("no_kabe", (x*CSIZE, y*CSIZE))
# キャラクタ描画
player.draw()
goal.draw()
# フレーム処理
def update():
draw_map() # マップを描画
# キーボードが押された時の処理
def on_key_down(key):
global px, py, xnext, ynext
# キー入力をチェック
if key == keys.A:
xnext -= 1 # 左
elif key == keys.D:
xnext += 1 # 右
elif key == keys.W:
ynext -= 1 # 上
elif key == keys.S:
ynext += 1 # 下
# 移動先が壁かどうかチェック
if check_kabe(): # 壁である
xnext = px
ynext = py
else: # 壁でない
px = xnext
py = ynext
# プレイヤーを移動先に描画
player.left = xnext * CSIZE
player.top = ynext * CSIZE
# プレイヤーがゴールに接触したか
if player.collidepoint(goal.pos):
goal.pos = -100, -100
print("ゲームクリア!")
# 移動先が壁かどうかのチェック関数
def check_kabe():
if xnext < 0 or xnext >= 5 or ynext < 0 or ynext >= 5: # マップ外も壁と判定
return True
elif map[ynext][xnext] == 1: # 壁
return True
return False # 移動可能
# ゲームスタート
pgzrun.go()
挑戦課題
map_simple_game.py を改良して以下に挑戦してみてください。
- ゲームクリアしたら中央に「GAME CLEAR!」と表示する
- ゲームクリアしたらキーボード入力できないようにする
- BGMを流してみる
- ゴールしたら効果音を流す
- ゲームクリア後、Rキーを押すと最初からプレイできる
コメント