【问题标题】:Bouncing ball game tkinter canvas弹跳球游戏 tkinter 帆布
【发布时间】:2020-05-23 22:49:29
【问题描述】:

我用 python 编写了一个游戏,其目标是将球从平台上弹起。 一切运作良好,但平台的运动并不那么顺畅。你能帮我让平台运动更顺畅吗?如果代码不是太清楚,对不起,我是python新手

import tkinter as tk
import random

root = tk.Tk()

width = 900
height = 500

canvas = tk.Canvas(root, bg='white', width=width, height=height)
canvas.pack()

x = random.randrange(700)

ball = canvas.create_oval(x+10, 10, x+50, 50, fill='green')

platform_y = height - 20
platform = canvas.create_rectangle(width//2-50, platform_y, width//2+50, platform_y+10, fill='black')

xspeed = 2
yspeed = 2
skore = 0
body = 0

def move_ball():
  global xspeed
  global yspeed
  x1, y1, x2, y2 = canvas.coords(ball)
  if x1 <= 0 or x2 >= width:
    xspeed = -xspeed
  if y1 <= 0:
    yspeed = 10
  elif y2 == platform_y: 
    cx = (x1 + x2) // 2
    px1, _, px2, _ = canvas.coords(platform)
    if px1 <= cx <= px2:
      yspeed = -10
    else:
      canvas.create_text(width//2, height//2, text='Game Over', font=('Arial Bold', 32), fill='red')
      return
  canvas.move(ball, xspeed, yspeed)
  canvas.after(20, move_ball)

def board_right(event):
  x1, y1, x2, y2 = canvas.coords(platform) 
  if x2 < width:
    dx = min(width-x2, 10)
    canvas.move(platform, dx, 0)

def board_left(event):
  x1, y1, x2, y2 = canvas.coords(platform)
  if x1 > 0:
    dx = min(x1, 10)
    canvas.move(platform, -dx, 0)

canvas.bind_all('<Right>', board_right)
canvas.bind_all('<Left>', board_left)

move_ball()

root.mainloop()

【问题讨论】:

  • 如果你想扼杀运动,那么你想减少之后的时间,比如 10 毫秒,然后将球移动的距离减少一半。这将改善平滑度。所以这个想法是更频繁地移动更短的距离。这是我所知道的提高运动平滑度的唯一方法。

标签: python animation canvas tkinter game-physics


【解决方案1】:

问题在于平台的速度取决于键盘的自动重复速度。

不是为每个&lt;Right&gt;&lt;Left&gt; 事件移动一次,而是使用按键来启动平台向所需方向移动,并使用按键释放来停止平台移动。然后,使用after 重复向给定方向移动平台。

例子:

after_id = None
def platform_move(direction):
    """
    direction should be -1 to move left, +1 to move right,
    or 0 to stop moving
    """
    global after_id
    speed = 10
    if direction == 0:
        canvas.after_cancel(after_id)
        after_id = None
    else:
        canvas.move(platform, direction*speed, 0)
        after_id = canvas.after(5, platform_move, direction)

canvas.bind_all("<KeyPress-Right>", lambda event: platform_move(1))
canvas.bind_all("<KeyRelease-Right>", lambda event: platform_move(0))
canvas.bind_all("<KeyPress-Left>", lambda event: platform_move(-1))
canvas.bind_all("<KeyRelease-Left>", lambda event: platform_move(0))

上面的代码不能处理同时按下两个键的情况,但可以通过一些额外的逻辑来处理。重点是展示如何使用按键来启动和停止动画。

【讨论】:

  • 但是当我按住右箭头或左箭头时,它会飞得很快,而且不会停止
  • 您可以使用speed 变量加快或减慢它,同时将提供的5 更改为after。至于不停止,这只是检查坐标并在到达边缘时停止的问题。重点是表明您可以设置一个动画循环,然后让事件停止和启动动画,而不是让事件成为动画。
猜你喜欢
  • 2020-05-22
  • 1970-01-01
  • 2014-09-07
  • 1970-01-01
  • 1970-01-01
  • 2019-06-01
  • 1970-01-01
  • 2015-07-01
  • 2012-11-03
相关资源
最近更新 更多