Home > Mobile >  Move two rects seperately with wasd and arrow keys in pygame?
Move two rects seperately with wasd and arrow keys in pygame?

Time:10-10

I am new to programming with pygame and python itself. I was trying to make a simple local multiplayer game using pygame. I wrote my code while watching a tutorial on moving only one rectangle because I did not find anything on what I am trying to do. When I finished, I copied the part of the script with the variables and the movement for the rectangle and then pasted it and changed the variable names so it does not crash or something. Now, here comes my problem: because the movement is simple, it would print a new rectangle, if I press the buttons to move. Because of that, the background is refreshing its color all the time (or something like that) so only the one rectangle I want to move is shown. But if there is a second rect, the color covers it, and only one is visible all the time. How can I fix that?

Here is the code:

import pygame
pygame.init()

win = pygame.display.set_mode((500, 500))

pygame.display.set_caption("local multiplayer")

#variables player 1

X = 200
Y = 200
Width = 40
Height = 60
Vel = 5

#variables player 2

x = 50
y = 50
width = 40
height = 60
vel = 5

run = True
while run:
    pygame.time.delay(100)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()

#player 1

    if keys[pygame.K_a]:
        X -= Vel
    if keys[pygame.K_d]:
        X  = Vel
    if keys[pygame.K_w]:
        Y -= Vel
    if keys[pygame.K_s]:
        Y  = Vel

    win.fill((0, 0, 0))
    pygame.draw.rect(win, (255, 255, 255), (X, Y, Width, Height))
    pygame.display.update()

#player 2

    if keys[pygame.K_LEFT]:
        x -= vel
    if keys[pygame.K_RIGHT]:
        x  = vel
    if keys[pygame.K_UP]:
        y -= vel
    if keys[pygame.K_DOWN]:
        y  = vel

    win.fill((0, 0, 0))
    pygame.draw.rect(win, (255, 255, 255), (x, y, width, height))
    pygame.display.update()

pygame.quit()

CodePudding user response:

You are doing win.fill((0, 0, 0)) right after displaying player 1. Remove this code before you display the second character. Also, keep the fill line at the top of your app loop. This would give:

pygame.init()

win = pygame.display.set_mode((500, 500))

pygame.display.set_caption("local multiplayer")

#variables player 1

X = 200
Y = 200
Width = 40
Height = 60
Vel = 5

#variables player 2

x = 50
y = 50
width = 40
height = 60
vel = 5

run = True
while run:
    win.fill((0, 0, 0))
    pygame.time.delay(100)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()

#player 1

    if keys[pygame.K_a]:
        X -= Vel
    if keys[pygame.K_d]:
        X  = Vel
    if keys[pygame.K_w]:
        Y -= Vel
    if keys[pygame.K_s]:
        Y  = Vel

    pygame.draw.rect(win, (255, 255, 255), (X, Y, Width, Height))

#player 2

    if keys[pygame.K_LEFT]:
        x -= vel
    if keys[pygame.K_RIGHT]:
        x  = vel
    if keys[pygame.K_UP]:
        y -= vel
    if keys[pygame.K_DOWN]:
        y  = vel

    pygame.draw.rect(win, (255, 255, 255), (x, y, width, height))
    pygame.display.update()

pygame.quit()

It is also good practice to only update the screen once per loop. Another thing I would do is put the input all in the same if block (but that is not necessary). To further improve your code- consider making a player class that has a render function to display itself, along with an update function to handle control.

CodePudding user response:

When you call win.fill((0, 0, 0)) the entire display is cleared. You have to draw the rectangles at once after clearing the display.
Update of the display at the end of the application loop. Multiple calls to pygame.display.update() or pygame.display.flip() cause flickering (see Why is the PyGame animation is flickering).

Simplify the code and use pygame.Rect objects to represent the players. Use pygame.Rect.clamp_ip to prevent the player from leaving the screen.

import pygame

pygame.init()
win = pygame.display.set_mode((500, 500))
pygame.display.set_caption("local multiplayer")
clock = pygame.time.Clock()

player1 = pygame.Rect(200, 200, 40, 60)
vel1 = 1
player2 = pygame.Rect(50, 40, 40, 60)
vel2 = 1

run = True
while run:
    clock.tick(50)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()
    player1.x  = (keys[pygame.K_d] - keys[pygame.K_a]) * vel1
    player1.y  = (keys[pygame.K_s] - keys[pygame.K_w]) * vel1
    player2.x  = (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel2
    player2.y  = (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * vel2
    player1.clamp_ip(win.get_rect())
    player2.clamp_ip(win.get_rect())

    win.fill((0, 0, 0))
    pygame.draw.rect(win, (255, 255, 255), player1)
    pygame.draw.rect(win, (255, 255, 255), player2)
    pygame.display.update()

pygame.quit()

The typical PyGame application loop has to:

  • Related