문제

Here is my code

import pygame, sys

pygame.init() #load pygame modules
size = width, height = 800, 600 #size of window
speed = [25,25] #speed and direction
x= 100
y= 100
screen = pygame.display.set_mode(size) #make window
s=pygame.Surface((50,50)) #create surface 50px by 50px
s.fill((33,66,99)) #color the surface blue
r=s.get_rect() #get the rectangle bounds for the surface
r[0] = x #changes initial x position
r[1] = y #changes initial y position
clock=pygame.time.Clock() #make a clock

while 1: #infinite loop

        clock.tick(30) #limit framerate to 30 FPS
        for event in pygame.event.get(): #if something clicked
                if event.type == pygame.QUIT:#if EXIT clicked
                        pygame.quit()
                        sys.exit() #close cleanly

        r=r.move(speed) #move the box by the "speed" coordinates
        #if we hit a  wall, change direction
        if r.left <= 0 or r.right >= width:
                speed[0] = -(speed[0])*0.9 #reduce x axis "speed" by 10% after hitting

        if r.top <= 0 or r.bottom >= height:
                speed[1] = -speed[1]*0.9 #reduce y axis "speed" by 10% after hitting

        screen.fill((0,0,0)) #make redraw background black
        screen.blit(s,r) #render the surface into the rectangle
        pygame.display.flip() #update the screen

It's a simple window that shows a square moving, hitting the edges and bouncing back. However, in this particular example (speed set to 25 on both axis) and speed reduction set to 0.9 after bouncing back (less 10%), my square seems to get stuck on the left side of the window (I suggest you to copy and paste it and see for yourself)

If I change the speed to a lower value or set no speed reduction whatsoever after bouncing everything works fine.

Any reason on why this is happening?

도움이 되었습니까?

해결책 2

Right! To make the square move and bounce freely without getting potentially stuck in an edge what you need to do is to reverse the speed (and decrease it by 10%) before you actually move the ball! This is my simple suggestion

if r.left + speed[0] <= 0 or r.right + speed[0] >= width:
    speed[0] = - (speed[0])*0.9

if r.top + speed[1] <= 0 or r.bottom + speed[1] >= height:
    speed[1] = -(speed[1])*0.9

What the above modifications manages, is that it essentialy does not allow the square to go out of bounds at any time! As far as to what caused your above issue, after doing some debugging, it is apparent that the square manages to move outside the screen! (i.e. negative x,negative y etc), While it might seem harmless, this behaviour especially at lower speeds can cause the square to rapidly reverse and at the same time lower it's speed by 10%!

For example if at any point the square is at position x = - 1 with an xspeed of 1. Due to this condition: if r.left + speed[0] <= 0 or r.right + speed[0] >= width: it's speed will reverse multiple times back and forth and decrease at the same time not allowing the square to escape this edge!

Phew! Sorry for the long answer and I hope I helped! Cheers!,

Alex

다른 팁

Let's step through this code one by one:

speed = [25,25] #speed and direction
if r.left <= 0 or r.right >= width:
      speed[0] = -(speed[0])*0.9

Let's just look at what happens at the x axis.

Let's assume the position before this check is 1. In the next frame, the value of position is 1-25 = -24. Since the condition is now fulfilled, the speed becomes 25 * 0.9 = 22.5.

The rectangle moves to position -1.5 and we are still on the wrong side of the wall. Since you change the direction of speed on each frame, the rectangle will be stuck there.

There are 2 solutions to the problem, the first one is already described by Alex.

The second one, is to move the rectangle first, and if the rectangle moves out of bounds, return it to before the wall.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top