DarkSlayer3202
DarkSlayer3202

Reputation: 25

How do I move to the mouse pointer and point towards it at the same time?

I am quite new to Pygame 2 (actually python in general), and I wanted to make a little game for school. I used the code from this, but I can't get it to move towards the cursor when I press SPACE. I don't want it to move in the x/y axis... This is the code btw

import sys, pygame, math
from pygame.locals import *
spaceship = ('spaceship.png')
mouse_c = ('cursor.png')
backg = ('background.jpg')
lazer = pygame.mixer.Sound("pew.WAV")
pygame.init()

display_width = 1280
display_height = 720
screen = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("Space Survival")

bk = pygame.image.load(backg).convert_alpha()
space_ship = pygame.image.load(spaceship).convert_alpha()
mousec = pygame.image.load(mouse_c).convert_alpha()
clock = pygame.time.Clock()
pygame.mouse.set_visible(False)
Ammo = 20
Fuel = 200

while True:
    for event in pygame.event.get():
    if event.type == QUIT:
        pygame.quit()
        sys.exit()
    elif event.type == MOUSEBUTTONDOWN and event.button == 1 and Ammo <= 20:
        print("Pew")
        pygame.mixer.Sound.play(lazer)
    elif event.type == MOUSEBUTTONDOWN and event.button == 3 and Fuel <= 200:
        print("Boost")

screen.blit(bk, (0, 0))
pos = pygame.mouse.get_pos()
angle = 270-math.atan2(pos[1]-(display_height/2),pos[0]-(display_width/2))*180/math.pi
rotimage = pygame.transform.rotate(space_ship,angle)
rect = rotimage.get_rect(center=((display_width/2),(display_height/2)))
screen.blit(rotimage,rect) #I need space_ship to rotate towards my cursor
screen.blit(mousec, (pos))
pygame.display.update()
clock.tick(60)   #FPS

Running Pygame 2.0 on Python 3.8. Any tips will be much appreciated :)

Upvotes: 1

Views: 716

Answers (1)

Rabbid76
Rabbid76

Reputation: 211220

Write a function that "follows2 an target:

def FollowMe(pops, fpos, step):
    # [...]

I recommend to compute the distance between the spaceship and the mouse and the unit direction vector from (fpos) to (pops).
The distance can be get by computing the Euclidean distance. Pygame provides distance_to() for that. Th unit direction vector can be computed by dividing the direction vector by the distance or by normalizing (normalize()) the direction vector:

target_vector       = pygame.math.Vector2(pops)
follower_vector     = pygame.math.Vector2(fpos)

distance = follower_vector.distance_to(target_vector)
direction_vector = target_vector - follower_vector
if distance > 0:
    direction_vector /= distance

Now you can define an exact step_distance and move to follower in direction of the sprite:

if distance > 0:
    new_follower_vector = follower_vector + direction_vector * step_distance.

Define a step and ensure that the step distance is not grater than the step:

step_distance = min(distance, step)

The maximum step distance is

max_step = distance - minimum_distance

Put it all together:

def FollowMe(pops, fpos, step):
    target_vector       = pygame.math.Vector2(pops)
    follower_vector     = pygame.math.Vector2(fpos)
    new_follower_vector = pygame.math.Vector2(fpos)

    distance = follower_vector.distance_to(target_vector)
    if distance > 0:
        direction_vector    = (target_vector - follower_vector) / distance
        step_distance       = min(distance, step)
        new_follower_vector = follower_vector + direction_vector * step_distance

    return (new_follower_vector.x, new_follower_vector.y)

See also How to make smooth movement in pygame.

Use the function to move the space ship in the direction of the mouse and pygame.key.get_pressed() to move the ship when SPACE is pressed. pygame.key.get_pressed() returns a list with the state of each key. If a key is held down, the state for the key is True, otherwise False. Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement:

ship_pos = display_width // 2, display_height // 2

while True:
    # [...]

    keys = pygame.key.get_pressed()
    if keys[pygame.K_SPACE]:
        ship_pos = FollowMe(pos, ship_pos, 3)
    angle = 270-math.atan2(pos[1]-ship_pos[1],pos[0]-ship_pos[0])*180/math.pi
    rotimage = pygame.transform.rotate(space_ship,angle)
    rect = rotimage.get_rect(center=ship_pos)

For the rotation of an image see How to rotate an image(player) to the mouse direction? and How do I rotate an image around its center using PyGame?

See also Rotate towards target or mouse respectivley Move towards target and the answer to the question How do I rotate a sprite towards the mouse and move it?


Minimal example without any usage of external resources (sound and images):

import sys, pygame, math
from pygame.locals import *
pygame.init()

def FollowMe(pops, fpos, step):
    target_vector       = pygame.math.Vector2(pops)
    follower_vector     = pygame.math.Vector2(fpos)
    new_follower_vector = pygame.math.Vector2(fpos)

    distance = follower_vector.distance_to(target_vector)
    if distance > 0:
        direction_vector    = (target_vector - follower_vector) / distance
        step_distance       = min(distance, step)
        new_follower_vector = follower_vector + direction_vector * step_distance

    return (new_follower_vector.x, new_follower_vector.y) 

display_width = 1280
display_height = 720
screen = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption("Space Survival")
clock = pygame.time.Clock() 

bk = pygame.Surface(screen.get_size())
space_ship = pygame.Surface((20, 50), pygame.SRCALPHA)
space_ship.fill((0, 255, 0)) 
mousec = pygame.Surface((20, 20), pygame.SRCALPHA)
mousec.fill((255, 0, 0)) 

ship_pos = display_width // 2, display_height // 2

while True:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()

    pos = pygame.mouse.get_pos()
    keys = pygame.key.get_pressed()
    if keys[pygame.K_SPACE]:
        ship_pos = FollowMe(pos, ship_pos, 3)
    angle = 270-math.atan2(pos[1]-ship_pos[1],pos[0]-ship_pos[0])*180/math.pi
    rotimage = pygame.transform.rotate(space_ship,angle)
    rect = rotimage.get_rect(center=ship_pos)
    
    screen.blit(bk, (0, 0))
    screen.blit(rotimage,rect)
    screen.blit(mousec, pos)
    pygame.display.update()

Upvotes: 1

Related Questions