-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcollisions.py
87 lines (69 loc) · 2.88 KB
/
collisions.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
import logging
import random
from math import copysign
from typing import Any, Optional
class CollisionHandler:
_next_handler: Optional["CollisionHandler"] = None
def set_next(self, next_handler: "CollisionHandler") -> None:
self._next_handler = next_handler
return next_handler
def handle(self, request: Any) -> None:
if self._next_handler is not None:
return self._next_handler.handle(request)
return None
def __repr__(self) -> str:
return "CollisionHandler"
class PaddleCollisionHandler(CollisionHandler):
def handle(self, request: Any) -> None:
if request["ball"].x == request["paddle"].x - 1:
if (
request["paddle"].y <= request["ball"].y
and request["ball"].y + request["ball"].width
<= request["paddle"].y + request["paddle"].width
):
if request["ball"]._dead:
logging.debug("Paddle dead collision")
request["ball"]._dead = False
request["ball"].vx = -1
if random.randint(0, 1) == 0:
request["ball"].vy = -1
else:
request["ball"].vy = 1
elif request["paddle"].grab:
request["ball"].set_vx(0)
request["ball"].set_vy(0)
else:
logging.debug("Paddle not dead collision")
request["ball"].reverse_vx()
paddle_mid = request["paddle"].y + request["paddle"].width // 2
bias = abs(request["ball"].y - paddle_mid) / request["paddle"].width
request["ball"].vy = copysign(
abs(request["ball"].vy + bias), request["ball"].vy
)
request["ball"].vy = int(request["ball"].vy)
return request
return super().handle(request)
def __repr__(self) -> str:
return "PaddleCollisionHandler()"
class BoundaryCollisionHandler(CollisionHandler):
def handle(self, request: Any) -> None:
# collide with the top wall
if request["ball"].x == 0:
logging.debug("top wall collision")
request["ball"].reverse_vx()
return request
# collide with side walls
if (
request["ball"].y == 0
or request["ball"].y + request["ball"].width == request["display"].width
):
logging.debug("side wall collision")
request["ball"].reverse_vy()
return super().handle(request)
def __repr__(self) -> str:
return "BoundaryCollisionHandler()"
class BrickCollisionHandler(CollisionHandler):
def handle(self, request: Any) -> None:
if request.type == "collision":
self._paddle.move_down()
return super().handle(request)