瀏覽代碼

breakout: collision with pieces

Signed-off-by: Thomas Buck <thomas@venom.fritz.box>
Jannis 1 年之前
父節點
當前提交
2399961348
共有 1 個文件被更改,包括 32 次插入14 次删除
  1. 32
    14
      breakout.py

+ 32
- 14
breakout.py 查看文件

@@ -14,7 +14,7 @@ import math
14 14
 import util
15 15
 
16 16
 class Breakout:
17
-    def __init__(self, g, i, ts = 0.1, to = 60.0):
17
+    def __init__(self, g, i, ts = 0.04, to = 60.0):
18 18
         self.gui = g
19 19
         self.input = i
20 20
         self.timestep = ts
@@ -43,8 +43,8 @@ class Breakout:
43 43
         self.ball = [
44 44
             self.player, # x
45 45
             self.gui.height - 2, # y
46
-            1, # v x
47
-            -1, # v y
46
+            math.sqrt(.5), # v x
47
+            -math.sqrt(.5), # v y
48 48
         ]
49 49
 
50 50
     def restart(self):
@@ -111,6 +111,7 @@ class Breakout:
111 111
 
112 112
     def step(self):
113 113
         # move ball
114
+        old_ball = self.ball.copy()
114 115
         self.ball[0] += self.ball[2]
115 116
         self.ball[1] += self.ball[3]
116 117
 
@@ -124,19 +125,36 @@ class Breakout:
124 125
             self.ball[2] = -self.ball[2]
125 126
             self.ball[0] = self.gui.width - 1
126 127
 
127
-        # check for collisions with pieces
128
-        if self.data[int(self.ball[0])][int(self.ball[1])] != self.bg_c:
129
-            self.data[int(self.ball[0])][int(self.ball[1])] = self.bg_c
130
-            self.score += 1
131
-
132
-            # just invert Y travel direction
133
-            # TODO inaccurate collision behaviour in "corners"
134
-            self.ball[3] = -self.ball[3]
135
-
136 128
         # check for collision with ceiling
137 129
         if self.ball[1] <= 0:
138 130
             self.ball[3] = -self.ball[3]
139 131
 
132
+        # check for collisions with pieces
133
+        grid_pos_x = int(self.ball[0])
134
+        grid_pos_y = int(self.ball[1])
135
+        if self.data[grid_pos_x][grid_pos_y] != self.bg_c:
136
+            self.data[grid_pos_x][grid_pos_y] = self.bg_c
137
+            self.score += 1
138
+
139
+            old_grid_pos_x = int(old_ball[0])
140
+            old_grid_pos_y = int(old_ball[1])
141
+
142
+            # horizontal collision
143
+            if old_grid_pos_y == grid_pos_y:
144
+                self.ball[2] = -self.ball[2]
145
+            # vertical collision
146
+            elif old_grid_pos_x == grid_pos_x:
147
+                self.ball[3] = -self.ball[3]
148
+            # "diagonal" collision with horizontal obstacle
149
+            elif self.data[old_grid_pos_x-1][old_grid_pos_y] != self.bg_c or self.data[old_grid_pos_x+1][old_grid_pos_y] != self.bg_c:
150
+                self.ball[2] = -self.ball[2]
151
+            # "diagonal" collision with vertical obstacle
152
+            elif self.data[old_grid_pos_x][old_grid_pos_y-1] != self.bg_c or self.data[old_grid_pos_x][old_grid_pos_y+1] != self.bg_c:
153
+                self.ball[3] = -self.ball[3]
154
+            # "diagonal" collision without obstacle
155
+            else:
156
+                self.ball[2] = -self.ball[2]
157
+                self.ball[3] = -self.ball[3]
140 158
 
141 159
         # check for collision with floor
142 160
         if self.ball[1] >= self.gui.height - 1:
@@ -159,8 +177,8 @@ class Breakout:
159 177
 
160 178
             # small angles in the middle, big angles at the end of the paddle (angle measured against the orthogonal of the paddle)
161 179
             angle_degree = 80 * pos_on_paddle / (self.paddle_width/2)
162
-            self.ball[2] = -1 * math.sin(angle_degree/180*3.14159) * math.sqrt(2)
163
-            self.ball[3] = -1 * math.cos(angle_degree/180*3.14159) * math.sqrt(2)
180
+            self.ball[2] = -1 * math.sin(angle_degree/180*3.14159)
181
+            self.ball[3] = -1 * math.cos(angle_degree/180*3.14159)
164 182
 
165 183
 
166 184
     def finishedEndScreen(self):

Loading…
取消
儲存