PyScene 1.1.1__tar.gz → 1.1.3__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.
Files changed (31) hide show
  1. {pyscene-1.1.1 → pyscene-1.1.3}/PKG-INFO +9 -2
  2. {pyscene-1.1.1 → pyscene-1.1.3}/README.md +8 -1
  3. {pyscene-1.1.1 → pyscene-1.1.3}/pyproject.toml +1 -1
  4. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/Game.py +14 -1
  5. pyscene-1.1.3/src/PyScene/objs/GameObj.py +45 -0
  6. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/objs/Shapes.py +8 -0
  7. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/objs/Text.py +2 -2
  8. pyscene-1.1.3/src/PyScene/tools/manager_gui.py +260 -0
  9. pyscene-1.1.1/src/PyScene/objs/GameObj.py +0 -24
  10. pyscene-1.1.1/src/PyScene/tools/manager_gui.py +0 -10
  11. {pyscene-1.1.1 → pyscene-1.1.3}/.gitignore +0 -0
  12. {pyscene-1.1.1 → pyscene-1.1.3}/LICENSE +0 -0
  13. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/Collisions.py +0 -0
  14. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/Keys.py +0 -0
  15. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/Math.py +0 -0
  16. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/Net.py +0 -0
  17. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/__init__.py +0 -0
  18. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/__main__.py +0 -0
  19. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/objs/Collision_shapes.py +0 -0
  20. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/objs/Tilemap.py +0 -0
  21. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/objs/Timer.py +0 -0
  22. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/objs/__init__.py +0 -0
  23. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/objs/animation.py +0 -0
  24. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/utils/Assets.py +0 -0
  25. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/utils/Subscreen.py +0 -0
  26. {pyscene-1.1.1 → pyscene-1.1.3}/src/PyScene/utils/__init__.py +0 -0
  27. {pyscene-1.1.1 → pyscene-1.1.3}/test.py +0 -0
  28. {pyscene-1.1.1 → pyscene-1.1.3}/tests/flappy_bird.py +0 -0
  29. {pyscene-1.1.1 → pyscene-1.1.3}/tests/pause.png +0 -0
  30. {pyscene-1.1.1 → pyscene-1.1.3}/tests/testColl.py +0 -0
  31. {pyscene-1.1.1 → pyscene-1.1.3}/tests/tileset.png +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: PyScene
3
- Version: 1.1.1
3
+ Version: 1.1.3
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
@@ -19,5 +19,12 @@ This is not a pygame wrapper, as it goed beyons the basic helper features and di
19
19
 
20
20
  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
21
 
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.1
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.3
23
23
 
24
+ Getting Started Basics:
25
+
26
+ 1. Use Game.init(...)
27
+ 2. Create custom Game Objects by inheriting GameObj
28
+ 3. Create a Scene by inheriting Scene
29
+ 4. Use Game.Run(...) #pass in True to have escape close the window
30
+ Not: remenber to use super().__init__(...) is any inherited scene or Game object
@@ -5,5 +5,12 @@ This is not a pygame wrapper, as it goed beyons the basic helper features and di
5
5
 
6
6
  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
7
 
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.1
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.3
9
9
 
10
+ Getting Started Basics:
11
+
12
+ 1. Use Game.init(...)
13
+ 2. Create custom Game Objects by inheriting GameObj
14
+ 3. Create a Scene by inheriting Scene
15
+ 4. Use Game.Run(...) #pass in True to have escape close the window
16
+ Not: remenber to use super().__init__(...) is any inherited scene or Game object
@@ -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.1"
6
+ version = "1.1.3"
7
7
  authors = [
8
8
  { name="Sam Fertig", email="sfertig007@gmail.com" },
9
9
  ]
@@ -190,7 +190,20 @@ class _game:
190
190
  self.queue_creation_coll = []
191
191
  self.queue_del_coll = []
192
192
  self._update_coll = False
193
-
193
+ def clear_global_objs(self):
194
+ self.objects = []
195
+ self.queue_creation = []
196
+ self.queue_del = []
197
+ self.render_queue = []
198
+ def clear_scene_objs(self):
199
+ if self.active_scene is not None:
200
+ self.active_scene._objects = []
201
+ self.active_scene.queue_creation = []
202
+ self.active_scene.queue_del = []
203
+ self.active_scene._render_queue = []
204
+ def clear_all_objs(self):
205
+ self.clear_global_objs()
206
+ self.clear_scene_objs()
194
207
  def _set_scene(self, scene=None):
