Move to Mouse Click
In this example, the tank turns and moves towards where ever the user clicks the mouse.
turn_and_move.py
1"""
2Turn and Move Example.
3
4Right-click to cause the tank to move to that point.
5
6If Python and Arcade are installed, this example can be run from the command line with:
7python -m arcade.examples.turn_and_move
8"""
9import math
10import arcade
11
12WINDOW_WIDTH = 1280
13WINDOW_HEIGHT = 720
14WINDOW_TITLE = "Turn and Move Example"
15
16# Image might not be lined up right, set this to offset
17IMAGE_ROTATION = -90
18
19
20class Player(arcade.Sprite):
21 """
22 Sprite that turns and moves
23 """
24 def __init__(self):
25 super().__init__(":resources:images/topdown_tanks/tank_green.png")
26
27 # Destination point is where we are going
28 self._destination_point = None
29
30 # Max speed px / s
31 self.speed = 300
32
33 # what percent of the angle do we move by each frame
34 self.rot_speed = 0.1
35
36 @property
37 def destination_point(self):
38 return self._destination_point
39
40 @destination_point.setter
41 def destination_point(self, destination_point):
42 self._destination_point = destination_point
43 self.change_x = 0.0
44 self.change_y = 0.0
45
46 def update(self, delta_time: float = 1 / 60):
47 """ Update the player """
48
49 # If we have no destination, don't go anywhere.
50 if not self._destination_point:
51 self.change_x = 0
52 self.change_y = 0
53 return
54
55 # Position the start at our current location
56 start_x = self.center_x
57 start_y = self.center_y
58
59 # Get the destination location
60 dest_x = self._destination_point[0]
61 dest_y = self._destination_point[1]
62
63 # Do math to calculate how to get the sprite to the destination.
64 # Calculation the angle in radians between the start points
65 # and end points. This is the angle the player will travel.
66 target_angle = arcade.math.get_angle_degrees(start_x, start_y, dest_x, dest_y)
67 current_angle = self.angle - IMAGE_ROTATION
68
69 new_angle = arcade.math.lerp_angle(current_angle, target_angle, self.rot_speed)
70
71 self.angle = new_angle + IMAGE_ROTATION
72 angle_diff = abs(target_angle - new_angle)
73 if angle_diff < 0.1 or 359.9 < angle_diff:
74 self.angle = target_angle + IMAGE_ROTATION
75 target_radians = math.radians(target_angle)
76 self.change_x = math.cos(-target_radians) * self.speed
77 self.change_y = math.sin(-target_radians) * self.speed
78
79 # Fine-tune our change_x/change_y if we are really close to destination
80 # point and just need to set to that location.
81 traveling = False
82 if abs(self.center_x - dest_x) < abs(self.change_x * delta_time):
83 self.center_x = dest_x
84 else:
85 self.center_x += self.change_x * delta_time
86 traveling = True
87
88 if abs(self.center_y - dest_y) < abs(self.change_y * delta_time):
89 self.center_y = dest_y
90 else:
91 self.center_y += self.change_y * delta_time
92 traveling = True
93
94 # If we have arrived, then cancel our destination point
95 if not traveling:
96 self._destination_point = None
97
98
99class GameView(arcade.View):
100 """
101 Main application class.
102 """
103
104 def __init__(self):
105 super().__init__()
106
107 self.background_color = arcade.color.SAND
108
109 self.player_sprite = None
110
111 # Sprite Lists
112 self.player_list = None
113
114 def setup(self):
115 """ Set up the game variables. Call to re-start the game. """
116
117 # Sprite Lists
118 self.player_list = arcade.SpriteList()
119 self.player_sprite = Player()
120 self.player_sprite.center_x = 300
121 self.player_sprite.center_y = 300
122 self.player_list.append(self.player_sprite)
123
124 def on_draw(self):
125 """
126 Render the screen.
127 """
128
129 # This command should happen before we start drawing. It will clear
130 # the screen to the background color, and erase what we drew last frame.
131 self.clear()
132
133 # Call draw() on all your sprite lists below
134 self.player_list.draw()
135
136 def on_update(self, delta_time):
137 """
138 All the logic to move, and the game logic goes here.
139 """
140 self.player_list.update(delta_time)
141
142 def on_mouse_press(self, x, y, button, key_modifiers):
143 """
144 Called when the user presses a mouse button.
145 """
146 if button == arcade.MOUSE_BUTTON_RIGHT:
147 self.player_sprite.destination_point = x, y
148
149
150def main():
151 """ Main function """
152 # Create a window class. This is what actually shows up on screen
153 window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE)
154
155 # Create and setup the GameView
156 game = GameView()
157 game.setup()
158
159 # Show GameView on screen
160 window.show_view(game)
161
162 # Start the arcade game loop
163 arcade.run()
164
165if __name__ == "__main__":
166 main()