0

I'm very new to programing and I decided to try and make a very simple game to practice using pygame. It's just a game where you're a rectangle and have to avoid geting hit by other rectangles(enemies). However I'm having issues spawning in the enemies, something I did makes it so when I draw them to the screen they will draw on the same spot making it look like I have one very fast moving enemy rather than multiple of them. I used a sprite for the enemy just to learn how to do sprites, it's just a red square and I'm aware that I could have used the drawRect function. I have tried to look for answers on this and found that apparently the best to do this is with classes but I can't seem to make that work either. Here is the code, I'm very sorry for the format of this post it's my first time posting here and I'm still not sure how to do this Please let me know if I posted this in the wrong place, again I don't know how this works.

from textwrap import fill
import pygame
import os
import random
pygame.font.init()

text = "GAMEOVER!"

WIDTH, HEIGHT = 450, 450
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Rando game")
HEALTH_FONT = pygame.font.SysFont('comicsans', 40)
FPS = 60
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
PURPLE = (255, 0, 255)
ENEMY_VEL = 5
PLAYER_VEL = 10
HIT = pygame.USEREVENT + 1
class enemy:
    enemy_x = random.randint(0, WIDTH)
    enemy_y = - 30
ENEMY_SPRITE = pygame.transform.scale(pygame.image.load(
    'RED.png'), (30, 30))


#DRAW STUFF
def draw_window(enemy, player, health, enemies):
    WIN.fill(WHITE)
    #health
    health_text = HEALTH_FONT.render(str(health), 1, PURPLE)
    WIN.blit(health_text,(0, 0))

    #enemies
    for enemy in enemies:
        WIN.blit(ENEMY_SPRITE, (enemy.enemy_x, enemy.enemy_y))
    #player
    pygame.draw.rect(WIN, BLUE, player)
   

    pygame.display.update()


def handle_player_movement(player, keys_pressed):
    if keys_pressed[pygame.K_d] and player.x + PLAYER_VEL <= WIDTH - 25:
        player.x += PLAYER_VEL
    if keys_pressed[pygame.K_a] and player.x - PLAYER_VEL >= 0:
        player.x -= PLAYER_VEL

def enemy_movement(enemy, enemies):
        for enemy in enemies:
            enemy.enemy_y += ENEMY_VEL
    
def handle_collision(player, enemy, enemies):
    for enemy in enemies:
        if player.x + 25 > enemy.enemy_x and player.x <= enemy.enemy_x + 25 and player.y == enemy.enemy_y + 25:
            enemies.remove(enemy)
            pygame.event.post(pygame.event.Event(HIT))
            enemies.append(enemy)
            enemy.enemy_y = 0
            enemy.enemy_x = random.randint(0, WIDTH - 30)
        elif enemy.enemy_y > HEIGHT:
            enemies.remove(enemy)
            enemies.append(enemy)
            enemy.enemy_y = 0
            enemy.enemy_x = random.randint(0, WIDTH - 30)        



def main():
    clock = pygame.time.Clock() #locks fps
    run = True

    
    player = pygame.Rect(0, 425, 25, 25)
    health = 3
  
    while run:
        clock.tick(FPS)
        enemies = []
        for n in range(6):
            enemies.append(enemy)
        for event in pygame.event.get():
            if event.type == pygame.QUIT: #quits
                run = False
                pygame.quit()
     
            if event.type == HIT:
                health -= 1
                
        if health <= 0:
            enemies.remove(enemy)
            draw_text = HEALTH_FONT.render(text, 1, PURPLE)
            WIN.blit(draw_text, (WIDTH / 2 - draw_text.get_width() / 2, HEIGHT / 2 - draw_text.get_height() / 2))
            pygame.display.update()
            pygame.time.delay(2000)
            break
                


        print(enemies)
        keys_pressed = pygame.key.get_pressed()
        enemy_movement(enemy, enemies)
        handle_player_movement(player, keys_pressed)
        handle_collision(player, enemy, enemies)
        draw_window(enemy, player, health, enemies)
    main()
    

