見出し画像

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.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)
このコードをPython初心者にもわかりやすく教えてください

さてさて、どんなコードなのか。

このコードは、プレイヤーとスターが衝突したかどうかを確認し、衝突していた場合にスコアを増やし、スターの位置を新しいランダムな位置に変更する処理を行っています。これを分かりやすく説明します。

目的

衝突判定
: プレイヤーがスターに触れたかどうかを確認します。
スコア更新: プレイヤーがスターに触れたらスコアを1増やします。
スターの再配置: スターの位置を画面内のランダムな場所に再設定します。

条件文self.player_x <= self.star_x <= self.player_x + 8
self.player_x: プレイヤーの左上の x 座標です。
self.player_x + 8: プレイヤーの右上の x 座標です(プレイヤーの幅が 8 ピクセルの場合)。
self.star_x: スターの x 座標です。
この条件は、スターの x 座標がプレイヤーの左端から右端の間にあるかどうかを確認します。
self.player_y <= self.star_y <= self.player_y + 8
self.player_y: プレイヤーの左上の y 座標です。
self.player_y + 8: プレイヤーの左下の y 座標です(プレイヤーの高さが 8 ピクセルの場合)。
self.star_y: スターの y 座標です。
この条件は、スターの y 座標がプレイヤーの上端から下端の間にあるかどうかを確認します。
and 演算子
上記の2つの条件を両方とも満たす場合に、if 文の中のブロックが実行されます。つまり、スターがプレイヤーの領域内にある場合です。


条件が真の場合に実行されるコードself.score += 1
self.score はスコアを表す変数です。このコードはスコアを1増やします。
self.star_x = pyxel.rndi(0, 160)
pyxel.rndi(0, 160) は 0 から 159 の間でランダムな整数を生成します。self.star_x にこの値を代入することで、スターの x 座標を画面の左端から右端の間のどこかにランダムに設定します。
self.star_y = pyxel.rndi(0, 120)
pyxel.rndi(0, 120) は 0 から 119 の間でランダムな整数を生成します。self.star_y にこの値を代入することで、スターの y 座標を画面の上端から下端の間のどこかにランダムに設定します。


まとめプレイヤーがスターに触れたかどうかを確認する。
触れた場合、スコアを1増やす。
スターの位置を画面内のランダムな位置に再設定する。


これで、このコードの目的と動作が理解できたと思います。もし他にも質問があれば教えてくださいね。

長っっっっっげぇ~~

だっっっっっるい~

ただ、if文の結果である

self.score += 1,
self.star_x = pyxel.rndi(0,160)
self.star_y = pyxel.rndi(0,120)

このコードは分かります。星に触ったらスコアが増えて、星のx座標とy座標がランダムに決定されて、再度配置される・・・という意味だよね。

問題は条件文の方です。しかも、↑の解説だと分かりにくい!
なので、もう一度、聞いてみます。

if (self.player_x <= self.star_x <= self.player_x + 8 and self.player_y <= self.star_y <= self.player_y + 8): すみません、こちらの内容が先程の説明では理解できませんでした。もう一度丁寧に教えてください。

すると、

もちろんです。if (self.player_x <= self.star_x <= self.player_x + 8 and self.player_y <= self.star_y <= self.player_y + 8) の条件文は、プレイヤーがスターに触れたかどうかを確認するためのものです。これを詳細に分解して説明します。

条件文の詳細

この条件文は2つの部分に分かれています。それぞれを分解してみましょう。

1. self.player_x <= self.star_x <= self.player_x + 8

この部分は、スターの x 座標がプレイヤーの左端から右端の間にあるかどうかを確認しています。

self.player_x: プレイヤーの左端の x 座標です。
self.star_x: スターの x 座標です。
self.player_x + 8: プレイヤーの右端の x 座標です(プレイヤーの幅が 8 ピクセルの場合)。


この条件が意味するのは、スターの x 座標がプレイヤーの左端から右端の間にあるかどうかです。
具体的には、以下のように解釈できます:

self.player_x <= self.star_x: スターの x 座標がプレイヤーの左端以上である。
self.star_x <= self.player_x + 8: スターの x 座標がプレイヤーの右端以下である。


この2つの条件が両方とも満たされる場合、スターの x 座標はプレイヤーの横幅内にあることになります。

2. self.player_y <= self.star_y <= self.player_y + 8

この部分は、スターの y 座標がプレイヤーの上端から下端の間にあるかどうかを確認しています。self.player_y: プレイヤーの上端の y 座標です。
self.star_y: スターの y 座標です。
self.player_y + 8: プレイヤーの下端の y 座標です(プレイヤーの高さが 8 ピクセルの場合)。


この条件が意味するのは、スターの y 座標がプレイヤーの上端から下端の間にあるかどうかです。具体的には、以下のように解釈できます:self.player_y <= self.star_y: スターの y 座標がプレイヤーの上端以上である。
self.star_y <= self.player_y + 8: スターの y 座標がプレイヤーの下端以下である。


この2つの条件が両方とも満たされる場合、スターの y 座標はプレイヤーの縦幅内にあることになります。

やっぱりややこしい笑

この辺はプログラミングの知識というより、算数とかの問題ですね。

なので、自分で絵を描いて理解してみようと思います。

見づらいのは許してね

まず、プレイヤーを8サイズの四角、星を4サイズの円としてみます。

そこで、先程のGPT君の回答にこんな説明が書いてありました。

self.player_x: プレイヤーの左端の x 座標です。

これは調べてみて分かったのですが、プレイヤーや敵といったオブジェクトにもx座標、Y座標が決められているみたいです。

四角のサイズは8です

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.star_x <= self.player_x + 8

これを先程説明したプレイヤーの座標に当てはめてみると・・・

自分でも見づらいと思う
しかも下の文も間違ってるし・・・

分かりやすいかな、と思って左上の角を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メソッドについて学んでいきます。

いいなと思ったら応援しよう!

この記事が参加している募集