问题描述
试图让球在平台上弹跳,但无法检测到碰撞?我们如何检测碰撞或使其从平台反弹?我们已经制作了球和它的重力.球也可以从画布的两侧反弹,并通过键盘箭头键使平台移动.
Trying to get the ball to bounce on the platform, but the collision can't be detected? How can we detect collision or make it bounce from the platform? We have made the ball and its gravity. The ball can also bounce from the sides of the canvas, and made the platform move from keyboard arrow keys.
from tkinter import*
import random
import time
import math
import tkinter
WIDTH = 800
HEIGHT = 1000
tk=Tk()
canvas = Canvas(tk, width=1200, height=900)
tk.title("Brick Breaker")
platform = canvas.create_rectangle(5, 40, 250, 30, fill ="black")
def leftKey(event):
canvas.move(platform, -40, 0)
pass
def rightKey(event):
canvas.move(platform, 40, 0)
pass
tk.bind('<Left>', leftKey)
tk.bind('<Right>', rightKey)
canvas.pack()
tk.update()
#alligns the platform
left = 0
for x in range(0,18):
canvas.move(1, 40, 40)
tk.update()
ball = canvas.create_oval(5, 5, 30, 30, fill ="black")
xspeed = 0.1 #gravity
yspeed = 0.4
while True:
canvas.move(ball, xspeed, yspeed)
pos = canvas.coords(ball)
if pos[3] >= 900 or pos[1] <= 0: # y range
yspeed = -yspeed
if pos[2] >= 1200 or pos[0] <= 0: # x range
xspeed = -xspeed
tk.update()
time.sleep(0.00000001) #speed
tk.mainloop()
推荐答案
您可以使用 canvas.find_overlapping(*ball_pos)
来检查球是否与其他对象重叠.它返回矩形 ball_pos
中所有对象的 ID - 事件球 - 所以它永远不会为空.
You can use canvas.find_overlapping(*ball_pos)
to check if ball overlaps other objects. It returns IDs of all objects in rectangle ball_pos
- event ball - so it is never empty.
这并不理想,因为它不检查球是否在下方/上方/左/右碰撞,因此您不知道如何改变方向.
It is not ideal because it doesn't check if ball collide below/above/left/right so you don't know how to change direction.
import tkinter as tk
# --- constants ---
WIDTH = 800
HEIGHT = 1000
# --- functions ---
# for smooth move of platform
def left_press(event):
global platform_left
platform_left = True
def left_release(event):
global platform_left
platform_left = False
def right_press(event):
global platform_right
platform_right = True
def right_release(event):
global platform_right
platform_right = False
def eventloop():
global xspeed
global yspeed
# move ball
canvas.move(ball, xspeed, yspeed)
ball_pos = canvas.coords(ball)
# move platform
if platform_left:
# move
canvas.move(platform, -20, 0)
platform_pos = canvas.coords(platform)
# check if not leave canvas
if platform_pos[0] < 0:
# move back
canvas.move(platform, 0-platform_pos[0], 0)
if platform_right:
# move
canvas.move(platform, 20, 0)
# check if not leave canvas
platform_pos = canvas.coords(platform)
if platform_pos[2] > 1200:
# move back
canvas.move(platform, -(platform_pos[2]-1200), 0)
# - collisions -
# check collision with border
if ball_pos[3] >= 900 or ball_pos[1] <= 0: # y range
yspeed = -yspeed
if ball_pos[2] >= 1200 or ball_pos[0] <= 0: # x range
xspeed = -xspeed
# check collisions with objects
collide = canvas.find_overlapping(*ball_pos)
if platform in collide:
yspeed = -yspeed
remove = []
# check collision with bricks
for brick in bricks:
if brick in collide:
remove.append(brick)
yspeed = -yspeed
# remove bricks
for brick in remove:
bricks.remove(brick)
canvas.delete(brick)
root.after(10, eventloop)
# --- main ---
# - init -
root = tk.Tk()
root.title("Brick Breaker")
canvas = tk.Canvas(root, width=1200, height=900)
canvas.pack()
# - objects -
ball = canvas.create_oval(5, 5, 30, 30, fill="black")
xspeed = 1 # gravity
yspeed = 4
platform = canvas.create_rectangle(5, 40, 250, 30, fill="black")
platform_left = False
platform_right = False
root.bind('<Left>', left_press)
root.bind('<KeyRelease-Left>', left_release)
root.bind('<Right>', right_press)
root.bind('<KeyRelease-Right>', right_release)
bricks = []
for i in range(10):
x = i*100
y = 700
brick = canvas.create_rectangle(x, y, x+50, y+30, fill="red")
bricks.append(brick)
# - mainloop -
root.after(100, eventloop)
root.mainloop()
顺便说一句:为了更好地控制速度改变xspeed
,yspeed
而不是after()
BTW: to control speed better change xspeed
, yspeed
instead of after()
这篇关于如何使用碰撞在另一种形状的桨游戏中弹跳球?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!