-
Notifications
You must be signed in to change notification settings - Fork 0
/
player.py
157 lines (123 loc) · 4.71 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
import sys
import pygame
from utils import Debug
from utils import Timer
from support import import_folder
from settings import *
class Player(pygame.sprite.Sprite):
def __init__(self, pos, group):
super().__init__(group)
# * Image Attributes * #
self.animations = {}
self.import_assets()
self.animation_status = "idle"
self.frame_index = 0
self.image = self.animations[self.animation_status][self.frame_index]
self.rect = self.image.get_rect(center=pos)
self.z = LAYERS["main"]
# * Movement Attributes * #
self.direction = pygame.math.Vector2()
self.pos = pygame.math.Vector2(self.rect.center)
# Speed Attributes
self.speed_x = 0
self.speed_y = 0
self.acceleration = 10
self.max_speed = 200
# * Timers * #
self.timers = {
# 函数后不应有 "()"
"jump": Timer(1000, self.done_jump)
}
Debug(DEBUG_MODE) << "Inited Player" << "\n"
def update(self, dt):
super().update()
self.respond_input()
self.horizontal_move(dt)
self.vertical_move(dt)
self.update_timers()
# Animation
self.switch_frame(dt)
self.switch_status()
def update_timers(self):
for timer in self.timers.values():
timer.update()
def respond_input(self):
if not self.timers["jump"].active:
# Better than "event.type == KEYDOWN"
keys = pygame.key.get_pressed()
# * Horizontal Movement * #
if keys[pygame.K_LEFT]:
self.animation_status = "walk"
self.direction.x = -1
if self.speed_x <= self.max_speed:
self.speed_x += self.acceleration
elif keys[pygame.K_RIGHT]:
self.animation_status = "walk"
self.direction.x = 1
if self.speed_x <= self.max_speed:
self.speed_x += self.acceleration
else:
if self.speed_x >= 0:
self.speed_x -= self.acceleration
else:
self.direction.x = 0
# * Vertical Movement * #
if keys[pygame.K_UP]:
self.direction.y = -1
if self.speed_y <= self.max_speed:
self.speed_y += self.acceleration
elif keys[pygame.K_DOWN]:
self.direction.y = 1
if self.speed_y <= self.max_speed:
self.speed_y += self.acceleration
else:
if self.speed_y >= 0:
self.speed_y -= self.acceleration
else:
self.direction.y = 0
# * Other Movement * #
if keys[pygame.K_SPACE]:
self.timers["jump"].activate()
self.direction = pygame.math.Vector2()
self.frame_index = 0 # Start a new animation
else:
pass
def horizontal_move(self, dt):
# Vector Normalize
# 获取单位向量, 防止斜走速度为根号2倍
if self.direction.magnitude() > 0:
self.direction = self.direction.normalize()
# Debug(DEBUG_MODE) << self.direction << "\n"
self.pos.x += self.direction.x * self.speed_x * dt
self.rect.centerx = self.pos.x
def vertical_move(self, dt):
if self.direction.magnitude() > 0:
self.direction.normalize()
self.pos.y += self.direction.y * self.speed_y * dt
self.rect.centery = self.pos.y
def import_assets(self):
self.animations = {
"idle": [],
"walk": [],
"jump": []
}
for animation in self.animations.keys():
full_path = PATH_PLAYER + animation
self.animations[animation] = import_folder(full_path)
def switch_frame(self, dt):
# 常数 4 控制动画帧速度
self.frame_index += 4 * dt
if self.frame_index >= len(self.animations[self.animation_status]):
self.frame_index = 0
# 必须在下一行使用 int()
self.image = self.animations[self.animation_status][int(self.frame_index)]
def switch_status(self):
# 注意优先级
# * Jump * #
if self.timers["jump"].active:
self.animation_status = "jump"
# * Idle * #
elif self.direction.magnitude() == 0:
self.animation_status = "idle"
def done_jump(self):
Debug(DEBUG_MODE) << "Done Jump" << "\n"