【问题标题】:Why does this code have the "ball" seem to slide along the edge为什么这段代码的“球”似乎沿着边缘滑动
【发布时间】:2010-01-22 23:34:42
【问题描述】:

我儿子问我是否可以写一个小程序让球在屏幕上弹跳,然后让我解释一下。 发现一个整洁的父子机会,我说“是的!没问题”。所以我挖出了我的python技能,写了这个..

#!/usr/bin/python

#
# We have to tell python what stuff we're
# going to use. We do this by asking to import
# the code we'll be making use of
#
import curses
import random
import time

#
# We'll be using a screen handling
# package called "curses" so we need
# to initialise the screen
stdscr = curses.initscr()

# We need to make sure that
# keys we type will not show up
# on the screen spoiling the
# stuff we're drawing
curses.noecho()

# We need to tell curses that we don't
# want to wait when we ask for keys from
# the user, if there's non there then 
# we want curses to carry on
stdscr.nodelay( True )

# This ones a bit tricky to explain.
# Basically it puts the keyboard into
# a mode which allows curses to do
# things with it...
curses.cbreak()

# Ok, now we can do the fun stuff

# First thing we need to do is to
# find out how big our screen is
max_y, max_x = stdscr.getmaxyx()

stdscr.box()

min_x = 1
min_y = 1

max_y = max_y - 2
max_x = max_x - 2

stdscr.addstr( min_y, min_x, "1" )
stdscr.addstr( min_y, max_x, "2" )
stdscr.addstr( max_y, min_x, "3" )
stdscr.addstr( max_y, max_x, "4" )

dir_x = 1
dir_y = 1

# Then we can pick a random point on the
# screen in both the y (up-down) and x
# (left-right) directions
y = random.randint( 0, max_y )
x = random.randint( 0, max_x )

# Ok, this basically says, while trying to
# get a key from the user keeps coming back
# with an error, meaning there aren't any keys
# to return, do the code inside the loop
while( stdscr.getch() == curses.ERR ):
    # Ok, at the location we got, put a "0"
    stdscr.addstr( y, x, "O" )
    # stdscr.addstr( str( (y, x) ) )

    # this just moves the cursor to a new location so we can see the "O" better
    stdscr.move( 0, 0 )

    # have the screen update
    stdscr.refresh()

    # now choose a new location
    x = x + dir_x
    y = y + dir_y

    # have we gone too far
    if x > max_x or x < min_x:
        # change direction
        dir_x = -dir_x
        x = x + dir_x

    if y > max_y or y < min_y:
        # change direction
        dir_y = -dir_y
        y = y + dir_y

    # wait a bit so we can see the screen we've drawn.
    time.sleep( 0.05 )

# Ok, we're finished. Tidy up
curses.nocbreak()
stdscr.keypad( False )
curses.echo()
curses.endwin()

我运行了这个程序并且非常高兴。然而,当球击中边缘时,它似乎会“滑动”而不是干净地反弹。

已经很晚了,所以我无法理解它,我想我会把它扔在那里,看看是否有人能解释原因。 我不是在修复代码之后,我很确定使用 = 测试会起作用。我只是不明白它做了什么......

谢谢 标记。

【问题讨论】:

    标签: python


    【解决方案1】:

    您需要在“改变方向”代码中添加两次 dir_*。

    【讨论】:

      【解决方案2】:

      在测试之前,您正在计算一个新的 x 和 y 坐标。因此,假设球在 20, 1 并被绘制,并假设 dir 是 North East,坡度为 1。下一个位置将在 21, 0 处计算。在这里您可以看到 y 现在超出了范围。因此,当您真正想要的是 2 时,您将其设置回 1,这样您就会得到一个滑过边缘的幻灯片。通常,我所做的是首先测试下一个条件,然后添加新的偏移量。所以...

      if x + dir_x > max_x or x - dir_x < min_x:
      

      【讨论】:

      • 啊!谢谢,我现在明白了。所以基本上,当我添加的方向让我走得太远时,添加一个相反的方向只会让我回到边缘。我需要增加两倍的“反弹”,这是 Chrispy 建议的......我必须承认,您的“更改前的测试”看起来更优雅而不是“神奇” x = x + (2 *dir_x )。
      • 嗯.. 我试图将其付诸实践,但我认为您的代码有点错误。在 "x - dir_x
      【解决方案3】:

      让这种模拟在边缘正常工作是很棘手的。我在这里运行它,它对我来说看起来不错(OS X)。当它击中边缘时,您将在边缘连续获得两个 O,但随后它又回来了。猜测一下,这与你的虚拟 x,y 点在反转发生之前必须穿透多远有关,这取决于它移动的速度。

      【讨论】:

      • 这是 OP 描述的问题。 chrispy 发布的答案是正确的解决方案。
      • 所以...对于那些不赞成投票的人,我自己做了这种模拟并遇到了这些问题,我仍然相信我的评论总体上是有效的,但不适用于这篇文章。原因是,b/c 这是一个玩具问题。此外,OP 的描述不准确,动画不会“滑动”,沿着边缘连续获得 2 个,这已按照@chrispy 描述的方式解决,并且 OP 对这个答案的回答是正确的。
      【解决方案4】:

      我花了一段时间才弄清楚你的意思。你的意思是当它改变方向时墙上的双'OO'?在我看来,条件允许球越过(不超过)线,然后再次将其拉回。我改变了这一点:

      # have we gone too far
      if x >= max_x or x <= min_x:
          # change direction
          dir_x = -dir_x
          #x = x + dir_x
      
      if y >= max_y or y <= min_y:
          # change direction
          dir_y = -dir_y
          #y = y + dir_y
      

      (请注意,我将 > 更改为 >= 并且与

      顺便说一句,很好的小例子。

      【讨论】:

        【解决方案5】:

        对python不太熟悉,但是

        dir_x = -dir_x
        

        可以接受吗?可以试试

        dir_x *= -1
        

        dir_x = dir_x * -1
        

        ?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-05-19
          • 2015-11-03
          • 2017-12-31
          • 2019-01-11
          • 2014-01-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多