My Python game enemies are moving in loops

Viewed 38

in my pygame code, I made my own simple enemy AI to make them follow the player around the screen, moving in that direction. But I have encountered a problem that causes them to start looping around strangely whenever the character moves, and only follow the player if it's staying still. the class that does the tracking is "calcSpeeds()". if someone can help me figure out what i need to do that would be grand.

import pygame
import random

import math

from fractions import Fraction

pygame.init()

swidth = int(1920/1.5)
sheight = int(1080/1.5)

groundheight = sheight*.9



win = pygame.display.set_mode((swidth,sheight))

pygame.display.set_caption("first time coding in pythong for realzies")

mx, my = pygame.mouse.get_pos()

class Player:
    def __init__(self,x,y,width,height):
        self.px = x
        self.py = y
        self.pwidth = width
        self.pheight = height
        self.psx = 0
        self.psy = 0
        self.masterspeed = 2
        # 4
        self.isjump = False

    def updatePos(self):
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                self.psy = self.masterspeed
                self.py -= self.psy
            else:
                self.psy = 0

            if event.key == pygame.K_DOWN:
                self.psy = self.masterspeed
                self.py += self.psy
            else:
                self.psy = 0

            if event.key == pygame.K_LEFT:
                self.psx = self.masterspeed
                self.px -= self.psx
            else:
                self.psx = 0

            if event.key == pygame.K_RIGHT:
                self.psx = self.masterspeed
                self.px += self.psx
            else:
                self.psx = 0


            if event.key == pygame.K_SPACE:
                print("Hey, you pressed the key, 'space bar'!")

            if event.key == pygame.K_x:
                print("Hey, you pressed the key, 'x'!")

    def drawCharacter(self):
        pygame.draw.rect(win, (222,2,2), (self.px-self.pwidth/2,self.py-self.pheight/2,self.pwidth,self.pheight))


class EnemyBird:
    def __init__(self,x,y,width,height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.sx = 0
        self.sy = 0
        self.vel = 1

    def drawEnemyBird(self):
        pygame.draw.ellipse(win, (245, 218, 17), (self.x,self.y,self.width,self.height))

    def calcSpeeds(self):

        self.slope = (me.py - self.y)/(me.px - self.x)

        # this variable holds the angle between the yellow birds and the player
        self.pointangle = math.degrees(math.atan2((me.py - self.y),(me.px - self.x)))

        self.sy = self.vel*math.sin(self.pointangle)
        self.sx = self.vel*math.cos(self.pointangle)

        print(self.sx,self.sy)

    def moveBird(self):
        self.x += self.sx
        self.y += self.sy

me = Player(swidth/2 ,sheight*.9,20,20)

birdies = []

for i in range(1):
    birdies.append(EnemyBird(random.randint(0,swidth), random.randint(0,sheight*.9), 20,20))

run = True
while run:
    pygame.time.delay(10)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    mx, my = pygame.mouse.get_pos()
    win.fill((135,206,235))
    pygame.draw.rect(win, (48, 110, 16), (0,groundheight,swidth,sheight*.2))

    me.updatePos()
    me.drawCharacter()

    for i in range(len(birdies)):

        birdies[i].moveBird()
        birdies[i].calcSpeeds()
        birdies[i].drawEnemyBird()

    pygame.display.update()
pygame.quit()
1 Answers

From Asocia's comment, removing the math.degrees() when computing self.pointangle solves the problem you are having.

    def calcSpeeds(self):

        self.slope = (me.py - self.y)/(me.px - self.x)

        # this variable holds the angle between the yellow birds and the player
        self.pointangle = math.atan2((me.py - self.y),(me.px - self.x))

        self.sy = self.vel*math.sin(self.pointangle)
        self.sx = self.vel*math.cos(self.pointangle)

        print(self.sx,self.sy)

Another method you can use when making the enemy track the player is:

    def calcSpeeds(self):

        y = (me.py - self.y)
        x = (me.px - self.x)
        direction = pygame.Vector2(x, y)
        direction.scale_to_length(self.vel)

        self.sx, self.sy = direction

        print(self.sx,self.sy)

First you find the vector x, y from the enemy to the player. Then, set up a pygame Vector2 so you can scale the vector to whatever length you want. This will determine how quickly the enemy moves toward the player.

Related