Bob The Bean
Bob The Bean

Reputation: 51

Trying to make the blue square follow the red square, but it doesn't work

I'm trying to make a program where you play as a red square and a blue square follows you. Pretty simple, right? Yes, except this is my first time doing this.

I have heard of A*, but I wanted to try an easier way, especially that in the example there aren't any obstacles for the blue square to calculate how it will go around them. It does work, but, the blue square can't go back. And I don't know why. The movement of the blue square is placed in a function which is placed in another function which is placed in the main game loop.

import pygame,sys
import random

#window
width=1600
height=800
window=pygame.display.set_mode((width,height))
pygame.display.set_caption("simulation")


black=(0,0,0)

#red circle
redCircleCoords=(60, 60)
redCircleSize=(60, 60)
redCircle = pygame.Rect(redCircleCoords[0], redCircleCoords[1], redCircleSize[0], redCircleSize[1])
red=(255,0,0)
velRed=1


#blue circle
blueCircleCoords=(width-120, height-120)
blueCircleSize=(60,60)
blueCircle=pygame.Rect(blueCircleCoords[0], blueCircleCoords[1], blueCircleSize[0], blueCircleSize[1])
blue=(0,0,255)
velBlue=0.5


def redCircleMovement():
    
    pressed=pygame.key.get_pressed()
    
    if pressed[pygame.K_a] and redCircle.x > 0: #left
        redCircle.x-=velRed
    if pressed[pygame.K_d] and redCircle.x < width - 60: #right
        redCircle.x+=velRed
    if pressed[pygame.K_s] and redCircle.y < height - 60: #down
        redCircle.y+=velRed
    if pressed[pygame.K_w] and redCircle.y > 0: #up
        redCircle.y-= velRed

    
def blueCircleMovement():
    
    if redCircle.x > blueCircle.x:
        blueCircle.x+=velBlue
    if redCircle.x < blueCircle.x:
        blueCircle.x-=velBlue
    if redCircle.y > blueCircle.y:
        blueCircle.y+=velBlue
    if redCircle.y < blueCircle.y:
        blueCircle.y-=velBlue
            
    
def draw():
    redCircleVector=(redCircle.x, redCircle.y)
    blueCircleVector=(blueCircle.x, blueCircle.y)
    print('red:',redCircleVector)
    print('blue:',blueCircleVector)
    window.fill(black) #fill the screen with black
    pygame.draw.rect(window, red, redCircle) #draw redCircle
    pygame.draw.rect(window,blue,blueCircle) #draw blueCircle
    pygame.display.flip() #update the display
    

    

def callFunctions():
    draw()
    
    redCircleMovement()
    blueCircleMovement()
    

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
    
    callFunctions()

Upvotes: 1

Views: 122

Answers (1)

Johan Kuylenstierna
Johan Kuylenstierna

Reputation: 189

A* is pointless if you have no obstacles so good call there.

I don't know exactly why your code doesn't work but if I was you I'd change it to calculate the unit vector pointing from blue to red. Something like this:

def get_unit_vec(r_x, r_y, b_x, b_y):
    x_diff = r_x - b_x
    y_diff = r_y - b_y
    magnitude = (x_diff ** 2 + y_diff ** 2) ** .5 # pythagoras
    if magnitude == 0:
        return 0, 0
    return x_diff/magnitude, y_diff/magnitude
...
#updating position
unit_vec = get_unit_vec(redCircle.x, redCircle.y, blueCircle.x, blueCircle.y)
blueCircle.x += unit_vec[0] * velBlue
blueCircle.y += unit_vec[1] * velBlue

This ensures that the blue circle always moves in the exact direction of the red circle.

Upvotes: 1

Related Questions