我正在用 python 撰寫一個基本的乒乓球游戲。
我有這個代碼:
from tkinter import *
from tkinter.ttk import *
from math import sqrt
import time, random
# creates tkinter window or root window
Window = Tk()
HEIGHT = 700
WIDTH = 700
c = Canvas(Window, width = WIDTH, height = HEIGHT)
c.pack()
c.configure(bg='black')
#Define mid x and y
MID_X = WIDTH / 2
MID_Y = HEIGHT / 2
#Create paddles and ball
paddle_1 = c.create_rectangle(0, 0, 100, 20, fill='grey', outline = 'white')
paddle_2 = c.create_rectangle(0, 0, 100, 20, fill='grey', outline = 'white')
ball = c.create_oval(0, 0, 30, 30, fill='white', outline = 'grey')
c.move(paddle_1, 300, 0)
c.move(paddle_2, 300, 680)
c.move(ball, 330, 340)
id = [paddle_1, paddle_2, ball]
ball_move_x = 0
ball_move_y = 10
cooldown = 0
#get co-ordinates of object
def get_coords(i):
pos = c.coords(i)
x = int(pos[0] pos[2]/2)
y = int(pos[1] pos[3]/2)
return x, y
#Bounce (makes goofy physics)
def bounce(x, y):
x = random.randint(1,20)/10
x *= -1
y = 1
y *= -1
return x, y
#Collision code (uses co-ords and checks if within a certain range)
def collision(paddle_x, paddle_y, ball_x, ball_y, x = ball_move_x, y = ball_move_y,):
if(ball_x in range(paddle_x-50, paddle_x 50, 1) and ball_y in range(paddle_y-30, paddle_y 30, 1)):
x, y = bounce(ball_move_x, ball_move_y)
print("collision")
return x, y
else:
return x, y
# Optimised movement functions without cycling through with an if operator
def move_paddle_1_left(e):
c.move(paddle_1, -100, 0)
def move_paddle_1_right(e):
c.move(paddle_1, 100, 0)
def move_paddle_2_left(e):
c.move(paddle_2, -100, 0)
def move_paddle_2_right(e):
c.move(paddle_2, 100, 0)
# bind functions to key
c.bind_all('<KeyPress-a>', move_paddle_1_left)
c.bind_all('<KeyPress-d>', move_paddle_1_right)
c.bind_all('<Left>', move_paddle_2_left)
c.bind_all('<Right>', move_paddle_2_right)
c.pack()
#MAIN GAME LOOP
while True:
Window.update()
paddle_1_x, paddle_1_y = get_coords(id[0])
paddle_2_x, paddle_2_y = get_coords(id[1])
ball_x, ball_y = get_coords(id[2])
ball_move_x, ball_move_y = collision(paddle_1_x, paddle_1_y, ball_x, ball_y)
ball_move_x, ball_move_y = collision(paddle_2_x, paddle_2_y, ball_x, ball_y)
c.move(ball, ball_move_x, ball_move_y)
time.sleep(0.0333333)
Window.update()
問題是碰撞(到目前為止,只實作了從槳上彈起)是有問題的:它本質上會無限地碰撞和碰撞。
我的碰撞檢測和回應方法是得到球的中間坐標和球棒的中間坐標;如果球的坐標在球棒坐標的范圍內,我將其視為碰撞。
從那時起,我一直遇到一個問題,基本上它會無限地碰撞并且只是上下垃圾郵件。為什么會發生這種情況,我該如何解決?
uj5u.com熱心網友回復:
當您檢測到碰撞時,您會使用不同的x *= -1方向移動up(-1
您應該將此值保留為全域變數
direction_x = 1
direction_y = 1
并且一直使用
return x*direction_x, y*direction_y
當你檢測到碰撞然后改變方向
direction_y = -direction_y
direction_x = 1
direction_y = 1
def collision(paddle_x, paddle_y, ball_x, ball_y, x = ball_move_x, y = ball_move_y,):
global direction_x
global direction_y
if (paddle_x-50 <= ball_x <= paddle_x 50) and (paddle_y-30 <= ball_y <= paddle_y 30):
direction_y = - direction_y
print("collision")
return x*direction_x, y*direction_y
具有其他更改的完整作業代碼
編輯:
您在計算中心()時忘記了 - 您必須先加后除,但沒有()先除后加。
x = int((pos[0] pos[2])/2)
y = int((pos[1] pos[3])/2)
import tkinter as tk # PEP8: `import *` is not preferred
from math import sqrt
import time
import random
# --- constants ---
HEIGHT = 700
WIDTH = 700
MID_X = WIDTH / 2
MID_Y = HEIGHT / 2
BALL_MOVE_X = 0
BALL_MOVE_Y = 10
# --- functions ---
def get_coords(canvas, item):
pos = canvas.coords(item)
x = int( (pos[0] pos[2]) / 2 )
y = int( (pos[1] pos[3]) / 2 )
return x, y
def collision(paddle_x, paddle_y, ball_x, ball_y, x=BALL_MOVE_X, y=BALL_MOVE_Y):
global direction_x
global direction_y
if (paddle_x-50 <= ball_x <= paddle_x 50) and (paddle_y-30 <= ball_y <= paddle_y 30):
direction_y = - direction_y
print("paddle collision")
return x*direction_x, y*direction_y
def move_paddle_1_left(e):
canvas.move(paddle_1, -100, 0)
def move_paddle_1_right(e):
canvas.move(paddle_1, 100, 0)
def move_paddle_2_left(e):
canvas.move(paddle_2, -100, 0)
def move_paddle_2_right(e):
canvas.move(paddle_2, 100, 0)
def gameloop():
# MAIN GAME LOOP
paddle_1_x, paddle_1_y = get_coords(canvas, paddle_1)
paddle_2_x, paddle_2_y = get_coords(canvas, paddle_2)
ball_x, ball_y = get_coords(canvas, ball)
ball_move_x, ball_move_y = collision(paddle_1_x, paddle_1_y, ball_x, ball_y)
ball_move_x, ball_move_y = collision(paddle_2_x, paddle_2_y, ball_x, ball_y)
canvas.move(ball, ball_move_x, ball_move_y)
window.after(25, gameloop) # repeat after 25ms
# --- main ---
window = tk.Tk() # PEP8: `lower case name`
canvas = tk.Canvas(window, width=WIDTH, height=HEIGHT, bg='black') # PEP8: `=` without spaces inside `( )`
canvas.pack()
paddle_1 = canvas.create_rectangle(0, 0, 100, 20, fill='grey', outline='white')
paddle_2 = canvas.create_rectangle(0, 0, 100, 20, fill='grey', outline='white')
canvas.move(paddle_1, 300, 0)
canvas.move(paddle_2, 300, 680)
ball = canvas.create_oval(0, 0, 30, 30, fill='white', outline='grey')
canvas.move(ball, 330, 340)
ball_move_x = 0
ball_move_y = 10
direction_x = 1
direction_y = 1
cooldown = 0
canvas.bind_all('<KeyPress-a>', move_paddle_1_left)
canvas.bind_all('<KeyPress-d>', move_paddle_1_right)
canvas.bind_all('<Left>', move_paddle_2_left)
canvas.bind_all('<Right>', move_paddle_2_right)
window.after(25, gameloop) # 25ms = 0.025s = 40 Frames Per Second (FPS)
window.mainloop()
PEP 8——Python 代碼風格指南
編輯:
觸摸視窗邊框時改變方向的版本
import tkinter as tk # PEP8: `import *` is not preferred
from math import sqrt
import time
import random
# --- constants ---
HEIGHT = 700
WIDTH = 700
MID_X = WIDTH / 2
MID_Y = HEIGHT / 2
BALL_MOVE_X = 5
BALL_MOVE_Y = 10
# --- functions ---
def get_coords(canvas, item):
pos = canvas.coords(item)
x = int((pos[0] pos[2])/2)
y = int((pos[1] pos[3])/2)
return x, y
def collision(paddle_x, paddle_y, ball_x, ball_y, x=BALL_MOVE_X, y=BALL_MOVE_Y):
global direction_x
global direction_y
if (paddle_x-50 <= ball_x <= paddle_x 50) and (paddle_y-30 <= ball_y <= paddle_y 30):
direction_y = - direction_y
print("paddle collision")
#return x, y
return x, y
def move_paddle_1_left(e):
canvas.move(paddle_1, -100, 0)
def move_paddle_1_right(e):
canvas.move(paddle_1, 100, 0)
def move_paddle_2_left(e):
canvas.move(paddle_2, -100, 0)
def move_paddle_2_right(e):
canvas.move(paddle_2, 100, 0)
def gameloop():
# MAIN GAME LOOP
global direction_x
global direction_y
paddle_1_x, paddle_1_y = get_coords(canvas, paddle_1)
paddle_2_x, paddle_2_y = get_coords(canvas, paddle_2)
ball_x, ball_y = get_coords(canvas, ball)
if ball_x <= 0 or ball_x >= WIDTH:
direction_x = - direction_x
if ball_y <= 0 or ball_y >= HEIGHT:
print("Get point")
direction_y = - direction_y
ball_move_x, ball_move_y = collision(paddle_1_x, paddle_1_y, ball_x, ball_y)
ball_move_x, ball_move_y = collision(paddle_2_x, paddle_2_y, ball_x, ball_y)
canvas.move(ball, ball_move_x*direction_x, ball_move_y*direction_y)
window.after(25, gameloop) # repeat after 25ms
# --- main ---
window = tk.Tk() # PEP8: `lower case name`
canvas = tk.Canvas(window, width=WIDTH, height=HEIGHT, bg='black') # PEP8: `=` without spaces inside `( )`
canvas.pack()
paddle_1 = canvas.create_rectangle(0, 0, 100, 20, fill='grey', outline='white')
paddle_2 = canvas.create_rectangle(0, 0, 100, 20, fill='grey', outline='white')
canvas.move(paddle_1, 300, 0)
canvas.move(paddle_2, 300, 680)
ball = canvas.create_oval(0, 0, 30, 30, fill='white', outline='grey')
canvas.move(ball, 330, 340)
ball_move_x = 0
ball_move_y = 10
direction_x = 1
direction_y = 1
cooldown = 0
canvas.bind_all('<KeyPress-a>', move_paddle_1_left)
canvas.bind_all('<KeyPress-d>', move_paddle_1_right)
canvas.bind_all('<Left>', move_paddle_2_left)
canvas.bind_all('<Right>', move_paddle_2_right)
window.after(25, gameloop) # 25ms = 0.025s = 40 Frames Per Second (FPS)
window.mainloop()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/490121.html
