-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathactor.py
More file actions
109 lines (95 loc) · 3.42 KB
/
actor.py
File metadata and controls
109 lines (95 loc) · 3.42 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
#!/usr/bin/env python3
'''
@author Michele Tomaiuolo - http://www.ce.unipr.it/people/tomamic
@license This software is free - http://www.gnu.org/licenses/gpl.html
'''
class Actor(object):
'''Interface to be implemented by each game character'''
def move(self):
'''Called by Arena, at the actor's turn'''
raise NotImplementedError('Abstract method')
def collide(self, other):
'''Called by Arena, when the actor collides with another one
Args:
other: Actor -- the other actor involved in the collision
'''
raise NotImplementedError('Abstract method')
def rect(self):
'''Return the rectangle containing the actor, as a 4-tuple of ints
Returns:
(int, int, int, int) -- (left, top, width, height)
'''
raise NotImplementedError('Abstract method')
def symbol(self):
'''Return (0, 0) or the (x, y) position of current sprite in a
larger image, containing more sprites
Returns:
(int, int) -- the position of current sprite
'''
raise NotImplementedError('Abstract method')
class Arena(object):
'''A generic 2D game, with a given size in pixels and a list of actors'''
def __init__(self, width, height):
'''Create an arena, with given dimensions
Args:
width: int -- width in pixels
height: int -- height in pixels
'''
self._w, self._h = width, height
self._actors = []
def add(self, a):
'''Register an actor into this arena
Args:
a: Actor
'''
if a not in self._actors:
self._actors.append(a)
def remove(self, a):
'''Cancel an actor from this arena
Args:
a: Actor
'''
if a in self._actors:
self._actors.remove(a)
def move_all(self):
'''Move all actors (through their own move method).
After each single move, collisions are checked and
The collide methods of both colliding actors are called
'''
actors = list(reversed(self._actors))
for a in actors:
previous_pos = a.rect()
a.move()
if a.rect() != previous_pos:
for other in actors:
# reversed order, so actors drawn on top of others
# (towards the end of the cycle) are checked first
if other is not a and self.check_collision(a, other):
a.collide(other)
other.collide(a)
def check_collision(self, a1, a2):
'''Check two actors for mutual collision
(bounding-box collision detection)
Args:
a1 -- The first actor to check
a2 -- The second actor
Returns:
bool -- Collision value
'''
x1, y1, w1, h1 = a1.rect()
x2, y2, w2, h2 = a2.rect()
return (y2 < y1 + h1 and y1 < y2 + h2
and x2 < x1 + w1 and x1 < x2 + w2
and a1 in self._actors and a2 in self._actors)
def actors(self):
'''Return a copy of the list of actors
Returns:
list[Actor] -- the registerd actors
'''
return list(self._actors)
def size(self):
'''Return the size of the arena as a 2-tuple of ints
Returns:
(int, int) -- (width, height)
'''
return (self._w, self._h)