skelform-pygame 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of skelform-pygame might be problematic. Click here for more details.
- skelform_pygame-0.1.0/PKG-INFO +14 -0
- skelform_pygame-0.1.0/README.md +3 -0
- skelform_pygame-0.1.0/pyproject.toml +19 -0
- skelform_pygame-0.1.0/readme.md +3 -0
- skelform_pygame-0.1.0/skelform_pygame/__init__.py +116 -0
- skelform_pygame-0.1.0/tests/main.py +68 -0
- skelform_pygame-0.1.0/tests/skellington.skf +0 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: skelform_pygame
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: SkelForm runtime for Pygame. Uses the generic runtime
|
|
5
|
+
Author-email: Retropaint <darkglasses1122@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Operating System :: OS Independent
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Requires-Python: >=3.9
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# SkelForm Pygame
|
|
13
|
+
|
|
14
|
+
SkelForm runtime for Pygame. Uses the [generic runtime](https://pypi.org/project/skelform-python/)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling >= 1.26"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "skelform_pygame"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name="Retropaint", email="darkglasses1122@gmail.com" },
|
|
10
|
+
]
|
|
11
|
+
description = "SkelForm runtime for Pygame. Uses the generic runtime"
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.9"
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Operating System :: OS Independent",
|
|
17
|
+
]
|
|
18
|
+
license = "MIT"
|
|
19
|
+
license-files = ["LICEN[CS]E*"]
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import pygame
|
|
2
|
+
import skelform_python
|
|
3
|
+
import math
|
|
4
|
+
import copy
|
|
5
|
+
import zipfile
|
|
6
|
+
import json
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def load_skelform(path):
|
|
10
|
+
with zipfile.ZipFile(path, "r") as zip_file:
|
|
11
|
+
skelform_root = json.load(zip_file.open("armature.json"))
|
|
12
|
+
texture_img = pygame.image.load(zip_file.open("textures.png"))
|
|
13
|
+
|
|
14
|
+
return (skelform_root, texture_img)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class AnimOptions:
|
|
18
|
+
def __init__(
|
|
19
|
+
self,
|
|
20
|
+
# Offset armature's position by this much.
|
|
21
|
+
pos_offset: pygame.Vector2 = pygame.Vector2(0, 0),
|
|
22
|
+
# Scale armature by a factor of this.
|
|
23
|
+
scale_factor=0.25,
|
|
24
|
+
# Should the armature immediately be rendered?
|
|
25
|
+
# Set to False if you would like to process the armature some more before rendering.
|
|
26
|
+
render=True,
|
|
27
|
+
):
|
|
28
|
+
self.pos_offset = pos_offset
|
|
29
|
+
self.scale_factor = scale_factor
|
|
30
|
+
self.render = render
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# Animate a SkelForm armature.
|
|
34
|
+
def animate(
|
|
35
|
+
screen,
|
|
36
|
+
armature,
|
|
37
|
+
texture_img,
|
|
38
|
+
anim_idx,
|
|
39
|
+
frame=-1,
|
|
40
|
+
elapsed_time=-1,
|
|
41
|
+
anim_options=AnimOptions(),
|
|
42
|
+
):
|
|
43
|
+
if elapsed_time != -1:
|
|
44
|
+
frame = get_frame_by_time(armature, anim_idx, elapsed_time, False)
|
|
45
|
+
|
|
46
|
+
props = skelform_python.animate(armature, anim_idx, frame)
|
|
47
|
+
|
|
48
|
+
ao = anim_options
|
|
49
|
+
|
|
50
|
+
for prop in props:
|
|
51
|
+
if prop["tex_idx"] == -1:
|
|
52
|
+
continue
|
|
53
|
+
|
|
54
|
+
tex = armature["textures"][prop["tex_idx"]]
|
|
55
|
+
tex_surf = clip(
|
|
56
|
+
texture_img,
|
|
57
|
+
tex["offset"]["x"],
|
|
58
|
+
tex["offset"]["y"],
|
|
59
|
+
tex["size"]["x"],
|
|
60
|
+
tex["size"]["y"],
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
scale_x = ao.scale_factor * prop["scale"]["x"]
|
|
64
|
+
scale_y = ao.scale_factor * prop["scale"]["y"]
|
|
65
|
+
tex_surf = pygame.transform.scale_by(
|
|
66
|
+
tex_surf,
|
|
67
|
+
(scale_x, scale_y),
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# pygame treats positive y as down
|
|
71
|
+
prop["pos"]["y"] = -prop["pos"]["y"]
|
|
72
|
+
|
|
73
|
+
# adjust positions for scale factor
|
|
74
|
+
# actual scale is already accounted for in core logic
|
|
75
|
+
prop["pos"]["x"] *= ao.scale_factor
|
|
76
|
+
prop["pos"]["y"] *= ao.scale_factor
|
|
77
|
+
|
|
78
|
+
# push textures back left and up so that it's centered
|
|
79
|
+
prop["pos"]["x"] -= tex_surf.get_size()[0] / 2
|
|
80
|
+
prop["pos"]["y"] -= tex_surf.get_size()[1] / 2
|
|
81
|
+
|
|
82
|
+
deg = prop["rot"] * 180 / 3.14
|
|
83
|
+
(tex_surf, rect) = rot_center(tex_surf, tex_surf.get_rect(), deg)
|
|
84
|
+
|
|
85
|
+
if not ao.render:
|
|
86
|
+
continue
|
|
87
|
+
|
|
88
|
+
screen.blit(
|
|
89
|
+
tex_surf,
|
|
90
|
+
rect.move(
|
|
91
|
+
prop["pos"]["x"] + ao.pos_offset.x,
|
|
92
|
+
prop["pos"]["y"] + ao.pos_offset.y,
|
|
93
|
+
),
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
return props
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def get_frame_by_time(armature, anim_idx, elapsed, reverse):
|
|
100
|
+
return skelform_python.get_frame_by_time(armature, anim_idx, elapsed, reverse)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# https://stackoverflow.com/a/71370036
|
|
104
|
+
def clip(surface, x, y, x_size, y_size): # Get a part of the image
|
|
105
|
+
handle_surface = surface.copy() # Sprite that will get process later
|
|
106
|
+
clipRect = pygame.Rect(x, y, x_size, y_size) # Part of the image
|
|
107
|
+
handle_surface.set_clip(clipRect) # Clip or you can call cropped
|
|
108
|
+
image = surface.subsurface(handle_surface.get_clip()) # Get subsurface
|
|
109
|
+
return image.copy() # Return
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
# https://www.pygame.org/wiki/RotateCenter
|
|
113
|
+
def rot_center(image, rect, angle):
|
|
114
|
+
rot_image = pygame.transform.rotate(image, angle)
|
|
115
|
+
rot_rect = rot_image.get_rect(center=rect.center)
|
|
116
|
+
return rot_image, rot_rect
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Example file showing a circle moving on screen
|
|
2
|
+
import pygame
|
|
3
|
+
import zipfile
|
|
4
|
+
import json
|
|
5
|
+
import skelform_pygame
|
|
6
|
+
import time
|
|
7
|
+
|
|
8
|
+
pygame.init()
|
|
9
|
+
screen = pygame.display.set_mode((1280, 720))
|
|
10
|
+
pygame.display.set_caption("SkelForm Basic Animation")
|
|
11
|
+
clock = pygame.time.Clock()
|
|
12
|
+
running = True
|
|
13
|
+
dt = 0
|
|
14
|
+
|
|
15
|
+
player_pos = pygame.Vector2(screen.get_width()/2, screen.get_height()/2)
|
|
16
|
+
|
|
17
|
+
(skelform_root, texture_img) = skelform_pygame.load_skelform("skellington.skf")
|
|
18
|
+
|
|
19
|
+
moving = False
|
|
20
|
+
|
|
21
|
+
while running:
|
|
22
|
+
# poll for events
|
|
23
|
+
# pygame.QUIT event means the user clicked X to close your window
|
|
24
|
+
for event in pygame.event.get():
|
|
25
|
+
if event.type == pygame.QUIT:
|
|
26
|
+
running = False
|
|
27
|
+
|
|
28
|
+
# fill the screen with a color to wipe away anything from last frame
|
|
29
|
+
screen.fill("black")
|
|
30
|
+
|
|
31
|
+
keys = pygame.key.get_pressed()
|
|
32
|
+
if keys[pygame.K_w]:
|
|
33
|
+
player_pos.y -= 300 * dt
|
|
34
|
+
moving = True
|
|
35
|
+
if keys[pygame.K_s]:
|
|
36
|
+
player_pos.y += 300 * dt
|
|
37
|
+
moving = True
|
|
38
|
+
if keys[pygame.K_a]:
|
|
39
|
+
player_pos.x -= 300 * dt
|
|
40
|
+
moving = True
|
|
41
|
+
if keys[pygame.K_d]:
|
|
42
|
+
player_pos.x += 300 * dt
|
|
43
|
+
moving = True
|
|
44
|
+
|
|
45
|
+
anim_idx = 0
|
|
46
|
+
|
|
47
|
+
if moving:
|
|
48
|
+
anim_idx = 1
|
|
49
|
+
|
|
50
|
+
skelform_pygame.animate(
|
|
51
|
+
screen,
|
|
52
|
+
skelform_root["armature"],
|
|
53
|
+
texture_img,
|
|
54
|
+
anim_idx,
|
|
55
|
+
-1,
|
|
56
|
+
time.time(),
|
|
57
|
+
skelform_pygame.AnimOptions(player_pos, 0.25, True),
|
|
58
|
+
)
|
|
59
|
+
# flip() the display to put your work on screen
|
|
60
|
+
pygame.display.flip()
|
|
61
|
+
|
|
62
|
+
# limits FPS to 60
|
|
63
|
+
# dt is delta time in seconds since last frame, used for framerate-
|
|
64
|
+
# independent physics.
|
|
65
|
+
dt = clock.tick(60) / 1000
|
|
66
|
+
moving = False
|
|
67
|
+
|
|
68
|
+
pygame.quit()
|
|
Binary file
|