Chicken Dinner
Chicken Dinner

Reputation: 11

Pygame rectangle movement left to right

I have created a enemy class with a pygame.rect and I'm trying to move it from right to left on the screen then back right and repeat that in the loop. So far in the enemy update I only have moving from right to left functioning, then the rect stops. Is this because it is constantly updating which causes the code not to work? I'm not sure how to implement going both directions.

# Pygame template - skeleton for a new pygame project
import pygame
import random
import os

# set up asset folders
os.environ['SDL_VIDEO_CENTERED'] = '1'
game_folder = os.path.dirname(__file__)
img_folder = os.path.join(game_folder, 'img')

# Screen resolution and frames
WIDTH = 480
HEIGHT = 600
FPS = 60

# define colors
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

# initialize pygame and create window
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Shmup!")
clock = pygame.time.Clock()

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((100, 40))
        self.image.fill(GREEN)
        self.rect = self.image.get_rect()
        self.rect.centerx = WIDTH / 2
        self.rect.bottom = HEIGHT - 10
        self.speedx = 0
        self.speedy = 0

    def update(self):
        self.speedx = 0
        self.speedy = 0
        keystate = pygame.key.get_pressed()
        if keystate[pygame.K_LEFT]:
            self.speedx = -8
        if keystate[pygame.K_RIGHT]:
            self.speedx = 8
        self.rect.x += self.speedx
        if keystate[pygame.K_UP]:
            self.speedy = -8
        if keystate[pygame.K_DOWN]:
            self.speedy = 8
        self.rect.y += self.speedy
        if self.rect.right > WIDTH:
            self.rect.right = WIDTH
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.bottom > HEIGHT:
            self.rect.bottom = HEIGHT
        if self.rect.top < 100:
            self.rect.top = 100



class Enemies(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((50, 40))
        self.image.fill(BLACK)
        self.rect = self.image.get_rect()
        self.rect.x = WIDTH - 10
        self.rect.bottom = HEIGHT / 2
        self.speedx = 0

    def update(self):
        self.speedx = 0
        if self.rect.right > 0:
            self.speedx = 2  
        self.speedx = -self.speedx
        if self.rect.left < 0:
            self.speedx *= -1
        self.speedx = self.speedx

        self.rect.x += self.speedx


all_sprites = pygame.sprite.Group()
player = Player()
enemies = Enemies()
all_sprites.add(player)
all_sprites.add(enemies)

# Game Loop
running = True
while running:
    # keep loop running at the right speed
    clock.tick(FPS)
    # Process input (events)
    for event in pygame.event.get():
        # check for closing window
        if event.type == pygame.QUIT:
            running = False


    # Update
    all_sprites.update()

    #Draw / render
    screen.fill(BLUE)
    all_sprites.draw(screen)
    # *after* drawing everything
    pygame.display.flip()

pygame.quit()
quit()

Upvotes: 1

Views: 1419

Answers (1)

Rabbid76
Rabbid76

Reputation: 211219

Don't over complicate things. Init the constant speed in the constructor:

class Enemies(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        # [...]
        self.speedx = 2

There are 2 cases where you've to change the speed.
If the enemy is at the left (self.rect.left <= 0), then the moving direction has to be changed to the right, this means self.speedx has to be positive. Use abs(x) to make the speed positive (e.g. self.speedx = abs(self.speedx)).
If the enemy is at the right (self.rect.right >= WIDTH), then direct has to be changed to the left. So the speed has to be negative (e.g. self.speedx = -abs(self.speedx)).

The following code moves the enemy always in the proper direction, even if the enemy is out of the window:

class Enemies(pygame.sprite.Sprite):

    # [...]

    def update(self):
        if self.rect.left <= 0:
            self.speedx = abs(self.speedx)
        elif self.rect.right >= WIDTH:
            self.speedx = -abs(self.speedx) 
        self.rect.x += self.speedx    

Upvotes: 1

Related Questions