Reputation: 124
(EDIT: The rotation doesn't matter too much to me anymore - just the movement. I am still curious and would love to know how to do the rotation however.)
def angle_between(p1, p2):
ang1 = np.arctan2(*p1[::-1])
ang2 = np.arctan2(*p2[::-1])
return (ang1 - ang2) % (2 * np.pi)
class Minion: # Shape: Triangle
def __init__(self):
self.rotation = 0
self.position = (200,200)
self.radius = 50
self.vertices = ((1,1), (10,10), (1,10))
def determine_vertices(self):
x = self.position[0]
y = self.position[1]
target_pos = pygame.mouse.get_pos()
x2 = target_pos[0]
y2 = target_pos[1]
# Will start off pointing to the right (pre-rotation)
vertex_A = (x + self.radius, y)
vertex_B = (x + (cos(2*pi/3))*self.radius, y + (sin(2*pi/3))*self.radius)
vertex_C = (x + (cos(4*pi/3))*self.radius, y + (sin(4*pi/3))*self.radius)
self.vertices = (vertex_A,vertex_B,vertex_C) # NOT YET ROTATED
# Now let's find the angle between my location and the target location
self.rotation = angle_between((x,y),(x2,y2))
# Here is where I am stuck
Okay, so I have found the location of my vertices before they are rotated, and have also found the angle (in radians) in which I want to rotate it towards. Here are the links I've looked at:
Didn't understand / know how to convert to my code
Graph data instead of raw data
EDIT: I have changed my vertex formulas to rotate but they rotate the wrong direction and way too fast. I have no clue why. Here is the code:
vertex_A = (x + (cos(self.rotation))*self.radius, y + (sin(self.rotation))*self.radius)
vertex_B = (x + (cos((2*pi/3) + self.rotation))*self.radius, y + (sin((2*pi/3) + self.rotation))*self.radius)
vertex_C = (x + (cos((4*pi/3) + self.rotation))*self.radius, y + (sin((4*pi/3) + self.rotation))*self.radius)
Upvotes: 1
Views: 2498
Reputation: 20458
To move an object towards the mouse, you can use vectors. Just subtract the position from the mouse pos, normalize the resulting vector and mutliply it by the desired speed. That gives you the velocity vector which you can add to the self.pos
each frame (also update the rect which serves as the blit position and for collision detection).
Call the Vector2.as_polar
method (it returns the polar coordinates) to get the angle of the vector and then use it to rotate the original image.
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((50, 30), pg.SRCALPHA) # A transparent image.
# Draw a triangle onto the image.
pg.draw.polygon(self.image, pg.Color('dodgerblue2'),
((0, 0), (50, 15), (0, 30)))
# A reference to the original image to preserve the quality.
self.orig_image = self.image
self.rect = self.image.get_rect(center=pos)
self.vel = Vector2(0, 0)
self.pos = Vector2(pos)
def update(self):
# Subtract the pos vector from the mouse pos to get the heading,
# normalize this vector and multiply by the desired speed.
self.vel = (pg.mouse.get_pos() - self.pos).normalize() * 5
# Update the position vector and the rect.
self.pos += self.vel
self.rect.center = self.pos
# Rotate the image.
# `Vector2.as_polar` returns the polar coordinates (radius and angle).
radius, angle = self.vel.as_polar()
self.image = pg.transform.rotozoom(self.orig_image, -angle, 1)
self.rect = self.image.get_rect(center=self.rect.center)
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
all_sprites = pg.sprite.Group()
entity = Entity((100, 300), all_sprites)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
all_sprites.update()
screen.fill((30, 30, 30))
all_sprites.draw(screen)
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
Upvotes: 2