Source code for scripts.nqp.main
from __future__ import annotations
import logging
import sys
import traceback
import pygame
import snecs
from snecs.world import default_world
from scripts.engine.core import hourglass, matter, state
from scripts.engine.core.component import NQPComponent
from scripts.engine.core.ui import ui
from scripts.engine.internal import debug
from scripts.engine.internal.constant import GameState
from scripts.engine.internal.event import event_hub
from scripts.nqp import processors
from scripts.nqp.command import initialise_game
from scripts.nqp.processors import display
from scripts.nqp.processors.input import process_input_event
from scripts.nqp.ui_elements.camera import camera
[docs]def main():
"""
The entry for the game initialisation and game loop
"""
# init engine resources
state.initialise_engine()
# initialise logging
if debug.is_logging():
debug.initialise_logging()
# initialise profiling
if debug.is_profiling():
debug.enable_profiling()
# initialise the game
initialise_game()
# run the game
try:
game_loop()
except Exception:
logging.critical(f"Something went wrong and killed the game loop!")
exc_type, exc_value, exc_traceback = sys.exc_info()
tb_list = traceback.format_exception(exc_type, exc_value, exc_traceback)
for line in tb_list:
clean_line = line.replace("\n", "")
logging.critical(f"{clean_line}")
traceback.print_exc()
# dump any held save data
state.dump_save_game()
# we've left the game loop so now close everything down
if debug.is_logging():
debug.kill_logging()
# print debug values
debug.print_values_to_console()
if debug.is_profiling():
debug.kill_profiler()
# clean up pygame resources
pygame.quit()
# exit window and python
raise SystemExit
[docs]def game_loop():
"""
The core game loop, handling input, rendering and logic.
"""
while not state.get_current() == GameState.EXITING:
# progress frame
time_delta = state.update_clock()
# get info to support UI updates and handling events
current_state = state.get_current()
turn_holder = hourglass.get_turn_holder()
# process any deletions from last frame
# this copies snecs.process_pending_deletions() but adds extra steps.
for entity in list(default_world._entities_to_delete):
components = dict(matter.get_entitys_components(entity))
for component in components.values():
assert isinstance(component, NQPComponent)
component.on_delete()
snecs.delete_entity_immediately(entity, default_world)
# have enemy take turn
if current_state == GameState.GAME_MAP:
if turn_holder != matter.get_player():
# just in case the turn holder has died but not been replaced as expected
try:
matter.take_turn(turn_holder)
except KeyError:
hourglass.rebuild_turn_queue()
# process pygame events
for event in pygame.event.get():
process_input_event(event, current_state)
ui.process_ui_events(event)
# process NQP events
event_hub.update()
# allow everything to update in response to new state
display.process_updates(time_delta, current_state)
debug.update()
ui.update(time_delta)
try:
if current_state in [GameState.GAME_MAP, GameState.MENU, GameState.TARGETING]:
# show the new state
camera.update(time_delta)
camera.render(ui._window)
except AttributeError:
pass
ui.draw()
if __name__ == "__main__": # prevents being run from other modules
main()