Arcadeを使って、再度、追いかけっこゲーム
プロローグ
pygameを使って簡単な追いかけっこゲームを作ってみました。そこそこのものはできたのですが、二つの物の姿勢とか、衝突条件とかがいまいちかと思いました。自分でもう少しいじるのもありかと思いましたが、テストをしているので、あまり、いじくりまわすのもどうかと思い、新しいライブラリのArcadeを使ってみることにしました。同じ手順に沿ってやっていきます。
最初のプログラム
お願い
PythonのArcadeを使って、追いかけっこゲームを作ります。 ステージの大きさを480×360ピクセル、背景をDesert.png,cat.svg がbeetle.svgを追いかけます。
のお願いをしたけど、何かいろいろとエラーが出てきた。新規プログラムのつもりだけど、同じフォルダーではあれこれ前の内容が残っているらしい。
それで最初から次のお願いをした。
「Arcadeライブラリーを使って、背景がDesert.pngの画面を作ってください。」
import arcade
# 定数の定義
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 360
SCREEN_TITLE = "背景表示"
class BackgroundDisplay(arcade.Window):
def __init__(self):
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
arcade.set_background_color(arcade.color.AMAZON)
self.background = None
def setup(self):
# 背景画像の設定
self.background = arcade.load_texture("Desert.png")
def on_draw(self):
arcade.start_render()
arcade.draw_lrwh_rectangle_textured(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, self.background)
def main():
window = BackgroundDisplay()
window.setup()
arcade.run()
if __name__ == "__main__":
main()
気持ち、前のよりもきれいにできた感がある(^^♪
2番目のプログラム・・・cat,beetleの配置
次のお願いです。
「cat.svg を左上の方に、beetle.svgを右下の方に配置してください」
import arcade
# 定数の定義
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 360
SCREEN_TITLE = "背景表示"
class BackgroundDisplay(arcade.Window):
def __init__(self):
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
arcade.set_background_color(arcade.color.AMAZON)
self.background = None
self.cat_sprite = None
self.beetle_sprite = None
def setup(self):
# 背景画像の設定
self.background = arcade.load_texture("Desert.png")
# catの設定
self.cat_sprite = arcade.Sprite("cat.png", 0.2)
self.cat_sprite.center_x = 50
self.cat_sprite.center_y = 50
# beetleの設定
self.beetle_sprite = arcade.Sprite("beetle.png", 0.2)
self.beetle_sprite.center_x = SCREEN_WIDTH - 50
self.beetle_sprite.center_y = SCREEN_HEIGHT - 50
def on_draw(self):
arcade.start_render()
arcade.draw_lrwh_rectangle_textured(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, self.background)
self.cat_sprite.draw()
self.beetle_sprite.draw()
def main():
window = BackgroundDisplay()
window.setup()
arcade.run()
if __name__ == "__main__":
main()
cat.png,beetle.pngは外部アプリで透明化した。
左下、右上が間違っている。このArcadeは左下が原点(0,0)かな。
3番目のプログラム・・・cat,beetleの移動
次のお願いです。
「catはマウスに追従して、動き、beetleはcatを追い掛ける。cat、beetleの姿勢は常に前向きとする。」
これだけでは姿勢がうまくいかなかったので追加のお願い。
「catは常にマウスの方を向き、beetleは常にcatの方を向いてください」
さらにお願い。
「catはマウスから少し離れてついてきてください」
import arcade
import mah
# 定数の定義
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 360
SCREEN_TITLE = "追いかけっこゲーム"
class BackgroundDisplay(arcade.Window):
def __init__(self):
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
arcade.set_background_color(arcade.color.AMAZON)
self.background = None
self.cat_sprite = None
self.beetle_sprite = None
def setup(self):
# 背景画像の設定
self.background = arcade.load_texture("Desert.png")
# catの設定
self.cat_sprite = arcade.Sprite("cat.png", 0.2)
self.cat_sprite.center_x = 50
self.cat_sprite.center_y = 50
# beetleの設定
self.beetle_sprite = arcade.Sprite("beetle.png", 0.2)
self.beetle_sprite.center_x = SCREEN_WIDTH - 50
self.beetle_sprite.center_y = SCREEN_HEIGHT - 50
def on_draw(self):
arcade.start_render()
arcade.draw_lrwh_rectangle_textured(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, self.background)
self.cat_sprite.draw()
self.beetle_sprite.draw()
def on_update(self, delta_time):
# catをマウスから少し離れて追従させる
distance = 50 # マウスからの距離
angle = math.atan2(self._mouse_y - self.cat_sprite.center_y, self._mouse_x - self.cat_sprite.center_x)
self.cat_sprite.center_x = self._mouse_x - distance * math.cos(angle)
self.cat_sprite.center_y = self._mouse_y - distance * math.sin(angle)
# catがマウスの方を向く
angle = math.degrees(math.atan2(self._mouse_y - self.cat_sprite.center_y, self._mouse_x - self.cat_sprite.center_x))
self.cat_sprite.angle = angle
# beetleがcatを追いかける
if self.beetle_sprite.center_x < self.cat_sprite.center_x:
self.beetle_sprite.center_x += 3
if self.beetle_sprite.center_x > self.cat_sprite.center_x:
self.beetle_sprite.center_x -= 3
if self.beetle_sprite.center_y < self.cat_sprite.center_y:
self.beetle_sprite.center_y += 3
if self.beetle_sprite.center_y > self.cat_sprite.center_y:
self.beetle_sprite.center_y -= 3
# beetleがcatの方を向く
angle = math.degrees(math.atan2(self.cat_sprite.center_y - self.beetle_sprite.center_y, self.cat_sprite.center_x - self.beetle_sprite.center_x))
self.beetle_sprite.angle = angle
def on_mouse_motion(self, x, y, dx, dy):
self._mouse_x = x
self._mouse_y = y
def main():
window = BackgroundDisplay()
window.setup()
arcade.run()
if __name__ == "__main__":
main()
4番目のプログラム・・・衝突そして終了
最後のお願いは次の通りです。
「beetleがcatに追いついたら、ゲームオーバーです。10秒逃げ切れたらゲームクリアです。終了したら画面に、「ゲームクリア」「ゲームオーバ」と書いてそのままの状態で残してください」
import arcade
import math
import time # 追加
# 定数の定義
SCREEN_WIDTH = 480
SCREEN_HEIGHT = 360
SCREEN_TITLE = "追いかけっこゲーム"
class BackgroundDisplay(arcade.Window):
def __init__(self):
super().__init__(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
arcade.set_background_color(arcade.color.AMAZON)
self.background = None
self.cat_sprite = None
self.beetle_sprite = None
self.game_over = False
self.game_clear = False
self.start_time = None
def setup(self):
# 背景画像の設定
self.background = arcade.load_texture("Desert.png")
# catの設定
self.cat_sprite = arcade.Sprite("cat.png", 0.2)
self.cat_sprite.center_x = 50
self.cat_sprite.center_y = 50
# beetleの設定
self.beetle_sprite = arcade.Sprite("beetle.png", 0.2)
self.beetle_sprite.center_x = SCREEN_WIDTH - 50
self.beetle_sprite.center_y = SCREEN_HEIGHT - 50
self.start_time = time.time() # 修正正
def on_draw(self):
arcade.start_render()
arcade.draw_lrwh_rectangle_textured(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, self.background)
self.cat_sprite.draw()
self.beetle_sprite.draw()
if self.game_over:
arcade.draw_text("ゲームオーバー", SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2,
arcade.color.RED, 30, anchor_x="center", anchor_y="center", bold=True)
elif self.game_clear:
arcade.draw_text("ゲームクリア", SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2,
arcade.color.GREEN, 30, anchor_x="center", anchor_y="center", bold=True)
def on_update(self, delta_time):
if self.game_over or self.game_clear:
return
# catをマウスに追従させる
speed = 5 # catの速度
angle = math.atan2(self._mouse_y - self.cat_sprite.center_y, self._mouse_x - self.cat_sprite.center_x)
self.cat_sprite.center_x += speed * math.cos(angle)
self.cat_sprite.center_y += speed * math.sin(angle)
# catがマウスの方を向く
angle = math.degrees(math.atan2(self._mouse_y - self.cat_sprite.center_y, self._mouse_x - self.cat_sprite.center_x))
self.cat_sprite.angle = angle
# beetleがcatを追いかける
if self.beetle_sprite.center_x < self.cat_sprite.center_x:
self.beetle_sprite.center_x += 3
if self.beetle_sprite.center_x > self.cat_sprite.center_x:
self.beetle_sprite.center_x -= 3
if self.beetle_sprite.center_y < self.cat_sprite.center_y:
self.beetle_sprite.center_y += 3
if self.beetle_sprite.center_y > self.cat_sprite.center_y:
self.beetle_sprite.center_y -= 3
# beetleがcatの方を向く
angle = math.degrees(math.atan2(self.cat_sprite.center_y - self.beetle_sprite.center_y, self.cat_sprite.center_x - self.beetle_sprite.center_x))
self.beetle_sprite.angle = angle
# 衝突判定
if arcade.check_for_collision(self.cat_sprite, self.beetle_sprite):
self.game_over = True
# 10秒経過したか確認
if time.time() - self.start_time >= 10: # 修正
self.game_clear = True
def on_mouse_motion(self, x, y, dx, dy):
self._mouse_x = x
self._mouse_y = y
def main():
window = BackgroundDisplay()
window.setup()
arcade.run()
if __name__ == "__main__":
main()
いろいろと細かいとこもいじったけれど、いまいちの部分もある。
エピローグ
ちょっと、気になってたとこ、姿勢と衝突が向上したように思う。
selfとかついて、見慣れないけど、慣れたらいいのかな。もう自分で書くという気もなくなっているので、見慣れないのはいいのだけど理解は必要だろう。子供たちにもある程度はpygameを使ってもらって、プログラム慣れしたらArcadeを使ってもらうのがいいかな。好き好きもあると思うけど。
この記事が気に入ったらサポートをしてみませんか?