Pygame, move a square on the screen, but can not e

2019-08-02 07:04发布

This is my first post in StackOverflow, hope you guys can help a newbie programmer. It's Pygame Python simple ask.

I am trying to move a square on the screen, but can not erase the previous movements.

import pygame

pygame.init()
screen = pygame.display.set_mode((400,300))
pygame.display.set_caption("shield hacking")
JogoAtivo = True
GAME_BEGIN = False
# Speed in pixels per frame
x_speed = 0
y_speed = 0
cordX = 10
cordY = 100


def desenha():
    quadrado = pygame.Rect(cordX, cordY ,50, 52)

    pygame.draw.rect(screen, (255, 0, 0), quadrado)
    pygame.display.flip()



while JogoAtivo:
    for evento in pygame.event.get():
        print(evento);
    #verifica se o evento que veio eh para fechar a janela
        if evento.type == pygame.QUIT:
               JogoAtivo = False
               pygame.quit();
        if evento.type == pygame.KEYDOWN:     
            if evento.key == pygame.K_SPACE:
                   print('GAME BEGIN')
                   desenha()
                   GAME_BEGIN = True;
            if evento.key == pygame.K_LEFT and GAME_BEGIN:   
                   speedX=-3
                   cordX+=speedX
                   desenha()


            if evento.key == pygame.K_RIGHT and GAME_BEGIN:
                   speedX=3
                   cordX+=speedX
                   desenha()   

3条回答
家丑人穷心不美
2楼-- · 2019-08-02 07:41

You have to draw over the previous image. Easiest is to fill the screen with a background color in the beginning of the game loop, like so:

screen.fill((0, 0, 0))
查看更多
smile是对你的礼貌
3楼-- · 2019-08-02 07:44

I am also a newbie and I am doing something similar and I hope this helps

import pygame

clock=pygame.time.Clock() #the frames per second BIF in pygame
pygame.init()
FPS=30
display_width=800
display_height=600
white=(255,255,255)
black=(0,0,0)
block_size=10
gameExit=False
lead_x = display_width / 2
lead_y = display_height / 2

lead_x_change = 0  # 0 beacuse we will not be changing the position in the beginning
lead_y_change = 0

gameDisplay=pygame.display.set_mode((display_width,display_height))

while not gameExit: #game loop

    for event in pygame.event.get():  #event handling BIF in pygame EVENT LOOP
        #print(event) # prints out the position of the mouse and the buttons pressed when in game window
        if event.type== pygame.QUIT: #if the user presses the [x] in game window, it quits the window
            gameExit=True    

    if event.key == pygame.K_LEFT:
                lead_x_change = -block_size #block size is number of pixels moved in one loop
                lead_y_change=0

            elif event.key==pygame.K_RIGHT:
                lead_x_change=  block_size
                lead_y_change=0

            elif event.key==pygame.K_UP:
                lead_y_change= -block_size
                lead_x_change=0

            elif event.key==pygame.K_DOWN:
                lead_y_change= block_size
                lead_x_change=0
    lead_y+=lead_y_change
    lead_x+=lead_x_change

   gameDisplay.fill(white) #fills the display surface object, backgroud color is the parameter filled in        

   pygame.draw.rect(gameDisplay,black,[lead_x,lead_y,block_size,block_size])

   pygame.display.update() #after done with all the action,update the surface

   clock.tick(FPS) #runs the game at 30FPS

pygame.quit()
quit()
查看更多
Rolldiameter
4楼-- · 2019-08-02 08:03

You also can draw everything from a previous surface, before the square was in place, then draw the square on it always in a different place. Then draw the new surface to screen each time.

But not really good strategy, it can be slow and/or induce flickering.

For instance:

# Draw anything to the display surface named screen, then do:
# By display surface I mean the surface returned by pygame.display.set_mode()
orig = screen.copy()
# Sometimes it will not be filled with a image from screen that you have drawn before, so you draw
# all to orig surface
# Then you make a surface that will be shown on the screen and do:
s = pygame.surface.Surface()
s.blit(orig, 0, 0)
# Then you draw the rectangle or whatever on s, and then:
screen.blit(s, 0, 0)
pygame.display.flip()
# and you keep orig as a starting point for every move

If you have many movable objects on the screen simultaneously this is good, or if you are refreshing restricted areas only, else redraw over the last image as suggested in other answer.

If you go about drawing directly to the display surface flicker will be bigger and sometimes, especially when display is hardware accelerated you will have problems. On non desktop devices like mobile phones especially. Drawing over and adding new usually works fine directly on display surface and would be the correct approach to your problem.

I know I sound contradictive, but some stuff you simply must see for yourself. Get experience by experimenting.

查看更多
登录 后发表回答