-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
148 lines (115 loc) · 5.03 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import time
import pygame as pg
from typing import Union
from random import randint
import threading
from modules.display import Display
from modules.player import Player
from modules.enemy import Enemy
from modules.resources import *
class IntoTheLight:
# public
THREAD_INTERVAL: float
THREAD_INTERVAL = 0.2
MAIN_THREAD_RUNNING = True
player: Player
# private
_enemy_events: list[GameEvents]
_enemy_actions: dict[EnemyActions, any]
_game_events: list[GameEvents]
_enemy: Union[Enemy, None]
def __init__(self) -> None:
pg.init()
self.resolution = [int(value) for value in CONFIG["resolution"].split("x")]
self._enemy_events = ThreadVariable([], threading.Lock())
self._enemy_actions = ThreadVariable({}, threading.Lock())
self._game_events = ThreadVariable([], threading.Lock())
self.player = None
self._enemy = None
def game_loop(self) -> None:
mouse_event = False
clock = pg.time.Clock()
dt = 0
self.screen = pg.display.set_mode(self.resolution)
pg.display.set_caption("IntoTheLight")
load_textures()
self.player = Player()
self.display = Display(self.screen, self.resolution, float(CONFIG["ratio"]), self.player)
self.enemy = Enemy(screen_size=(self.resolution[0] * float(CONFIG["ratio"]), self.resolution[1]), offset=(self.resolution[0] * float(CONFIG["ratio"]),0))
mouse_pos = (0,0)
while self.MAIN_THREAD_RUNNING: # game loop
mouse_focused = pg.mouse.get_focused()
if mouse_focused:
mouse_pos = pg.mouse.get_pos()
mouse_event = False
for event in pg.event.get():
if event.type == pg.QUIT:
self.MAIN_THREAD_RUNNING = False
return
if event.type == pg.MOUSEBUTTONDOWN and mouse_focused:
mouse_event = True
mouse_clicked = pg.mouse.get_pressed()
self.display.mouse_clicked(mouse_pos, mouse_clicked)
if event.button == 1:
self.player.update(dt, mouse_pos, mouse_clicked)
if event.type == pg.KEYDOWN and event.key in keybinds.values():
self.player.key_pressed(event.key)
# spawn enemy ship
if event.type == pg.KEYDOWN and event.key == pg.K_F1:
if self.enemy == None:
self.enemy = Enemy(screen_size=(self.resolution[0] * float(CONFIG["ratio"]), self.resolution[1]), offset=(self.resolution[0] * float(CONFIG["ratio"]),0))
# if the mouse was not clicked, check if it's hovering over objects
if not mouse_event:
self.display.check_mouse_hover(mouse_pos)
self.player.update(dt, mouse_pos)
if self.enemy is not None:
self._enemy_events.set_value(self.enemy.update(dt))
self.display.update()
self.display.draw()
pg.display.flip()
self.screen.fill((0,0,0))
dt = clock.tick(60) / 1000 # cap the game's framerate at 60 fps
def enemy_controller(self) -> None:
"""Controls the enemy ship's actions."""
while self.MAIN_THREAD_RUNNING:
if self.enemy is None:
time.sleep(2)
else:
for event in self._enemy_events.get_value():
match event:
case GameEvents.SHIP_DESTROYED:
pass
case GameEvents.REMOVE_ENEMY:
print("Enemy destroyed, stopping thread...")
self.player.scrap += randint(10, 20)
del self.enemy
return
case GameEvents.TOOK_DAMAGE: # TODO: send crew to the damaged system
print("Enemy system took damage")
continue
self._enemy_events.revert_default()
# TODO: implement a timer so the checks don't happend every thread tick
self.enemy.check_weapon_states(self.player)
self.enemy.manage_power()
time.sleep(self.THREAD_INTERVAL)
@property
def enemy(self) -> Union[Enemy, None]:
return self._enemy
@enemy.setter
def enemy(self, value: Enemy) -> None:
self._enemy = value
self.display.enemy_ship = self._enemy
enemy_controller_thread = threading.Thread(target=game_instance.enemy_controller)
enemy_controller_thread.start()
@enemy.deleter
def enemy(self) -> None:
self._enemy = None
self._enemy_events.set_value([])
del self.display.enemy_ship
if __name__ == "__main__":
game_instance = IntoTheLight()
game_loop_thread = threading.Thread(target=game_instance.game_loop)
game_loop_thread.start()
game_loop_thread.join()
pg.quit()
exit(0)