Pygame Zero演習10(ゴールするだけのゲーム)

Python

順を追っていくと流れが理解できるようになっています。

項目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 を改良して以下に挑戦してみてください。

  1. ゲームクリアしたら中央に「GAME CLEAR!」と表示する
  2. ゲームクリアしたらキーボード入力できないようにする
  3. BGMを流してみる
  4. ゴールしたら効果音を流す
  5. ゲームクリア後、Rキーを押すと最初からプレイできる

コメント