I have a fixed player in center of the screen and for now I'm moving the background and the elements in the opposite direction to give the illusion of moving forward with the directional keys.
But now, I want to detect the position of the mouse and deplace the player in the direction of the mouse (as in the game agar.io for example) and that the acceleration depends on the distance with the object (the further the mouse is, the faster the player moves forward and if the mouse is on the player,he does not advance anymore)
My program work like this :
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
if y_max > -1000:
y_max -= int(player_1.speed * dt)
bg_y += int(player_1.speed * dt)
if bg_y > 0:
bg_y = -400
if keys[pygame.K_DOWN]:
if y_max < 1000:
y_max += int(player_1.speed * dt)
bg_y -= int(player_1.speed * dt)
if bg_y < -HEIGHT:
bg_y = -400
if keys[pygame.K_LEFT]:
if x_max > -1000:
x_max -= int(player_1.speed * dt)
bg_x += int(player_1.speed * dt)
if bg_x > 0:
bg_x = -400
if keys[pygame.K_RIGHT]:
if x_max < 1000:
x_max += int(player_1.speed * dt)
bg_x -= int(player_1.speed * dt)
if bg_x < -WIDTH:
bg_x = -400
I found that to help but I do not understand how it works :
dX, dY = pygame.mouse.get_pos()
rotation = math.atan2(dY - (float(HEIGHT) / 2), dX - (float(WIDTH) / 2)) * 180 / math.pi
and maybe I have to use sine and cosine but I do not know how ?
Thanks for your help !
Making an object follow the mouse is pretty easy if you know how to use vectors. You just need to create a vector that points to the target (in this case the mouse) by subtracting the target position from the position of the object:
heading = pg.mouse.get_pos() - self.pos # self.pos is a pygame.math.Vector2
Then move the object by adding this vector to its position vector:
self.pos += heading * 0.1
self.rect.center = self.pos # Update the rect of the sprite as well.
I also scale the heading
vector here, otherwise it would move to the target immediately. By multiplying it by 0.1 the speed will be a tenth of the distance to the target (the length of the heading vector).
Here's a minimal, complete example:
import pygame as pg
from pygame.math import Vector2
class Entity(pg.sprite.Sprite):
def __init__(self, pos, *groups):
super().__init__(*groups)
self.image = pg.Surface((30, 30))
self.image.fill(pg.Color('dodgerblue1'))
self.rect = self.image.get_rect(center=pos)
self.pos = Vector2(pos)
def update(self):
# Get a vector that points from the position to the target.
heading = pg.mouse.get_pos() - self.pos
self.pos += heading * 0.1 # Scale the vector to the desired length.
self.rect.center = self.pos
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
all_sprites = pg.sprite.Group()
entity = Entity((100, 300), all_sprites)
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
return
all_sprites.update()
screen.fill((30, 30, 30))
all_sprites.draw(screen)
pg.display.flip()
clock.tick(60)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
Here's a version without vectors and sprites if you're not familiar with them. It does pretty much the same as the code above.
import pygame as pg
from pygame.math import Vector2
def main():
pg.init()
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
image = pg.Surface((30, 30))
image.fill(pg.Color('dodgerblue1'))
x, y = 300, 200 # Actual position.
rect = image.get_rect(center=(x, y)) # Blit position.
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
return
mouse_pos = pg.mouse.get_pos()
# x and y distances to the target.
run = (mouse_pos[0] - x) * 0.1 # Scale it to the desired length.
rise = (mouse_pos[1] - y) * 0.1
# Update the position.
x += run
y += rise
rect.center = x, y
screen.fill((30, 30, 30))
screen.blit(image, rect)
pg.display.flip()
clock.tick(60)
if __name__ == '__main__':
main()
pg.quit()