【问题标题】:How to fix the the direction of movement of a pinball and make it collide如何固定弹球的运动方向并使其发生碰撞
【发布时间】:2012-07-28 16:54:11
【问题描述】:

我已将这个弹球游戏程序作为我班级的作业,但我一直无法解决弹球运动和碰撞问题。

第一个问题是,无论用户将速度设置为哪个方向,球都只会以特定角度移动。

我真的不知道为什么它不应该工作,根据我的笔记、讲座幻灯片和讨论讲义,它应该没问题。那么有人知道为什么它不起作用吗?我环顾四周,找不到明确的答案。任何帮助将不胜感激。我被难住了:(

不工作意味着无论用户将弹球设置为哪个方向,它都只会向一个方向移动(例如,用户设置弹球向左,弹球向右;用户设置弹球向上,它是正确的;等等) 此外,弹球不会与墙壁或任何目标发生碰撞。

图形是graphics.py:http://mcsp.wartburg.edu/zelle/python/graphics/graphics/index.html

这里是碰撞代码(连同速度反转,只保持与游戏板右墙的碰撞):

def checkHit(ball,target,dispX,dispY,VelX,VelY,hit): ###pulled the definition out of the loop but keeping it here for easier reference
     center = ball.getCenter() ###defines the center of the pinball as a point
     hit = 0 ###used for differentiating between objects collided with
     if center.getX() + 1 <= 45 and center.getX() + 1 + dispX > 45: ####if the pinball collides with the right wall of the board
         VelX = VelX *(-1) ###velocity in the x direction reverses
         hit = 0  ###did not collide with a target

for j in range(1000):####1000 frames (ball isn't expected to last long in the air, only a couple seconds)
     vy = vy - 9.8 ###effect of gravity
     dx = vx / math.sqrt(vx**2 + vy**2) ###speed in x direction over time
     dy = vy / math.sqrt(vx**2 + vy**2) ###speed in y direction over time
     checkHit(pinball,target_front1,dx,dy,vx,vy,0) ####runs function each frame for collision testing
     pinball.move(dx , dy) ###moves pinball

【问题讨论】:

  • 根据您的问题定义“不起作用”。
  • 你提到了“讲义”。这是作业吗?如果是,请标记它。
  • 一般情况下,尽量避免发布整个代码(尤其是当我们无法访问必要的模块时,graphics)并将其细化为尽可能小的代码块。让我们更容易为您提供帮助,让您自己了解问题。
  • Graphics.py 在这里mcsp.wartburg.edu/zelle/python

标签: python game-physics collision


【解决方案1】:

我不能确定,因为你没有告诉我们你从哪里得到graphics 模块。最有可能上学。

尝试将部分if 语句更改为elifs。您可能同时评估了太多东西或其他东西。考虑以下代码,您只希望运行以下if 语句中的一个,但实际上,所有这些语句都在运行:

def foo(x):
 if x < 5:
  print 'x is greater than five'
 if x == 10:
  print 'x is 10'

foo(10)

>>> x is greater than 5
>>> x is 10

如果将第二个if 更改为elif,那么如果运行第一个if 语句,则elif 的其余部分将被忽略:

def bar(x):
 if x < 5:
  print 'x is greater than five'
 elif x == 10:  #changed this line to an 'elif' 
  print 'x is 10'

bar(10)

>>> x is greater than 5   #only prints once, because the first if statement is True

你还定义checkHit每个循环,浪费系统资源。最好将其拉出循环并进入模块的最顶部。


edit:实际上,上面的例子虽然是对的,但并不是很好。想象一下,如果x(一个速度)大于5,一个球会停止滚动,所以您现在将x 更改为0。然后在第二个if 语句之后立即检查它,看看它是否已停止。如果它停止了,请再次开始移动(x == 5 或其他东西)。这意味着球永远不会停止移动,因为无论如何,在if 语句结束时,球总是会再次开始移动。

所以你需要做的是使用elif 语句而不是第二个if,因为除非前面的if 语句不是True,否则不会评估elif

【讨论】:

  • 嗯,我尝试将多个“if”更改为一些“elif”,但没有解决问题 =/
  • 浏览整个代码,至少每隔 3 行注释一次,并证明您了解自己在做什么。这会很乏味,但你可能会弄清楚你做错了什么。您似乎没有尝试删除重现错误所不需要的部分代码。你给了我们大约 200 行代码,而重现错误可能只需要四分之一。
  • 删除了一些冗余代码,希望对您有所帮助,对不起,我是新手。我决定仅以与右侧墙壁的碰撞为例,因为球不会与任何东西发生碰撞。
  • 这都是好人。诀窍是只发布让我们运行的代码。通常这意味着一些导入,例如graphics.py,然后是win = ... 之类的初始化内容,然后是导致问题的逻辑。
  • 好吧,添加了这些,并将其精简到我认为搞砸的逻辑。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多