Sign in to follow this  
Esys

Sprite Rotation about Point

Recommended Posts

I'm designing a top-down mech combat game, and I'd like to have the body and arms to be seperate sprites. The body has mount points which are offsets from the center of the body sprite that the arms attach to. I'm trying to get the mount points to rotate with the body sprite, but I can't seem to get the math right. Any help would be appreciated.

Share this post


Link to post
Share on other sites

x = originx + (cos(theta)*(posx-originx) - sin(theta)*(posy-originy));
y = originy + (sin(theta)*(posx-originx) + cos(theta)*(posy-originy));




This is in screen space so vertical axis gets bigger as it goes down rather as it goes up.

- x and y are the final positions.
- posx and poy are the starting positions.
- originx and origin y are the positions you want to rotate around.

hope that helps I just wrote that code yesterday for my engine.
*Edit* this where I got it from http://gpwiki.org/index.php/VB:Tutorials:Rotating_A_Point_In_2D

Share this post


Link to post
Share on other sites
Theta is the angle to rotate in radians (that like i added has an equation to convert degrees to radians if needed).

What I would do is rotate everything around the main bodies center when the main body moves. if the arms move rotate them around the joint.

the origin would be either the joint or the main bodies center. posx and y are whatever your rotateing original position. x, and y are the new positions after you've rotated them.

Share this post


Link to post
Share on other sites
Thank you for your help, freeworld and Nanoha. I've finally managed to get it working right with your assistance.

Full code, zits and all:


import pygame, math
from Vector import *
pygame.init()

class MechBody(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.imgMaster = pygame.image.load("mech_body.bmp").convert()
trans = self.imgMaster.get_at((20,0))
self.imgMaster.set_colorkey(trans)
self.dir = 0
self.turnRate = 3
self.speed = 3
self.dx = 0
self.dy = 0
self.x = 320
self.y = 240
self.image = self.imgMaster
self.rect = self.image.get_rect()
self.rect.center = (self.x, self.y)
self.lArmMountOffset = vector(35,-40)
self.lArmMountPoints = vector(
self.x + self.lArmMountOffset.x,
self.y + self.lArmMountOffset.y)
self.isRotating = False
self.original = vector(self.lArmMountPoints.x, self.lArmMountPoints.y)
self.turnDir = 0

def checkKeys(self):
keys = pygame.key.get_pressed()
self.isRotating = False
if keys[pygame.K_RIGHT]:
self.isRotating = True
self.dir -= self.turnRate
self.turnDir = self.turnRate
if self.dir < 0:
self.dir = 360 - self.turnRate
elif keys[pygame.K_LEFT]:
self.isRotating = True
self.dir += self.turnRate
self.turnDir = -self.turnRate
if self.dir >= 360:
self.dir = self.turnRate
elif keys[pygame.K_UP]:
self.calcVect()
self.rotate()

def calcVect(self):
radians = math.radians(self.dir)
self.dx = math.cos(radians) * self.speed
self.dy = math.sin(radians) * self.speed
self.dy *= -1
self.calcPos()

def calcPos(self):
self.x += self.dx
self.y += self.dy
self.lArmMountPoints = vector(self.lArmMountPoints.x + self.dx,
self.lArmMountPoints.y + self.dy)
self.original = vector(self.lArmMountPoints.x, self.lArmMountPoints.y)

def rotate(self):
self.image = pygame.transform.rotate(self.imgMaster, self.dir)
self.rect = self.image.get_rect()
if self.isRotating:
self.rotateMounts()

def rotateMounts(self):
sinT = math.sin(math.radians(self.turnDir))
cosT = math.cos(math.radians(self.turnDir))
self.lArmMountPoints = vector(self.x + (cosT * (self.original.x - self.x) - sinT * (self.original.y - self.y)),
self.y + (sinT * (self.original.x - self.x) + cosT * (self.original.y - self.y)))
self.original = vector(self.lArmMountPoints.x, self.lArmMountPoints.y)

def update(self):
self.checkKeys()
self.rect.center = (self.x, self.y)

class MechArm(pygame.sprite.Sprite):
def __init__(self, mechBody):
pygame.sprite.Sprite.__init__(self)
self.imgMaster = pygame.image.load("mech_arm.bmp").convert()
trans = self.imgMaster.get_at((1,1))
self.imgMaster.set_colorkey(trans)
self.image = self.imgMaster
self.mechBody = mechBody
self.dir = self.mechBody.dir
self.rect = self.image.get_rect()
self.x = self.mechBody.lArmMountPoints.x
self.y = self.mechBody.lArmMountPoints.y
self.rect.center = (self.x, self.y)

def rotate(self):
oldX, oldY = self.x, self.y
self.image = pygame.transform.rotate(self.imgMaster, self.mechBody.dir)
self.rect = self.image.get_rect()
self.rect.center = (oldX, oldY)

def update(self):
self.rotate()
self.x = self.mechBody.lArmMountPoints.x
self.y = self.mechBody.lArmMountPoints.y
self.rect.center = (self.x, self.y)

def main():
screen = pygame.display.set_mode((640,480))
background = pygame.Surface(screen.get_size())
background.fill((0,0,0))

clock = pygame.time.Clock()

running = True

screen.blit(background, (0,0))

body = MechBody()
arm = MechArm(body)

allsprites = pygame.sprite.Group(arm, body)

while running:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
allsprites.clear(screen, background)
allsprites.update()
allsprites.draw(screen)

pygame.display.flip()

if __name__ == "__main__": main()

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this