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

Python

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

項目1~3は徐々に機能を拡張しています。項目4が最終段階です。
まずは1~3を理解した後、項目4を作成し最後の挑戦課題に取り組んでみてください。

マップ上をキャラクタが移動できる

map_move.py

2次元リストで作ったマップ上をプレイヤーが移動できます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# 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キーを押すと最初からプレイできる

コメント