Why does this code have a “ball” seems to be sliding along the edge

My son asked me if I could write a small program so that the ball would bounce around the screen, and then I will explain it. Having marked the neat possibility of fatherhood, I said: "Yes, no problem." So I dug up my python skills and wrote this.

#!/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 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() 

I ran the program and was very pleased. However, when the ball hits the edge, it seems to “slip” and does not bounce cleanly.

It is quite late in the evening, so I could not lower my head, and I thought that I would throw it away and see if anyone could explain why. I do not fix the code, I am sure that with <= or> = the tests will work. I just can’t understand what he is doing, what he is doing ...

thanks Mark.

+4
source share
5 answers

You need to add dir_ * twice to the "change direction" code.

+10
source

You check the new x and y coordinate before testing. So, let's say the ball is at 20, 1 and drawn, and suppose that the edge is in the northeast with a slope of 1. The next position will be calculated at 21, 0. Here you can see that y is now out of range. So you set it to 1 when what you really want is 2, so you get a slide around the edge. Usually what I do is first checked for the following conditions, and then adds new offsets. So that...

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

Obtaining such a simulation for correct operation around the edges is difficult. I ran it here and it looks good to me (OS X). When it hits the edge, you get two O in a row along the edge, but then it returns. I believe this is due to how much your virtual x, y point needs to penetrate before the turn, which depends on how fast it moves.

0
source

Spent me to figure out what you mean. Do you mean the double “OO” on the wall when it changes direction? It seems that the condition allows the ball to pass (not up to) the line, and then pulls it back again. I changed this bit:

 # 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 

(Note that I changed> na> = the same one with <and I also commented on the second increment - if you catch it on a line in which you don't need it.)

Good example, by the way.

0
source

Not very familiar with python, but

 dir_x = -dir_x 

Acceptable? Maybe try

 dir_x *= -1 

or

 dir_x = dir_x * -1 

?

-2
source

Source: https://habr.com/ru/post/1299165/


All Articles