pythonpygamegame-developmentpython-3.9pygame2

Unpredictable enemy speed changes


I made a game where enemies chase a player while the player collects coins through the map. It worked properly when i ran it in the idle but when i run it as an application (using auto-py-to-exe) the enemy movement has randomly changed..now they are moving at a very high speed. I am not sure where the error might lie. I ve found that changing my screen size or adding a print statement is also somehow affecting this. Could you suggest an explanation?...I am new to pygame and made most of the game piece by piece going through the docs

Heres my full code

import sys, pygame,time
import numpy as np
import math

pygame.init()

size = width, height = 410,310

screen = pygame.display.set_mode(size)
screen.set_colorkey((255,255,255))
pygame.display.set_caption('Game')


player = pygame.Surface((68,72))
player.set_colorkey((0,0,0))

bg=pygame.image.load("vf.jpg").convert_alpha()
bg.set_colorkey((255,255,255))
bgrect = bg.get_rect()

ash=pygame.image.load("ash.png").convert_alpha()
ashrect = ash.get_rect()
ashrect.x,ashrect.y=205,155
ashrect.w,ashrect.h=10,10

en1=pygame.image.load("charmander.png").convert_alpha()
en1rect = en1.get_rect()
en1rect.x,en1rect.y=500,200
en1rect.w,en1rect.h=10,10

en2=pygame.image.load("squirtle.png").convert_alpha()
en2rect = en2.get_rect()
en2rect.x,en2rect.y=500,700
en2rect.w,en2rect.h=10,10

en3=pygame.image.load("bulbasaur.png").convert_alpha()
en3rect = ash.get_rect()
en3rect.x,en3rect.y=100,500
en3rect.w,en3rect.h=10,10

poke=pygame.image.load("poke.png").convert_alpha()
pokerect = poke.get_rect()
pokerect.x,pokerect.y=100,100


score=0


x,y=0,0

def enSpeed(enx,eny,asx,asy,bs):

    if asx==enx and asy==eny:
        return [0,0]
    else:
        dirvect=pygame.math.Vector2(asx-enx,asy-eny)
        
        if dirvect.magnitude()<=200 or not bgrect.collidepoint((enx,eny)):
            dirvect.normalize_ip()
            dirvect.scale_to_length(5)
            spd=pygame.math.Vector2(dirvect[0]-bs[0],dirvect[1]-bs[1])
            spd.scale_to_length(5)
            return spd
        else:
            print("test print")
            
            return [-bs[0],-bs[1]]

    
bgspd=[0,0]


while 1:
    
    keys=pygame.key.get_pressed()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
            pygame.mixer.music.stop()


        if bgrect.colliderect(ashrect):
            if keys[pygame.K_d]:
                bgspd=[10,0]
                bgrect.move_ip([-10,0])
                pokerect.move_ip([-10,0]) 
                player.fill((0,0,0))
                x,y=-1,-2
            if keys[pygame.K_a]:
                bgspd=[-10,0]
                bgrect.move_ip([10,0])
                pokerect.move_ip([10,0])
                player.fill((0,0,0))
                x,y=-1,-1
            if keys[pygame.K_s]:
                bgspd=[0,10]
                bgrect.move_ip([0,-10])
                pokerect.move_ip([0,-10])
                player.fill((0,0,0))
                x,y=-1,0
            if keys[pygame.K_w]:
                bgspd=[0,-10]
                bgrect.move_ip([0,10])
                pokerect.move_ip([0,10])
                player.fill((0,0,0))
                x,y=-3,-3
        
            if event.type==pygame.KEYUP:
               x+=1
               bgspd=[0,0]
           
            if pokerect.colliderect(ashrect):
                pokerect.x=np.random.randint(bgrect.x,bgrect.x+900)
                pokerect.y=np.random.randint(bgrect.y,bgrect.y+1100)
                score+=1

            if en1rect.colliderect(ashrect) or en2rect.colliderect(ashrect)or en3rect.colliderect(ashrect) :
                gameOver()
                
        else:
            gameOver()
            
        if en1rect.colliderect(en2rect):
            en1rect.move_ip([np.random.randint(-100,100),np.random.randint(-100,100)])
            en2rect.move_ip([np.random.randint(-100,100),np.random.randint(-100,100)])
            
        if en2rect.colliderect(en3rect):
            en3rect.move_ip([np.random.randint(-100,100),np.random.randint(-100,100)])
            en2rect.move_ip([np.random.randint(-100,100),np.random.randint(-100,100)])
            
        if en3rect.colliderect(en1rect):
            en3rect.move_ip([np.random.randint(-100,100),np.random.randint(-100,100)])
            en1rect.move_ip([np.random.randint(-100,100),np.random.randint(-100,100)])
    
    en1rect.move_ip(enSpeed(en1rect.x,en1rect.y,ashrect.x,ashrect.y,bgspd))
    en2rect.move_ip(enSpeed(en2rect.x,en2rect.y,ashrect.x,ashrect.y,bgspd))
    en3rect.move_ip(enSpeed(en3rect.x,en3rect.y,ashrect.x,ashrect.y,bgspd))

    screen.blit(bg,bgrect)
    player.blit(ash,(68*x,72*y))
    screen.blit(player,(205,155))
    screen.blit(poke,pokerect)
    screen.blit(en1,en1rect)
    screen.blit(en2,en2rect)
    screen.blit(en3,en3rect)
    screen.blit(pygame.font.Font.render(ft,"SCORE: "+str(score),True,(255,255,255)),dest=(200,0))
    pygame.display.flip()

A rough description of the intended game is that the player can move in any direction throughout the map and collects the pokeballs (coins) to earn a score.If the player is in enemy range the enemy will start chasing the player, otherwise the enemy remains stationary.The game ends when the player is either caught or the player goes outside the background map


Solution

  • Your code is currently running as fast as it can. You have to limit the speed of your game (FPS). The FPS (Frames Per Second) in games is generally set to 60. And fortunately this is really simple to do in pygame.

    import pygame
    from sys import exit
    
    FPS = 60    
    clock = pygame.time.Clock()
    
    while True:
       for event in pygame.event.get():
           if event.type == pygame.QUIT:
              pygame.quit()
              exit()
    
       clock.tick(FPS)