Pyxel学習日記(3日目)

今日はキャラを物にアニメーションを付け、当たり判定もいれた。
updateメソッドで物やキャラが動くようにする。
if文でキーを押したときに反応するようにした。pyxel.btn()はキーが押されてるかどうか判定する関数
if pyxel.btn(pyxel.KEY_RIGHT) 括弧内はPyxelライブラリで定義されている定数で右矢印キー。
if文で物が毎フレーム下に移動するようにした。if文で物がキャラの枠内に完全に入ったら衝突判定をとる
ようにした。

今日書いたコード

結果:物を落下させて、キャラ左右に移動できるようにする。キャラに当たり判定をつける。

import pyxel

SCREEN_WIDTH = 160
SCREEN_HEIGHT = 120

class App:
    def __init__(self): #イニシャライザー。初期化関数。初期設定を書く
        pyxel.init(SCREEN_WIDTH, SCREEN_HEIGHT, title="はじめてのゲーム") #ゲーム画面の幅と高さとタイトル
        pyxel.mouse(True)
        pyxel.load("my_resource.pyxres") #リソースを読み込む
        self.player_x = SCREEN_WIDTH // 2 #プレイヤーのX座標のデフォルト値
        self.player_y = SCREEN_HEIGHT * 4 // 5
        self.stone_x = SCREEN_WIDTH // 2
        self.stone_y = 0 #物のY座標のデフォルト値
        self.is_collision = False
        pyxel.run(self.update, self.draw)

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

        #プレイヤーが右をおした時。ただし条件として画面の幅より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 self.stone_y < SCREEN_HEIGHT:
            self.stone_y += 1

        #衝突
        if (self.player_x <= self.stone_x <= self.player_x + 8 and
            self.player_y <= self.stone_y <= self.player_y + 8):
            self.is_collision = True

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

        #イメージバンクを表示させる
        #引数は左からX座標、Y座標、イメージバンクのINDEX、イメージバンクのX座標、イメージバンクのY座標、ピクセルアートの幅、ピクセルアートの高さ、透明として扱う色
        pyxel.blt(self.stone_x, self.stone_y, 0, 8, 0, 8, 8, pyxel.COLOR_BLACK) #物

        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)

App() #オブジェクト化

Gemini先生の説明

コードの解説:

  • pyxel.btn(key): この関数は、指定されたキーが押されている間 True を返し、押されていない場合は False を返します。
  • pyxel.KEY_RIGHT: これは、Pyxelライブラリで定義されている定数で、キーボードの右矢印キーを表します。

全体の意味:

if pyxel.btn(pyxel.KEY_RIGHT): は、「もし右矢印キーが押されていたら」という意味になります。この条件式が True の場合、if ブロック内のコードが実行されます。

  • self.stone_y: これは、オブジェクト(例:落下する石、弾丸など)のY座標を表す変数です。self は、オブジェクト指向プログラミングにおけるインスタンス自身を指します。
  • SCREEN_HEIGHT: これは、画面の高さ(ピクセル単位)を表す定数または変数です。
  • <: これは、比較演算子で、「より小さい」という意味です。
  • += 1: これは、複合代入演算子で、「右辺の値を左辺に加算する」という意味です。つまり、self.stone_y += 1 は、self.stone_y = self.stone_y + 1 と同じ意味です。

全体の意味:

if self.stone_y < SCREEN_HEIGHT: self.stone_y += 1

このコードは、「もしオブジェクトのY座標が画面の高さより小さければ、オブジェクトのY座標を1だけ増加させる」という意味になります。

処理の流れ:

  1. if self.stone_y < SCREEN_HEIGHT: の条件式が評価されます。
    • self.stone_ySCREEN_HEIGHT より小さい場合、条件式は True となり、次の行のコードが実行されます。
    • self.stone_ySCREEN_HEIGHT 以上の場合、条件式は False となり、次の行のコードは実行されません。
  2. 条件式が True の場合、self.stone_y += 1 が実行され、オブジェクトのY座標が1だけ増加します。

使用例:

このコードは、オブジェクトが画面の下方向に移動する処理を実装するために使用できます。例えば、落下する石のゲームでは、石のY座標をこのコードで更新することで、石が下に向かって落下するアニメーションを実現できます。

補足:

  • SCREEN_HEIGHT は、ゲームの画面サイズに合わせて適切な値を設定する必要があります。
  • self.stone_y += 1 の値を変更することで、オブジェクトの移動速度を調整できます。例えば、self.stone_y += 2 とすると、オブジェクトは2倍の速度で移動します。
  • オブジェクトが画面外に出た場合の処理(例:オブジェクトを消去する、ゲームオーバーにするなど)は、別途実装する必要があります。

self.is_collision = True の説明をして

このコード self.is_collision = True は、Pythonのクラス内で使用され、オブジェクトの属性 is_collisionTrue に設定するものです。つまり、このコードは、オブジェクトが衝突状態にあることを示すために使用されます。

以下に、このコードについて詳しく説明します。

コードの構成要素

  • self: これは、メソッドが呼び出されたオブジェクト自身を指します。クラス内で定義されたメソッドは、そのオブジェクトの属性やメソッドにアクセスするために self を使用します。
  • is_collision: これは、オブジェクトの属性(変数)です。この属性は、オブジェクトが衝突状態にあるかどうかを示すために使用されます。
  • True: これは、ブール値の True です。ブール値は、真偽値(True または False)を表します。

コードの動作

このコードが実行されると、self で指定されたオブジェクトの is_collision 属性の値が True に設定されます。これにより、オブジェクトは衝突状態にあるとみなされます。

使用例

このコードは、ゲーム開発や物理シミュレーションなど、オブジェクト間の衝突を検出する必要があるさまざまな状況で使用されます。

例えば、ゲーム開発では、キャラクターや物体が衝突したときに、このコードを使用して衝突状態を記録することができます。

例)
class GameObject:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.is_collision = False

    def check_collision(self, other_object):
        # 衝突判定のロジック(ここでは省略)
        if self.x == other_object.x and self.y == other_object.y: #仮の判定
            self.is_collision = True
            other_object.is_collision = True

# オブジェクトの作成
object1 = GameObject(10, 20)
object2 = GameObject(10, 20)

# 衝突判定
object1.check_collision(object2)

# 衝突状態の確認
print(object1.is_collision)  # 出力: True
print(object2.is_collision)  # 出力: True

この例では、GameObject クラスの check_collision メソッドは、2つのオブジェクトが衝突したかどうかを判定し、衝突した場合に is_collision 属性を True に設定します。

補足

  • is_collision 属性は、通常、衝突が解消されたときに False に設定されます。
  • 衝突判定のロジックは、オブジェクトの形状や速度など、さまざまな要因を考慮して実装する必要があります。