PyScene 1.1.3__tar.gz → 1.1.5__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.
- {pyscene-1.1.3 → pyscene-1.1.5}/PKG-INFO +4 -2
- {pyscene-1.1.3 → pyscene-1.1.5}/README.md +2 -1
- {pyscene-1.1.3 → pyscene-1.1.5}/pyproject.toml +3 -2
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/Game.py +11 -10
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/Keys.py +11 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/objs/GameObj.py +13 -11
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/objs/Shapes.py +3 -3
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/objs/Text.py +25 -4
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/objs/Tilemap.py +1 -1
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/objs/Timer.py +1 -1
- pyscene-1.1.5/test.py +26 -0
- pyscene-1.1.3/test.py +0 -28
- {pyscene-1.1.3 → pyscene-1.1.5}/.gitignore +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/LICENSE +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/Collisions.py +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/Math.py +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/Net.py +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/__init__.py +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/__main__.py +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/objs/Collision_shapes.py +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/objs/__init__.py +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/objs/animation.py +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/tools/manager_gui.py +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/utils/Assets.py +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/utils/Subscreen.py +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/src/PyScene/utils/__init__.py +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/tests/flappy_bird.py +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/tests/pause.png +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/tests/testColl.py +0 -0
- {pyscene-1.1.3 → pyscene-1.1.5}/tests/tileset.png +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: PyScene
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.5
|
|
4
4
|
Summary: A python and pygame Game Engine
|
|
5
5
|
Project-URL: Homepage, https://github.com/sfertig/PyScene
|
|
6
6
|
Project-URL: Issues, https://github.com/sfertig/PyScene/issues
|
|
7
|
+
Project-URL: GUI-editor, https://github.com/sfertig/PyScene-Studio
|
|
7
8
|
Author-email: Sam Fertig <sfertig007@gmail.com>
|
|
8
9
|
License-Expression: MIT
|
|
9
10
|
License-File: LICENSE
|
|
@@ -16,10 +17,11 @@ Description-Content-Type: text/markdown
|
|
|
16
17
|
|
|
17
18
|
PyScene is a custom python + pygame framework / engine developed to streamline 2d game development.
|
|
18
19
|
This is not a pygame wrapper, as it goed beyons the basic helper features and dives into a mini engine / framework.
|
|
20
|
+
There is also a GUI editor being developed alongside PyScene that can be veiwed at: https://github.com/sfertig/PyScene-Studio
|
|
19
21
|
|
|
20
22
|
Please Note: This engine is still in development and many features, like tilemaps and audio, are a work in progress. It also lack any form of documentation, I ask for patience as docs will be rolled out once the core features are more solidified.
|
|
21
23
|
|
|
22
|
-
PyScene is in developement and API's may change offten, a fully stable version should come with v2.0.0, currently on v1.1.
|
|
24
|
+
PyScene is in developement and API's may change offten, a fully stable version should come with v2.0.0, currently on v1.1.5
|
|
23
25
|
|
|
24
26
|
Getting Started Basics:
|
|
25
27
|
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
PyScene is a custom python + pygame framework / engine developed to streamline 2d game development.
|
|
4
4
|
This is not a pygame wrapper, as it goed beyons the basic helper features and dives into a mini engine / framework.
|
|
5
|
+
There is also a GUI editor being developed alongside PyScene that can be veiwed at: https://github.com/sfertig/PyScene-Studio
|
|
5
6
|
|
|
6
7
|
Please Note: This engine is still in development and many features, like tilemaps and audio, are a work in progress. It also lack any form of documentation, I ask for patience as docs will be rolled out once the core features are more solidified.
|
|
7
8
|
|
|
8
|
-
PyScene is in developement and API's may change offten, a fully stable version should come with v2.0.0, currently on v1.1.
|
|
9
|
+
PyScene is in developement and API's may change offten, a fully stable version should come with v2.0.0, currently on v1.1.5
|
|
9
10
|
|
|
10
11
|
Getting Started Basics:
|
|
11
12
|
|
|
@@ -3,7 +3,7 @@ requires = ["hatchling >= 1.26"]
|
|
|
3
3
|
build-backend = "hatchling.build"
|
|
4
4
|
[project]
|
|
5
5
|
name = "PyScene"
|
|
6
|
-
version = "1.1.
|
|
6
|
+
version = "1.1.5"
|
|
7
7
|
authors = [
|
|
8
8
|
{ name="Sam Fertig", email="sfertig007@gmail.com" },
|
|
9
9
|
]
|
|
@@ -19,4 +19,5 @@ license-files = ["LICEN[CS]E*"]
|
|
|
19
19
|
|
|
20
20
|
[project.urls]
|
|
21
21
|
Homepage = "https://github.com/sfertig/PyScene"
|
|
22
|
-
Issues = "https://github.com/sfertig/PyScene/issues"
|
|
22
|
+
Issues = "https://github.com/sfertig/PyScene/issues"
|
|
23
|
+
GUI-editor = "https://github.com/sfertig/PyScene-Studio"
|
|
@@ -12,7 +12,7 @@ class _game:
|
|
|
12
12
|
pygame.init()
|
|
13
13
|
pygame.font.init()
|
|
14
14
|
|
|
15
|
-
def init(self, width, height, title, bg="black", fps=60, fullscreen=False):
|
|
15
|
+
def init(self, width, height, title, bg="black", fps=60, fullscreen=False, _no_dir=False):
|
|
16
16
|
self.__on = True
|
|
17
17
|
self.width = width
|
|
18
18
|
self.height = height
|
|
@@ -60,7 +60,7 @@ class _game:
|
|
|
60
60
|
#other flags
|
|
61
61
|
self.always_global = False
|
|
62
62
|
|
|
63
|
-
self.__check_dir_files()
|
|
63
|
+
if not _no_dir: self.__check_dir_files()
|
|
64
64
|
|
|
65
65
|
def __check_dir_files(self): #check and create dir and files
|
|
66
66
|
if os.path.exists(".pyscene"): return
|
|
@@ -72,7 +72,7 @@ class _game:
|
|
|
72
72
|
if self.active_scene is None: self.queue_creation.append(obj)
|
|
73
73
|
else: self.active_scene._queue_add(obj)
|
|
74
74
|
def _queue_remove(self, obj):
|
|
75
|
-
if obj in self.objects: self.
|
|
75
|
+
if obj in self.objects: self.queue_del.append(obj)
|
|
76
76
|
else: self.active_scene._queue_remove(obj)
|
|
77
77
|
def _get_id(self):
|
|
78
78
|
self.id += 1
|
|
@@ -128,7 +128,8 @@ class _game:
|
|
|
128
128
|
self.__handle_queue()
|
|
129
129
|
|
|
130
130
|
#update objs
|
|
131
|
-
for obj in self.objects:
|
|
131
|
+
for obj in self.objects:
|
|
132
|
+
if obj._active: obj.update()
|
|
132
133
|
#update scene
|
|
133
134
|
if self.active_scene is not None:
|
|
134
135
|
self.active_scene.update()
|
|
@@ -159,11 +160,10 @@ class _game:
|
|
|
159
160
|
for coll in self.collisions:
|
|
160
161
|
pygame.draw.rect(self.screen, "yellow", coll, 2)
|
|
161
162
|
|
|
162
|
-
def quit(self):
|
|
163
|
+
def quit(self, _quit_program=True):
|
|
163
164
|
self.__on = False
|
|
164
165
|
pygame.quit()
|
|
165
|
-
sys.exit()
|
|
166
|
-
|
|
166
|
+
if _quit_program: sys.exit()
|
|
167
167
|
def set_title(self, title):
|
|
168
168
|
self.title = title
|
|
169
169
|
pygame.display.set_caption(self.title)
|
|
@@ -171,10 +171,10 @@ class _game:
|
|
|
171
171
|
def Tick(self):
|
|
172
172
|
self.update()
|
|
173
173
|
self.render()
|
|
174
|
-
def Run(self, _esc=False):
|
|
174
|
+
def Run(self, _esc=False, _quit_program=True):
|
|
175
175
|
while True:
|
|
176
176
|
self.Tick()
|
|
177
|
-
if _esc and Keys.is_pressed(pygame.K_ESCAPE): self.quit()
|
|
177
|
+
if _esc and Keys.is_pressed(pygame.K_ESCAPE): self.quit(_quit_program)
|
|
178
178
|
def full_reset(self):
|
|
179
179
|
self.objects = []
|
|
180
180
|
self.queue_creation = []
|
|
@@ -226,7 +226,8 @@ class Scene:
|
|
|
226
226
|
def update(self): pass #user defined
|
|
227
227
|
def _update(self): #built in method
|
|
228
228
|
self.__handle_queue()
|
|
229
|
-
for obj in self._objects:
|
|
229
|
+
for obj in self._objects:
|
|
230
|
+
if obj._active: obj.update()
|
|
230
231
|
|
|
231
232
|
def render(self): pass #user defined
|
|
232
233
|
def _render(self): #built in method
|
|
@@ -61,6 +61,17 @@ class _keys:
|
|
|
61
61
|
|
|
62
62
|
self.shift = pygame.K_LSHIFT
|
|
63
63
|
|
|
64
|
+
#func
|
|
65
|
+
self.f1 = pygame.K_F1
|
|
66
|
+
self.f2 = pygame.K_F2
|
|
67
|
+
self.f3 = pygame.K_F3
|
|
68
|
+
self.f4 = pygame.K_F4
|
|
69
|
+
self.f5 = pygame.K_F5
|
|
70
|
+
self.f6 = pygame.K_F6
|
|
71
|
+
self.f7 = pygame.K_F7
|
|
72
|
+
self.f8 = pygame.K_F8
|
|
73
|
+
self.f9 = pygame.K_F9
|
|
74
|
+
|
|
64
75
|
#mouse
|
|
65
76
|
self.mouse_x, self.mouse_y = 0, 0
|
|
66
77
|
|
|
@@ -7,12 +7,12 @@ class GameObj: #this will be the base class of every game obj
|
|
|
7
7
|
self.pos: Vector2D = pos
|
|
8
8
|
self.vel: Vector2D = Vector2D(0, 0)
|
|
9
9
|
self.z_index = z_index
|
|
10
|
-
self.
|
|
10
|
+
self._active = active
|
|
11
11
|
self.visible = visible
|
|
12
12
|
self._id = Game._get_id()
|
|
13
13
|
|
|
14
|
-
self.
|
|
15
|
-
self.
|
|
14
|
+
self._parent: GameObj = None
|
|
15
|
+
self._children: list[GameObj] = []
|
|
16
16
|
|
|
17
17
|
#add to creation
|
|
18
18
|
if Game.always_global: Global = True
|
|
@@ -22,24 +22,26 @@ class GameObj: #this will be the base class of every game obj
|
|
|
22
22
|
self._global = Global
|
|
23
23
|
|
|
24
24
|
def child(self, obj): #obj is a game object
|
|
25
|
-
self.
|
|
25
|
+
self._children.append(obj)
|
|
26
26
|
obj.parent(self)
|
|
27
|
+
return obj #QOF
|
|
27
28
|
|
|
28
29
|
def parent(self, obj):
|
|
29
30
|
# If we already have a parent, remove ourselves from its list first
|
|
30
|
-
if self.
|
|
31
|
-
self.
|
|
32
|
-
self.
|
|
31
|
+
if self._parent and self in self._parent._children:
|
|
32
|
+
self._parent._children.remove(self)
|
|
33
|
+
self._parent = obj
|
|
33
34
|
|
|
34
35
|
def update(self): pass
|
|
35
36
|
def render(self): pass
|
|
36
37
|
def destroy(self):
|
|
37
38
|
Game._queue_remove(self)
|
|
38
|
-
for i in self.
|
|
39
|
+
for i in self._children:
|
|
39
40
|
i.destroy()
|
|
40
41
|
|
|
41
|
-
if self.
|
|
42
|
+
if self._parent:
|
|
43
|
+
if self in self._parent._children: self._parent._children.remove(self)
|
|
42
44
|
|
|
43
|
-
self.
|
|
44
|
-
self.
|
|
45
|
+
self._children = []
|
|
46
|
+
self._parent = None
|
|
45
47
|
|
|
@@ -5,7 +5,7 @@ from ..Game import Game
|
|
|
5
5
|
from .GameObj import GameObj
|
|
6
6
|
|
|
7
7
|
class Rect(GameObj):
|
|
8
|
-
def __init__(self, x, y, w, h, color,
|
|
8
|
+
def __init__(self, x, y, w, h, color, width=0, z_index=0, active=True, visible=True, offset=True, Global=False):
|
|
9
9
|
super().__init__(Vector2D(x, y), z_index, active, visible, Global)
|
|
10
10
|
self.dim = Vector2D(w, h)
|
|
11
11
|
self.color = color
|
|
@@ -23,7 +23,7 @@ class Rect(GameObj):
|
|
|
23
23
|
pygame.draw.rect(screen, self.color, self.rect, self.width)
|
|
24
24
|
|
|
25
25
|
class Circle(GameObj):
|
|
26
|
-
def __init__(self, x, y, r, color,
|
|
26
|
+
def __init__(self, x, y, r, color, width=0, z_index=0, active=True, visible=True, offset=True, Global=False):
|
|
27
27
|
super().__init__(Vector2D(x, y), z_index, active, visible, Global)
|
|
28
28
|
self.radius = r
|
|
29
29
|
self.color = color
|
|
@@ -37,7 +37,7 @@ class Circle(GameObj):
|
|
|
37
37
|
pygame.draw.circle(screen, self.color, self.pos.to_int(), self.radius, self.width)
|
|
38
38
|
|
|
39
39
|
class Line(GameObj):
|
|
40
|
-
def __init__(self, x1, y1, x2, y2, color,
|
|
40
|
+
def __init__(self, x1, y1, x2, y2, color, width=1, z_index=0, active=True, visible=True, offset=True, Global=False):
|
|
41
41
|
super().__init__(Vector2D(x1, y1), z_index, active, visible, Global)
|
|
42
42
|
self.end = Vector2D(x2, y2)
|
|
43
43
|
self.color = color
|
|
@@ -18,9 +18,28 @@ class Text(GameObj):
|
|
|
18
18
|
|
|
19
19
|
def _update_surface(self):
|
|
20
20
|
"""Internal method to re-render surface only when text changes."""
|
|
21
|
-
self.surface = self.font.render(str(self.text), False, self.color)
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
self.surface = self.font.render(str(self.text), False, self.color)
|
|
22
|
+
self._apply_alignment()
|
|
23
|
+
|
|
24
|
+
def _apply_alignment(self):
|
|
25
|
+
"""Safely positions the rect based on single or multi-coordinate alignment."""
|
|
26
|
+
xy = self.pos.to_int() # Assuming this returns (x, y)
|
|
27
|
+
|
|
28
|
+
# Group single-coordinate attributes by which axis they care about
|
|
29
|
+
x_aligns = {"left", "right", "centerx", "x"}
|
|
30
|
+
y_aligns = {"top", "bottom", "centery", "y"}
|
|
31
|
+
|
|
32
|
+
if self.align in x_aligns:
|
|
33
|
+
# Create a default rect at (0,0), then assign the specific X coordinate
|
|
34
|
+
self.rect = self.surface.get_rect()
|
|
35
|
+
setattr(self.rect, self.align, xy[0])
|
|
36
|
+
elif self.align in y_aligns:
|
|
37
|
+
# Create a default rect at (0,0), then assign the specific Y coordinate
|
|
38
|
+
self.rect = self.surface.get_rect()
|
|
39
|
+
setattr(self.rect, self.align, xy[1])
|
|
40
|
+
else:
|
|
41
|
+
# Multi-coordinate alignments (center, topleft, etc.) safely accept the full tuple
|
|
42
|
+
self.rect = self.surface.get_rect(**{self.align: xy})
|
|
24
43
|
|
|
25
44
|
def set_text(self, new_text, color=None):
|
|
26
45
|
"""Only call this when the string actually changes!"""
|
|
@@ -32,13 +51,15 @@ class Text(GameObj):
|
|
|
32
51
|
|
|
33
52
|
def set_pos(self, new_pos: Vector2D):
|
|
34
53
|
self.pos = new_pos
|
|
35
|
-
self.
|
|
54
|
+
self._apply_alignment()
|
|
36
55
|
|
|
37
56
|
def render(self):
|
|
38
57
|
Game.cam.draw_text(self.surface, self.rect, self.offset)
|
|
58
|
+
|
|
39
59
|
def render_to(self, surface):
|
|
40
60
|
surface.blit(self.surface, self.rect)
|
|
41
61
|
|
|
62
|
+
|
|
42
63
|
class Image(GameObj):
|
|
43
64
|
def __init__(self, image, pos=Vector2D(0, 0), z_index=0, active=True, visible=True, offset=True, Global=False):
|
|
44
65
|
super().__init__(pos, z_index, active, visible, Global)
|
|
@@ -7,7 +7,7 @@ from ..Math import Vector2D
|
|
|
7
7
|
from ..utils import SubScreen
|
|
8
8
|
|
|
9
9
|
class Tilemap(GameObj):
|
|
10
|
-
def __init__(self, name, tileset, size=16, z_index=0, active=True, visible=True, Global=False ):
|
|
10
|
+
def __init__(self, name, tileset, size=16, z_index=0, active=True, visible=True, offset=True, Global=False ):
|
|
11
11
|
super().__init__(Vector2D(0, 0), z_index, active, visible, Global)
|
|
12
12
|
self.name = name
|
|
13
13
|
self.tileset: dict[list[int], pygame.surface.Surface] = tileset
|
|
@@ -3,7 +3,7 @@ from ..Game import Game
|
|
|
3
3
|
from ..Math import Vector2D
|
|
4
4
|
|
|
5
5
|
class Timer(GameObj):
|
|
6
|
-
def __init__(self, duration, active=True, Global=False):
|
|
6
|
+
def __init__(self, duration, z_index=0, active=True, visible=True, offset=True, Global=False):
|
|
7
7
|
super().__init__(Vector2D(0, 0), 0, active, True, Global)
|
|
8
8
|
self.duration = duration
|
|
9
9
|
self.elapsed = 0.0
|
pyscene-1.1.5/test.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from src.PyScene import *
|
|
2
|
+
|
|
3
|
+
Game.init(640, 360, "Test - 01", "darkblue", fullscreen=False)
|
|
4
|
+
|
|
5
|
+
class Player(GameObj):
|
|
6
|
+
def __init__(self, x, y):
|
|
7
|
+
super().__init__(Vector2D(x, y)) #z index is 0 by default
|
|
8
|
+
self.rect = self.child(Rect(0, 0, 16, 16, "green")) #if player is destroyed so will the rect
|
|
9
|
+
|
|
10
|
+
def update(self):
|
|
11
|
+
self.pos += (Keys.get_vector(Keys.a, Keys.d, Keys.w, Keys.s, False)*150)*Game.dt
|
|
12
|
+
self.rect.pos = self.pos
|
|
13
|
+
|
|
14
|
+
#if Keys.is_pressed(Keys.enter): self.destroy()
|
|
15
|
+
|
|
16
|
+
class GameScene(Scene):
|
|
17
|
+
def __init__(self):
|
|
18
|
+
super().__init__("main")
|
|
19
|
+
Player(Game.width/2, Game.height/2) #this will live with scene, if scene changed player will be destroyed
|
|
20
|
+
|
|
21
|
+
#Player(200, 200) This would be a global object and live through scene changes
|
|
22
|
+
|
|
23
|
+
GameScene() #calling this will create the scene and the super will set it as the current scene
|
|
24
|
+
|
|
25
|
+
Game.Run(True) #or you can have a manual game loop with Game.Tick or using Game.update and Game.render
|
|
26
|
+
#Also passing true will make the window close if ascape is presed
|
pyscene-1.1.3/test.py
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
from src.PyScene import *
|
|
2
|
-
import pygame
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Game.init(640, 360, "Test - 01", "darkblue", fullscreen=False)
|
|
6
|
-
|
|
7
|
-
class Player(GameObj):
|
|
8
|
-
def __init__(self):
|
|
9
|
-
super().__init__(Vector2D(0, 0), 0)
|
|
10
|
-
self.rect = Rect(0, 0, 16, 16, "green")
|
|
11
|
-
|
|
12
|
-
def update(self):
|
|
13
|
-
self.vel = (Keys.get_vector(Keys.a, Keys.d, Keys.w, Keys.s, False)*150)*Game.dt
|
|
14
|
-
self.pos += self.vel
|
|
15
|
-
self.rect.pos = self.pos
|
|
16
|
-
|
|
17
|
-
Game.cam.pos.x = -Game.width/2
|
|
18
|
-
Game.cam.pos.y = -Game.height/2
|
|
19
|
-
Player()
|
|
20
|
-
|
|
21
|
-
Assets.new_tileset("tests/tileset.png", "tileset")
|
|
22
|
-
t = Tilemap("test", Assets.get_tileset("tileset"), 16, -1)
|
|
23
|
-
|
|
24
|
-
#t.tilemap[(0, 0)] = (1, 0)
|
|
25
|
-
#t.tilemap[(0, 1)] = (1, 1)
|
|
26
|
-
#t.dirty = True
|
|
27
|
-
|
|
28
|
-
Game.Run(True)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|