jeski 0.5.0__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.
- jeski/__init__.py +245 -0
- jeski/__main__.py +21 -0
- jeski/animations.py +32 -0
- jeski/commands.py +43 -0
- jeski/config.py +197 -0
- jeski/credits.py +3 -0
- jeski/deps.py +39 -0
- jeski/entities/__init__.py +3 -0
- jeski/entities/_shapes.py +202 -0
- jeski/entities/base.py +182 -0
- jeski/entities/entity.py +550 -0
- jeski/entities/shapes.py +370 -0
- jeski/entities/ui.py +114 -0
- jeski/grid.py +6 -0
- jeski/imageTools.py +31 -0
- jeski/math.py +34 -0
- jeski/mesh.py +108 -0
- jeski/scripts.py +35 -0
- jeski/sounds.py +88 -0
- jeski/tests.py +62 -0
- jeski/utils.py +364 -0
- jeski-0.5.0.dist-info/METADATA +262 -0
- jeski-0.5.0.dist-info/RECORD +25 -0
- jeski-0.5.0.dist-info/WHEEL +5 -0
- jeski-0.5.0.dist-info/top_level.txt +1 -0
jeski/__init__.py
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
from .deps import *
|
|
2
|
+
from .utils import *
|
|
3
|
+
from .entities import *
|
|
4
|
+
from .scripts import *
|
|
5
|
+
from .commands import *
|
|
6
|
+
from .config import *
|
|
7
|
+
from .tests import *
|
|
8
|
+
from .credits import *
|
|
9
|
+
from .sounds import *
|
|
10
|
+
from .mesh import *
|
|
11
|
+
from .math import *
|
|
12
|
+
|
|
13
|
+
# print(__file__)
|
|
14
|
+
if __name__ != '__main__':
|
|
15
|
+
CORE.RUNNING = False
|
|
16
|
+
CORE.CALLER_GLOBALS = inspect.stack()[1].frame.f_globals
|
|
17
|
+
else:
|
|
18
|
+
CORE.CALLER_GLOBALS = globals()
|
|
19
|
+
|
|
20
|
+
class temp:
|
|
21
|
+
for x in string.ascii_lowercase:
|
|
22
|
+
globals()[x] = None
|
|
23
|
+
|
|
24
|
+
t = temp
|
|
25
|
+
|
|
26
|
+
def startConfigSync(data_dict):
|
|
27
|
+
data_dict = getG(data_dict)
|
|
28
|
+
def main():
|
|
29
|
+
while True:
|
|
30
|
+
for key in data_dict.keys():
|
|
31
|
+
try:
|
|
32
|
+
data_dict[key] = getG(key)
|
|
33
|
+
except Exception as e:
|
|
34
|
+
sPrint(f'SYNC ERROR: {e}', preset=2)
|
|
35
|
+
|
|
36
|
+
SMOOTH()
|
|
37
|
+
|
|
38
|
+
Script(main)
|
|
39
|
+
|
|
40
|
+
def INITIALIZE(**kwargs):
|
|
41
|
+
CORE.CALLER_GLOBALS = inspect.stack()[1].frame.f_globals
|
|
42
|
+
atexit.register(lambda: CONFIG.atExit())
|
|
43
|
+
try:
|
|
44
|
+
tmp = getGlobal('__APPNAME__')
|
|
45
|
+
except NameError:
|
|
46
|
+
CORE.CALLER_GLOBALS['__APPNAME__'] = 'PygameNewGame'
|
|
47
|
+
|
|
48
|
+
if not kwargs.get('stayInActiveDirectory', False): os.chdir(os.path.dirname(os.path.abspath(getGlobal('__file__'))))
|
|
49
|
+
|
|
50
|
+
CORE.WIN = WINDOW()
|
|
51
|
+
CONFIG.centerX, CONFIG.centerY = CORE.WIN.w // 2, CORE.WIN.h // 2
|
|
52
|
+
pygame.mixer.pre_init(
|
|
53
|
+
CONFIG.sounds.frequency,
|
|
54
|
+
CONFIG.sounds.size,
|
|
55
|
+
CONFIG.sounds.channels,
|
|
56
|
+
CONFIG.sounds.buffer
|
|
57
|
+
)
|
|
58
|
+
pygame.init()
|
|
59
|
+
pygame.mixer.set_num_channels(CONFIG.sounds.maxChannels)
|
|
60
|
+
pygame.font.init()
|
|
61
|
+
pygame.mixer.init()
|
|
62
|
+
CORE.RUNNING = True
|
|
63
|
+
|
|
64
|
+
CORE.ENTITIES = []
|
|
65
|
+
CORE.SCRIPTS = {}
|
|
66
|
+
CORE.STAMPS = []
|
|
67
|
+
|
|
68
|
+
CORE.SCREEN = pygame.display.set_mode(CORE.WIN.size)
|
|
69
|
+
if CONFIG.WINDOWLOGO:
|
|
70
|
+
setattr(CONFIG, 'ICON', pygame.image.load(CONFIG.WINDOWLOGO))
|
|
71
|
+
pygame.display.set_icon(CONFIG.ICON)
|
|
72
|
+
CORE.CLOCK = pygame.time.Clock()
|
|
73
|
+
CORE.BROADCASTS = {'clonesCreated' : False}
|
|
74
|
+
|
|
75
|
+
CORE.GRID = {}
|
|
76
|
+
|
|
77
|
+
class tmpCl: pass
|
|
78
|
+
tmpCl.x = 20
|
|
79
|
+
tmpCl.y = 10
|
|
80
|
+
tmpCl.sx = CORE.WIN.w // tmpCl.x
|
|
81
|
+
tmpCl.sy = CORE.WIN.h // tmpCl.y
|
|
82
|
+
|
|
83
|
+
CONFIG.GRIDSIZE = tmpCl
|
|
84
|
+
#print(tmpCl.__dict__)
|
|
85
|
+
CORE.GRIDBOXES = ['']
|
|
86
|
+
|
|
87
|
+
if os.path.exists('dot.png'): os.remove('dot.png')
|
|
88
|
+
tmpsurf = pygame.Surface((20,20), pygame.SRCALPHA)
|
|
89
|
+
pygame.draw.circle(tmpsurf, (0,0,0), (10,10), 10)
|
|
90
|
+
pygame.image.save(tmpsurf, 'dot.png')
|
|
91
|
+
|
|
92
|
+
dotCostumeImage = Image('dot.png', trueEntity=False)
|
|
93
|
+
CONFIG.dotCostume = Costume('__dotCostume__', object=dotCostumeImage)
|
|
94
|
+
|
|
95
|
+
CORE.CALLER_GLOBALS['CORE'] = CORE
|
|
96
|
+
os.makedirs(fr'.\assets\{getGlobal("__APPNAME__")}', exist_ok=True)
|
|
97
|
+
|
|
98
|
+
globals()['TESTS'] = TESTS_()
|
|
99
|
+
#setupGrid()
|
|
100
|
+
|
|
101
|
+
def CoreScript():
|
|
102
|
+
while CORE.RUNNING:
|
|
103
|
+
#UPDATE() # pygame issues, can't run this in thread :(
|
|
104
|
+
SMOOTH()
|
|
105
|
+
|
|
106
|
+
#if not kwargs.get('lazy', False): Script(CoreScript)
|
|
107
|
+
StartWorldTime()
|
|
108
|
+
INITIALISE = INITIALIZE
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def ScrollWindowX(n):
|
|
112
|
+
if not CONFIG.scroll.enabled:
|
|
113
|
+
print("Scroll Not Enabled!")
|
|
114
|
+
return
|
|
115
|
+
CONFIG.scroll.x += n
|
|
116
|
+
|
|
117
|
+
def ScrollWindowY(n):
|
|
118
|
+
if not CONFIG.scroll.enabled:
|
|
119
|
+
print("Scroll Not Enabled!")
|
|
120
|
+
return
|
|
121
|
+
CONFIG.scroll.y += n
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def SHUTDOWN():
|
|
125
|
+
CORE.RUNNING = False
|
|
126
|
+
|
|
127
|
+
def HANGON():
|
|
128
|
+
while CORE.RUNNING:
|
|
129
|
+
wait(60)
|
|
130
|
+
SMOOTH()
|
|
131
|
+
|
|
132
|
+
def setupGrid():
|
|
133
|
+
gSize = CONFIG.GRIDSIZE
|
|
134
|
+
gridEntity = Entity(x=0, y=0, sizeX=gSize.sx, sizeY=gSize.sy)
|
|
135
|
+
gridEntity.transparency = 255
|
|
136
|
+
for _ in range(gSize.y):
|
|
137
|
+
for _ in range(gSize.x):
|
|
138
|
+
et = gridEntity.createClone(ret=True)
|
|
139
|
+
et.type = 'grid'
|
|
140
|
+
CORE.GRIDBOXES.append(et)
|
|
141
|
+
gridEntity.x += gSize.sx
|
|
142
|
+
gridEntity.x -= CORE.WIN.w
|
|
143
|
+
gridEntity.y += gSize.sy
|
|
144
|
+
|
|
145
|
+
def toggle_mask():
|
|
146
|
+
CONFIG.showMask = not CONFIG.showMask
|
|
147
|
+
GUI.k.add_hotkey('t', lambda: toggle_mask() if CONFIG.debug else None)
|
|
148
|
+
|
|
149
|
+
def updateTerminal():
|
|
150
|
+
while True:
|
|
151
|
+
print(len(CORE.ENTITIES), end='')
|
|
152
|
+
print('\r', end='')
|
|
153
|
+
|
|
154
|
+
def DRAWSCREEN():
|
|
155
|
+
try:
|
|
156
|
+
CORE.STAMPS = [e for e in CORE.STAMPS if not e.var.get('erasePerFrame', False)]
|
|
157
|
+
CORE.ENTITIES = [e for e in CORE.ENTITIES if not e.deleted]
|
|
158
|
+
CORE.STAMPS = [e for e in CORE.STAMPS if not e.deleted]
|
|
159
|
+
|
|
160
|
+
# as an experiment, it is modified such that the BASICDRAW manages hidden
|
|
161
|
+
for stamp in CORE.STAMPS:
|
|
162
|
+
#if not stamp.hidden:
|
|
163
|
+
stamp.draw(CORE.SCREEN)
|
|
164
|
+
|
|
165
|
+
for entity in CORE.ENTITIES:
|
|
166
|
+
#if not entity.hidden:
|
|
167
|
+
entity.draw(CORE.SCREEN)
|
|
168
|
+
|
|
169
|
+
pygame.display.update()
|
|
170
|
+
except Exception as e:
|
|
171
|
+
print("\n\nSCREENDRAWERROR: ", e)
|
|
172
|
+
if repr(e).lower() == 'display surface quit':
|
|
173
|
+
SHUTDOWN()
|
|
174
|
+
|
|
175
|
+
def UPDATEVARS():
|
|
176
|
+
CONFIG.mouse.x, CONFIG.mouse.y = pygame.mouse.get_pos()
|
|
177
|
+
CORE.KEYS = pygame.key.get_pressed()
|
|
178
|
+
|
|
179
|
+
CONFIG.mouse.clicked = False
|
|
180
|
+
CORE.EVENTS = pygame.event.get()
|
|
181
|
+
|
|
182
|
+
def click():
|
|
183
|
+
CONFIG.mouse.clicked = True
|
|
184
|
+
wait(0.1)
|
|
185
|
+
CONFIG.mouse.clicked = False
|
|
186
|
+
|
|
187
|
+
for event in CORE.EVENTS:
|
|
188
|
+
if event.type == pygame.QUIT:
|
|
189
|
+
CORE.RUNNING = False
|
|
190
|
+
SOUNDPLAYER.stopAll()
|
|
191
|
+
pygame.mixer.quit()
|
|
192
|
+
pygame.quit()
|
|
193
|
+
return
|
|
194
|
+
#sys.exit()
|
|
195
|
+
|
|
196
|
+
if event.type == pygame.KEYDOWN:
|
|
197
|
+
if event.key == pygame.K_q:
|
|
198
|
+
CORE.ENTITIES = [e for e in CORE.ENTITIES if e.type != "Stamp"]
|
|
199
|
+
elif event.key == pygame.K_m:
|
|
200
|
+
toggle_mask()
|
|
201
|
+
|
|
202
|
+
if event.type == pygame.MOUSEBUTTONDOWN:
|
|
203
|
+
#CONFIG.mouse.down = True
|
|
204
|
+
Script(click)
|
|
205
|
+
CONFIG.mouse.clicked = True
|
|
206
|
+
|
|
207
|
+
# if not event.type == pygame.MOUSEBUTTONDOWN:
|
|
208
|
+
# CONFIG.mouse.clicked = False
|
|
209
|
+
|
|
210
|
+
if event.type == pygame.MOUSEBUTTONUP:
|
|
211
|
+
CONFIG.mouse.down = False
|
|
212
|
+
|
|
213
|
+
def UPDATE():
|
|
214
|
+
try:
|
|
215
|
+
pygame.display.set_caption(CONFIG.WINDOWTITLE)
|
|
216
|
+
CORE.SCREEN.fill(CONFIG.backgroundColor)
|
|
217
|
+
|
|
218
|
+
#if not hasattr(CONFIG, 'GlobalClockTick'): CONFIG.GlobalClockTick = 0
|
|
219
|
+
|
|
220
|
+
#if CONFIG.GlobalClockTick % 3 == 0:
|
|
221
|
+
UPDATEVARS()
|
|
222
|
+
SOUNDPLAYER.update()
|
|
223
|
+
|
|
224
|
+
DRAWSCREEN()
|
|
225
|
+
CORE.CLOCK.tick(CONFIG.FPS)
|
|
226
|
+
#CONFIG.GlobalClockTick += 1
|
|
227
|
+
|
|
228
|
+
#except ValueError:
|
|
229
|
+
except Exception as e:
|
|
230
|
+
sPrint(f'RUNTIME ERROR: {e}', preset=2)
|
|
231
|
+
QUIT()
|
|
232
|
+
CORE.RUNNING = False
|
|
233
|
+
pygame.quit()
|
|
234
|
+
sys.exit()
|
|
235
|
+
|
|
236
|
+
def QUIT():
|
|
237
|
+
try:
|
|
238
|
+
pygame.event.post(pygame.event.Event(pygame.QUIT))
|
|
239
|
+
except:
|
|
240
|
+
pass
|
|
241
|
+
|
|
242
|
+
# DEBUG CONSOLE THREAD
|
|
243
|
+
# threading.Thread(target=updateTerminal, daemon=True).start()
|
|
244
|
+
|
|
245
|
+
print("Greetings from XQX Engine, by Enirb!")
|
jeski/__main__.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from . import *
|
|
2
|
+
|
|
3
|
+
def GAMEPLAY():
|
|
4
|
+
while CORE.RUNNING:
|
|
5
|
+
UPDATE()
|
|
6
|
+
|
|
7
|
+
PLAYER1.move(20*(G.k.is_pressed('w') - G.k.is_pressed('s')))
|
|
8
|
+
PLAYER1.turn(5*(G.k.is_pressed('d') - G.k.is_pressed('a')))
|
|
9
|
+
|
|
10
|
+
PLAYER2.move(20*(G.k.is_pressed('up') - G.k.is_pressed('down')))
|
|
11
|
+
PLAYER2.turn(5*(G.k.is_pressed('right') - G.k.is_pressed('left')))
|
|
12
|
+
|
|
13
|
+
SMOOTH()
|
|
14
|
+
|
|
15
|
+
INITIALIZE()
|
|
16
|
+
|
|
17
|
+
PLAYER1 = Entity(name='Player1', x=CONFIG.centerX-100, image=Paths.image1)
|
|
18
|
+
PLAYER2 = Entity(name='Player2', x=CONFIG.centerX+100, image=Paths.image2)
|
|
19
|
+
|
|
20
|
+
GAMEPLAY()
|
|
21
|
+
|
jeski/animations.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from .deps import *
|
|
2
|
+
from .config import *
|
|
3
|
+
from .scripts import *
|
|
4
|
+
from .utils import *
|
|
5
|
+
|
|
6
|
+
def startAnimation(object, costs=[], fps=10, type='simple'):
|
|
7
|
+
if len(costs) == 0: return
|
|
8
|
+
|
|
9
|
+
def main(obj, costs, fps):
|
|
10
|
+
n = 0
|
|
11
|
+
while CORE.RUNNING:
|
|
12
|
+
SMOOTH()
|
|
13
|
+
wait(1/fps)
|
|
14
|
+
n += 1
|
|
15
|
+
if n == len(costs): n = 0
|
|
16
|
+
|
|
17
|
+
obj.changeCostume(costs[n])
|
|
18
|
+
|
|
19
|
+
Script(lambda: main(object, costs, fps))
|
|
20
|
+
|
|
21
|
+
def blink(obj, fast=False):
|
|
22
|
+
t = obj.brightness
|
|
23
|
+
|
|
24
|
+
for i in range(0, 100, 10 if not fast else 20):
|
|
25
|
+
obj.brightness = i
|
|
26
|
+
SMOOTH()
|
|
27
|
+
|
|
28
|
+
for j in range(100, 0, -10 if not fast else -20):
|
|
29
|
+
obj.brightness = j
|
|
30
|
+
SMOOTH()
|
|
31
|
+
|
|
32
|
+
obj.brightness = t
|
jeski/commands.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from .deps import *
|
|
2
|
+
|
|
3
|
+
def RunCommand(com, noWindow=True, getOutput=True, cwd=None):
|
|
4
|
+
cwd = cwd or os.getcwd()
|
|
5
|
+
args = shlex.split(com)
|
|
6
|
+
|
|
7
|
+
flags = sb.CREATE_NO_WINDOW if noWindow else 0
|
|
8
|
+
|
|
9
|
+
result = sb.run(
|
|
10
|
+
args,
|
|
11
|
+
capture_output=getOutput,
|
|
12
|
+
text=True,
|
|
13
|
+
creationflags=flags,
|
|
14
|
+
cwd=cwd
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
if getOutput:
|
|
18
|
+
return result.stdout.strip()
|
|
19
|
+
|
|
20
|
+
def GetResource(relPath):
|
|
21
|
+
return os.path.join(
|
|
22
|
+
getattr(
|
|
23
|
+
sys,
|
|
24
|
+
'_MEIPASS',
|
|
25
|
+
os.path.dirname(os.path.abspath(__file__))
|
|
26
|
+
),
|
|
27
|
+
relPath
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def RunAsAdmin():
|
|
31
|
+
if ctypes.windll.shell32.IsUserAnAdmin():
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
params = " ".join([f'"{arg}"' for arg in sys.argv])
|
|
35
|
+
ctypes.windll.shell32.ShellExecuteW(
|
|
36
|
+
None,
|
|
37
|
+
"runas",
|
|
38
|
+
sys.executable,
|
|
39
|
+
params,
|
|
40
|
+
None,
|
|
41
|
+
1
|
|
42
|
+
)
|
|
43
|
+
sys.exit()
|
jeski/config.py
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
from .deps import *
|
|
2
|
+
|
|
3
|
+
class GUI:
|
|
4
|
+
k = keyboard
|
|
5
|
+
m = mouse
|
|
6
|
+
g = pyautogui
|
|
7
|
+
|
|
8
|
+
G = GUI
|
|
9
|
+
|
|
10
|
+
class CORE:
|
|
11
|
+
ENTITIES = []
|
|
12
|
+
SCRIPTS = {}
|
|
13
|
+
SCREEN = None
|
|
14
|
+
CLOCK = None
|
|
15
|
+
KEYS = None
|
|
16
|
+
EVENTS = None
|
|
17
|
+
BROADCASTS = {}
|
|
18
|
+
RUNNING = False
|
|
19
|
+
STAMPS = []
|
|
20
|
+
CALLER_GLOBALS = {}
|
|
21
|
+
WIN = None
|
|
22
|
+
|
|
23
|
+
class WINDOW:
|
|
24
|
+
WIDTH = 1200
|
|
25
|
+
HEIGHT = 600
|
|
26
|
+
|
|
27
|
+
@classmethod
|
|
28
|
+
@property
|
|
29
|
+
def w(cls):
|
|
30
|
+
return cls.WIDTH
|
|
31
|
+
|
|
32
|
+
@classmethod
|
|
33
|
+
@property
|
|
34
|
+
def h(cls):
|
|
35
|
+
return cls.HEIGHT
|
|
36
|
+
|
|
37
|
+
@classmethod
|
|
38
|
+
@property
|
|
39
|
+
def size(cls):
|
|
40
|
+
return (cls.WIDTH, cls.HEIGHT)
|
|
41
|
+
|
|
42
|
+
#w = WIDTH
|
|
43
|
+
#h = HEIGHT
|
|
44
|
+
#size = (w,h)
|
|
45
|
+
|
|
46
|
+
class EmptyClass: pass
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class CONFIG:
|
|
50
|
+
CHANGED = []
|
|
51
|
+
classes = []
|
|
52
|
+
WINDOWTITLE = 'BeastBrine'
|
|
53
|
+
#WINDOWLOGO = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'Logo.png')
|
|
54
|
+
WINDOWLOGO = None
|
|
55
|
+
debug = False
|
|
56
|
+
def atExit():
|
|
57
|
+
pass
|
|
58
|
+
size = 40
|
|
59
|
+
speed = 4
|
|
60
|
+
PAUSED = False
|
|
61
|
+
centerX, centerY = 0, 0
|
|
62
|
+
stampSpamMode = False
|
|
63
|
+
showMask = False
|
|
64
|
+
backgroundColor = (255, 255, 255)
|
|
65
|
+
scroll = EmptyClass()
|
|
66
|
+
scroll.enabled = False
|
|
67
|
+
scroll.x = 0
|
|
68
|
+
scroll.y = 0
|
|
69
|
+
LOG = ''
|
|
70
|
+
FPS = 60
|
|
71
|
+
smoothWait = 1/60
|
|
72
|
+
class strings:
|
|
73
|
+
a2z = 'abcdefghijklmnopqrstuvwxyz'
|
|
74
|
+
A2Z = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
75
|
+
num = '0123456789'
|
|
76
|
+
allChar = a2z + A2Z + num
|
|
77
|
+
alph = a2z + A2Z
|
|
78
|
+
key_map = {
|
|
79
|
+
"Player1": (pygame.K_w, pygame.K_s, pygame.K_a, pygame.K_d, pygame.K_e, pygame.K_z, pygame.K_x, pygame.K_LSHIFT),
|
|
80
|
+
"Player2": (pygame.K_UP, pygame.K_DOWN, pygame.K_LEFT, pygame.K_RIGHT, pygame.K_0, pygame.K_5, pygame.K_2, pygame.K_RSHIFT),
|
|
81
|
+
}
|
|
82
|
+
class mouse:
|
|
83
|
+
x = 0
|
|
84
|
+
y = 0
|
|
85
|
+
down = False
|
|
86
|
+
clicked = False
|
|
87
|
+
noCollide = ['Text', 'Box', 'Stamp', 'Line', 'Polygon', 'grid']
|
|
88
|
+
class screen:
|
|
89
|
+
WIDTH = G.g.size()[0]
|
|
90
|
+
HEIGHT = G.g.size()[1]
|
|
91
|
+
w = WIDTH
|
|
92
|
+
h = HEIGHT
|
|
93
|
+
size = (w,h)
|
|
94
|
+
costumeFormat = []
|
|
95
|
+
class sounds:
|
|
96
|
+
frequency = 44100
|
|
97
|
+
size = -16
|
|
98
|
+
channels = 2
|
|
99
|
+
buffer = 512
|
|
100
|
+
maxChannels = 16
|
|
101
|
+
volume = 50
|
|
102
|
+
fade_ms = 0
|
|
103
|
+
class empty: pass
|
|
104
|
+
|
|
105
|
+
class Paths:
|
|
106
|
+
base_path = r"C:\Users\Siddharth\Pictures\tmp"
|
|
107
|
+
image1 = os.path.join(base_path, 'print1.jpeg')
|
|
108
|
+
image2 = os.path.join(base_path, 'print2.jpeg')
|
|
109
|
+
|
|
110
|
+
@classmethod
|
|
111
|
+
def add(cls, name, path):
|
|
112
|
+
setattr(cls, name, path)
|
|
113
|
+
|
|
114
|
+
@classmethod
|
|
115
|
+
def get(cls, name):
|
|
116
|
+
return getattr(cls, name, None)
|
|
117
|
+
|
|
118
|
+
import colorsys
|
|
119
|
+
|
|
120
|
+
class Color:
|
|
121
|
+
def __init__(self, r, g, b, a=255):
|
|
122
|
+
self.r = int(r)
|
|
123
|
+
self.g = int(g)
|
|
124
|
+
self.b = int(b)
|
|
125
|
+
self.a = int(a)
|
|
126
|
+
|
|
127
|
+
def __iter__(self):
|
|
128
|
+
return iter((self.r, self.g, self.b, self.a) if self.a < 255 else (self.r, self.g, self.b))
|
|
129
|
+
|
|
130
|
+
def __len__(self):
|
|
131
|
+
return 4 if self.a < 255 else 3
|
|
132
|
+
|
|
133
|
+
def __getitem__(self, index): # to support color[1]
|
|
134
|
+
return (self.r, self.g, self.b, self.a)[index]
|
|
135
|
+
|
|
136
|
+
def __repr__(self):
|
|
137
|
+
return f"Color(R={self.r}, G={self.g}, B={self.b}, A={self.a})"
|
|
138
|
+
|
|
139
|
+
@property
|
|
140
|
+
def hex(self) -> str:
|
|
141
|
+
return f"#{self.r:02x}{self.g:02x}{self.b:02x}"
|
|
142
|
+
|
|
143
|
+
def with_alpha(self, alpha):
|
|
144
|
+
return Color(self.r, self.g, self.b, max(0, min(255, alpha)))
|
|
145
|
+
|
|
146
|
+
def lighten(self, factor):
|
|
147
|
+
h, l, s = colorsys.rgb_to_hls(self.r/255, self.g/255, self.b/255)
|
|
148
|
+
r, g, b = colorsys.hls_to_rgb(h, min(1.0, l + (1.0 - l) * factor), s)
|
|
149
|
+
return Color(r * 255, g * 255, b * 255, self.a)
|
|
150
|
+
|
|
151
|
+
def darken(self, factor):
|
|
152
|
+
h, l, s = colorsys.rgb_to_hls(self.r/255, self.g/255, self.b/255)
|
|
153
|
+
r, g, b = colorsys.hls_to_rgb(h, max(0.0, l * (1.0 - factor)), s)
|
|
154
|
+
return Color(r * 255, g * 255, b * 255, self.a)
|
|
155
|
+
|
|
156
|
+
def lerp(self, other, weight):
|
|
157
|
+
weight = max(0.0, min(1.0, weight))
|
|
158
|
+
return Color(
|
|
159
|
+
self.r + (other.r - self.r) * weight,
|
|
160
|
+
self.g + (other.g - self.g) * weight,
|
|
161
|
+
self.b + (other.b - self.b) * weight,
|
|
162
|
+
self.a + (other.a - self.a) * weight
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class colors:
|
|
167
|
+
RED = Color(255, 0, 0)
|
|
168
|
+
WHITE = Color(255, 255, 255)
|
|
169
|
+
GREEN = Color(0, 255, 0)
|
|
170
|
+
BLUE = Color(0, 0, 255)
|
|
171
|
+
CYAN = Color(0, 255, 255)
|
|
172
|
+
YELLOW = Color(255, 255, 0)
|
|
173
|
+
PURPLE = Color(255, 0, 255)
|
|
174
|
+
BLACK = Color(0, 0, 0)
|
|
175
|
+
TRANSPARENT = Color(0, 0, 0, 0)
|
|
176
|
+
|
|
177
|
+
GRAY = Color(128, 128, 128)
|
|
178
|
+
LIGHT_GRAY = Color(211, 211, 211)
|
|
179
|
+
DARK_GRAY = Color(64, 64, 64)
|
|
180
|
+
ORANGE = Color(255, 165, 0)
|
|
181
|
+
PINK = Color(255, 192, 203)
|
|
182
|
+
GOLD = Color(255, 215, 0)
|
|
183
|
+
MAGENTA = Color(255, 0, 255)
|
|
184
|
+
|
|
185
|
+
class custom:
|
|
186
|
+
@classmethod
|
|
187
|
+
def add(cls, name: str, r: int, g: int, b: int, a: int = 255):
|
|
188
|
+
setattr(cls, name.upper(), Color(r, g, b, a))
|
|
189
|
+
|
|
190
|
+
@classmethod
|
|
191
|
+
def from_hex(cls, hex_str: str) -> Color:
|
|
192
|
+
hex_str = hex_str.lstrip('#')
|
|
193
|
+
if len(hex_str) == 6:
|
|
194
|
+
return Color(*(int(hex_str[i:i+2], 16) for i in (0, 2, 4)))
|
|
195
|
+
elif len(hex_str) == 8:
|
|
196
|
+
return Color(*(int(hex_str[i:i+2], 16) for i in (0, 2, 4, 6)))
|
|
197
|
+
raise ValueError("Invalid hex format. Use #RRGGBB or #RRGGBBAA.")
|
jeski/credits.py
ADDED
jeski/deps.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
|
|
2
|
+
import ctypes
|
|
3
|
+
import secrets
|
|
4
|
+
import time
|
|
5
|
+
import math
|
|
6
|
+
import os
|
|
7
|
+
import random
|
|
8
|
+
import sys
|
|
9
|
+
import threading
|
|
10
|
+
import inspect
|
|
11
|
+
import functools
|
|
12
|
+
import string
|
|
13
|
+
from safeImport import safe_import
|
|
14
|
+
import atexit
|
|
15
|
+
import subprocess as sb
|
|
16
|
+
import shlex # for reliable splitting of strings which have spaces
|
|
17
|
+
from tkinter import messagebox as mb
|
|
18
|
+
import traceback as tb # for safe yet detailed Error Detection
|
|
19
|
+
#import copy # for copying classes
|
|
20
|
+
|
|
21
|
+
os.environ.setdefault("PYGAME_HIDE_SUPPORT_PROMPT", "1") # to hide the pygame intro print lines
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
import pygame
|
|
27
|
+
import pygame.gfxdraw
|
|
28
|
+
import asteval
|
|
29
|
+
import mouse
|
|
30
|
+
import keyboard
|
|
31
|
+
import pyautogui
|
|
32
|
+
import numpy
|
|
33
|
+
except ModuleNotFoundError:
|
|
34
|
+
safe_import('pygame', verifyOnly=True)
|
|
35
|
+
safe_import('asteval', verifyOnly=True)
|
|
36
|
+
safe_import('mouse', verifyOnly=True)
|
|
37
|
+
safe_import('keyboard', verifyOnly=True)
|
|
38
|
+
safe_import('pyautogui', verifyOnly=True)
|
|
39
|
+
safe_import('numpy', verifyOnly=True)
|