1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonのarcadeでクリックでユニットをスムーズに移動

Posted at

コードの実行結果

初期画面
スクリーンショット 2024-11-04 21.12.25.png

画面上の適当な位置を押すとユニットが移動
スクリーンショット 2024-11-04 21.12.38.png

コードの概要

マウスをクリックした位置に作成したユニットが移動します。
ユニットの.png画像は適宜好きなものを使ってください。

コード

import arcade
import arcade.color
import arcade.key
import math

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_TITLE = "ユニット移動の例"
UNIT_FILEPATH = "xxxx.png"
UNIT_SCALE = 0.5
UNIT_SPEED = 3

class MyUnit(arcade.Sprite):
    def __init__(self, filename, scale, speed):
        super().__init__(filename, scale)
        self.speed = speed
        self.destination_x = None # destinationは方向という意味。
        self.destination_y = None
    
    def update(self):
        # 方向先が指定されたら、ユニットを移動
        if self.destination_x is not None and self.destination_y is not None:
            # 移動方向の正規化
            """
            現在地とマウスクリック時の距離を計算し、移動するときに反映
            
            # Geminiさんに移動の正規化をするようにした理由を説明
            ユニットがクリックされた地点へ一定の速度で滑らかに移動するようにするためです。
            正規化によって、移動ベクトル (dx, dy) の長さを1に保ち
            方向のみを表す単位ベクトルに変換しています。
            """
            dx = self.destination_x - self.center_x
            dy = self.destination_y - self.center_y
            distance = math.sqrt(dx**2 + dy**2)
            
            if distance > self.speed:
                # 移動方向を正規化
                # 移動のスケールをmax1にしている
                dx = dx/distance
                dy = dy/distance
                
                # ユニットの移動
                self.center_x = self.center_x + dx
                self.center_y = self.center_y + dy
            else:
                self.center_x = self.destination_x
                self.center_y = self.destination_y            
                # 初期値に戻す
                self.destination_x = None
                self.destination_y = None

class MyWindow(arcade.Window):
    def __init__(self, width, height, title):
        super().__init__(width, height, title)
        self.unit_list = arcade.SpriteList()
        
    def setup(self):
        # 背景の設定
        arcade.set_background_color(arcade.color.AQUAMARINE)
        
        # ユニットの設定
        self.unit = MyUnit(filename=UNIT_FILEPATH, scale=UNIT_SCALE, speed=UNIT_SPEED)
        self.unit.center_x = SCREEN_WIDTH / 2
        self.unit.center_y = SCREEN_HEIGHT / 2
        self.unit_list.append(self.unit)
    
    def on_draw(self):
        arcade.start_render()
        self.unit_list.draw()
    
    def on_mouse_press(self, x, y, button, modifiers):
        self.unit.center_x = x
        self.unit.center_y = y
    
    def on_update(self, delta_time):
        self.unit.update()
    
    def on_key_press(self, symbol, modifiers):
        if symbol == arcade.key.Q:
            print("Q key press")
            arcade.close_window()

def main():
    mywindow = MyWindow(width=SCREEN_WIDTH, height=SCREEN_HEIGHT, title=SCREEN_TITLE)
    mywindow.setup()
    arcade.run()

if __name__ == "__main__":
    main()

ほかにもこんなのやってます

参考文献

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?