skyport-engine 0.1.5__py3-none-any.whl
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.
- skyport/__init__.py +127 -0
- skyport/assets/images/None.png +0 -0
- skyport/assets/images/buttons/how_to_play.png +0 -0
- skyport/assets/images/buttons/menue.png +0 -0
- skyport/assets/images/buttons/play.png +0 -0
- skyport/assets/images/buttons/quit.png +0 -0
- skyport/assets/images/error.png +0 -0
- skyport/assets/images/pt-17.png +0 -0
- skyport/assets/layar_manager.py +249 -0
- skyport/assets/loader/game_file_maps/engine_assets.json +10 -0
- skyport/assets/loader/sound_maps/engine_sounds.json +6 -0
- skyport/assets/loader/texture_maps/engine_textures.json +30 -0
- skyport/assets/sounds/error.mp3 +0 -0
- skyport/assets/sprites/test1.sprite/settings.json +5 -0
- skyport/core/paths.py +57 -0
- skyport/engine_setup.py +4 -0
- skyport/gf_map_cunstructor.py +51 -0
- skyport/global_utils.py +415 -0
- skyport/logs/engine_logs.json +31 -0
- skyport/rendering_eng.py +129 -0
- skyport/skyport.py +9 -0
- skyport_engine-0.1.5.dist-info/METADATA +6 -0
- skyport_engine-0.1.5.dist-info/RECORD +25 -0
- skyport_engine-0.1.5.dist-info/WHEEL +5 -0
- skyport_engine-0.1.5.dist-info/top_level.txt +1 -0
skyport/__init__.py
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"""
|
|
2
|
+
made by : Matthew R and William L
|
|
3
|
+
|
|
4
|
+
////////////////////////////
|
|
5
|
+
-----welcome to skyport-----
|
|
6
|
+
////////////////////////////
|
|
7
|
+
|
|
8
|
+
the purpos of skyport is to:
|
|
9
|
+
provide a simpler way to make a 2d game with pygame without having to learn how to use pygame itself.
|
|
10
|
+
|
|
11
|
+
engine classes:
|
|
12
|
+
- Display_manager: main display manager class
|
|
13
|
+
- Delta_timer: delta time couculator
|
|
14
|
+
- Util: utility functions
|
|
15
|
+
- Layar_manager: manager for multiple layers (cameras)
|
|
16
|
+
- Camera: layer (camera) class
|
|
17
|
+
- r_obj: renderable object class
|
|
18
|
+
- Loader: asset loader class
|
|
19
|
+
- loger: logging utility
|
|
20
|
+
- Sprite: animated texture class
|
|
21
|
+
|
|
22
|
+
important info:
|
|
23
|
+
-when making chunk genorator funcions make shure that it
|
|
24
|
+
takes in at least 1 peramiter for the chunk obj it will be called in
|
|
25
|
+
and the same gose for chunk update funcions.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
import os
|
|
29
|
+
import sys
|
|
30
|
+
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
31
|
+
if BASE_DIR not in sys.path:
|
|
32
|
+
sys.path.insert(0, BASE_DIR)
|
|
33
|
+
|
|
34
|
+
from rendering_eng import *
|
|
35
|
+
from global_utils import *
|
|
36
|
+
from assets.layar_manager import *
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# example usage:
|
|
41
|
+
"""
|
|
42
|
+
import random
|
|
43
|
+
import time
|
|
44
|
+
#import skyport as sp
|
|
45
|
+
|
|
46
|
+
# 1. Setup Display (Using your scaling logic: 500x500 window -> 1500x750 internal)
|
|
47
|
+
dm = sp.Display_manager((500, 500), (1500, 750), False)
|
|
48
|
+
loader = sp.Loader(None, "idk_tm.json")
|
|
49
|
+
sp.r_obj.loader = loader
|
|
50
|
+
|
|
51
|
+
# 2. Define a "Chunk Generator" that draws a grid background
|
|
52
|
+
def chunk_script(sself):
|
|
53
|
+
sself.bg_image = sp.pygame.Surface((sself.size, sself.size))
|
|
54
|
+
sself.bg_image.fill((30, 30, 30))
|
|
55
|
+
# Draw a grid border so we can see the chunks move
|
|
56
|
+
sp.pygame.draw.rect(sself.bg_image, (50, 50, 50), (0, 0, sself.size, sself.size), 2)
|
|
57
|
+
def update_gen(sself):
|
|
58
|
+
sself.surf.blit(sself.bg_image, (0, 0))
|
|
59
|
+
sself.update_gen_script = update_gen
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# 3. Create the Layer (Camera)
|
|
63
|
+
# World size: 5000x5000, Chunk size: 250
|
|
64
|
+
layar = sp.Camera(dm.display, 250, (5000, 5000), (10, 10, 10), 0, chunk_genorator_func=chunk_script)
|
|
65
|
+
dm.get_lm().add_layar(layar)
|
|
66
|
+
|
|
67
|
+
# 4. Stress Test Variables
|
|
68
|
+
objects = []
|
|
69
|
+
spawn_rate = 10 # How many objects to add per frame
|
|
70
|
+
max_objects = 2000
|
|
71
|
+
|
|
72
|
+
def spawn_stress_objs(count):
|
|
73
|
+
for _ in range(count):
|
|
74
|
+
# Random position within the 5000x5000 world
|
|
75
|
+
rx = random.randint(0, 4900)
|
|
76
|
+
ry = random.randint(0, 4900)
|
|
77
|
+
# Random size and rotation speed
|
|
78
|
+
obj = sp.r_obj(rx, ry, 40, 40, random.randint(0, 360), 0, "asd.jeff")
|
|
79
|
+
obj.rot_speed = random.uniform(-5, 5)
|
|
80
|
+
dm.get_lm().add_obj(obj, 0)
|
|
81
|
+
objects.append(obj)
|
|
82
|
+
|
|
83
|
+
# 5. Start the engine
|
|
84
|
+
dm.START_RENDERING_THREAD(60) # Capped at 60 for stability, or 0 for unlimited
|
|
85
|
+
|
|
86
|
+
print("--- SKYPORT ENGINE BENCHMARK STARTING ---")
|
|
87
|
+
print("Controls: Arrows to Move, I/K to Zoom, SPACE to spawn 100 more")
|
|
88
|
+
|
|
89
|
+
try:
|
|
90
|
+
while dm.running:
|
|
91
|
+
time.sleep(0.01) # Low sleep to keep input responsive
|
|
92
|
+
|
|
93
|
+
# Benchmarking Stats
|
|
94
|
+
fps = dm.clock.get_fps()
|
|
95
|
+
obj_count = len(objects)
|
|
96
|
+
print(f"FPS: {fps:.2f} | Objects: {obj_count} | Cam: ({layar.x}, {layar.y})", end="\r")
|
|
97
|
+
|
|
98
|
+
# Automatic Spawning until we hit max
|
|
99
|
+
if obj_count < max_objects and fps > 30:
|
|
100
|
+
spawn_stress_objs(spawn_rate)
|
|
101
|
+
|
|
102
|
+
# Update Object Logic (Rotating them to stress the transform.rotate calls)
|
|
103
|
+
for o in objects:
|
|
104
|
+
o.angle += o.rot_speed
|
|
105
|
+
|
|
106
|
+
# Input Handling
|
|
107
|
+
keys = sp.pygame.key.get_pressed()
|
|
108
|
+
if keys[sp.pygame.K_LEFT]: layar.x -= 10
|
|
109
|
+
if keys[sp.pygame.K_RIGHT]: layar.x += 10
|
|
110
|
+
if keys[sp.pygame.K_UP]: layar.y -= 10
|
|
111
|
+
if keys[sp.pygame.K_DOWN]: layar.y += 10
|
|
112
|
+
if keys[sp.pygame.K_i]: layar.set_zoom(layar.zoom + 0.05)
|
|
113
|
+
if keys[sp.pygame.K_k]: layar.set_zoom(layar.zoom - 0.05)
|
|
114
|
+
if keys[sp.pygame.K_SPACE]: spawn_stress_objs(100)
|
|
115
|
+
|
|
116
|
+
dm.event()
|
|
117
|
+
|
|
118
|
+
except Exception as e:
|
|
119
|
+
# Your "Loving Feature" should catch this!
|
|
120
|
+
print(f"\nBenchmark stopped: {e}")
|
|
121
|
+
|
|
122
|
+
finally:
|
|
123
|
+
dm.STOP_RENDERING_THREAD()
|
|
124
|
+
print(f"\nFinal Score: Handled {len(objects)} objects at {dm.clock.get_fps():.2f} FPS")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
"""
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import pygame
|
|
2
|
+
import math
|
|
3
|
+
from rendering_eng import pygame
|
|
4
|
+
|
|
5
|
+
# engine imports
|
|
6
|
+
from skyport.core.paths import PathUtil as pu
|
|
7
|
+
from skyport.core.paths import loger
|
|
8
|
+
from global_utils import *
|
|
9
|
+
|
|
10
|
+
class Camera:
|
|
11
|
+
instances = 0
|
|
12
|
+
def __init__(self, display_surface, chunk_size,world_size,bg_fill_color=None,pryoraty=None,chunk_genorator_func=None):
|
|
13
|
+
self.tiles = {}
|
|
14
|
+
self.all_game_objs = []
|
|
15
|
+
self._qued_game_objs = []
|
|
16
|
+
self.display_surface = display_surface
|
|
17
|
+
self.chunk_size = chunk_size
|
|
18
|
+
self.offset_x = 0
|
|
19
|
+
self.offset_y = 0
|
|
20
|
+
self.x,self.y = 0,0
|
|
21
|
+
self.zoom = 1.0
|
|
22
|
+
self.old_zoom = self.zoom
|
|
23
|
+
self.WORLD_HIGHT = world_size[0]
|
|
24
|
+
self.WORLD_WIDTH = world_size[1]
|
|
25
|
+
self.CHUNKS_ON_X = self.WORLD_WIDTH // self.chunk_size
|
|
26
|
+
self.CHUNKS_ON_Y = self.WORLD_HIGHT // self.chunk_size
|
|
27
|
+
self.print_queue = ""
|
|
28
|
+
self.genorator = chunk_genorator_func
|
|
29
|
+
Camera.instances += 1
|
|
30
|
+
self.pryoraty = util.pryoraty(pryoraty,Camera.instances)
|
|
31
|
+
self.bg_fill_color = bg_fill_color
|
|
32
|
+
self.obj_render_surf = pygame.Surface(display_surface.get_size(),flags=pygame.SRCALPHA)
|
|
33
|
+
loger.log(f"Initialized camera with pryoraty of {self.pryoraty} and {Camera.instances} instances")
|
|
34
|
+
|
|
35
|
+
def render_offset_objs(self,disp=None):
|
|
36
|
+
sw, sh = self.display_surface.get_size() # sw and sh stand for screen width and screen height
|
|
37
|
+
for obj in self.all_game_objs: # r_objs need a .x ,.y .og_x .og_y ,.get_surf
|
|
38
|
+
screen_x = obj.x * self.zoom + self.offset_x
|
|
39
|
+
screen_y = obj.y * self.zoom + self.offset_y
|
|
40
|
+
self.display_surface.blit(obj.get_surf(self.zoom),(screen_x,screen_y))
|
|
41
|
+
|
|
42
|
+
def chunkify(self,obj):
|
|
43
|
+
c_pos = self.get_chunk_cords(obj.x,obj.y)
|
|
44
|
+
chunk = self.get_chunk(c_pos[0], c_pos[1])
|
|
45
|
+
chunk.all_objs.append(obj)
|
|
46
|
+
#self._qued_game_objs.append(obj)
|
|
47
|
+
#if obj not in chunk.all_objs:
|
|
48
|
+
# chunk.all_objs.append(obj)
|
|
49
|
+
# #print(f"{prin_GREEN}Added obj {obj.id} to chunk {c_pos}{prin_RESET}")
|
|
50
|
+
#else:
|
|
51
|
+
# self._qued_game_objs.remove(obj)
|
|
52
|
+
|
|
53
|
+
def re_chunk(self,all_objs,obj):
|
|
54
|
+
all_objs.remove(obj)
|
|
55
|
+
self.chunkify(obj)
|
|
56
|
+
|
|
57
|
+
def get_chunk_cords(self,x,y):
|
|
58
|
+
cx = int(x) // self.chunk_size
|
|
59
|
+
cy = int(y) // self.chunk_size
|
|
60
|
+
return (cx,cy)
|
|
61
|
+
|
|
62
|
+
def get_chunk(self,cx, cy):
|
|
63
|
+
#return chunk at (cx, cy), create if it doesnt exist yet
|
|
64
|
+
if (cx, cy) not in self.tiles:
|
|
65
|
+
self.tiles[(cx, cy)] = Chunk(cx, cy, self.chunk_size,genorator=self.genorator,bg_fill_color=self.bg_fill_color,zoom=self.zoom,cam=self)
|
|
66
|
+
Util.print(f"{prin_GREEN}Created chunk {cx},{cy}{prin_RESET}")
|
|
67
|
+
return self.tiles[(cx, cy)]
|
|
68
|
+
|
|
69
|
+
def tick_ops(self):
|
|
70
|
+
if self.print_queue != "":
|
|
71
|
+
Util.print(self.print_queue)
|
|
72
|
+
self.print_queue = ""
|
|
73
|
+
|
|
74
|
+
def set_zoom(self, level):
|
|
75
|
+
self.zoom = max(0.1, level)
|
|
76
|
+
|
|
77
|
+
def get_min_max_c_pos(self,z,W,H):
|
|
78
|
+
world_left = -self.offset_x / z
|
|
79
|
+
world_top = -self.offset_y / z
|
|
80
|
+
world_right = world_left + W / z
|
|
81
|
+
world_bottom = world_top + H / z
|
|
82
|
+
|
|
83
|
+
min_cx = max(0, int(math.floor(world_left / self.chunk_size)))
|
|
84
|
+
max_cx = min(self.CHUNKS_ON_X - 1, int(math.floor(world_right / self.chunk_size)))
|
|
85
|
+
min_cy = max(0, int(math.floor(world_top / self.chunk_size)))
|
|
86
|
+
max_cy = min(self.CHUNKS_ON_Y - 1, int(math.floor(world_bottom / self.chunk_size)))
|
|
87
|
+
return min_cx,min_cy,max_cx,max_cy
|
|
88
|
+
|
|
89
|
+
def render(self, target_x, target_y):
|
|
90
|
+
W, H = self.display_surface.get_size()
|
|
91
|
+
z = self.zoom
|
|
92
|
+
self.obj_render_surf.fill((0,0,0,0))
|
|
93
|
+
self.offset_x = -target_x * z + W // 2
|
|
94
|
+
self.offset_y = -target_y * z + H // 2
|
|
95
|
+
|
|
96
|
+
min_cx,min_cy,max_cx,max_cy = self.get_min_max_c_pos(z,W,H)
|
|
97
|
+
|
|
98
|
+
for cx in range(min_cx, max_cx + 1):
|
|
99
|
+
for cy in range(min_cy, max_cy + 1):
|
|
100
|
+
chunk = self.get_chunk(cx, cy)
|
|
101
|
+
screen_x = cx * self.chunk_size * z + self.offset_x
|
|
102
|
+
screen_y = cy * self.chunk_size * z + self.offset_y
|
|
103
|
+
surf = chunk.scaled_surface(z)
|
|
104
|
+
self.display_surface.blit(surf, (screen_x, screen_y))
|
|
105
|
+
chunk.update(self.zoom,self,screen_x,screen_y)
|
|
106
|
+
self.display_surface.blit(self.obj_render_surf,(0,0))
|
|
107
|
+
self.tick_ops()
|
|
108
|
+
|
|
109
|
+
def get_surf(self):
|
|
110
|
+
return self.display_surface
|
|
111
|
+
|
|
112
|
+
def remove_chunk_obj(self,obj):
|
|
113
|
+
obj_chunk = self.get_chunk_cords(obj.x,obj.y)
|
|
114
|
+
for y in range(-1,1):
|
|
115
|
+
for x in range(-1,1):
|
|
116
|
+
chunk = self.get_chunk(obj_chunk[0]+x,obj_chunk[1]+y)
|
|
117
|
+
if obj in chunk.all_objs:
|
|
118
|
+
chunk.all_objs.remove(obj)
|
|
119
|
+
|
|
120
|
+
class Chunk:
|
|
121
|
+
instances = 0
|
|
122
|
+
def __init__(self, cx, cy, chunk_size ,bg_fill_color=None,genorator=None,zoom=0,cam=None):
|
|
123
|
+
self.cx = cx
|
|
124
|
+
self.cy = cy
|
|
125
|
+
self.size = chunk_size
|
|
126
|
+
self.surf = pygame.Surface((chunk_size, chunk_size), flags=pygame.SRCALPHA)
|
|
127
|
+
self.surf.fill((0, 0, 0))
|
|
128
|
+
self._scaled = None
|
|
129
|
+
self._last_zoom = None
|
|
130
|
+
self.tags = {}
|
|
131
|
+
self.all_objs = []
|
|
132
|
+
self.bg_surf = None
|
|
133
|
+
self.update_gen_script = None
|
|
134
|
+
self.generate_terrain(genorator)
|
|
135
|
+
self.bg_fill_color = bg_fill_color
|
|
136
|
+
#self.update(zoom,cam,)
|
|
137
|
+
if self.bg_fill_color != None:
|
|
138
|
+
self.surf.fill(self.bg_fill_color)
|
|
139
|
+
if self.update_gen_script != None:
|
|
140
|
+
self.update_gen_script(self)
|
|
141
|
+
self.scaled_surface(zoom)
|
|
142
|
+
Chunk.instances += 1
|
|
143
|
+
loger.log(f"Initialized chunk at {cx},{cy} with a total of {Chunk.instances} created")
|
|
144
|
+
|
|
145
|
+
def scale__(self,zoom):
|
|
146
|
+
w = max(1, int(self.size * zoom))
|
|
147
|
+
h = max(1, int(self.size * zoom))
|
|
148
|
+
self._scaled = pygame.transform.scale(self.surf, (w, h))
|
|
149
|
+
self._last_zoom = zoom
|
|
150
|
+
|
|
151
|
+
def scaled_surface(self, zoom):
|
|
152
|
+
if self._last_zoom != zoom or self._scaled is None:
|
|
153
|
+
self.scale__(zoom)
|
|
154
|
+
return self._scaled
|
|
155
|
+
|
|
156
|
+
def generate_terrain(self,genorator=None):
|
|
157
|
+
if genorator != None:
|
|
158
|
+
genorator(self)
|
|
159
|
+
|
|
160
|
+
def blit_objs_v2(self,zoom,cam,chunk_screen_x,chunk_screen_y):
|
|
161
|
+
for obj in self.all_objs: # requierd atributes of rendering obj is .get_surf, .x ,.og_x , .y ,.og_y
|
|
162
|
+
surf = obj.get_surf(zoom)
|
|
163
|
+
obj.rect.x = obj.x * zoom + cam.offset_x
|
|
164
|
+
obj.rect.y = obj.y * zoom + cam.offset_y
|
|
165
|
+
screen_x,screen_y = obj.rect.centerx - surf.get_width()//2, obj.rect.centery - surf.get_height()//2
|
|
166
|
+
cam.obj_render_surf.blit(surf,(screen_x,screen_y)) # i was working on centerd rotations -----------------------------------------------
|
|
167
|
+
|
|
168
|
+
if abs(obj.x - obj.og_x) >= self.size or abs(obj.y - obj.og_y) >= self.size: # rechunking
|
|
169
|
+
cam.print_queue += f"obj {obj.id} is at {obj.x},{obj.y} and beeing rechunked\n"
|
|
170
|
+
obj.og_x,obj.og_y = obj.x,obj.y
|
|
171
|
+
cam.re_chunk(self.all_objs,obj)
|
|
172
|
+
|
|
173
|
+
def update(self,zoom,cam,screen_x,screen_y):
|
|
174
|
+
if self.bg_fill_color != None:
|
|
175
|
+
self.surf.fill(self.bg_fill_color)
|
|
176
|
+
if self.update_gen_script != None:
|
|
177
|
+
self.update_gen_script(self)
|
|
178
|
+
self.blit_objs_v2(zoom,cam,screen_x,screen_y)
|
|
179
|
+
#self.scale__(zoom)
|
|
180
|
+
|
|
181
|
+
class Layar_manager:
|
|
182
|
+
def __init__(self,surf):
|
|
183
|
+
self.surf = surf
|
|
184
|
+
self.layars = []
|
|
185
|
+
self.stashed_layars = []
|
|
186
|
+
loger.log("Initialized layar manager")
|
|
187
|
+
|
|
188
|
+
def render(self):
|
|
189
|
+
for l in self.layars:
|
|
190
|
+
l.render(l.x,l.y)
|
|
191
|
+
self.surf.blit(l.get_surf(),(0,0))
|
|
192
|
+
return self.surf
|
|
193
|
+
|
|
194
|
+
def get_surf(self):
|
|
195
|
+
return self.surf
|
|
196
|
+
|
|
197
|
+
def sort(self):
|
|
198
|
+
self.layars = util.sort_objects_by_attr(self.layars,"pryoraty")
|
|
199
|
+
|
|
200
|
+
def add_layar(self,layar):
|
|
201
|
+
self.layars.append(layar)
|
|
202
|
+
self.sort()
|
|
203
|
+
def del_layar(self,pryoraty):
|
|
204
|
+
if pryoraty in self.layars:
|
|
205
|
+
self.layars.pop(pryoraty)
|
|
206
|
+
return True
|
|
207
|
+
return False
|
|
208
|
+
def remove_layar(self,pryoraty):
|
|
209
|
+
if pryoraty in self.layars:
|
|
210
|
+
self.stashed_layars.append(self.layars[pryoraty])
|
|
211
|
+
return True
|
|
212
|
+
print(f"layar {pryoraty} duse not exsis")
|
|
213
|
+
return False
|
|
214
|
+
|
|
215
|
+
def get_layar(self,pryoraty):
|
|
216
|
+
return self.layars[pryoraty]
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def get_layar_objs(self,layar):
|
|
220
|
+
offset_objs = layar.all_game_objs
|
|
221
|
+
chunk_objs = {}
|
|
222
|
+
for pos in layar.tiles.key():
|
|
223
|
+
chunk = layar.tiles[pos]
|
|
224
|
+
c_obj = chunk.all_objs
|
|
225
|
+
chunk_objs[pos] = c_obj
|
|
226
|
+
return chunk_objs,offset_objs
|
|
227
|
+
|
|
228
|
+
def set_layar_objs(self,chunk_objs,offset_objs,layar):
|
|
229
|
+
layar.all_game_objs + offset_objs
|
|
230
|
+
for pos in layar.tiles.key():
|
|
231
|
+
chunk = layar.tiles[pos]
|
|
232
|
+
chunk.all_objs + chunk_objs[pos]
|
|
233
|
+
return layar
|
|
234
|
+
|
|
235
|
+
def add_obj(self,obj,layar_pryoraty):
|
|
236
|
+
layar = self.get_layar(layar_pryoraty)
|
|
237
|
+
if obj.render_type == "chunk" or obj.render_type == "CHUNK":
|
|
238
|
+
layar.chunkify(obj)
|
|
239
|
+
else:
|
|
240
|
+
layar.all_game_objs.append(obj)
|
|
241
|
+
def remove_obj(self,obj,layar_pryoraty):
|
|
242
|
+
layar = self.get_layar(layar_pryoraty)
|
|
243
|
+
if obj.render_type == "chunk" or obj.render_type == "CHUNK":
|
|
244
|
+
layar.remove_chunk_obj(obj)
|
|
245
|
+
else:
|
|
246
|
+
if obj in layar.all_game_objs:
|
|
247
|
+
layar.all_game_objs.remove(obj)
|
|
248
|
+
|
|
249
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"assets/images/error.png": {
|
|
3
|
+
"type": "d",
|
|
4
|
+
"value": null
|
|
5
|
+
},
|
|
6
|
+
"assets/images/None.png": {
|
|
7
|
+
"type": "d",
|
|
8
|
+
"value": null
|
|
9
|
+
},
|
|
10
|
+
"assets/images/pt-17.png": {
|
|
11
|
+
"type": "d",
|
|
12
|
+
"value": null
|
|
13
|
+
},
|
|
14
|
+
"assets/images/buttons/how_to_play.png": {
|
|
15
|
+
"type": "d",
|
|
16
|
+
"value": null
|
|
17
|
+
},
|
|
18
|
+
"assets/images/buttons/menue.png": {
|
|
19
|
+
"type": "d",
|
|
20
|
+
"value": null
|
|
21
|
+
},
|
|
22
|
+
"assets/images/buttons/play.png": {
|
|
23
|
+
"type": "d",
|
|
24
|
+
"value": null
|
|
25
|
+
},
|
|
26
|
+
"assets/images/buttons/quit.png": {
|
|
27
|
+
"type": "d",
|
|
28
|
+
"value": null
|
|
29
|
+
}
|
|
30
|
+
}
|
|
Binary file
|
skyport/core/paths.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
|
|
2
|
+
import datetime
|
|
3
|
+
import os
|
|
4
|
+
import json
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
ENGINE_ROOT = Path(__file__).resolve().parent.parent
|
|
8
|
+
|
|
9
|
+
class PathUtil:
|
|
10
|
+
@staticmethod
|
|
11
|
+
def fp(relative_path: str) -> Path:
|
|
12
|
+
p = Path(relative_path)
|
|
13
|
+
if p.is_absolute():
|
|
14
|
+
return p
|
|
15
|
+
return (ENGINE_ROOT / p).resolve()
|
|
16
|
+
|
|
17
|
+
class ENG_Loger:
|
|
18
|
+
ENGINE_LOG_PATH = PathUtil.fp("logs/engine_logs.json")
|
|
19
|
+
if not os.path.exists(ENGINE_LOG_PATH):
|
|
20
|
+
with open(ENGINE_LOG_PATH,"w") as f:
|
|
21
|
+
json.dump({"total_logs": 5,"record_engine_logs": True,"logs": []},indent=4)
|
|
22
|
+
with open(ENGINE_LOG_PATH,"r") as f:
|
|
23
|
+
log_file = json.load(f)
|
|
24
|
+
take_logs = log_file["record_engine_logs"]
|
|
25
|
+
log_data_retaintion_amount = 5
|
|
26
|
+
print(f"--engine logging is set to {take_logs}--")
|
|
27
|
+
def __init__(self):
|
|
28
|
+
self.log_start_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
29
|
+
self.run_time_log = ""
|
|
30
|
+
if ENG_Loger.take_logs:
|
|
31
|
+
self.log = self._true_log
|
|
32
|
+
else:
|
|
33
|
+
self.log = self._false_log
|
|
34
|
+
|
|
35
|
+
def save(self):
|
|
36
|
+
ENG_Loger.log_file["logs"].append({
|
|
37
|
+
"log_start_time":self.log_start_time,
|
|
38
|
+
"log_end_time":datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
39
|
+
"run_time_log":self.run_time_log
|
|
40
|
+
})
|
|
41
|
+
if len(ENG_Loger.log_file["logs"]) > ENG_Loger.log_data_retaintion_amount:
|
|
42
|
+
ENG_Loger.log_file["logs"].pop(0)
|
|
43
|
+
ENG_Loger.log_file["total_logs"] = ENG_Loger.log_data_retaintion_amount
|
|
44
|
+
with open(ENG_Loger.ENGINE_LOG_PATH,"w") as f:
|
|
45
|
+
json.dump(ENG_Loger.log_file,f,indent=4)
|
|
46
|
+
def print(self):
|
|
47
|
+
for log in ENG_Loger.log_file["logs"]:
|
|
48
|
+
for line in log["run_time_log"].split("\n"):
|
|
49
|
+
print(line)
|
|
50
|
+
print("----- end of log")
|
|
51
|
+
|
|
52
|
+
def _true_log(self,message):
|
|
53
|
+
self.run_time_log += f"[{datetime.datetime.now().strftime('%H:%M:%S')}] :-: {message}\n"
|
|
54
|
+
def _false_log(self,message):
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
loger = ENG_Loger()
|
skyport/engine_setup.py
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
def main():
|
|
5
|
+
base_dir = input("enter the file dir : ").strip()
|
|
6
|
+
base_dir = os.path.abspath(base_dir)
|
|
7
|
+
|
|
8
|
+
count = int(input("how meny file formats to use : "))
|
|
9
|
+
extensions = []
|
|
10
|
+
|
|
11
|
+
for i in range(count):
|
|
12
|
+
ext = input("file type : ").strip().lower()
|
|
13
|
+
if not ext.startswith("."):
|
|
14
|
+
ext = "." + ext
|
|
15
|
+
extensions.append(ext)
|
|
16
|
+
|
|
17
|
+
print(f"\nScanning directory: {base_dir}")
|
|
18
|
+
print(f"Including file types: {extensions}\n")
|
|
19
|
+
|
|
20
|
+
manifest = {}
|
|
21
|
+
|
|
22
|
+
for root, _, files in os.walk(base_dir):
|
|
23
|
+
for file in files:
|
|
24
|
+
if any(file.lower().endswith(ext) for ext in extensions):
|
|
25
|
+
full_path = os.path.join(root, file)
|
|
26
|
+
rel_path = os.path.relpath(full_path, base_dir)
|
|
27
|
+
rel_path = rel_path.replace("\\", "/") # engine-safe
|
|
28
|
+
|
|
29
|
+
manifest[rel_path] = {
|
|
30
|
+
"type": "d",
|
|
31
|
+
"value": None
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
print("--- GENERATED ASSET MANIFEST (JSON) ---")
|
|
35
|
+
print(json.dumps(manifest, indent=4))
|
|
36
|
+
"""
|
|
37
|
+
save = input("\nSave to file? (y/n): ").lower()
|
|
38
|
+
if save == "y":
|
|
39
|
+
out_name = input("Output file name (ex: assets.json): ").strip()
|
|
40
|
+
with open(out_name, "w", encoding="utf-8") as f:
|
|
41
|
+
json.dump(manifest, f, indent=4)
|
|
42
|
+
print(f"Saved to {out_name}")
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
#input("\npress any key to exit:")
|
|
46
|
+
def gen_map():
|
|
47
|
+
main()
|
|
48
|
+
|
|
49
|
+
if __name__ == "__main__":
|
|
50
|
+
main()
|
|
51
|
+
confirm = input("Press Enter to exit...")
|
skyport/global_utils.py
ADDED
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
|
|
2
|
+
import numpy as np
|
|
3
|
+
#import pygame
|
|
4
|
+
import math
|
|
5
|
+
import time
|
|
6
|
+
import json
|
|
7
|
+
import os
|
|
8
|
+
from skyport.core.paths import PathUtil as pu
|
|
9
|
+
from skyport.core.paths import loger
|
|
10
|
+
from rendering_eng import pygame
|
|
11
|
+
|
|
12
|
+
class Util:
|
|
13
|
+
instanses = 0
|
|
14
|
+
print_que = ""
|
|
15
|
+
def __init__(self):
|
|
16
|
+
Util.instanses += 1
|
|
17
|
+
#print(Util.instanses)
|
|
18
|
+
#self.ROOT_PATH = Path(__file__).resolve().parent.parent
|
|
19
|
+
if Util.instanses <= 3:
|
|
20
|
+
self.fp = self.e_fp
|
|
21
|
+
else:
|
|
22
|
+
self.fp = self.m_fp
|
|
23
|
+
loger.log(f"Util instans {Util.instanses} inisalized")
|
|
24
|
+
self.tags = {}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def output_print_data():
|
|
28
|
+
print(f"{Util.print_que}__")
|
|
29
|
+
Util.print_que = ""
|
|
30
|
+
def print(string):
|
|
31
|
+
Util.print_que += string+"\n"
|
|
32
|
+
|
|
33
|
+
def m_fp(self, relative_fp):
|
|
34
|
+
return relative_fp
|
|
35
|
+
def e_fp(self, relative_fp):
|
|
36
|
+
return pu.fp(relative_fp)
|
|
37
|
+
|
|
38
|
+
def get_angle_and_dist(self,x1,y1,x,y):
|
|
39
|
+
dx = x1 - x
|
|
40
|
+
dy = y1 - y
|
|
41
|
+
dist = math.hypot(dx, dy)
|
|
42
|
+
angle = (math.degrees(math.atan2(dy, dx)) + 180) % 360
|
|
43
|
+
return angle,dist
|
|
44
|
+
|
|
45
|
+
def color_swap(self,surface: pygame.Surface, old_color: tuple, new_color: tuple) -> pygame.Surface:
|
|
46
|
+
arr_rgb = pygame.surfarray.array3d(surface)
|
|
47
|
+
arr_alpha = pygame.surfarray.array_alpha(surface)
|
|
48
|
+
mask = np.all(arr_rgb == old_color, axis=-1)
|
|
49
|
+
arr_rgb[mask] = new_color
|
|
50
|
+
new_surface = pygame.Surface(surface.get_size(), pygame.SRCALPHA, 32)
|
|
51
|
+
new_surface = new_surface.convert_alpha()
|
|
52
|
+
pygame.surfarray.blit_array(new_surface, arr_rgb)
|
|
53
|
+
pygame.surfarray.pixels_alpha(new_surface)[:] = arr_alpha
|
|
54
|
+
return new_surface
|
|
55
|
+
|
|
56
|
+
def pryoraty(self,a=None,b=None):
|
|
57
|
+
if a != None:
|
|
58
|
+
return a
|
|
59
|
+
else:
|
|
60
|
+
return b
|
|
61
|
+
|
|
62
|
+
def sort_objects_by_attr(self,obj_list : list, attr_name : str, reverse=False):
|
|
63
|
+
return sorted(obj_list, key=lambda x: getattr(x, attr_name), reverse=reverse)
|
|
64
|
+
|
|
65
|
+
class Loader:
|
|
66
|
+
loader_instanses = 0
|
|
67
|
+
lutil = Util()
|
|
68
|
+
error_img=pygame.image.load(lutil.fp("assets/images/error.png")).convert_alpha()
|
|
69
|
+
error_sound=pygame.mixer.Sound(lutil.fp("assets/sounds/error.mp3"))
|
|
70
|
+
def __init__(self,texture_map_path=None,GF_map_path=None,sound_map_path=None,loader_name=None,error_img=None,error_sound=None):
|
|
71
|
+
self.lutil = Util()
|
|
72
|
+
self.texture_map = {}
|
|
73
|
+
self.file_map = {}
|
|
74
|
+
self.sound_map = {}
|
|
75
|
+
if texture_map_path != None:
|
|
76
|
+
self.load_texture_map(texture_map_path)
|
|
77
|
+
if GF_map_path != None:
|
|
78
|
+
self.load_file_map(GF_map_path)
|
|
79
|
+
if sound_map_path != None:
|
|
80
|
+
self.load_sound_map(sound_map_path)
|
|
81
|
+
# loader naming for debuging
|
|
82
|
+
self.error_assets = {"img":self.lutil.pryoraty(error_img,Loader.error_img),"sound":self.lutil.pryoraty(error_sound,Loader.error_sound)}
|
|
83
|
+
Loader.loader_instanses += 1
|
|
84
|
+
self.loader_name = util.pryoraty(loader_name,str(Loader.loader_instanses))
|
|
85
|
+
print(f"{prin_BLUE}++| inisalized Loader instans '{self.loader_name}' |++{prin_RESET}")
|
|
86
|
+
loger.log(f"Loader instans '{self.loader_name}' inisalized with {Loader.loader_instanses} loader_instanses")
|
|
87
|
+
|
|
88
|
+
def _error(self,Type,error,path):
|
|
89
|
+
error_msg = f"{prin_RED}!!-error loading {Type} : {path} ->> in loader {self.loader_name} with error >> {error} -!!{prin_RESET}"
|
|
90
|
+
loger.log(error_msg)
|
|
91
|
+
print(error_msg)
|
|
92
|
+
|
|
93
|
+
def _loade_img_catagory(self,val):
|
|
94
|
+
paths = val["value"]
|
|
95
|
+
images = []
|
|
96
|
+
for path in paths:
|
|
97
|
+
images.append(pygame.image.load(self.lutil.fp(path)).convert_alpha())
|
|
98
|
+
val["value"] = images
|
|
99
|
+
return val
|
|
100
|
+
def init_comon_textures(self,texture_map):
|
|
101
|
+
all_keys = texture_map.keys()
|
|
102
|
+
TM = texture_map
|
|
103
|
+
for key in all_keys:
|
|
104
|
+
val = TM[key]
|
|
105
|
+
Type = val["type"].lower()
|
|
106
|
+
if Type == "d" or Type == "defalt":
|
|
107
|
+
val["value"] = pygame.image.load(self.lutil.fp(key)).convert_alpha()
|
|
108
|
+
TM[key] = val
|
|
109
|
+
elif Type == "r" or Type == "replace":
|
|
110
|
+
val["value"] = pygame.image.load(val["value"]).convert_alpha()
|
|
111
|
+
TM[key] = val
|
|
112
|
+
elif Type == "c" or Type == "catagory":
|
|
113
|
+
val = self._loade_img_catagory(self.lutil.fp(val))
|
|
114
|
+
else:
|
|
115
|
+
val["value"] = pygame.image.load(self.lutil.fp(key)).convert_alpha()
|
|
116
|
+
TM[key] = val
|
|
117
|
+
return TM
|
|
118
|
+
def load_texture_map(self,map_path):
|
|
119
|
+
map_path = self.lutil.fp(map_path)
|
|
120
|
+
with open(map_path,"r") as file:
|
|
121
|
+
texture_map = json.load(file)
|
|
122
|
+
self.texture_map = self.init_comon_textures(texture_map)
|
|
123
|
+
|
|
124
|
+
def _loade_file_catagory(self,val):
|
|
125
|
+
paths = val["value"]
|
|
126
|
+
files = []
|
|
127
|
+
for path in paths:
|
|
128
|
+
with open(self.lutil.fp(path),"r") as file:
|
|
129
|
+
files.append(json.load(file))
|
|
130
|
+
val["value"] = files
|
|
131
|
+
return val
|
|
132
|
+
def init_game_files(self,file_map):
|
|
133
|
+
all_keys = file_map.keys()
|
|
134
|
+
TM = file_map
|
|
135
|
+
for key in all_keys:
|
|
136
|
+
val = TM[key]
|
|
137
|
+
Type = val["type"].lower()
|
|
138
|
+
if Type == "d" or Type == "defalt":
|
|
139
|
+
with open(self.lutil.fp(key),"r") as file:
|
|
140
|
+
val["value"] = json.load(file)
|
|
141
|
+
TM[key] = val
|
|
142
|
+
elif Type == "r" or Type == "replace":
|
|
143
|
+
with open(self.lutil.fp(val["value"]),"r") as file:
|
|
144
|
+
val["value"] = json.load(file)
|
|
145
|
+
TM[key] = val
|
|
146
|
+
elif Type == "c" or Type == "catagory":
|
|
147
|
+
val = self._loade_file_catagory(val)
|
|
148
|
+
else:
|
|
149
|
+
with open(self.lutil.fp(key),"r") as file:
|
|
150
|
+
val["value"] = json.load(file)
|
|
151
|
+
TM[key] = val
|
|
152
|
+
return TM
|
|
153
|
+
def load_file_map(self,map_path):
|
|
154
|
+
map_path = self.lutil.fp(map_path)
|
|
155
|
+
with open(map_path,"r") as file:
|
|
156
|
+
file_map = json.load(file)
|
|
157
|
+
self.file_map = self.init_game_files(file_map)
|
|
158
|
+
|
|
159
|
+
def _loade_sound_catagory(self,val):
|
|
160
|
+
file_paths = val["value"]
|
|
161
|
+
sounds = []
|
|
162
|
+
for file_path in file_paths:
|
|
163
|
+
sounds.append(pygame.mixer.Sound(self.lutil.fp(file_path)))
|
|
164
|
+
val["value"] = sounds
|
|
165
|
+
return val
|
|
166
|
+
def init_sound_map(self,sound_map):
|
|
167
|
+
all_keys = sound_map.keys()
|
|
168
|
+
TM = sound_map
|
|
169
|
+
for key in all_keys:
|
|
170
|
+
val = TM[key]
|
|
171
|
+
Type = val["type"].lower()
|
|
172
|
+
if Type == "d" or Type == "defalt":
|
|
173
|
+
val["value"] = pygame.mixer.Sound(self.lutil.fp(key))
|
|
174
|
+
TM[key] = val
|
|
175
|
+
elif Type == "r" or Type == "replace":
|
|
176
|
+
val["value"] = pygame.mixer.Sound(self.lutil.fp(val["value"]))
|
|
177
|
+
TM[key] = val
|
|
178
|
+
elif Type == "c" or Type == "catagory":
|
|
179
|
+
val = self._loade_sound_catagory(val)
|
|
180
|
+
else:
|
|
181
|
+
val["value"] = pygame.mixer.Sound(self.lutil.fp(key))
|
|
182
|
+
TM[key] = val
|
|
183
|
+
return TM
|
|
184
|
+
def load_sound_map(self,map_path):
|
|
185
|
+
map_path = self.lutil.fp(map_path)
|
|
186
|
+
with open(map_path,"r") as file:
|
|
187
|
+
sound_map = json.load(file)
|
|
188
|
+
self.sound_map = self.init_sound_map(sound_map)
|
|
189
|
+
|
|
190
|
+
def image(self,path):
|
|
191
|
+
try:
|
|
192
|
+
return self.texture_map[path]["value"]
|
|
193
|
+
except KeyError:
|
|
194
|
+
try:
|
|
195
|
+
return pygame.image.load(self.lutil.fp(path)).convert_alpha()
|
|
196
|
+
except Exception as e:
|
|
197
|
+
self._error("image",e,path)
|
|
198
|
+
return self.error_assets["img"]
|
|
199
|
+
def data(self,file_path):
|
|
200
|
+
try:
|
|
201
|
+
return self.file_map[file_path]["value"]
|
|
202
|
+
except KeyError:
|
|
203
|
+
try:
|
|
204
|
+
with open(self.lutil.fp(file_path),"r") as file:
|
|
205
|
+
return json.load(file)
|
|
206
|
+
except Exception as e:
|
|
207
|
+
self._error("data",e,file_path)
|
|
208
|
+
return -1
|
|
209
|
+
def sound(self,file_path):
|
|
210
|
+
try:
|
|
211
|
+
return self.sound_map[file_path]["value"]
|
|
212
|
+
except KeyError:
|
|
213
|
+
try:
|
|
214
|
+
return pygame.mixer.Sound(self.lutil.fp(file_path))
|
|
215
|
+
except Exception as e:
|
|
216
|
+
self._error("sound",e,file_path)
|
|
217
|
+
return self.error_assets["sound"]
|
|
218
|
+
|
|
219
|
+
def warp_image(self,image,sizex,sizey,angle):
|
|
220
|
+
image1 = pygame.transform.scale(image,(sizex,sizey))
|
|
221
|
+
image2 = pygame.transform.rotate(image1,angle)
|
|
222
|
+
return image2
|
|
223
|
+
def rotate_image(self,image,angle):
|
|
224
|
+
image2 = pygame.transform.rotate(image,angle)
|
|
225
|
+
return image2
|
|
226
|
+
def scale_image(self,image,sizex,sizey):
|
|
227
|
+
image1 = pygame.transform.scale(image,(sizex,sizey))
|
|
228
|
+
return image1
|
|
229
|
+
|
|
230
|
+
def play_sound(self,file_path, volume=0.5,loops=0):
|
|
231
|
+
try:
|
|
232
|
+
sound = self.sound(file_path)
|
|
233
|
+
sound.set_volume(volume)
|
|
234
|
+
sound.play(loops)
|
|
235
|
+
return 1
|
|
236
|
+
except Exception as e:
|
|
237
|
+
print(f" error >> {e} from loader >> {self.loader_name} ")
|
|
238
|
+
|
|
239
|
+
prin_RED = '\033[91m'
|
|
240
|
+
prin_GREEN = '\033[92m'
|
|
241
|
+
prin_BLUE = '\033[94m'
|
|
242
|
+
prin_RESET = '\033[0m'
|
|
243
|
+
util = Util()
|
|
244
|
+
loader = Loader(
|
|
245
|
+
"assets/loader/texture_maps/engine_textures.json",
|
|
246
|
+
"assets/loader/game_file_maps/engine_assets.json",
|
|
247
|
+
"assets/loader/sound_maps/engine_sounds.json",
|
|
248
|
+
loader_name="engine_loader"
|
|
249
|
+
)
|
|
250
|
+
class Delta_timer:
|
|
251
|
+
def __init__(self):
|
|
252
|
+
# Using perf_counter for highest precision
|
|
253
|
+
self.prev_time = time.perf_counter()
|
|
254
|
+
self.dt = 0.0
|
|
255
|
+
|
|
256
|
+
def get_dt(self):
|
|
257
|
+
now = time.perf_counter()
|
|
258
|
+
self.dt = now - self.prev_time
|
|
259
|
+
self.prev_time = now
|
|
260
|
+
return self.dt
|
|
261
|
+
|
|
262
|
+
class Sprite:
|
|
263
|
+
instanses = 0
|
|
264
|
+
ld = loader
|
|
265
|
+
def __init__(self,file_path,game_fps):
|
|
266
|
+
self.dt = Delta_timer()
|
|
267
|
+
Sprite.instanses += 1
|
|
268
|
+
self.bace_path = file_path # bace path would be something like assets/sprites/test1.sptite
|
|
269
|
+
self.data = Sprite.ld.data(f"{self.bace_path}/settings.json")
|
|
270
|
+
self.game_fps = game_fps
|
|
271
|
+
self.fps = self.data["fps"]
|
|
272
|
+
self.total_frames = self.data["total_frames"]
|
|
273
|
+
self.img_dt = self.data["img_dt"]
|
|
274
|
+
self._imgs = []
|
|
275
|
+
self.scaled_imgs = []
|
|
276
|
+
self.elapsed_time = 0.0
|
|
277
|
+
self._last_zoom = None
|
|
278
|
+
self.init_imgs(file_path)
|
|
279
|
+
|
|
280
|
+
def get_frame_index(self, dt):
|
|
281
|
+
self.elapsed_time += dt
|
|
282
|
+
raw_frame = int(self.elapsed_time * self.fps)
|
|
283
|
+
index = raw_frame % self.total_frames
|
|
284
|
+
return index
|
|
285
|
+
|
|
286
|
+
def get_surf(self,zoom,angle):
|
|
287
|
+
if self._last_zoom != zoom:
|
|
288
|
+
self.scale_all(zoom)
|
|
289
|
+
ind = self.get_frame_index(self.dt.get_dt())
|
|
290
|
+
surf = self.scaled_imgs[ind]
|
|
291
|
+
surf = pygame.transform.rotate(surf,angle)
|
|
292
|
+
|
|
293
|
+
def scale_all(self,zoom):
|
|
294
|
+
surf = pygame.surface.Surface((10,10))
|
|
295
|
+
surf.get_size()
|
|
296
|
+
self.scaled_imgs.clear()
|
|
297
|
+
for i in self._imgs:
|
|
298
|
+
surf = i
|
|
299
|
+
surf_size = i.get_size()
|
|
300
|
+
surf_size[0] *= zoom
|
|
301
|
+
surf_size[1] *= zoom
|
|
302
|
+
surf = pygame.transform.scale(surf,surf_size)
|
|
303
|
+
self.scaled_imgs.append(surf)
|
|
304
|
+
|
|
305
|
+
def init_imgs(self,FP):
|
|
306
|
+
self._imgs = Sprite.ld.image(FP)
|
|
307
|
+
|
|
308
|
+
def manual_init_imgs(self,FP):
|
|
309
|
+
for i in range(self.total_frames):
|
|
310
|
+
fp = f"img_{i}{self.img_dt}"
|
|
311
|
+
full_fp = f"{self.bace_path}/images/{fp}"
|
|
312
|
+
self._imgs.append(Sprite.ld.image(full_fp))
|
|
313
|
+
|
|
314
|
+
class r_obj:
|
|
315
|
+
instanses = 0
|
|
316
|
+
loader = loader
|
|
317
|
+
def __init__(self,x,y,sx,sy,angle,zoom,texture_fp=None,hitbox_rect=None,render_type="chunk",children=[]):
|
|
318
|
+
self.obj_bound_to = children
|
|
319
|
+
self.tags = {}
|
|
320
|
+
r_obj.instanses += 1
|
|
321
|
+
self.id = r_obj.instanses
|
|
322
|
+
self.x,self.y,self.sx,self.sy = x,y,sx,sy
|
|
323
|
+
self.og_x,self.og_y = self.x,self.y
|
|
324
|
+
self.angle = angle
|
|
325
|
+
self.last_zoom = None
|
|
326
|
+
self.last_angle = None
|
|
327
|
+
self.texture_path = texture_fp
|
|
328
|
+
self.render_type = render_type
|
|
329
|
+
|
|
330
|
+
self.init_bound_objs_realative_cords()
|
|
331
|
+
self.init_render_type(texture_fp)
|
|
332
|
+
self.OG_IMAGE = self.get_df_img(texture_fp)
|
|
333
|
+
self.surf = self.get_surf(zoom)
|
|
334
|
+
self.rect = self.surf.get_rect()
|
|
335
|
+
|
|
336
|
+
if hitbox_rect != None:
|
|
337
|
+
self.hitbox_rect = hitbox_rect
|
|
338
|
+
else:
|
|
339
|
+
self.hitbox_rect = pygame.Rect(x,y,sx,sy)
|
|
340
|
+
loger.log(f"r_obj instans {self.id} inisalized at position ({self.x},{self.y}) with size ({self.sx},{self.sy})")
|
|
341
|
+
|
|
342
|
+
def init_render_type(self,fp):
|
|
343
|
+
if fp != None:
|
|
344
|
+
file_extension = os.path.splitext(fp)[1]
|
|
345
|
+
if file_extension == "sprite":
|
|
346
|
+
self.render_method = self.sprite_render
|
|
347
|
+
return
|
|
348
|
+
self.render_method = self.render
|
|
349
|
+
return
|
|
350
|
+
else:
|
|
351
|
+
self.render_method = self.render
|
|
352
|
+
return
|
|
353
|
+
|
|
354
|
+
def get_df_img(self,fp):
|
|
355
|
+
if fp == None:
|
|
356
|
+
return loader.image("assets/images/error.png")
|
|
357
|
+
return self.image(fp)
|
|
358
|
+
|
|
359
|
+
def image(self,fp):
|
|
360
|
+
return r_obj.loader.image(fp)
|
|
361
|
+
def file(self,fp):
|
|
362
|
+
return r_obj.loader.data(fp)
|
|
363
|
+
|
|
364
|
+
def get_img(self,zoom):
|
|
365
|
+
return self.OG_IMAGE
|
|
366
|
+
def get_scaled_img(self,zoom,angle):
|
|
367
|
+
return self.scaled_surf
|
|
368
|
+
|
|
369
|
+
def should_scale(self,zoom):
|
|
370
|
+
if self.last_zoom != zoom:
|
|
371
|
+
self.last_zoom = zoom
|
|
372
|
+
return True
|
|
373
|
+
return False
|
|
374
|
+
|
|
375
|
+
def should_rotate(self,angle):
|
|
376
|
+
if angle != self.last_angle:
|
|
377
|
+
self.last_angle = angle
|
|
378
|
+
return True
|
|
379
|
+
return False
|
|
380
|
+
|
|
381
|
+
def sprite_render(self,zoom):
|
|
382
|
+
img = self.OG_IMAGE.get_surf(zoom,self.angle)
|
|
383
|
+
return img
|
|
384
|
+
|
|
385
|
+
def render(self,zoom):
|
|
386
|
+
if self.should_scale(zoom):
|
|
387
|
+
self.scaled_surf = pygame.transform.scale(self.OG_IMAGE,(self.sx * zoom , self.sy * zoom))
|
|
388
|
+
self.surf = pygame.transform.rotate(self.scaled_surf,self.angle)
|
|
389
|
+
elif self.should_rotate(self.angle):
|
|
390
|
+
self.surf = pygame.transform.rotate(self.scaled_surf,self.angle)
|
|
391
|
+
return self.surf
|
|
392
|
+
|
|
393
|
+
def init_bound_objs_realative_cords(self):
|
|
394
|
+
for obj in self.obj_bound_to:
|
|
395
|
+
dx = self.x - obj.x
|
|
396
|
+
dy = self.y - obj.y
|
|
397
|
+
obj.tags["rel_dx"] = dx
|
|
398
|
+
obj.tags["rel_dy"] = dy
|
|
399
|
+
#print(f"{dx}---{dy}\n")
|
|
400
|
+
def update_bound_objs(self):
|
|
401
|
+
for obj in self.obj_bound_to:
|
|
402
|
+
x = self.x + obj.tags.get("rel_dx",0)
|
|
403
|
+
y = self.y + obj.tags.get("rel_dy",0)
|
|
404
|
+
obj.set_pos(x,y)
|
|
405
|
+
#print(f"updated bound obj {obj.id} to ({obj.x},{obj.y}) from parent obj {self.id} at ({self.x},{self.y})")
|
|
406
|
+
|
|
407
|
+
def get_surf(self,zoom):
|
|
408
|
+
return self.render_method(zoom)
|
|
409
|
+
|
|
410
|
+
def set_pos(self,x,y):
|
|
411
|
+
self.x = x
|
|
412
|
+
self.y = y
|
|
413
|
+
self.hitbox_rect.topleft = (self.x,self.y)
|
|
414
|
+
self.update_bound_objs()
|
|
415
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"total_logs": 5,
|
|
3
|
+
"record_engine_logs": true,
|
|
4
|
+
"logs": [
|
|
5
|
+
{
|
|
6
|
+
"log_start_time": "2026-01-31 18:16:33",
|
|
7
|
+
"log_end_time": "2026-01-31 18:16:35",
|
|
8
|
+
"run_time_log": "[18:16:33] :-: Util instans 1 inisalized\n[18:16:33] :-: Util instans 2 inisalized\n[18:16:33] :-: Util instans 3 inisalized\n[18:16:34] :-: Loader instans 'engine_loader' inisalized with 1 loader_instanses\n[18:16:34] :-: Initialized layar manager\n[18:16:34] :-: Util instans 4 inisalized\n[18:16:34] :-: Display manager initialized\n[18:16:34] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:16:34] :-: r_obj instans 1 inisalized at position (300,250) with size (40,40)\n[18:16:34] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:16:34] :-: r_obj instans 2 inisalized at position (400,300) with size (40,40)\n[18:16:34] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:16:34] :-: r_obj instans 3 inisalized at position (240,150) with size (40,40)\n[18:16:34] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:16:34] :-: r_obj instans 4 inisalized at position (100,90) with size (40,40)\n[18:16:34] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:16:34] :-: r_obj instans 5 inisalized at position (200,200) with size (40,40)\n[18:16:34] :-: Initialized camera with pryoraty of 0 and 1 instances\n[18:16:34] :-: Initialized chunk at 0,0 with a total of 1 created\n[18:16:34] :-: Initialized chunk at 1,1 with a total of 2 created\n[18:16:34] :-: Initialized chunk at 0,1 with a total of 3 created\n[18:16:34] :-: Initialized chunk at 1,0 with a total of 4 created\n[18:16:34] :-: Initialized chunk at 2,0 with a total of 5 created\n[18:16:34] :-: Initialized chunk at 2,1 with a total of 6 created\n[18:16:34] :-: Initialized chunk at 3,0 with a total of 7 created\n[18:16:34] :-: Initialized chunk at 3,1 with a total of 8 created\n[18:16:35] :-: Rendering thread stopped\n[18:16:35] :-: Rendering thread stopped\n"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"log_start_time": "2026-01-31 18:17:02",
|
|
12
|
+
"log_end_time": "2026-01-31 18:17:08",
|
|
13
|
+
"run_time_log": "[18:17:02] :-: Util instans 1 inisalized\n[18:17:02] :-: Util instans 2 inisalized\n[18:17:02] :-: Util instans 3 inisalized\n[18:17:02] :-: Loader instans 'engine_loader' inisalized with 1 loader_instanses\n[18:17:02] :-: \u001b[91m!!-error loading image : asd.asd ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.asd'. -!!\u001b[0m\n[18:17:03] :-: Initialized layar manager\n[18:17:03] :-: Util instans 4 inisalized\n[18:17:03] :-: Display manager initialized\n[18:17:03] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:03] :-: r_obj instans 1 inisalized at position (300,250) with size (40,40)\n[18:17:03] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:03] :-: r_obj instans 2 inisalized at position (400,300) with size (40,40)\n[18:17:03] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:03] :-: r_obj instans 3 inisalized at position (240,150) with size (40,40)\n[18:17:03] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:03] :-: r_obj instans 4 inisalized at position (100,90) with size (40,40)\n[18:17:03] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:03] :-: r_obj instans 5 inisalized at position (200,200) with size (40,40)\n[18:17:03] :-: Initialized camera with pryoraty of 0 and 1 instances\n[18:17:03] :-: Initialized chunk at 0,0 with a total of 1 created\n[18:17:03] :-: Initialized chunk at 1,1 with a total of 2 created\n[18:17:03] :-: Initialized chunk at 0,1 with a total of 3 created\n[18:17:03] :-: Initialized chunk at 1,0 with a total of 4 created\n[18:17:03] :-: Initialized chunk at 2,0 with a total of 5 created\n[18:17:03] :-: Initialized chunk at 2,1 with a total of 6 created\n[18:17:03] :-: Initialized chunk at 3,0 with a total of 7 created\n[18:17:03] :-: Initialized chunk at 3,1 with a total of 8 created\n[18:17:06] :-: Initialized chunk at 1,-1 with a total of 9 created\n[18:17:08] :-: Initialized chunk at 2,-1 with a total of 10 created\n[18:17:08] :-: Rendering thread stopped\n"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"log_start_time": "2026-01-31 18:17:02",
|
|
17
|
+
"log_end_time": "2026-01-31 18:17:08",
|
|
18
|
+
"run_time_log": "[18:17:02] :-: Util instans 1 inisalized\n[18:17:02] :-: Util instans 2 inisalized\n[18:17:02] :-: Util instans 3 inisalized\n[18:17:02] :-: Loader instans 'engine_loader' inisalized with 1 loader_instanses\n[18:17:02] :-: \u001b[91m!!-error loading image : asd.asd ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.asd'. -!!\u001b[0m\n[18:17:03] :-: Initialized layar manager\n[18:17:03] :-: Util instans 4 inisalized\n[18:17:03] :-: Display manager initialized\n[18:17:03] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:03] :-: r_obj instans 1 inisalized at position (300,250) with size (40,40)\n[18:17:03] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:03] :-: r_obj instans 2 inisalized at position (400,300) with size (40,40)\n[18:17:03] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:03] :-: r_obj instans 3 inisalized at position (240,150) with size (40,40)\n[18:17:03] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:03] :-: r_obj instans 4 inisalized at position (100,90) with size (40,40)\n[18:17:03] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:03] :-: r_obj instans 5 inisalized at position (200,200) with size (40,40)\n[18:17:03] :-: Initialized camera with pryoraty of 0 and 1 instances\n[18:17:03] :-: Initialized chunk at 0,0 with a total of 1 created\n[18:17:03] :-: Initialized chunk at 1,1 with a total of 2 created\n[18:17:03] :-: Initialized chunk at 0,1 with a total of 3 created\n[18:17:03] :-: Initialized chunk at 1,0 with a total of 4 created\n[18:17:03] :-: Initialized chunk at 2,0 with a total of 5 created\n[18:17:03] :-: Initialized chunk at 2,1 with a total of 6 created\n[18:17:03] :-: Initialized chunk at 3,0 with a total of 7 created\n[18:17:03] :-: Initialized chunk at 3,1 with a total of 8 created\n[18:17:06] :-: Initialized chunk at 1,-1 with a total of 9 created\n[18:17:08] :-: Initialized chunk at 2,-1 with a total of 10 created\n[18:17:08] :-: Rendering thread stopped\n[18:17:08] :-: Rendering thread stopped\n"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"log_start_time": "2026-01-31 18:17:16",
|
|
22
|
+
"log_end_time": "2026-01-31 18:17:27",
|
|
23
|
+
"run_time_log": "[18:17:16] :-: Util instans 1 inisalized\n[18:17:16] :-: Util instans 2 inisalized\n[18:17:16] :-: Util instans 3 inisalized\n[18:17:16] :-: Loader instans 'engine_loader' inisalized with 1 loader_instanses\n[18:17:16] :-: \u001b[91m!!-error loading image : asd.asd ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.asd'. -!!\u001b[0m\n[18:17:16] :-: Initialized layar manager\n[18:17:16] :-: Util instans 4 inisalized\n[18:17:16] :-: Display manager initialized\n[18:17:16] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:16] :-: r_obj instans 1 inisalized at position (300,250) with size (40,40)\n[18:17:16] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:16] :-: r_obj instans 2 inisalized at position (400,300) with size (40,40)\n[18:17:16] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:16] :-: r_obj instans 3 inisalized at position (240,150) with size (40,40)\n[18:17:16] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:16] :-: r_obj instans 4 inisalized at position (100,90) with size (40,40)\n[18:17:16] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:16] :-: r_obj instans 5 inisalized at position (200,200) with size (40,40)\n[18:17:16] :-: Initialized camera with pryoraty of 0 and 1 instances\n[18:17:16] :-: Initialized chunk at 0,0 with a total of 1 created\n[18:17:16] :-: Initialized chunk at 1,1 with a total of 2 created\n[18:17:16] :-: Initialized chunk at 0,1 with a total of 3 created\n[18:17:16] :-: Initialized chunk at 1,0 with a total of 4 created\n[18:17:16] :-: Initialized chunk at 2,0 with a total of 5 created\n[18:17:16] :-: Initialized chunk at 2,1 with a total of 6 created\n[18:17:16] :-: Initialized chunk at 3,0 with a total of 7 created\n[18:17:16] :-: Initialized chunk at 3,1 with a total of 8 created\n[18:17:19] :-: Initialized chunk at 1,-1 with a total of 9 created\n[18:17:21] :-: Initialized chunk at 2,-1 with a total of 10 created\n[18:17:23] :-: Initialized chunk at 3,-1 with a total of 11 created\n[18:17:27] :-: Rendering thread stopped\n"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"log_start_time": "2026-01-31 18:17:16",
|
|
27
|
+
"log_end_time": "2026-01-31 18:17:27",
|
|
28
|
+
"run_time_log": "[18:17:16] :-: Util instans 1 inisalized\n[18:17:16] :-: Util instans 2 inisalized\n[18:17:16] :-: Util instans 3 inisalized\n[18:17:16] :-: Loader instans 'engine_loader' inisalized with 1 loader_instanses\n[18:17:16] :-: \u001b[91m!!-error loading image : asd.asd ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.asd'. -!!\u001b[0m\n[18:17:16] :-: Initialized layar manager\n[18:17:16] :-: Util instans 4 inisalized\n[18:17:16] :-: Display manager initialized\n[18:17:16] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:16] :-: r_obj instans 1 inisalized at position (300,250) with size (40,40)\n[18:17:16] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:16] :-: r_obj instans 2 inisalized at position (400,300) with size (40,40)\n[18:17:16] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:16] :-: r_obj instans 3 inisalized at position (240,150) with size (40,40)\n[18:17:16] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:16] :-: r_obj instans 4 inisalized at position (100,90) with size (40,40)\n[18:17:16] :-: \u001b[91m!!-error loading image : asd.jeff ->> in loader engine_loader with error >> No such file or directory: 'C:\\Users\\matth\\source\\repos\\ex2\\ex2\\skyport\\asd.jeff'. -!!\u001b[0m\n[18:17:16] :-: r_obj instans 5 inisalized at position (200,200) with size (40,40)\n[18:17:16] :-: Initialized camera with pryoraty of 0 and 1 instances\n[18:17:16] :-: Initialized chunk at 0,0 with a total of 1 created\n[18:17:16] :-: Initialized chunk at 1,1 with a total of 2 created\n[18:17:16] :-: Initialized chunk at 0,1 with a total of 3 created\n[18:17:16] :-: Initialized chunk at 1,0 with a total of 4 created\n[18:17:16] :-: Initialized chunk at 2,0 with a total of 5 created\n[18:17:16] :-: Initialized chunk at 2,1 with a total of 6 created\n[18:17:16] :-: Initialized chunk at 3,0 with a total of 7 created\n[18:17:16] :-: Initialized chunk at 3,1 with a total of 8 created\n[18:17:19] :-: Initialized chunk at 1,-1 with a total of 9 created\n[18:17:21] :-: Initialized chunk at 2,-1 with a total of 10 created\n[18:17:23] :-: Initialized chunk at 3,-1 with a total of 11 created\n[18:17:27] :-: Rendering thread stopped\n[18:17:27] :-: Rendering thread stopped\n"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
skyport/rendering_eng.py
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
import pygame
|
|
5
|
+
import threading
|
|
6
|
+
#from pygame._sdl2.video import Window, Renderer, Texture
|
|
7
|
+
from skyport.core.paths import PathUtil as pu
|
|
8
|
+
from skyport.core.paths import loger
|
|
9
|
+
|
|
10
|
+
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
11
|
+
if BASE_DIR not in sys.path:
|
|
12
|
+
sys.path.insert(0, BASE_DIR)
|
|
13
|
+
|
|
14
|
+
pygame.init()
|
|
15
|
+
pygame.display.init()
|
|
16
|
+
pygame.display.set_mode((1, 1), pygame.HIDDEN)
|
|
17
|
+
|
|
18
|
+
# engine imports
|
|
19
|
+
from assets.layar_manager import *
|
|
20
|
+
from global_utils import *
|
|
21
|
+
|
|
22
|
+
class Display_manager:
|
|
23
|
+
def __init__(self,window_size,display_size,force_full_screen=True,window_name="spyport engine window",window_ico=None,resizable=True):
|
|
24
|
+
self.loops = 0
|
|
25
|
+
self.print_rate = 8
|
|
26
|
+
#self.win = Window("skyport engine window--", size=window_size)
|
|
27
|
+
self.running = True
|
|
28
|
+
self.window_ico = window_ico
|
|
29
|
+
self.clock = pygame.time.Clock()
|
|
30
|
+
self._stop_event = threading.Event()
|
|
31
|
+
self.rendering_thread = None
|
|
32
|
+
self.force_full_screen = force_full_screen
|
|
33
|
+
self.window_size = window_size
|
|
34
|
+
self.display_size = display_size
|
|
35
|
+
self.display = pygame.Surface(self.display_size)
|
|
36
|
+
pygame.display.set_icon(self.window_ico) if self.window_ico else None
|
|
37
|
+
self.window = pygame.display.set_mode(window_size,pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.RESIZABLE)
|
|
38
|
+
pygame.display.set_caption(window_name)
|
|
39
|
+
lm = Layar_manager(self.display)
|
|
40
|
+
self.dt = Delta_timer()
|
|
41
|
+
self.util = Util()
|
|
42
|
+
self.print_que = ""
|
|
43
|
+
self.curent_game_state = "main"
|
|
44
|
+
self.game_states = {"main":lm}
|
|
45
|
+
|
|
46
|
+
if not pygame.display.is_fullscreen() and force_full_screen:
|
|
47
|
+
pygame.display.toggle_fullscreen()
|
|
48
|
+
|
|
49
|
+
self.couculate_window_scaling()
|
|
50
|
+
loger.log("Display manager initialized")
|
|
51
|
+
|
|
52
|
+
def get_lm(self):
|
|
53
|
+
return self.game_states[self.curent_game_state]
|
|
54
|
+
def add_game_stare(self,name,lm):
|
|
55
|
+
self.game_states[name] = lm
|
|
56
|
+
loger.log(f"added game state {name}")
|
|
57
|
+
def remove_game_stare(self,name):
|
|
58
|
+
if name in self.game_states:
|
|
59
|
+
del self.game_states[name]
|
|
60
|
+
loger.log(f"removed game state {name}")
|
|
61
|
+
else:
|
|
62
|
+
loger.log(f"tried to remove game state {name} but it does not exist")
|
|
63
|
+
|
|
64
|
+
def cclock(self,TFPS):
|
|
65
|
+
#self._event()
|
|
66
|
+
self.loops += 1
|
|
67
|
+
self.s_display = pygame.transform.scale(self.display, self.new_size)
|
|
68
|
+
self.window.blit(self.s_display,self.W_pos)
|
|
69
|
+
Util.print(f"loops are at {self.loops} and fps is at {self.clock.get_fps():.2f}")
|
|
70
|
+
pygame.display.flip()
|
|
71
|
+
self.clock.tick(TFPS)
|
|
72
|
+
|
|
73
|
+
def couculate_window_scaling(self):
|
|
74
|
+
self.display_rect = self.display.get_rect(center=(self.window.get_width() // 2, self.window.get_height() // 2))
|
|
75
|
+
self.window_width = self.window.get_width()
|
|
76
|
+
self.window_height = self.window.get_height()
|
|
77
|
+
self._scale = min(self.window_width / self.display.get_width(), self.window_height / self.display.get_height())
|
|
78
|
+
self.new_size = (int(self.display.get_width() * self._scale), int(self.display.get_height() * self._scale))
|
|
79
|
+
self.W_pos = ((self.window_width - self.new_size[0]) // 2, (self.window_height - self.new_size[1]) // 2)
|
|
80
|
+
|
|
81
|
+
self.center_x = self.display.get_width() / 2
|
|
82
|
+
self.center_y = self.display.get_height() / 2
|
|
83
|
+
|
|
84
|
+
def get_mouse_pos(self):
|
|
85
|
+
mx, my = pygame.mouse.get_pos()
|
|
86
|
+
self,mouse_pos = (((mx - self.W_pos[0]) / self._scale),((my - self.W_pos[1]) / self._scale))
|
|
87
|
+
|
|
88
|
+
def render(self):
|
|
89
|
+
self.display.blit(self.game_states[self.curent_game_state].render(),(0,0))
|
|
90
|
+
|
|
91
|
+
def _rendering_loop(self):
|
|
92
|
+
try:
|
|
93
|
+
while not self._stop_event.is_set():
|
|
94
|
+
self.render()
|
|
95
|
+
self.cclock(self.fps)
|
|
96
|
+
self.dt.get_dt()
|
|
97
|
+
except Exception as e:
|
|
98
|
+
print(f"exiting render loop do to {e}")
|
|
99
|
+
loger.log(f"exiting render loop do to {e}")
|
|
100
|
+
|
|
101
|
+
def START_RENDERING_THREAD(self, fps):
|
|
102
|
+
self.fps = fps
|
|
103
|
+
self._stop_event.clear()
|
|
104
|
+
self.rendering_thread = threading.Thread(target=self._rendering_loop, daemon=True)
|
|
105
|
+
self.rendering_thread.start()
|
|
106
|
+
|
|
107
|
+
def STOP_RENDERING_THREAD(self):
|
|
108
|
+
if self.rendering_thread and self.rendering_thread.is_alive():
|
|
109
|
+
self._stop_event.set()
|
|
110
|
+
self.rendering_thread.join()
|
|
111
|
+
loger.log("Rendering thread stopped")
|
|
112
|
+
loger.save()
|
|
113
|
+
def event(self):
|
|
114
|
+
if self.loops % self.print_rate == 0:
|
|
115
|
+
Util.output_print_data()
|
|
116
|
+
try:
|
|
117
|
+
events = pygame.event.get()
|
|
118
|
+
for event in events:
|
|
119
|
+
if event.type == pygame.QUIT:
|
|
120
|
+
self.running = False
|
|
121
|
+
print("\nquit pressed\n")
|
|
122
|
+
self.STOP_RENDERING_THREAD()
|
|
123
|
+
pygame.quit()
|
|
124
|
+
if event.type == pygame.VIDEORESIZE:
|
|
125
|
+
self.couculate_window_scaling()
|
|
126
|
+
except Exception as e:
|
|
127
|
+
loger.log(f"error in event handeling: {e}")
|
|
128
|
+
|
|
129
|
+
|
skyport/skyport.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
skyport/__init__.py,sha256=ViK91Cd6Ze_qsbOpY8GLiNQ7QSKr1ki-MQcYYoAF8ds,4148
|
|
2
|
+
skyport/engine_setup.py,sha256=5sdnqqu2eO1NP7T1yRk8Vav5c59kEJVwXpTxmPCAEPk,8
|
|
3
|
+
skyport/gf_map_cunstructor.py,sha256=K6FSGKH8_EotVzR_LBRkedsCjipdu-ZuEitg0SRv_fA,1556
|
|
4
|
+
skyport/global_utils.py,sha256=kxY1kWyrfsdDrkfpzHkaSogb4MFnv77qreM0-RdSsdA,15228
|
|
5
|
+
skyport/rendering_eng.py,sha256=XPWkHdW_p04SlMLuRoGTzmfL6loLn34tLtOFy93R9GQ,5160
|
|
6
|
+
skyport/skyport.py,sha256=tJ00Pkjpjd-_eeM7oSQMn5XIBjr1jrKceaRYJQSqUUY,71
|
|
7
|
+
skyport/assets/layar_manager.py,sha256=q1GSm-1-icUny-OkJ4MzJKUKY5WVSfwMkA9xmce6Qjo,9731
|
|
8
|
+
skyport/assets/images/None.png,sha256=0urW0ZB_4ddxrYffE0wuF7ShPyaZSJod7AT-WPqiXlI,3671
|
|
9
|
+
skyport/assets/images/error.png,sha256=Z6b61fSltSN94nyiQ2rGDxHFl7_RQxTXkeT4x-SOO80,196
|
|
10
|
+
skyport/assets/images/pt-17.png,sha256=h59z8YBrmWWlP5ZG-sxyBVRF_42rlpGEji1CSr-vxJc,1547257
|
|
11
|
+
skyport/assets/images/buttons/how_to_play.png,sha256=tedo3MEr3L_Zf6frwZnyXZkFa0cKXaR3MVGzFvb61RI,45907
|
|
12
|
+
skyport/assets/images/buttons/menue.png,sha256=FZjDQtn1xzhXGfRvnw4dr6MQINp8mYbfFo4DB1H7YCE,41692
|
|
13
|
+
skyport/assets/images/buttons/play.png,sha256=usmnjEYXLvsAUtFn8BKJjGxM5I9xyHtaPTjqR0eBeB8,97590
|
|
14
|
+
skyport/assets/images/buttons/quit.png,sha256=XCgR5Z1ZFfbXa8DJyw9MoyglqcvQmYbEcqGS9DHGxho,40163
|
|
15
|
+
skyport/assets/loader/game_file_maps/engine_assets.json,sha256=M_n1Xe-csV3Z9xUpRzFW8psWPaJfUuw4WDnvyA7zQYw,201
|
|
16
|
+
skyport/assets/loader/sound_maps/engine_sounds.json,sha256=RypKTcPanKpADaXsL41dPrUb4JDmLymDHRVCRrkc01Q,80
|
|
17
|
+
skyport/assets/loader/texture_maps/engine_textures.json,sha256=uL3OLAC7iz4wcl4g25hQdYbSswlxkezbgjXwSlZZs2U,563
|
|
18
|
+
skyport/assets/sounds/error.mp3,sha256=GiRq15Y1p8HzXhesV-kEPQoRuuYDUx0utv6iixa37hU,33980
|
|
19
|
+
skyport/assets/sprites/test1.sprite/settings.json,sha256=_JjJGeinwE9aFgVl-WV2LllgeWk24sxaNaF7WqwbXz0,61
|
|
20
|
+
skyport/core/paths.py,sha256=2i7LtLnTAKJJdga5KqwdjPd8qGZyDZicdFLckzBrXIM,2064
|
|
21
|
+
skyport/logs/engine_logs.json,sha256=SKyaVjO9d1bJIx3XqRM7gPQDG81hQcXk19Ugrpeh_o4,14645
|
|
22
|
+
skyport_engine-0.1.5.dist-info/METADATA,sha256=ysiX7d3v4q63UL1MROQL8jkpkhioC9xltKa4L94DZC0,147
|
|
23
|
+
skyport_engine-0.1.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
24
|
+
skyport_engine-0.1.5.dist-info/top_level.txt,sha256=g8xjslL_dIkWs5dI5eCtG2YX3GC3qNzUhc5XKGWXJ0g,8
|
|
25
|
+
skyport_engine-0.1.5.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
skyport
|