-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathentities.py
132 lines (109 loc) · 3.6 KB
/
entities.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
import global_values as g
import utilities as util
import graphics as gfx
import elements
import math as m
class Entity(elements.Element):
"""
Base class for all entities (world objects)
"""
def __init__(self, rect, level, entity_gfx=None, solid=True, mask=None, collision_exceptions=[], collision_dict={}):
super().__init__(rect)
self.level = None
self.set_level(level)
self.gfx = entity_gfx
self.surface = None
self.solid = solid
self.last_collision = None
self.collision_exceptions = collision_exceptions
self.collision_dict = collision_dict
self.mask = mask
self.old_vx = self.x
self.old_vy = self.y
self.change_x = self.x-self.old_vx
self.change_y = self.y-self.old_vy
def update(self):
super().update()
self.change_x = self.x-self.old_vx
self.change_y = self.y-self.old_vy
self.old_vx = self.x
self.old_vy = self.y
def update_inactive(self):
"""
Update this entity when it's not in the same level as the player
"""
pass
def set_level(self, level):
"""
Set the level this entity is in
"""
#remove from old level
if self.level:
self.level.entities.remove(self)
if level:
self.level = level
#add to new level
self.level.entities.append(self)
def move_towards(self, x, y, speed, detail=False):
"""
Move some distance towards a point, accounting for collision
"""
if util.get_distance(self.x, self.y, x, y) <= speed:
dx = x-self.x
dy = y-self.y
else:
angle = util.get_angle(self.x, self.y, x, y)
dx = round(m.cos(angle)*speed, 6)
dy = round(m.sin(angle)*speed, 6)
result = self.move(dx, dy, detail=detail)
return result
def move(self, x, y, detail=False):
"""
Move some distance, accounting for collision
"""
steps = m.ceil(max(abs(x), abs(y)))
nx = self.x
ny = self.y
new_rect = self.rect.copy()
if not steps:
return
ax = x/steps
ay = y/steps
result = None
for _ in range(steps):
nx += ax
ny += ay
new_rect.x = nx
new_rect.y = ny
result = util.check_collision(new_rect, obj=self, _collision_dict=self.collision_dict, exceptions=self.collision_exceptions, detail=detail, mask=self.mask)
if result:
nx -= ax
ny -= ay
new_rect.x = nx
new_rect.y = ny
self.last_collision = result
break
self.x = nx
self.y = ny
if result:
return result
def delete(self):
if not self.deleted:
if self.level:
self.level.entities.remove(self)
super().delete()
def level_left(self):
"""
Called when the player leaves a level with this entity in it
"""
pass
def level_entered(self):
"""
Called when a player enters a level with this entity in it
"""
pass
def draw(self):
#g.camera.draw_rect("red", self.rect, 1)
if self.gfx:
self.surface = gfx.get_surface(self.gfx)
g.camera.draw_gfx(self.surface, self.rect.topleft)