次はプレイヤーが操作するための「バー」を作っていくよ!
バーってことは長方形を作る感じ??
その通り!
「長方形」を配置する場合は「pyxel.rect(x座標, y座標, 幅, 高さ, 色)」で出来るよ
この時の「x座標」「y座標」は長方形の左上が基準になる点に気を付けてね
def draw(self):
pyxel.cls(0)
pyxel.circ(pyxel.width // 2, pyxel.height // 2, 4, 8)
pyxel.rect(10, 50, 5, 20, 11) # これを追加
座標の基準が円の時と違うのは気を付けないとだね
ちなみにy軸座標の「50」って値は、初期状態でバーがウィンドウの中央ラインに来るように「ウィンドウの高さの半分 - バーの高さの半分」という計算で求めているよ
おお!なるほど!適当じゃないんだね
次はバーのy座標を管理する「self.bar_y」を用意するよ!
ついでに、ウィンドウの端を判定するために、バーの高さを管理する「self.bar_height」も追加しておくよ
class App:
def __init__(self):
pyxel.init(160, 120, title="ホッケーゲーム")
self.x = pyxel.width // 2
self.y = pyxel.height // 2
self.vx = 1
self.vy = 1
self.r = 4
self.bar_height = 20 # バーの高さ
self.bar_y = (pyxel.height - self.bar_height) // 2 # バーのy座標
pyxel.run(self.update, self.draw)
# 一部省略
def draw(self):
pyxel.cls(0)
pyxel.circ(self.x, self.y, self.r, 8)
pyxel.rect(10, self.bar_y, 5, self.bar_height, 11) # y座標と高さをインスタンス変数に変更
ちゃんと計算式で座標を設定してるの、ちょっとカッコいい...
起動してみたけど問題なさそうだね
ばっちりだね!
そしたら、今の変数を利用して関数「update」の中で「バーを操作するプログラム」を追加しよう
今回はキーボード入力で操作するために「pyxel.btn(ボタンの種類)」を使うよ!
ボタンの種類はどうやって指定するの?そのまま文字列で「"A"」って感じ??
ボタンの種類を指定する場合は「pyxel.A」って感じで、「pixel.大文字」で指定にするよ!
今回は上下の矢印キーを使いたいから「pyxel.UP」「pixel.DOWN」だね
アルファベット以外はキーの名前を全部大文字で指定するんだね!
あとはif文で、上下キーが入力された時に「self.bar_y」が増減するようにすればOK
def update(self):
self.x += self.vx
self.y += self.vy
# 矢印の上キーが押されたら上へ移動
if pyxel.btn(pyxel.KEY_UP):
self.bar_y -= 2
# 矢印の下キーが押されたら下へ移動
if pyxel.btn(pyxel.KEY_DOWN):
self.bar_y += 2
# 以下省略
おおー!ちゃんと上下に動いた!!
上手くいったみたいだね!今回は1フレーム当たりに動く量を「2」にしてるけど、自分なりにちょうど良い量に調整してみたら良いからね
分かった!ところで、ずっと下か上を押しっぱなしにしてるとウィンドウの外に行っちゃうけど、もし外に出ないようにしたい場合はホッケーの時みたいにif文で設定したら良いの??
その方法でも良いんだけど、今回は跳ね返るわけじゃなくて「それ以上先に行かないようにする」から、もう少し簡単な方法で管理してみるよ
簡単な方法?つまり、if文を使わないってこと??
そういうことだね
バーの基準点はバーの左上になるから、y座標の移動範囲は最小が「0」、最大が「ウィンドウの高さ - バーの高さ」になるよね
その説明をするってことは、「最小」と「最大」を出してくれる関数があるんだねっ!!
その通り!「最小」と「最大」はそれぞれ、「min()」と「max()」を使うことで簡単に出してくれるようになるんだ
じゃあ、現在のバーの位置「self.bar_y」と比較する形になるんだね
ここでちょっとした問題!
「バーの位置が0よりも小さい場合、バーの位置を0にする」時は、「min()」と「max()」のどっちを使ったら良いと思う?
え?そんなの「0よりも小さい場合」だから、「min()」を使えば...
あれ?そうするとバーの位置の値が選ばれちゃってダメだから「max()」を使わないといけない??
そうだね!「max()」を使うのが正解だよ!!ちょっと混乱しちゃうでしょ
小さい値を気にしないといけないのに「max()」を使うってちょっと変な感じだね
「最終的にどうしたいか?」が大事だから、このあたりのイメージはしっかり持てるようになっておこうね
ということで、バーがウィンドウの外に出ないようにするプログラムを、さっきのif文の下に追加してみよう!
# 矢印の上キーが押されたら上へ移動
if pyxel.btn(pyxel.KEY_UP):
self.bar_y -= 2
# 矢印の下キーが押されたら下へ移動
if pyxel.btn(pyxel.KEY_DOWN):
self.bar_y += 2
# 画面外に出ないように制限
self.bar_y = max(0, min(pyxel.height - self.bar_height, self.bar_y))
お、ちゃんとウィンドウの外に出なくなった!
もちろんif文で作っても良いけど、今回みたいに「シンプルに作れないか」「便利な関数はないか」とかを意識できるようになろうね
そうだね、ちょっと意識してみるよ!
この時点での全体のプログラム
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 # 半径
self.bar_height = 20 # バーの高さ
self.bar_y = (pyxel.height - self.bar_height) // 2 # バーのy座標
pyxel.run(self.update, self.draw)
def update(self):
self.x += self.vx
self.y += self.vy
# 矢印の上キーが押されたら上へ移動
if pyxel.btn(pyxel.KEY_UP):
self.bar_y -= 2
# 矢印の下キーが押されたら下へ移動
if pyxel.btn(pyxel.KEY_DOWN):
self.bar_y += 2
# 画面外に出ないように制限
self.bar_y = max(0, min(pyxel.height - self.bar_height, self.bar_y))
# ウィンドウの端に当たったら反射(跳ね返る)
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)
pyxel.rect(10, self.bar_y, 5, self.bar_height, 11) # y座標と高さをインスタンス変数に変更
App()