195
208
  if self.active_scene is not None: self.active_scene.destroy()
196
209
  self._clear_all_collisions_()
@@ -0,0 +1,45 @@
1
+ import pygame
2
+ from ..Math import Vector2D
3
+ from ..Game import Game
4
+
5
+ class GameObj: #this will be the base class of every game obj
6
+ def __init__(self, pos=Vector2D(0, 0), z_index=0, active=True, visible=True, Global=False):
7
+ self.pos: Vector2D = pos
8
+ self.vel: Vector2D = Vector2D(0, 0)
9
+ self.z_index = z_index
10
+ self.active = active
11
+ self.visible = visible
12
+ self._id = Game._get_id()
13
+
14
+ self.__parent: GameObj = None
15
+ self.__children: list[GameObj] = []
16
+
17
+ #add to creation
18
+ if Game.always_global: Global = True
19
+ if not Global: Game._queue_add(self)
20
+ else: Game.queue_creation.append(self) #if obj is just global anyway
21
+
22
+ self._global = Global
23
+
24
+ def child(self, obj): #obj is a game object
25
+ self.__children.append(obj)
26
+ obj.parent(self)
27
+
28
+ def parent(self, obj):
29
+ # If we already have a parent, remove ourselves from its list first
30
+ if self.__parent and self in self.__parent.__children:
31
+ self.__parent.__children.remove(self)
32
+ self.__parent = obj
33
+
34
+ def update(self): pass
35
+ def render(self): pass
36
+ def destroy(self):
37
+ Game._queue_remove(self)
38
+ for i in self.__children:
39
+ i.destroy()
40
+
41
+ if self.__parent: self.__parent.__children.remove(self)
42
+
43
+ self.__children = []
44
+ self.__parent = None
45
+
@@ -19,6 +19,9 @@ class Rect(GameObj):
19
19
  def render(self):
20
20
  Game.cam.draw_rect(self.rect, self.color, self.width, self.offset)
21
21
 
22
+ def render_to(self, screen):
23
+ pygame.draw.rect(screen, self.color, self.rect, self.width)
24
+
22
25
  class Circle(GameObj):
23
26
  def __init__(self, x, y, r, color, z_index=0, width=0, active=True, visible=True, offset=True, Global=False):
24
27
  super().__init__(Vector2D(x, y), z_index, active, visible, Global)
@@ -30,6 +33,9 @@ class Circle(GameObj):
30
33
  def render(self):
31
34
  Game.cam.draw_circle(self.pos, self.radius, self.color, self.width, self.offset)
32
35
 
36
+ def render_to(self, screen):
37
+ pygame.draw.circle(screen, self.color, self.pos.to_int(), self.radius, self.width)
38
+
33
39
  class Line(GameObj):
34
40
  def __init__(self, x1, y1, x2, y2, color, z_index=0, width=1, active=True, visible=True, offset=True, Global=False):
35
41
  super().__init__(Vector2D(x1, y1), z_index, active, visible, Global)
@@ -40,3 +46,5 @@ class Line(GameObj):
40
46
 
41
47
  def render(self):
42
48
  Game.cam.draw_line(self.pos, self.end, self.color, self.width, self.offset)
49
+ def render_to(self, screen):
50
+ pygame.draw.line(screen, self.color, self.pos.to_int(), self.end.to_int(), self.width)
@@ -30,9 +30,9 @@ class Text(GameObj):
30
30
  self.text = new_text
31
31
  self._update_surface()
32
32
 
33
- def set_pos(self, new_pos):
33
+ def set_pos(self, new_pos: Vector2D):
34
34
  self.pos = new_pos
35
- self.rect = self.surface.get_rect(**{self.align: self.pos})
35
+ self.rect = self.surface.get_rect(**{self.align: self.pos.to_int()})
36
36
 
37
37
  def render(self):
38
38
  Game.cam.draw_text(self.surface, self.rect, self.offset)
