前回土台となるウィンドウが出せるようになったから、次はウィンドウ内の真ん中にホッケーを配置してみよう!
今回はシンプルに「円」をホッケーとして扱うよ
円を表示するから、関数「draw」の中に作るんだね!
そうだね!
「円」を配置する場合は「pyxel.circ(円の中心のx座標, 円の中心のy座標, 円の半径, 円の色)」ってするよ
def draw(self):
pyxel.cls(0) # 背景色(黒)
pyxel.circ(pyxel.width // 2, pyxel.height // 2, 4, 8) # 赤い円(色番号8)
円の中心の座標で考えられるのは分かりやすいね!
ちなみに、xy座標(0, 0)はウィンドウ内の一番左上だから覚えておいてね
おお!ちゃんと真ん中に円が現れた!
ちゃんと表示されたね!あとは更新する度に、円の中心の「x座標」と「y座標」が変化すれば動くようになるよ
ということは、それぞれの座標用の変数を用意すれば良いんだね!
そういうこと!
じゃあ円を動かす準備として、インスタンス変数「self.x」「self.y」を用意して、さっきの「pyxel.circ()」の引数を書き換えよう
class App:
def __init__(self):
pyxel.init(160, 120, title="ホッケーゲーム")
self.x = pyxel.width // 2 # 円のx座標の変数
self.y = pyxel.height // 2 # 円のy座標の変数
pyxel.run(self.update, self.draw)
def update(self):
pass
def draw(self):
pyxel.cls(0)
pyxel.circ(self.x, self.y, 4, 8) # 引数を変更
変更完了!起動してみたけど問題なさそう
おっけー!
じゃあ次は、円の座標に変化をつけるために関数「update」の中で、それぞれのインスタンス変数が「+1」されるようにしよう
def update(self):
self.x += 1
self.y += 1
おお!右下に向かって円が動いt...って画面の外に消えていっちゃったよ!?
これは、別にウィンドウの端に壁があるわけじゃないから、「ウィンドウの端に来た時」の処理を作る必要があるんだ
なんかややこしそうな予感が...汗
そしたら、図で説明してみよう
なるほど
ということは、ウィンドウの範囲を指定したif文を作る必要があるんだね!
ここで気を付けないといけない点は、「円には半径分の大きさがある」ことだね
そうか、普通に円の中心座標がウィンドウからはみ出してるかをチェックしても、実際は半分はみ出しちゃうのか
そういうことだね
だから、「ウィンドウの端より内側に円の半径分小さくなった見えない壁がある」って考え方で判定を作るよ
なんとなくイメージしやすくなった!
じゃあ次はこのイメージを基準に「ホッケーがウィンドウの端に来たら跳ね返す」プログラムにしていくよ
「跳ね返す」っていうのは具体的にどうしたら良いの??
ウィンドウの左右の端に来た場合は「self.x」、上下の端に来た時は「self.y」の値が変化する処理のプラスマイナスが逆になれば良いんだ
なるほど
でも、それってどうやるの?
関数「update」内で変化している量は「+1」になってるけど、これをフレームごとに変化する速度「self.vx」「self.vy」にして、端に来た時に「-1の掛け算をする」ことでいけるようになるよ!
そうか!-1を掛ければプラスマイナスが逆になるもんね!
なんとなくやり方が分かったところで、実際にプログラムに反映してみようか
import pyxel
class App:
def __init__(self):
pyxel.init(160, 120, title="ホッケーゲーム")
self.x = pyxel.width // 2
self.y = pyxel.height // 2
self.vx = 1 # 速度(x方向)
self.vy = 1 # 速度(y方向)
self.r = 4 # 半径
pyxel.run(self.update, self.draw)
def update(self):
self.x += self.vx
self.y += self.vy
# ウィンドウの端に当たったら反射(跳ね返る)
if self.x <= self.r or self.x >= pyxel.width - self.r:
self.vx *= -1
if self.y <= self.r or self.y >= pyxel.height - self.r:
self.vy *= -1
def draw(self):
pyxel.cls(0)
pyxel.circ(self.x, self.y, self.r, 8) # 半径もインスタンス変数に変更
App()
おおーーちゃんと跳ね返るようになった!なんか、動きが付くと一気にゲームっぽくなったね
そうでしょー
