見出し画像

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()
大きさも480×360で作られた。画像の大きさか?

気持ち、前のよりもきれいにできた感がある(^^♪

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,beetleを0.2倍に縮小

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を使ってもらうのがいいかな。好き好きもあると思うけど。


この記事が気に入ったらサポートをしてみませんか?