@@ -220,6 +220,36 @@ <h5 id="message"></h5>
220
220
}
221
221
}
222
222
223
+ function calculateCollision ( sx , sy , px , py , qx , qy , r , R ) {
224
+ // 计算小球到大球的单位法向量
225
+ const dx = px - qx ;
226
+ const dy = py - qy ;
227
+ const distance = Math . sqrt ( dx * dx + dy * dy ) ;
228
+
229
+ // 单位法向量
230
+ const nx = dx / distance ;
231
+ const ny = dy / distance ;
232
+
233
+ // 计算小球在法向量方向的速度分量(投影)
234
+ const vDotN = sx * nx + sy * ny ;
235
+
236
+ // 计算法向量方向的反射速度分量
237
+ const reflectedVx = sx - 2 * vDotN * nx ;
238
+ const reflectedVy = sy - 2 * vDotN * ny ;
239
+
240
+ return { reflectedVx, reflectedVy } ;
241
+ }
242
+
243
+ function hasCollided ( px , py , qx , qy , r , R ) {
244
+ // 计算两个球中心的距离
245
+ const dx = px - qx ;
246
+ const dy = py - qy ;
247
+ const distance = Math . sqrt ( dx * dx + dy * dy ) ;
248
+
249
+ // 检查是否碰撞
250
+ return distance <= r + R ;
251
+ }
252
+
223
253
// Update game state
224
254
function update ( ) {
225
255
// Move paddles
@@ -260,23 +290,33 @@ <h5 id="message"></h5>
260
290
}
261
291
262
292
// Check if ball collides with left paddle
263
- if (
293
+ /* if (
264
294
ballX - ballRadius < paddleWidth &&
265
295
ballY > leftPaddleY &&
266
296
ballY < leftPaddleY + paddleHeight
267
297
) {
268
298
ballSpeedX = -ballSpeedX;
269
- }
299
+ }*/
300
+
301
+ if ( hasCollided ( ballX , ballY , leftPaddleX , leftPaddleY , ballRadius , paddleHeight / 2 ) ) {
302
+ var ballMove = calculateCollision ( ballSpeedX , ballSpeedY , ballX , ballY , leftPaddleX , leftPaddleY , ballRadius , paddleHeight / 2 ) ;
303
+ ballSpeedX = ballMove . reflectedVx ;
304
+ ballSpeedY = ballMove . reflectedVy ;
305
+ }
270
306
271
307
// Check if ball collides with right paddle
272
- if (
308
+ /* if (
273
309
ballX + ballRadius > canvas.width - paddleWidth &&
274
310
ballY > rightPaddleY &&
275
311
ballY < rightPaddleY + paddleHeight
276
312
) {
277
313
ballSpeedX = -ballSpeedX;
278
- }
279
-
314
+ }*/
315
+ if ( hasCollided ( ballX , ballY , rightPaddleX , rightPaddleY , ballRadius , paddleHeight / 2 ) ) {
316
+ var ballMove = calculateCollision ( ballSpeedX , ballSpeedY , ballX , ballY , rightPaddleX , rightPaddleY , ballRadius , paddleHeight / 2 ) ;
317
+ ballSpeedX = ballMove . reflectedVx ;
318
+ ballSpeedY = ballMove . reflectedVy ;
319
+ }
280
320
// Check if ball goes out of bounds on left or right side of canvas
281
321
if ( ballY > canvas . height / 2 - paddleHeight && ballY < canvas . height / 2 + paddleHeight ) {
282
322
if ( ballX < effectiveBounds ) {
0 commit comments