if __name__ == '__main__':
        main()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Oct 23 '22 at 14:43

1 Answers1

0

My recommendation is to learn classes. They are absolutely a life saver in game programming.

Some info about classes from w3schools

All classes have a function called init(), which is always executed when the class is being initiated.

Use the init() function to assign values to object properties, or other operations that are necessary to do when the object is being created


In your posted example, all six enemies were spawning in the exact same spot each time. I've updated your code example so that multiple enemies spawn in different location.

from textwrap import fill
import pygame
import os
import random
pygame.font.init()

text = "GAMEOVER!"

WIDTH, HEIGHT = 450, 450
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Rando game")
HEALTH_FONT = pygame.font.SysFont('comicsans', 40)
FPS = 60
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
PURPLE = (255, 0, 255)
ENEMY_VEL = 5
PLAYER_VEL = 10
HIT = pygame.USEREVENT + 1
ENEMY_SPRITE = pygame.transform.scale(pygame.image.load(
    'RED.png'), (30, 30))

# Enemy class that stores a single enemy
class Enemy:
    def __init__(self):
        # Each time you call Enemy(), a new enemy is created with a random x value
        self.enemy_x = random.randint(0, WIDTH)
        self.enemy_y = -30

#DRAW STUFF
def draw_window(player, health, enemies):
    WIN.fill(WHITE)
    #health
    health_text = HEALTH_FONT.render(str(health), 1, PURPLE)
    WIN.blit(health_text,(0, 0))

    #enemies
    for enemy in enemies:
        WIN.blit(ENEMY_SPRITE, (enemy.enemy_x, enemy.enemy_y))
    #player
    pygame.draw.rect(WIN, BLUE, player)
   

    pygame.display.update()


def handle_player_movement(player, keys_pressed):
    if keys_pressed[pygame.K_d] and player.x + PLAYER_VEL <= WIDTH - 25:
        player.x += PLAYER_VEL
    if keys_pressed[pygame.K_a] and player.x - PLAYER_VEL >= 0:
        player.x -= PLAYER_VEL

def enemy_movement(enemies):
    for enemy in enemies:
        enemy.enemy_y += ENEMY_VEL
    
def handle_collision(player, enemies):
    for enemy in enemies:
        if player.x + 25 > enemy.enemy_x and player.x <= enemy.enemy_x + 25 and player.y == enemy.enemy_y + 25:
            enemies.remove(enemy)
            pygame.event.post(pygame.event.Event(HIT))
            enemies.append(enemy)
            enemy.enemy_y = 0
            enemy.enemy_x = random.randint(0, WIDTH - 30)
        elif enemy.enemy_y > HEIGHT:
            enemies.remove(enemy)
            enemies.append(enemy)
            enemy.enemy_y = 0
            enemy.enemy_x = random.randint(0, WIDTH - 30)        

def main():
    clock = pygame.time.Clock() #locks fps
    run = True

    
    player = pygame.Rect(0, 425, 25, 25)
    health = 3
  
    enemies = []
    for _ in range(6):
        enemies.append(Enemy()) # Instantiates 6 new enemies with different x values

    while run:
        clock.tick(FPS)
        for event in pygame.event.get():
            if event.type == pygame.QUIT: #quits
                run = False
                pygame.quit()
            if event.type == HIT:
                health -= 1
                
        if health <= 0:
            enemies = []                                        # Remove all enemies
            draw_window(player, health, enemies)                # Update the window
            draw_text = HEALTH_FONT.render(text, 1, PURPLE)
            WIN.blit(draw_text, (WIDTH / 2 - draw_text.get_width() / 2, HEIGHT / 2 - draw_text.get_height() / 2))
            pygame.display.update()
            pygame.time.delay(2000)
            break
        
        keys_pressed = pygame.key.get_pressed()
        enemy_movement(enemies)
        handle_player_movement(player, keys_pressed)
        handle_collision(player, enemies)
        draw_window(player, health, enemies)

if __name__ == '__main__':
    main()
Alexander Freyr
  • 569
  • 1
  • 6
  • 19