Skip to content

Commit 4bfb6ef

Browse files
committed
Finally, rotation centre!
1 parent a66dbaf commit 4bfb6ef

File tree

4 files changed

+71
-58
lines changed

4 files changed

+71
-58
lines changed

costume.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def __init__(self):
1313
self.dataFormat = "svg"
1414
self.rotationCenterX = 0
1515
self.rotationCenterY = 0
16-
self.currentRotationCenter = (0, 0)
16+
self.offset = None
1717
self.bitmapResolution = 1
1818
self.file = None
1919
self.name = "" # display name

sb3Unpacker.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ def sb3Unpack(sb3):
6161
if "md5ext" in costumeObj:
6262
c.md5ext = costumeObj["md5ext"]
6363
c.rotationCenterX, c.rotationCenterY = costumeObj["rotationCenterX"], costumeObj["rotationCenterY"]
64-
c.currentRotationCenter = (c.rotationCenterX, c.rotationCenterY)
6564
c.dataFormat = costumeObj["dataFormat"]
65+
c.offset = pygame.math.Vector2(c.rotationCenterX, c.rotationCenterY)
6666
c.file = project.read(costumeObj["assetId"] + "." + costumeObj["dataFormat"])
6767
c.name = costumeObj["name"]
6868
if costumeObj["dataFormat"] != "svg":

targetSprite.py

+6-8
Original file line numberDiff line numberDiff line change
@@ -81,20 +81,18 @@ def setXy(self, x, y):
8181
y = scratch.HEIGHT / 2 + self.rect.height / 2 - 16
8282
elif y < scratch.HEIGHT / -2 - self.rect.height / 2 + 16:
8383
y = scratch.HEIGHT / -2 - self.rect.height / 2 + 16
84-
# Set X and Y
8584
self.x = x
8685
self.y = y
87-
print("aici")
8886
# print(_("debug-prefix"), _("new-sprite-position", x=x, y=y, name=self.name), file=sys.stderr)
8987
#rect = self.sprite.get_rect(topleft=(self.x - self.target.costumes[self.target.currentCostume].rotationCenterX, self.y - self.target.costumes[self.target.currentCostume].rotationCenterY))
90-
offset = pygame.Vector2(self.target.costumes[self.target.currentCostume].rotationCenterX - self.sprite.get_rect().width / 2, self.target.costumes[self.target.currentCostume].rotationCenterY - self.sprite.get_rect().height / 2)
88+
offset = self.target.costumes[self.target.currentCostume].offset - pygame.math.Vector2(self.sprite.get_width() / 2, self.sprite.get_height() / 2)
9189
offset.rotate_ip(90 + self.direction)
92-
self.image = pygame.transform.rotozoom(self.sprite, 90 - self.direction, 1)
90+
self.image = pygame.transform.rotate(self.sprite, 90 - self.direction)
9391
# offset = pygame.Vector2(0, 0)
94-
self.rect.centerx = scratch.WIDTH // 2 + self.x + offset.x
95-
self.rect.centery = scratch.HEIGHT // 2 - self.y + offset.y
96-
print(self.rect.x, self.rect.y, "/", self.x, self.y, "/", offset.x, offset.y)
97-
# TODO update current rotation centre to correct sprite position
92+
relativePosition = pygame.math.Vector2(self.spriteRect.centerx, self.spriteRect.centery)
93+
position = pygame.math.Vector2(self.x - self.sprite.get_width() / 2 + scratch.WIDTH / 2, self.y - self.sprite.get_height() / 2 + scratch.HEIGHT / 2)
94+
95+
self.rect = self.image.get_rect(center=position+relativePosition+offset)
9896

9997
# Relatively set self position
10098
def setXyDelta(self, dx, dy):

tests.py

+63-48
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,63 @@
1-
import pygame
2-
3-
pygame.init()
4-
5-
# Set up the window
6-
screen = pygame.display.set_mode((640, 480))
7-
8-
# Load the sprite image
9-
sprite_image = pygame.image.load("sprite.png")
10-
11-
# Define the rotation center offset relative to the sprite's origin
12-
rotation_center_offset = (20, 10)
13-
14-
# Define the initial angle of the sprite
15-
angle = 0
16-
17-
while True:
18-
for event in pygame.event.get():
19-
if event.type == pygame.QUIT:
20-
pygame.quit()
21-
quit()
22-
23-
# Calculate the rotation center position relative to the sprite's origin
24-
rotation_center = (
25-
rotation_center_offset[0],
26-
rotation_center_offset[1]
27-
)
28-
29-
# Rotate the sprite image around the rotation center
30-
rotated_image = pygame.transform.rotate(sprite_image, angle)
31-
32-
# Get the rect of the rotated image
33-
rect = rotated_image.get_rect()
34-
35-
# Calculate the position of the sprite based on the rotation center and rect dimensions
36-
position = (
37-
rotation_center[0] - rect.width / 2,
38-
rotation_center[1] - rect.height / 2
39-
)
40-
41-
# Draw the rotated image to the screen at the calculated position
42-
screen.blit(rotated_image, position)
43-
44-
# Increment the angle
45-
angle += 0.125
46-
47-
# Update the screen
48-
pygame.display.update()
1+
import pygame as pg
2+
from pygame.math import Vector2
3+
4+
5+
class Entity(pg.sprite.Sprite):
6+
7+
def __init__(self, pos):
8+
super().__init__()
9+
self.image = pg.Surface((122, 70), pg.SRCALPHA)
10+
pg.draw.polygon(self.image, pg.Color('dodgerblue1'),
11+
((1, 0), (120, 35), (1, 70)))
12+
# A reference to the original image to preserve the quality.
13+
self.orig_image = self.image
14+
self.rect = self.image.get_rect(center=pos)
15+
self.pos = Vector2(pos) # The original center position/pivot point.
16+
self.offset = Vector2(50, 0) # We shift the sprite 50 px to the right.
17+
self.angle = 0
18+
19+
def update(self):
20+
self.angle += 2
21+
self.rotate()
22+
23+
def rotate(self):
24+
"""Rotate the image of the sprite around a pivot point."""
25+
# Rotate the image.
26+
self.image = pg.transform.rotozoom(self.orig_image, -self.angle, 1)
27+
# Rotate the offset vector.
28+
offset_rotated = self.offset.rotate(self.angle)
29+
# Create a new rect with the center of the sprite + the offset.
30+
self.rect = self.image.get_rect(center=self.pos+offset_rotated)
31+
32+
33+
def main():
34+
screen = pg.display.set_mode((640, 480))
35+
clock = pg.time.Clock()
36+
entity = Entity((320, 240))
37+
all_sprites = pg.sprite.Group(entity)
38+
39+
while True:
40+
for event in pg.event.get():
41+
if event.type == pg.QUIT:
42+
return
43+
44+
keys = pg.key.get_pressed()
45+
if keys[pg.K_d]:
46+
entity.pos.x += 5
47+
elif keys[pg.K_a]:
48+
entity.pos.x -= 5
49+
50+
all_sprites.update()
51+
screen.fill((30, 30, 30))
52+
all_sprites.draw(screen)
53+
pg.draw.circle(screen, (255, 128, 0), [int(i) for i in entity.pos], 3)
54+
pg.draw.rect(screen, (255, 128, 0), entity.rect, 2)
55+
pg.draw.line(screen, (100, 200, 255), (0, 240), (640, 240), 1)
56+
pg.display.flip()
57+
clock.tick(30)
58+
59+
60+
if __name__ == '__main__':
61+
pg.init()
62+
main()
63+
pg.quit()

0 commit comments

Comments
 (0)