PyxelとChatGPTを使ってPythonを勉強してみる【第3回】
前回(第2回)はこちらです。
Pyxel記事のまとめはこちらです。
・・・・・・・
ChatGPTが考えてくれたPyxelで動くゲームをもとにPythonを勉強中です。ゲーム内容は、「プレイヤーを動かして1つの星を集める」というものです。
コードの全容は↓の通りです。
import pyxel
#初期化
class Simplegame:
def __init__(self):
pyxel.init(160,120)
self.player_x = 72
self.player_y = 56
self.star_x = pyxel.rndi(0,160)
self.star_y = pyxel.rndi(0,120)
self.score = 0
pyxel.run(self.update,self.draw)
def update(self):
#playerの移動
if pyxel.btn(pyxel.KEY_UP):
self.player_y = max(self.player_y - 2,0)
if pyxel.btn(pyxel.KEY_DOWN):
self.player_y = min(self.player_y + 2,112)
if pyxel.btn(pyxel.KEY_LEFT):
self.player_x = max(self.player_x - 2,0)
if pyxel.btn(pyxel.KEY_RIGHT):
self.player_x =min(self.player_x + 2,152)
#スターとの衝突判定
if (self.player_x <= self.star_x <= self.player_x + 8 and
self.player_y <= self.star_y <= self.player_y + 8):
self.score += 1
self.star_x = pyxel.rndi(0,160)
self.star_y = pyxel.rndi(0,120)
def draw(self):
pyxel.cls(0)
pyxel.text(5,4,f"Score:{self.score}",pyxel.COLOR_WHITE)
pyxel.rect(self.player_x,self.player_y,8,8,pyxel.COLOR_RED)
pyxel.circ(self.star_x,self.star_y,3,pyxel.COLOR_WHITE)
Simplegame()
前回まではここまで勉強しました。
def update(self):
#playerの移動
if pyxel.btn(pyxel.KEY_UP):
self.player_y = max(self.player_y - 2,0)
if pyxel.btn(pyxel.KEY_DOWN):
self.player_y = min(self.player_y + 2,112)
if pyxel.btn(pyxel.KEY_LEFT):
self.player_x = max(self.player_x - 2,0)
if pyxel.btn(pyxel.KEY_RIGHT):
self.player_x =min(self.player_x + 2,152)
コード全体を見て長っ!と思ってたけど、もう半分は終わってるのよね。
だから、思ってたよりも簡単じゃん!って感じました。
もう半分もちゃんと理解したい…!
・・・・・・・
今回学ぶのは、星との接触を判定する所謂「当たり判定」のコードです。
コードの内容は以下の通りです。
#スターとの衝突判定
if (self.player_x <= self.star_x <= self.player_x + 8 and
self.player_y <= self.star_y <= self.player_y + 8):
self.score += 1
self.star_x = pyxel.rndi(0,160)
self.star_y = pyxel.rndi(0,120)
早速、勉強しましょう!
さてさて、どんなコードなのか。
長っっっっっげぇ~~
だっっっっっるい~
ただ、if文の結果である
self.score += 1,
self.star_x = pyxel.rndi(0,160)
self.star_y = pyxel.rndi(0,120)
このコードは分かります。星に触ったらスコアが増えて、星のx座標とy座標がランダムに決定されて、再度配置される・・・という意味だよね。
問題は条件文の方です。しかも、↑の解説だと分かりにくい!
なので、もう一度、聞いてみます。
すると、
やっぱりややこしい笑
この辺はプログラミングの知識というより、算数とかの問題ですね。
なので、自分で絵を描いて理解してみようと思います。
まず、プレイヤーを8サイズの四角、星を4サイズの円としてみます。
そこで、先程のGPT君の回答にこんな説明が書いてありました。
これは調べてみて分かったのですが、プレイヤーや敵といったオブジェクトにもx座標、Y座標が決められているみたいです。
x=0は、左端!y=0は、天井!というのは第2回で勉強しましたね。基本的にはこの考え方がオブジェクトの座標にも適用されます。例えば、プレイヤーの四角であれば、左上の角の部分が(0,0)であり、このコードのself.player_xというのは、プレイヤーの(0,?)に当たる部分のことを指しています。
self.player_x = プレイヤーの(0,?)
というわけですね。self.player_yはxの逆なので、
self.player_y = プレイヤーの(?,0)
ということです。
肝心の当たり判定についてですが、コードでは以下のように書いてあります。
これを先程説明したプレイヤーの座標に当てはめてみると・・・
分かりやすいかな、と思って左上の角をself.player_xとしたのですが、プレイヤーの左端ならどこでもself.player_xです。
要は、四角の中に円が被さったことをここでは言ってるわけですね。
うん、普通に文字見ればそうやろ、と思う人が多数だとは思うのですが、私はこうして見やすくしてやっと分かりました。
self.player_y <= self.star_y <= self.player_y + 8も一緒ですね。プレイヤーの上端から下端の間に星が重なっていれば当たる、という判定をつける、なおかつ、これは同時に起こっている必要があるので、andを間に入れる・・・
ちょっと考えればすぐ分かるようなものでしたね!
やった!!!
あとは、もう簡単ですね。
もし、プレイヤーと星が重なったら・・・
self.score += 1・・・スコアを1増やす!
self.star_x = pyxel.rndi(0,160)・・・0〜160の範囲で新しい星のx座標を決める!
self.star_y = pyxel.rndi(0,120)・・・0〜120の範囲で新しい星のy座標を決める!
・・・・・・・・
これでここのコードは全て理解出来ました。
というより、ゲームの動きやロジックを決めるupdateメソッドの部分は全て理解しました!
バンザーイ!!!
あとは、実際に画面にキャラや背景を描きだすdrawメソッドの部分だけです。もう少しでプログラムが完成しますね。楽しみ〜
次回はプレイヤーと星、スコアを表示するdrawメソッドについて学んでいきます。