@@ -0,0 +1,260 @@
1
+ import pygame
2
+ import os
3
+ import json
4
+
5
+ from ..Game import Game, Scene
6
+ from ..utils import SubScreen
7
+ from ..Math import Vector2D
8
+ from ..Keys import Keys
9
+ from ..objs import *
10
+
11
+ class GUI(Scene):
12
+ def __init__(self):
13
+ super().__init__("GUI")
14
+ Text(pygame.font.Font(None, 25), "PyScene Tilemaps:", (141, 144, 148), Vector2D(10, 10), "topleft", 1)
15
+ Rect(Game.width-200, 35, 190, Game.height-40, (35, 35, 35), 0, 5)
16
+ Text(pygame.font.Font(None, 25), "Tilemap Options:", (141, 144, 148), Vector2D(Game.width-200, 10), "topleft", 1)
17
+ FileWin()
18
+
19
+
20
+ class ManagerGUI:
21
+ def __init__(self):
22
+ Game.init(640, 360, "PyScene Tilemap Manager GUI", (53, 56, 59))
23
+ GUI()
24
+ Game.Run()
25
+
26
+ class FileWin(GameObj):
27
+ def __init__(self):
28
+ super().__init__(Vector2D(10, 35), 1)
29
+ self.subscreen = SubScreen(10, 35, 200, Game.height-40, (35, 35, 35), Game.screen)
30
+ self.screen = self.subscreen.screen
31
+
32
+ self.files: list[FileDefined] = []
33
+ self.__load()
34
+
35
+ def __load(self):
36
+ y = 10
37
+ #scan the files in .pyscene/tilemaps
38
+ for file in os.listdir(".pyscene/tilemaps"):
39
+ name = file.split(".")[0]
40
+ self.files.append(FileDefined(y, name))
41
+ y += self.files[-1].rect.height+5
42
+
43
+ def update(self):
44
+ for file in self.files:
45
+ file.update(self.subscreen)
46
+ for file in self.files:
47
+ if file.RESET:
48
+ self.files.clear()
49
+ self.__load()
50
+ #using mouse wheel to scroll through files, or arrow keys
51
+ change = 0
52
+ for event in Game.events:
53
+ if event.type == pygame.MOUSEWHEEL: change = event.y
54
+ if Keys.is_held(Keys.down): change = 1
55
+ elif Keys.is_held(Keys.up): change = -1
56
+ change*=5
57
+ if change != 0:
58
+ for file in self.files:
59
+ file.move_y(change)
60
+
61
+
62
+ def render(self):
63
+ self.subscreen.clear()
64
+ for file in self.files:
65
+ file.render(self.subscreen.screen)
66
+ self.subscreen.render()
67
+
68
+ class FileDefined():
69
+ def __init__(self, y, name, w=150, h=30):
70
+ self.pos = Vector2D(25, y)
71
+ self.name = name
72
+ self.rect = pygame.Rect(self.pos.x, self.pos.y, w, h)
73
+ self.text = Text(pygame.font.Font(None, 25), self.name, (141, 144, 148), Vector2D(self.rect.centerx, self.rect.centery), "center", 1, visible=False)
74
+ self.w = 3
75
+ self.hovered = False
76
+ self.selected = False
77
+
78
+ self.RESET = False
79
+
80
+ self.options: FileOptions = None
81
+
82
+ def move_y(self, addition):
83
+ self.pos.y += addition
84
+ self.rect.y += addition
85
+ self.text.set_pos(Vector2D(self.text.pos.x, self.text.pos.y+addition))
86
+
87
+ def update(self, sub: SubScreen):
88
+ if not self.selected:
89
+ mpos = sub.local_mouse_pos().to_int()
90
+ self.hovered = self.rect.collidepoint(mpos)
91
+ if self.hovered: self.w = 5
92
+ else: self.w = 3
93
+ if Game.click and self.hovered:
94
+ self.selected = True
95
+ self.w = 0
96
+ self.options = FileOptions(self.name)
97
+ return
98
+ else: #selected
99
+ if (Game.click and sub.screen.get_rect().collidepoint(pygame.mouse.get_pos())) or (Keys.is_pressed(Keys.escape) and self.options.renameWidth == 2):
100
+ self.selected = False
101
+ self.w = 3
102
+ self.options._destroy()
103
+ self.options = None
104
+ else:
105
+ if self.options.RENAME:
106
+ new = self.options.renameName.text
107
+ old = self.name
108
+ self.name = new
109
+ self.text.set_text(new)
110
+ self.options.RENAME = False
111
+ self.options.renameName.set_text("")
112
+ self.options.name.set_text(f"Name: {new}")
113
+ #rename file
114
+ os.rename(f".pyscene/tilemaps/{old}.json", f".pyscene/tilemaps/{new}.json")
115
+ elif self.options.DUPE:
116
+ self.options.DUPE = False
117
+ self.RESET = True
118
+ #duplicate file
119
+ with open(f".pyscene/tilemaps/{self.name}.json", "r") as f:
120
+ data = json.load(f)
121
+ with open(f".pyscene/tilemaps/{self.name}_copy.json", "w") as f:
122
+ json.dump(data, f)
123
+ self.options._destroy()
124
+ elif self.options.DEL:
125
+ self.options.DEL = False
126
+ self.RESET = True
127
+ #delete file
128
+ os.remove(f".pyscene/tilemaps/{self.name}.json")
129
+ self.options._destroy()
130
+
131
+
132
+ def render(self, screen):
133
+ pygame.draw.rect(screen, (0, 0, 0), self.rect, self.w)
134
+ self.text.render_to(screen)
135
+
136
+ class FileOptions(GameObj):
137
+ def __init__(self, name):
138
+ super().__init__(Vector2D(Game.width-200, 35), 1)
139
+ self.sub = SubScreen(Game.width-200, 35, 190, Game.height-40, (35, 35, 35), Game.screen)
140
+
141
+ #name text and details
142
+ self.name = Text(pygame.font.Font(None, 25), f"Name: {name}", (141, 144, 148), Vector2D(5, 10), "topleft", 1, visible=False)
143
+ self.line = Line(5, 30, self.sub.screen.get_rect().width-10, 30, (0, 0, 0), 1, visible=False)
144
+ #rename
145
+ self.renameText = Text(pygame.font.Font(None, 25), "Rename:", (141, 144, 148), Vector2D(5, 40), "topleft", 1, visible=False)
146
+ self.renameRect = pygame.Rect(10, 60, self.sub.screen.get_rect().width-20, 30)
147
+ self.renameWidth = 2
148
+ self.renameName = Text(pygame.font.Font(None, 25), "", (141, 144, 148), Vector2D(self.renameRect.centerx, self.renameRect.centery), "center", 1, visible=False)
149
+ self.RENAME = False
150
+ self.renameLine = Line(5, 100, self.sub.screen.get_rect().width-10, 100, (0, 0, 0), 1, visible=False)
151
+ #dupe
152
+ self.dupeRect = pygame.Rect(10, 110, self.sub.screen.get_rect().width-20, 30)
153
+ self.dupeWidth = 2
154
+ self.dupeText = Text(pygame.font.Font(None, 25), "Duplicate", (141, 144, 148), Vector2D(self.dupeRect.centerx, self.dupeRect.centery), "center", 1, visible=False)
155
+ self.DUPE = False
156
+ self.dupeLine = Line(5, 150, self.sub.screen.get_rect().width-10, 150, (0, 0, 0), 1, visible=False)
157
+ #del
158
+ self.delRect = pygame.Rect(10, 160, self.sub.screen.get_rect().width-20, 30)
159
+ self.delWidth = 2
160
+ self.delText = Text(pygame.font.Font(None, 25), "Delete", (141, 144, 148), Vector2D(self.delRect.centerx, self.delRect.centery), "center", 1, visible=False)
161
+ self.DEL = False
162
+ self.DELCHECK = False
163
+ self.delCnf_rect = pygame.Rect(30, 200, self.sub.screen.get_rect().width-60, 30)
164
+ self.delCnf_text = Text(pygame.font.Font(None, 25), "Confirm", (141, 144, 148), Vector2D(self.delCnf_rect.centerx, self.delCnf_rect.centery), "center", 1, visible=False)
165
+ self.delDnf_width = 2
166
+
167
+ def update(self):
168
+ #rename
169
+ if Game.click:
170
+ mpos = self.sub.local_mouse_pos().to_int()
171
+ if self.renameRect.collidepoint(mpos):
172
+ self.renameWidth = 5
173
+ else:
174
+ self.renameWidth = 2
175
+ elif Keys.is_pressed(Keys.escape):
176
+ if self.renameWidth == 5:
177
+ self.renameWidth = 2
178
+ if self.renameWidth == 5:
179
+ text = self.renameName.text
180
+ done = False
181
+ for event in Game.events:
182
+ if event.type == pygame.KEYDOWN:
183
+ if event.key == pygame.K_BACKSPACE:
184
+ text = text[:-1]
185
+ elif event.key == pygame.K_RETURN:
186
+ if len(text) > 0: done = True
187
+ else:
188
+ if len(text) > 15: continue
189
+ text += event.unicode
190
+ self.renameName.set_text(text)
191
+ if done:
192
+ self.RENAME = True
193
+ self.renameWidth = 2
194
+ #dupe
195
+ mpos = self.sub.local_mouse_pos().to_int()
196
+ if self.dupeRect.collidepoint(mpos):
197
+ self.dupeWidth = 5
198
+ else:
199
+ self.dupeWidth = 2
200
+ if self.dupeWidth == 5 and Game.click:
201
+ self.DUPE = True
202
+
203
+ #del
204
+ mpos = self.sub.local_mouse_pos().to_int()
205
+ if self.delRect.collidepoint(mpos):
206
+ self.delWidth = 5
207
+ else:
208
+ self.delWidth = 2
209
+ if self.delWidth == 5 and Game.click:
210
+ self.DELCHECK = True
211
+ return
212
+
213
+ if self.DELCHECK:
214
+ mpos = self.sub.local_mouse_pos().to_int()
215
+ if self.delCnf_rect.collidepoint(mpos):
216
+ self.delDnf_width = 5
217
+ else:
218
+ self.delDnf_width = 2
219
+ if self.delDnf_width == 5 and Game.click:
220
+ self.DEL = True
221
+ elif Keys.is_pressed(Keys.escape) or Game.click:
222
+ self.DELCHECK = False
223
+
224
+ def render(self):
225
+ self.sub.clear()
226
+
227
+ self.name.render_to(self.sub.screen)
228
+ self.line.render_to(self.sub.screen)
229
+
230
+ self.renameText.render_to(self.sub.screen)
231
+ pygame.draw.rect(self.sub.screen, (0, 0, 0), self.renameRect, self.renameWidth)
232
+ self.renameName.render_to(self.sub.screen)
233
+ self.renameLine.render_to(self.sub.screen)
234
+
235
+ pygame.draw.rect(self.sub.screen, (0, 0, 0), self.dupeRect, self.dupeWidth)
236
+ self.dupeText.render_to(self.sub.screen)
237
+ self.dupeLine.render_to(self.sub.screen)
238
+
239
+ pygame.draw.rect(self.sub.screen, (0, 0, 0), self.delRect, self.delWidth)
240
+ self.delText.render_to(self.sub.screen)
241
+
242
+ if self.DELCHECK:
243
+ pygame.draw.rect(self.sub.screen, (173, 103, 85), self.delCnf_rect, self.delDnf_width)
244
+ self.delCnf_text.render_to(self.sub.screen)
245
+
246
+ self.sub.render()
247
+
248
+ def _destroy(self): #destroys self and all objects used
249
+ self.destroy()
250
+ self.name.destroy()
251
+ self.line.destroy()
252
+ self.renameText.destroy()
253
+ self.dupeText.destroy()
254
+ self.renameLine.destroy()
255
+ self.dupeLine.destroy()
256
+ self.delText.destroy()
257
+ self.delCnf_text.destroy()
258
+
259
+
260
+
@@ -1,24 +0,0 @@
1
- import pygame
2
- from ..Math import Vector2D
3
- from ..Game import Game
4
-
5
- class GameObj: #this will be the base class of every game obj
6
- def __init__(self, pos=Vector2D(0, 0), z_index=0, active=True, visible=True, Global=False):
7
- self.pos: Vector2D = pos
8
- self.vel: Vector2D = Vector2D(0, 0)
9
- self.z_index = z_index
10
- self.active = active
11
- self.visible = visible
12
- self._id = Game._get_id()
13
-
14
- #add to creation
15
- if Game.always_global: Global = True
16
- if not Global: Game._queue_add(self)
17
- else: Game.queue_creation.append(self) #if obj is just global anyway
18
-
19
- self._global = Global
20
-
21
- def update(self): pass
22
- def render(self): pass
23
- def destroy(self): Game._queue_remove(self)
24
-
@@ -1,10 +0,0 @@
1
- import pygame
2
-
3
- from ..Game import Game
4
- from ..utils import SubScreen
5
-
6
- class ManagerGUI:
7
- def __init__(self):
8
- Game.init(640, 360, "PyScene Tilemap Manager GUI", "darkblue")
9
- Game.Run(True)
10
-
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