0
我有一場乒乓球比賽(改編)。 每次玩家的槳沒有擊中球時,我都想要一個窗口出現在裏面。如果他的回答正確,應該銷燬該窗口並且用戶可以繼續遊戲,在用戶正確之前失敗會導致更多問題 - 然後他們可以繼續遊戲。當Toplevel窗口處於活動狀態(直到它被銷燬)時暫停動畫循環?
當Toplevel
窗口處於活動狀態時如何暫停動畫循環,以及如何在Toplevel
窗口被銷燬時取消暫停動畫循環?
代碼的主要焦點是Paddle類的第一個類(questions_window),game_flow函數和paddle_collisions方法。
這裏是所有代碼:
from tkinter import *
import time
#starting velocity for the ball
x_speed = 25
y_speed = 25
class questions_window():
def __init__(self, master):
self.master = master
self.master.geometry("300x300")
self.master.title("Questions")
def focus(self):
self.master.attributes("-topmost", 1)
self.master.grab_set()
class table():
'''This is the table class - the background for the game and it's drawings'''
def __init__ (self, window, colour = 'green', width=600, height = 400, score1 = 0, score2 = 0):
self. colour = colour
self.width = width
self.height = height
self.canvas = Canvas(window, bg=self.colour, height=self.height, width=self.width)
self.canvas.pack()
self.canvas.create_line(300, 0, 300, 400, fill="red")
self.score1 = score1
self.score2 = score2
#this receives the coordinates of the ball and draws an oval based on these coordinates
#the instance of this item is returned to the ball class' 'circle' attribute
def draw_oval(self, oval):
x1 = oval.x_posn
x2 = oval.x_posn + oval.width
y1 = oval.y_posn
y2 = oval.y_posn + oval.height
c = oval.colour
return self.canvas.create_oval(x1, y1, x2, y2, fill=c)
#this recieves the coordinates of the paddle and draws a rectangle based on these coordinates
#the instance of this item is returned to the paddle class' 'rectangle' attribute
def draw_rectangle(self, rectangle):
x1 = rectangle.x_posn
x2 = rectangle.x_posn + rectangle.width
y1 = rectangle.y_posn
y2 = rectangle.y_posn + rectangle.height
c = rectangle.colour
return self.canvas.create_rectangle(x1, y1, x2, y2, fill=c)
#this method creates text on the canvas (the scores separated with a dash)
def reset_scorecard(self):
scores = str(self.score1) + " - " + str(self.score2)
self.scorecard = self.canvas.create_text(300, 50, font=("Purisa",40), text=scores)
#this finds out who has won a point and updates the scores on the canvas
def update_scorecard(self, player):
if player == 1:
self.score1 = self.score1 + 1
elif player == 2:
self.score2 = self.score2 + 1
scores = str(self.score1) + " - " + str(self.score2)
self.canvas.itemconfig(self.scorecard, text=scores)
#this method, when called, recieves a drawing object and updates its position on the canvas
def move_item(self, item, x1, y1, x2, y2):
self.canvas.coords(item, x1, y1, x2, y2)
class ball():
'''This is the ball class'''
def __init__(self, table, colour = 'red', width = 25, height = 25, x_speed = 15,
y_speed = 15, x_start = 5, y_start = 5):
self.colour = colour
self.width = width
self.height = height
self.x_posn = x_start
self.y_posn = y_start
self.table = table
self.x_start = x_start
self.y_start = y_start
self.x_speed = x_speed
self.y_speed = y_speed
self.circle = self.table.draw_oval(self)
#this method updates the ball's x and y coordinates by the speed values
#it then checks if the ball has hit any walls - if it has it
#reverses the x or y speeds depending on the wall it has hit
#it then moves the item to the new coordinates
def move_next(self):
self.x_posn = self.x_posn + self.x_speed
self.y_posn = self.y_posn + self.y_speed
if (self.x_posn <=3):
self.x_posn = 3
self.x_speed = -self.x_speed
if(self.x_posn >= (self.table.width - (self.width - 3))):
self.x_posn = (self.table.width - (self.width - 3))
self.x_speed = -self.x_speed
if (self.y_posn <=3):
self.y_posn = 3
self.y_speed = -self.y_speed
if(self.y_posn >= (self.table.height - (self.height - 3))):
self.y_posn = (self.table.height - (self.height - 3))
self.y_speed = -self.y_speed
x1 = self.x_posn
x2 = self.x_posn + self.width
y1 = self.y_posn
y2 = self.y_posn + self.height
self.table.move_item(self.circle, x1, y1, x2, y2)
class paddle():
'''This is the ball class'''
def __init__(self, master, table, colour = 'blue', width = 10, height = 110,
x_start = 0, y_start = 20):
self.colour = colour
self.width = width
self.height = height
self.x_posn = x_start
self.y_posn = y_start
self.table = table
self.master = master
self.x_start = x_start
self.y_start = y_start
self.rectangle = self.table.draw_rectangle(self)
#this method updates the paddles position on the screen
#it recieves the mouse' x and y positions and updates the y position
#of the paddle to match the y position of the mouse
#it then moves the paddle to the new coordinates
def move(self, event):
self.y_posn = event.y
x1 = self.x_posn
x2 = self.x_posn + self.width
y1 = self.y_posn
y2 = self.y_posn + self.height
self.table.move_item(self.rectangle, x1, y1, x2, y2)
#this method checks if the ball has moved passed the paddle
#if it has it will update the scorecard passing in the value of 2
#if it has BUT has done so between the top and bottom ends of the paddle
#it takes this as a paddle hit and updates score with 1 passed to the method
def paddle_collision(self, ball, master):
global switch_value
if ((self.x_posn + self.width) > ball.x_posn) and (self.y_posn < ball.y_posn < (self.y_posn + self.height)):
ball.x_speed = abs(ball.x_speed)
print("Yes!")
self.table.update_scorecard(1)
elif (self.x_posn+4) > ball.x_posn:
print("Collision")
self.table.update_scorecard(2)
question_win = Toplevel(self.master)
question_window = questions_window(question_win)
question_window.focus()
#create the window object
window = Tk()
window.title("Tennis")
#create the table, ball and paddle objects
myTable = table(window)
myTable.reset_scorecard()
myBall = ball(table=myTable, x_speed = x_speed, y_speed = y_speed)
paddle1 = paddle(table=myTable, master = window)
#this is the animation loop which calls itself after every 40ms
#each call calls the ball objects move_next method and the paddle's collision method
def game_flow():
myBall.move_next()
paddle1.paddle_collision(myBall,window)
window.after(40, game_flow)
#first call of game_flow to start game
game_flow()
#binds the mouse events to the padde's move method
window.bind("<Motion>", paddle1.move)
window.mainloop()