2

so, I'm making this simple game in python 3.7.7 with pygame and I'm trying to make a "random" movement for the enemies. But when I run the program with the enemies movement, my player moves a bit jerky (I hope I'm using the verb as it's intended). I cannot find what is making me move so weird. I have tried 2 diferent aproaches for the enemy movement and in both the problem is the same.

1st Try:

import pygame,random
pygame.init()
clock = pygame.time.Clock()
run= True
#imatges


#screen
sw= 1000
sh= 1000




wind = pygame.display.set_mode((sw,sh))
pygame.display.set_caption('PYgeon')

#sounds


####################################################################################################################
#                   PLAYER
####################################################################################################################
#Prot
class prot (object):
    def __init__(self,x,y,width,height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 10

####################################################################################################################
#                   ENEMY
####################################################################################################################
#Enemy
class enem (object):
    def __init__(self,x,y,width,height):
        self.x = x
        self.y = y
        self.width = width
        self. height = height
        self.vel = 5
        self.cem = 0
    def mov (self):
        self.cem +=1
        if self.cem >= 3:
            self.cem=0
            opt = random.randint(1,2)#1 o 2 directions
            dis = random.randint(5,10)#distance
            screenupdt()
            if opt == 1:
                pos = random.randint(1,2)#positive / negative (1->+||2->-)
                if pos == 1:
                    dir = random.randint(1,2)#movement x(1) o movement y(2)
                    if dir == 1:
                        for ul in range (dis):
                            if enemy.x + enemy.width <= sw:
                                enemy.x += enemy.vel
                                screenupdt()
                    else:
                        for ul in range (dis):
                            if enemy.y + enemy.height <= sh:
                                enemy.y += enemy.vel
                                screenupdt()
                else:
                    dir = random.randint(1,2)#movement x(1) o movement y(2)
                    if dir == 1:
                        for ul in range (dis):
                            if enemy.x - enemy.width >= 0:
                                enemy.x -= enemy.vel
                                screenupdt()
                    else:
                        for ul in range (dis):
                            if enemy.y - enemy.height >= 0:
                                enemy.y -= enemy.vel
                                screenupdt()
            else:
                dirb = random.randint(1,4)#to choose one of the four directions 1(+x,+y) 2(+x,-y) 3(-x,+y) 4(-x,-y)
                if dirb == 1:
                    for ul in range (dis):
                        if enemy.x + enemy.width < sw and enemy.y + enemy.height < sh:
                            enemy.x += enemy.vel
                            enemy.y += enemy.vel
                            screenupdt()
                elif dirb == 2:
                    for ul in range (dis):
                        if enemy.x + enemy.width < sw and enemy.y - enemy.height > 0:
                            enemy.x += enemy.vel
                            enemy.y -= enemy.vel
                            screenupdt()
                elif dirb == 3:
                    for ul in range (dis):
                        if enemy.x - enemy.width > 0 and enemy.y + enemy.height < sh:
                            enemy.x -= enemy.vel
                            enemy.y += enemy.vel
                            screenupdt()
                else:
                    for ul in range (dis):
                        if enemy.x - enemy.width > 0 and enemy.y - enemy.height > 0:
                            enemy.x -= enemy.vel
                            enemy.y -= enemy.vel
                            screenupdt()
####################################################################################################################
#                   BOSS
####################################################################################################################

class boss (object):
    def __init__(self):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 5

####################################################################################################################
#                   PROJECTILES
####################################################################################################################

class proj (object):
    def __init__(self,x,y,width,height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 25
####################################################################################################################
#                                   SCREEN LOADING
####################################################################################################################
#screen loading
def screenupdt ():
    wind.fill(0)
    pygame.draw.rect(wind , (255,100,255) , (aris.x,aris.y,aris.width,aris.height))
    pygame.draw.circle(wind, (250,255,100), (enemy.x,enemy.y), 25)
    pygame.display.update()

####################################################################################################################
####################################################################################################################
#                   LOOP
####################################################################################################################
####################################################################################################################


#variables
aris = prot(250,250,64,64)
enemy = enem (500,500,25,25)
enemy2 = enem (510,510,25,25)
cem= 0 #contador per el moviment dels enemics
#while

while run:
    clock.tick(40)
    screenupdt()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run= False
    keys = pygame.key.get_pressed()
    if keys[pygame.K_a] and aris.x > 0:
        aris.x -= aris.vel
        screenupdt()
    if keys[pygame.K_d] and aris.x + aris.width < 1000:
        aris.x += aris.vel
        screenupdt()
    if keys[pygame.K_w] and aris.y > 0:
        aris.y -= aris.vel
        screenupdt()
    if keys[pygame.K_s] and aris.y + aris.height < 1000:
        aris.y += aris.vel
        screenupdt()
    enemy.mov()
pygame.quit()

2n Try:

import pygame,random
pygame.init()
clock = pygame.time.Clock()
run= True
#imatges


#screen
sw= 1000
sh= 1000




wind = pygame.display.set_mode((sw,sh))
pygame.display.set_caption('PYgeon')

#sounds


####################################################################################################################
#                   PLAYER
####################################################################################################################
#Prot
class prot (object):
    def __init__(self,x,y,width,height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 10

####################################################################################################################
#                   ENEMY
####################################################################################################################
#Enemy
class enem (object):
    def __init__(self,x,y,width,height):
        self.x = x
        self.y = y
        self.width = width
        self. height = height
        self.vel = 5
        self.cem = 0
    def mov (self):
        self.cem += 1
        if self.cem == 6:
            self.cem = 0
            opt=[1,2,3,4,5,6,7,8]#1(+x) 2(-x) 3(+y) 4(-y) 5(+x,+y) 6(+x,-y) 7(-x,+y) 8(-x,-y)
            copt= random.choice(opt)
            dis = random.randint (1,10)
            if copt == 1:
                for asdf in range (dis):
                    self.x += self.vel
                    screenupdt()
            elif copt == 2:
                for asdf in range (dis):
                    self.x -= self.vel
                    screenupdt()
            elif copt == 3:
                for asdf in range (dis):
                    self.y += self.vel
                    screenupdt()
            elif copt == 4:
                for asdf in range (dis):
                    self.y -= self.vel
                    screenupdt()
            elif copt == 5:
                for asdf in range (dis):
                    self.x += self.vel
                    self.y += self.vel
                    screenupdt()
            elif copt == 6:
                for asdf in range (dis):
                    self.x += self.vel
                    self.y -= self.vel
                    screenupdt()
            elif copt == 7:
                for asdf in range (dis):
                    self.x -= self.vel
                    self.y += self.vel
                    screenupdt()
            elif copt == 8:
                for asdf in range (dis):
                    self.x -= self.vel
                    self.y -= self.vel
                    screenupdt()
####################################################################################################################
#                   BOSS
####################################################################################################################

class boss (object):
    def __init__(self):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 5

####################################################################################################################
#                   PROJECTILES
####################################################################################################################

class proj (object):
    def __init__(self,x,y,width,height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 25
####################################################################################################################
#                                   SCREEN LOADING
####################################################################################################################
#screen loading
def screenupdt ():
    wind.fill(0)
    pygame.draw.rect(wind , (255,100,255) , (aris.x,aris.y,aris.width,aris.height))
    pygame.draw.circle(wind, (250,255,100), (enemy.x,enemy.y), 25)
    pygame.display.update()

####################################################################################################################
####################################################################################################################
#                   LOOP
####################################################################################################################
####################################################################################################################


#variables
aris = prot(250,250,64,64)
enemy = enem (500,500,25,25)
cem= 0 #contador per el moviment dels enemics
#while

while run:
    enemy.mov()            
                                                
    keys = pygame.key.get_pressed()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run= False
    if keys[pygame.K_a]:
        aris.x -= aris.vel
        screenupdt()
    if keys[pygame.K_d]:
        aris.x += aris.vel
        screenupdt()
    if keys[pygame.K_w]:
        aris.y -= aris.vel
        screenupdt()
    if keys[pygame.K_s]:
        aris.y += aris.vel
        screenupdt()
pygame.quit()

Thank you :)

python_user
  • 5,375
  • 2
  • 13
  • 32
Salipoke
  • 23
  • 3
  • I don't know how to explain it, while the enemy movement is smooth, and you can see how he is all the time moving, the player stops moving every like half a second and it looks like it is moving at steps, not like floating. – Salipoke May 08 '21 at 08:51

1 Answers1

0

Remove the multiple calls to screenupdt from your code. It is sufficient to draw the scene and update the display once per frame. Remove it from the enem.move method and the application loop. Call it once at the end of the application loop:

while run:
    clock.tick(40)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run= False
    keys = pygame.key.get_pressed()
    if keys[pygame.K_a] and aris.x > 0:
        aris.x -= aris.vel
    if keys[pygame.K_d] and aris.x + aris.width < 1000:
        aris.x += aris.vel
    if keys[pygame.K_w] and aris.y > 0:
        aris.y -= aris.vel
    if keys[pygame.K_s] and aris.y + aris.height < 1000:
        aris.y += aris.vel

    enemy.mov()
    screenupdt() # <--- call it just here, but nowhere else

pygame.quit()

See also Why is the PyGame animation is flickering

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Thank you :D It was that, I just made it so it moves in the same direction for some more frames, and then in changes. :) – Salipoke May 08 '21 at 09:09