-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplayer.py
303 lines (178 loc) · 8.82 KB
/
player.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
#init stuff
import pygame
import math
from laser import Laser
pygame.init()
#makes a class!
class Player:
#this method is always called when a new instance of a class is created
def __init__(self, img, laser_img, x, y):
#creating all the values the player will need
self.img = img
self.laser_img = laser_img
self.x = x
self.y = y
self.x_velocity = 0
self.y_velocity = 0
self.previous_x_velocity = 0
self.previous_y_velocity = 0
self.angle = 0
self.angle_velocity = 0
self.angle_friction = 1 / 20
self.turning_speed = 3
self.turning_right = False
self.turning_left = False
self.moving_forward = False
self.slowing_down = False
self.speed = 0
self.acceleration = 0.07
self.top_speed = 6
self.current_vector = self.angle
self.lasers = []
self.shot_cooldown = 10
self.laser_timer = 0
self.dead = False
self.ammo = 7
#builds a laser and shoots it
def shoot(self, sound, channel):
if self.laser_timer == 0 and self.ammo > 0:
new_laser = Laser(self.laser_img, self.x, self.y, self.angle, 15)
self.lasers.append(new_laser)
self.laser_timer = self.shot_cooldown
channel.play(sound)
self.ammo -= 1
#this needs to be stuck into the event checking loop
def get_input(self, event, sound, channel):
#sets boolean values of moving checks for the three different
#types of movement
if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
self.turning_right = True
print("player has begun turning right")
elif event.type == pygame.KEYUP and event.key == pygame.K_RIGHT:
self.turning_right = False
print("player has stopped turning right")
elif event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
self.turning_left = True
print("player has begun turning left")
elif event.type == pygame.KEYUP and event.key == pygame.K_LEFT:
self.turning_left = False
print("player has stopped turning left")
elif event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
self.moving_forward = True
print("player has begun moving forward")
elif event.type == pygame.KEYUP and event.key == pygame.K_UP:
self.moving_forward = False
print("player has stopped moving forward")
elif event.type == pygame.KEYUP and event.key == pygame.K_SPACE:
self.shoot(sound, channel)
#draw method, must be placed after background is drawn but before display is updated
def draw(self, screen, camera):
#rotates the image to be the correct angle
rotated_img = pygame.transform.rotate(self.img, self.angle)
#displays the rotated image at the player's position
screen.blit(rotated_img, (self.x - camera.x_offset - int(rotated_img.get_width() / 2), self.y - camera.y_offset - int(rotated_img.get_height() / 2)))
#displays the child lasers if the player is alive
for laser in self.lasers:
if self.dead == False:
laser.draw(screen, camera)
#Draws the HUD elements
def HUD(self, screen):
#draws ammo bars
for i in range(0, self.ammo):
pygame.draw.rect(screen, (104, 233, 255), pygame.Rect(4, 344 + (28 * i), 20, 20))
#update method, using some trig to get the angles right for movement
def update(self, screen_width, screen_height):
#sets angle velocity based on whether or not the player is turning right or left
if self.turning_right and not self.turning_left:
self.angle_velocity = -self.turning_speed
elif self.turning_left and not self.turning_right:
self.angle_velocity = self.turning_speed
#adds the angle velocity to the angle value
self.angle += self.angle_velocity
#gradually decrease angle velocity
if self.angle_velocity != 0:
if self.angle_velocity > 0:
if self.angle_velocity - self.angle_friction <= 0:
self.angle_velocity = 0
else:
self.angle_velocity -= self.angle_friction
else:
if self.angle_velocity + self.angle_friction >= 0:
self.angle_velocity = 0
else:
self.angle_velocity += self.angle_friction
if self.angle_velocity > 0:
if self.angle_velocity - self.angle_friction < 0:
self.angle_velocity = 0
else:
self.angle_velocity -= self.angle_friction
else:
if self.angle_velocity + self.angle_friction > 0:
self.angle_velocity = 0
else:
self.angle_velocity += self.angle_friction
#accelerates the velocity of the player based on its movement state
if self.moving_forward == True and self.slowing_down == False:
self.current_vector = self.angle
if self.speed < self.top_speed:
if self.speed + self.acceleration >= self.top_speed:
self.speed = self.top_speed
else:
self.speed += self.acceleration
else:
if self.speed > 0:
if self.speed - self.acceleration <= 0:
self.speed = 0
else:
self.speed -= self.acceleration
#uses trig to get which way to move given the angle and speed
self.x_velocity = self.speed * math.sin(math.radians(self.current_vector + 180))
self.y_velocity = self.speed * math.cos(math.radians(self.current_vector + 180))
#adds the previous velocity to the current velocity
self.x_velocity += self.previous_x_velocity
self.y_velocity += self.previous_y_velocity
#caps the speed
if self.speed > 0:
total_speed = math.sqrt((self.x_velocity ** 2) + (self.y_velocity ** 2))
if total_speed > self.top_speed:
vector = math.atan2(self.y_velocity, self.x_velocity)
self.x_velocity = self.top_speed * math.cos(vector)
self.y_velocity = self.top_speed * math.sin(vector)
#stores the current velocity for next frame
self.previous_x_velocity = self.x_velocity
self.previous_y_velocity = self.y_velocity
#updates player position
self.x += self.x_velocity
self.y += self.y_velocity
#keeps player inside the play area
if self.x >= screen_width * 2:
self.x = screen_width * 2
self.previous_x_velocity = 0
elif self.x <= 0:
self.x = 0
self.previous_x_velocity = 0
if self.y >= screen_height * 2:
self.y = screen_height * 2
self.previous_y_velocity = 0
elif self.y <= 0:
self.y = 0
self.previous_y_velocity = 0
#updates child lasers and checks if they need deletion
for laser in self.lasers:
laser.update()
if laser.age >= 50:
self.lasers.remove(laser)
#decreases laser timer
if self.laser_timer != 0:
self.laser_timer -= 1
#method for detecting asteroid collisions
def detect_collision(self, asteroid):
player_collider = pygame.Rect(0, 0, 40, 40)
player_collider.centerx = self.x
player_collider.centery = self.y
asteroid_collider = pygame.Rect(0, 0, 40, 40)
asteroid_collider.centerx = asteroid.x
asteroid_collider.centery = asteroid.y
if player_collider.colliderect(asteroid_collider):
print("asteroid has collided with player")
self.dead = True