Pyxel学習日記(6日目)

画面がゲームのスタート前かプレー中かを判定する処理。プレー中に物に当たったらゲームオーバーとなり
2秒後にスタート前に戻す処理をいれた。また別で作った画像を使用する方法やサウンドの入れ方を学んだ。

今日書いたコード

結果:GAME OVERになったらタイトルに戻る処理をいれた

import pyxel

SCREEN_WIDTH = 160
SCREEN_HEIGHT = 120
STONE_INTERVAL = 30
GAME_OVER_DISPLAY_TIME = 60
START_SCENE = "start"
PLAY_SCENE = "play"

class Stone:
    def __init__(self, x, y): #座標を表すxとyというインスタンス変数
        self.x = x
        self.y = y

    def update(self):
        if self.y < SCREEN_HEIGHT:
            self.y += 1

    def draw(self):
        pyxel.blt(self.x, self.y, 0, 8, 0, 8, 8, pyxel.COLOR_BLACK)

class App:
    def __init__(self): #イニシャライザー。初期化関数。初期設定を書く
        pyxel.init(SCREEN_WIDTH, SCREEN_HEIGHT, title="はじめてのゲーム") #ゲーム画面の幅と高さとタイトル
        pyxel.mouse(True)
        pyxel.load("my_resource.pyxres") #リソースを読み込む
        self.jp_font = pyxel.Font("umplus_j10r.bdf") #日本語フォントが使用可能
        pyxel.playm(0, loop = True)
        self.current_scene = START_SCENE
        pyxel.run(self.update, self.draw)

    def reset_play_scene(self):
        self.player_x = SCREEN_WIDTH // 2  # プレイヤーのX座標のデフォルト値
        self.player_y = SCREEN_HEIGHT * 4 // 5
        self.stones = []
        self.is_collision = False
        self.game_over_display_timer = GAME_OVER_DISPLAY_TIME

    def update_start_scene(self): #画面がクリックされたらプレー画面に切り替わる
        if pyxel.btnp(pyxel.MOUSE_BUTTON_LEFT):
            self.reset_play_scene()
            self.current_scene = PLAY_SCENE

    def update_play_scene(self):
        #ゲームオーバー時
        if self.is_collision:
            if self.game_over_display_timer > 0:
                self.game_over_display_timer -= 1
            else:
                self.current_scene = START_SCENE
            return

        #プレイヤーが右をおした時。ただし条件として画面の幅より12小さい時
        if pyxel.btn(pyxel.KEY_RIGHT) and self.player_x < SCREEN_WIDTH - 12:
            self.player_x += 1

        #プレイヤーが左をおした時。ただし条件として画面の幅より4大きい時:
        elif pyxel.btn(pyxel.KEY_LEFT) and self.player_x > - 4:
            self.player_x -= 1

        if pyxel.frame_count % STONE_INTERVAL == 0: #pyxel.frame_countは経過フレーム数が(自動)で格納されている
            self.stones.append(Stone(pyxel.rndi(0, SCREEN_WIDTH -8), 0)) #rndiの引数は最小と最大

        #物の落下
        for stone in self.stones.copy():
            stone.update()

            #衝突
            if (self.player_x <= stone.x <= self.player_x + 8 and
                self.player_y <= stone.y <= self.player_y + 8):
                self.is_collision = True

            #画面外に出た物を削除
            if stone.y >= SCREEN_HEIGHT:
                self.stones.remove(stone)

    def update(self): #フレーム更新時に呼び出される処理
        if pyxel.btnp(pyxel.KEY_ESCAPE): #quit関数でesc押下で終了する処理。btnはおされつづけてる、btnpは押した瞬間
            pyxel.quit()

        if self.current_scene == START_SCENE:
            self.update_start_scene()
        elif self.current_scene == PLAY_SCENE:
            self.update_play_scene()

    def draw_start_scene(self):
        pyxel.blt(0, 0, 0, 32, 0, 160, 120)
        pyxel.text(SCREEN_WIDTH // 10, SCREEN_HEIGHT // 10,
                   "クリックしてね!", pyxel.COLOR_PINK, self.jp_font)

    def draw_play_scene(self):
        pyxel.cls(pyxel.COLOR_DARK_BLUE) #画面を特定の色でクリアするための関数

        for stone in self.stones:
            stone.draw()

        pyxel.blt(self.player_x, self.player_y, 0, 16, 0, 16, 16, pyxel.COLOR_BLACK) #プレイヤー
        #ユーザーからの操作で状態が変化するような値はインスタンス変数として扱い、updateでもdrawでも扱えるようにする

        if self.is_collision:
            pyxel.text(SCREEN_WIDTH // 2 - 20, SCREEN_HEIGHT // 2,
                       "Game Over", pyxel.COLOR_YELLOW)

    def draw(self): #描画処理
        if self.current_scene == START_SCENE:
            self.draw_start_scene()
        elif self.current_scene == PLAY_SCENE:
            self.draw_play_scene()

App() #オブジェクト化