Geordyd
Geordyd

Reputation: 165

Moving a sprite while it is moving pygame

The problem I am facing is that I have an enemy sprite that is walking on a predetermined path and he needs to keep doing that, but when I press a button he needs to move to the right for example but he still needs to move on the predetermined path. So it's like the predetermined path has to move to the right on a keypress.

This is my code:

import pygame
import random
import os
import time
from random import choices
from random import randint
from pygame.math import Vector2
import itertools

pygame.init()
a = 0
b = 0
width = 1280
height = 720
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Game")
done = False
n = 0
x = 0
y = 0
x_wall = 0
y_wall = 0
clock = pygame.time.Clock()
WHITE = (255,255,255)
RED = (255,0,0)
change_x = 0
change_y = 0
HW = width / 2
HH = height / 2
background = pygame.image.load('mountains.png')
x1 = 200
y1 = 100
x2 = 500
y2 = 400
x3 = 100
y3 = 300

#player class
class Player(pygame.sprite.Sprite):
    def __init__(self):
      pygame.sprite.Sprite.__init__(self)
      self.image = pygame.image.load("character.png") 
      self.rect = self.image.get_rect()
      self.rect.x = width / 2
      self.rect.y = height / 2

#enemy class
class Enemy(pygame.sprite.Sprite):

  def __init__(self, pos, waypoints):
    super().__init__()
    self.image = pygame.image.load("enemy.png")
    self.image = pygame.transform.scale(self.image, (int(50), int(50)))
    self.rect = self.image.get_rect(center=pos)
    self.vel = Vector2(0, 0)
    self.max_speed = 5
    self.pos = Vector2(pos)
    self.waypoints = waypoints
    self.waypoint_index = 0
    self.target = self.waypoints[self.waypoint_index]
    self.target_radius = 50
    self.rect.x = width / 2
    self.rect.y = height / 2

  def update(self):

    # A vector pointing from self to the target.
    heading = self.target - self.pos
    distance = heading.length()  # Distance to the target.
    heading.normalize_ip()
    if distance <= 2:  # We're closer than 2 pixels.
      # Increment the waypoint index to swtich the target.
      # The modulo sets the index back to 0 if it's equal to the length.
      self.waypoint_index = (self.waypoint_index + 1) % len(self.waypoints)
      self.target = self.waypoints[self.waypoint_index]
    if distance <= self.target_radius:
            # If we're approaching the target, we slow down.
      self.vel = heading * (distance / self.target_radius * self.max_speed)
    else:  # Otherwise move with max_speed.
      self.vel = heading * self.max_speed

    self.pos += self.vel
    self.rect.center = self.pos


#Enemy waypoints
waypoints = [(x1, y1), (x2, y2), (x3, y3)]
enemy = Enemy((100, 300), waypoints)
all_sprites = pygame.sprite.Group(enemy)



#wall class
class Wall(pygame.sprite.Sprite):
  def __init__(self, x, y):
    pygame.sprite.Sprite.__init__(self)
    self.image = pygame.image.load("wall.png") 
    self.image = pygame.transform.scale(self.image, (int(50), int(50)))
    self.rect = self.image.get_rect()
    self.rect.x = x
    self.rect.y = y

#wall movement
  def update(self):
    self.vx = 0
    self.vy = 0
    key = pygame.key.get_pressed()
    if key[pygame.K_LEFT]:
      self.vx = 5
      self.vy = 0
    elif key[pygame.K_RIGHT]:
      self.vx = -5
      self.vy = 0
    if key[pygame.K_UP]:
      self.vy = 5
      self.vx = 0
    elif key[pygame.K_DOWN]:
      self.vy = -5
      self.vx = 0
    self.rect.x = self.rect.x + self.vx
    self.rect.y = self.rect.y + self.vy

#player sprite group
sprites = pygame.sprite.Group()
player = Player()
sprites.add(player)



#all the wall sprites
wall_list = pygame.sprite.Group()
wall = Wall(x_wall, y_wall)
wall2 = Wall((x_wall + 50), y_wall)
wall3 = Wall((x_wall + 100), y_wall)
wall4 = Wall((x_wall + 150), y_wall)
wall5 = Wall((x_wall + 200), y_wall)
wall6 = Wall((x_wall + 250), y_wall)


#add all the walls to the list to draw them later
wall_list.add(wall, wall2, wall3, wall4, wall5, wall6)

#add all the walls here to fix the collision
all_walls = (wall, wall2, wall3, wall4, wall5, wall6)

while not done:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
    #fill the screen
    screen.fill((0, 0, 0))

    #update sprites
    sprites.update()
    wall_list.update()
    all_sprites.update()


    ##collision between player and and walls
    #if player.rect.collidelist(all_walls) >= 0:
    #  print("Collision !!")
    #  player.rect.x = player.rect.x - player.vx
    #  player.rect.y = player.rect.y - player.vx

    #draw the sprites
    sprites.draw(screen)
    wall_list.draw(screen)
    all_sprites.draw(screen)

    pygame.display.flip()
    clock.tick(30)

pygame.quit()

Here is the download link with the images if you want to run it: https://geordyd.stackstorage.com/s/hZZ1RWcjal6ecZM

Upvotes: 1

Views: 137

Answers (1)

Micheal O&#39;Dwyer
Micheal O&#39;Dwyer

Reputation: 1261

Inside your update method of the Enemy class add in some input handling to move the waypoints in the event of a keypress.

key = pygame.get_key_pressed()

if key[pygame.K_RIGHT]:
    for i in range(len(waypoints)):
        waypoints[i][0] += 2 # Increment the x value of every waypoint

# Ect

I hope this helped you and if you have any further questions please feel free to comment below.

Upvotes: 1

Related Questions