-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplayer.py
More file actions
129 lines (109 loc) · 4.07 KB
/
player.py
File metadata and controls
129 lines (109 loc) · 4.07 KB
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
from settings import *
import pygame as pg
import math
class Player:
def __init__(self, game):
self.game = game
self.x, self.y = PLAYER_POS
self.angle = PLAYER_ANGLE
self.shot = False
self.health = PLAYER_MAX_HEALTH
self.rel = 0
self.health_recovery_delay = 700
self.time_prev = pg.time.get_ticks()
# diagonal movement correction
self.diag_move_corr = 1 / math.sqrt(2)
def recover_health(self):
if self.check_health_recovery_delay() and self.health < PLAYER_MAX_HEALTH:
self.health += 1
def check_health_recovery_delay(self):
time_now = pg.time.get_ticks()
if time_now - self.time_prev > self.health_recovery_delay:
self.time_prev = time_now
return True
def check_game_over(self):
if self.health < 1:
self.game.game_ended = True
return True
return False
def check_victory(self):
if len([npc for npc in self.game.object_handler.npc_list if npc.alive]) == 0:
self.game.game_ended = True
return True
return False
def get_damage(self, damage):
self.health = max(0, self.health - damage) # Ensure health doesn't go below 0
self.game.object_renderer.player_damage()
self.game.sound.player_pain.play()
return self.check_game_over()
def single_fire_event(self, event):
if event.type == pg.MOUSEBUTTONDOWN:
if event.button == 1 and not self.shot and not self.game.weapon.reloading:
self.game.sound.shotgun.play()
self.shot = True
self.game.weapon.reloading = True
def movement(self):
sin_a = math.sin(self.angle)
cos_a = math.cos(self.angle)
dx, dy = 0, 0
speed = PLAYER_SPEED * self.game.delta_time
speed_sin = speed * sin_a
speed_cos = speed * cos_a
keys = pg.key.get_pressed()
num_key_pressed = -1
if keys[pg.K_w]:
num_key_pressed += 1
dx += speed_cos
dy += speed_sin
if keys[pg.K_s]:
num_key_pressed += 1
dx += -speed_cos
dy += -speed_sin
if keys[pg.K_a]:
num_key_pressed += 1
dx += speed_sin
dy += -speed_cos
if keys[pg.K_d]:
num_key_pressed += 1
dx += -speed_sin
dy += speed_cos
# diag move correction
if num_key_pressed:
dx *= self.diag_move_corr
dy *= self.diag_move_corr
self.check_wall_collision(dx, dy)
self.angle %= math.tau
def check_wall(self, x, y):
return (x, y) not in self.game.map.world_map
def check_wall_collision(self, dx, dy):
scale = PLAYER_SIZE_SCALE / self.game.delta_time
if self.check_wall(int(self.x + dx * scale), int(self.y)):
self.x += dx
if self.check_wall(int(self.x), int(self.y + dy * scale)):
self.y += dy
def draw(self):
pg.draw.line(self.game.screen, 'yellow', (self.x * 100, self.y * 100),
(self.x * 100 + WIDTH * math.cos(self.angle),
self.y * 100 + WIDTH * math.sin(self.angle)), 2)
pg.draw.circle(self.game.screen, 'green', (self.x * 100, self.y * 100), 15)
def mouse_control(self):
mx, my = pg.mouse.get_pos()
if mx < MOUSE_BORDER_LEFT or mx > MOUSE_BORDER_RIGHT:
pg.mouse.set_pos([HALF_WIDTH, HALF_HEIGHT])
self.rel = pg.mouse.get_rel()[0]
self.rel = max(-MOUSE_MAX_REL, min(MOUSE_MAX_REL, self.rel))
self.angle += self.rel * MOUSE_SENSITIVITY * self.game.delta_time
def update(self):
self.movement()
self.mouse_control()
self.recover_health()
if self.check_victory():
self.game.trigger_game_end('victory')
elif self.check_game_over():
self.game.trigger_game_end('game_over')
@property
def pos(self):
return self.x, self.y
@property
def map_pos(self):
return int(self.x), int(self.y)