Почему этот код имеет "шар", кажется, скользит по краю - PullRequest
4 голосов
/ 23 января 2010

Мой сын спросил меня, могу ли я написать небольшую программу, чтобы мяч отскакивал от экрана, и попросил меня объяснить это. Обнаружив изящную возможность отца и сына, я сказал: «Да! Нет проблем». Поэтому я выкопал свои навыки 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()

Я запустил программу и был вполне доволен. Однако, когда мяч ударяется о край, он, кажется, «скользит» и не отскакивает чисто.

Уже довольно поздно вечером, поэтому я не мог обдумать это, и я подумал, что брошу это туда и посмотрю, сможет ли кто-нибудь объяснить почему. Я не после исправления кода, я почти уверен, что с <= или> = тесты будут работать. Я просто не могу понять, что он делает, что делает ...

Thx Марк.

Ответы [ 5 ]

10 голосов
/ 23 января 2010

Вам нужно дважды добавить dir_ * в коде "изменить направление".

4 голосов
/ 23 января 2010

Вы вычисляете новые координаты x и y перед тестированием. Итак, допустим, что мяч находится в положении 20, 1 и нарисован, и предположим, что уклон - это северо-восток с уклоном 1. Следующая позиция будет рассчитана в 21, 0. Здесь вы видите, что y вне диапазона. Таким образом, вы устанавливаете его обратно в 1, когда то, что вы действительно хотите, равняется 2, так что вы получаете слайд через край. Обычно я сначала проверяю следующие условия, а затем добавляю новые смещения. Итак ...

if x + dir_x > max_x or x - dir_x < min_x:
0 голосов
/ 24 февраля 2010

Мне понадобилось время, чтобы понять, что ты имеешь в виду. Вы имеете в виду двойное «ОО» на стене, когда оно меняет направление? Мне кажется, что условие позволяет мячу пересечь (не до) линию и затем снова вытягивает ее. Я изменил этот бит:

# 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

(Обратите внимание, что я изменил> на> = и то же самое с <, и я также закомментировал второй шаг - если вы поймаете его в строке, он вам не нужен.) </p>

Кстати, хороший маленький пример.

0 голосов
/ 23 января 2010

Получить этот вид симуляции для правильной работы по краям сложно. Я запустил его здесь, и он выглядит хорошо для меня (OS X). Когда он достигает края, вы получите два О подряд на краю, но затем он возвращается. По-видимому, это связано с тем, как далеко должна проникнуть ваша виртуальная точка x, y, прежде чем произойдет разворот, который зависит от того, насколько быстро она движется.

0 голосов
/ 23 января 2010

Не совсем знаком с python, но

dir_x = -dir_x

Приемлемая? Может быть, попробуйте

dir_x *= -1

или

dir_x = dir_x * -1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...