197 lines
6.6 KiB
Python
197 lines
6.6 KiB
Python
# libraries
|
|
import pygame
|
|
import time
|
|
from pyglet.gl import * # for blocky textures
|
|
import random
|
|
# other files of this project
|
|
import project_constants as const
|
|
import minefield as mf
|
|
from mine_models.time_mine import TimeMine
|
|
|
|
import searching_algorithms.a_star as a_star
|
|
|
|
from display_assets import blit_graphics
|
|
from project_constants import HIGHLIGHT, INPUT_ROW, INPUT_COLUMN, RANDOM_BUTTON, OK_BUTTON
|
|
from ui.ui_components_list import UiComponentsList
|
|
from ui.text_box import TextBox
|
|
from ui.button import Button
|
|
|
|
|
|
def main():
|
|
pygame.init()
|
|
pygame.display.set_caption(const.V_NAME_OF_WINDOW)
|
|
|
|
# for blocky textures
|
|
glEnable(GL_TEXTURE_2D)
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
|
|
|
# FPS clock
|
|
clock = pygame.time.Clock()
|
|
|
|
# create an instance of Minefield, pass necessary data
|
|
minefield = mf.Minefield(const.MAP_RANDOM_10x10)
|
|
|
|
# getting agent's instance
|
|
agent = minefield.agent
|
|
|
|
# setting flags for program
|
|
running = True
|
|
in_menu = True
|
|
is_game_over = False
|
|
|
|
# creating list storing all ui components
|
|
ui_components_list = UiComponentsList([INPUT_ROW, INPUT_COLUMN, RANDOM_BUTTON, OK_BUTTON])
|
|
|
|
# initializing goal position
|
|
row, column = 0, 0
|
|
|
|
# drawing map so black screen doesn't appear
|
|
blit_graphics(minefield)
|
|
|
|
while running:
|
|
|
|
# ============== #
|
|
# ==== MENU ==== #
|
|
# ============== #
|
|
|
|
while running and in_menu:
|
|
events = pygame.event.get()
|
|
|
|
for event in events:
|
|
if event.type == pygame.QUIT:
|
|
running = False
|
|
|
|
# graphics (from display_assets)
|
|
blit_graphics(minefield)
|
|
|
|
agent.update_and_draw(const.SCREEN, 0)
|
|
|
|
# drawing gui
|
|
ui_components_list.run_all(const.SCREEN, pygame.mouse.get_pos(), events)
|
|
|
|
# highlighting chosen tile destination (if exists)
|
|
if not (INPUT_ROW.empty() or INPUT_COLUMN.empty()):
|
|
row = min(9, int(INPUT_ROW.get_input()))
|
|
column = min(9, int(INPUT_COLUMN.get_input()))
|
|
const.SCREEN.blit(HIGHLIGHT, const.get_tile_coordinates((row, column)))
|
|
|
|
# updating graphics
|
|
pygame.display.flip()
|
|
|
|
ui_components_list.switch_selected_objects_with_arrow_keys(events, pygame.mouse.get_pos())
|
|
|
|
OK_BUTTON.set_flags(is_active=(not (INPUT_ROW.empty() or INPUT_COLUMN.empty())))
|
|
|
|
if OK_BUTTON.is_clicked(pygame.mouse.get_pos(), events) or OK_BUTTON.enter_pressed(events):
|
|
in_menu = False
|
|
|
|
if RANDOM_BUTTON.is_clicked(pygame.mouse.get_pos(), events) or RANDOM_BUTTON.enter_pressed(events):
|
|
INPUT_ROW.set_texts(user_input=str(random.randint(0, 9)))
|
|
INPUT_COLUMN.set_texts(user_input=str(random.randint(0, 9)))
|
|
|
|
clock.tick(const.V_FPS)
|
|
|
|
# ========================== #
|
|
# ==== BEFORE GAME LOOP ==== #
|
|
# ========================== #
|
|
|
|
if running:
|
|
for component in ui_components_list.selectable_ui_components:
|
|
component.set_flags(is_active=False)
|
|
|
|
action_sequence = a_star.graphsearch(
|
|
initial_state=a_star.State(
|
|
row=minefield.agent.position[0],
|
|
column=minefield.agent.position[1],
|
|
direction=minefield.agent.direction),
|
|
minefield=minefield, tox=row, toy=column)
|
|
|
|
action = None
|
|
in_game_timer = 0
|
|
|
|
# =================== #
|
|
# ==== GAME LOOP ==== #
|
|
# =================== #
|
|
|
|
while running and not in_menu and not is_game_over:
|
|
|
|
for event in pygame.event.get():
|
|
if event.type == pygame.QUIT:
|
|
running = False
|
|
|
|
# FPS control
|
|
clock.tick(const.V_FPS)
|
|
delta_time = clock.get_time() / 1000
|
|
action_delta_time = delta_time / const.ACTION_INTERVAL
|
|
|
|
# graphics (from display_assets)
|
|
blit_graphics(minefield)
|
|
const.SCREEN.blit(HIGHLIGHT, const.get_tile_coordinates((row, column)))
|
|
|
|
agent.update_and_draw(const.SCREEN, action_delta_time)
|
|
|
|
# drawing ui components so they don't "disappear"
|
|
ui_components_list.draw_all(const.SCREEN, pygame.mouse.get_pos())
|
|
|
|
# updating graphics
|
|
pygame.display.flip()
|
|
|
|
# make the next move from sequence of actions
|
|
if in_game_timer >= const.ACTION_INTERVAL and any(action_sequence):
|
|
in_game_timer -= const.ACTION_INTERVAL
|
|
minefield.next_turn()
|
|
|
|
agent.take_action(action)
|
|
|
|
action = action_sequence.pop(0)
|
|
|
|
agent.animate(action)
|
|
|
|
elif in_game_timer >= const.ACTION_INTERVAL:
|
|
agent.take_action(action)
|
|
|
|
agent.update_and_draw(const.SCREEN, delta_time)
|
|
agent.reset_actions()
|
|
|
|
in_menu = True
|
|
if not any([x.is_selected for x in ui_components_list.ui_components]):
|
|
INPUT_ROW.set_is_selected(True)
|
|
|
|
for component in ui_components_list.selectable_ui_components:
|
|
component.set_flags(is_active=True)
|
|
|
|
in_game_timer += delta_time
|
|
for x in minefield.matrix:
|
|
for y in x:
|
|
if y.mine is not None:
|
|
if isinstance(y.mine, TimeMine):
|
|
if y.mine.timer == 0:
|
|
is_game_over = True
|
|
|
|
while running and is_game_over:
|
|
clock.tick(const.V_FPS)
|
|
const.SCREEN.fill((255, 255, 255))
|
|
tb = TextBox(position=(150, 200), dimensions=(500, 100), text="Game Over")
|
|
cont = Button(position=(350, 350), dimensions=(100, 50), text="Try again")
|
|
close = Button(position=(350, 450), dimensions=(100, 50), text="Close")
|
|
ev = pygame.event.get()
|
|
if close.is_clicked(pygame.mouse.get_pos(), ev):
|
|
running = False
|
|
if cont.is_clicked(pygame.mouse.get_pos(), ev):
|
|
minefield = mf.Minefield(const.MAP_RANDOM_10x10)
|
|
agent = minefield.agent
|
|
in_menu = True
|
|
is_game_over = False
|
|
for component in ui_components_list.selectable_ui_components:
|
|
component.set_flags(is_active=True)
|
|
cont.draw(const.SCREEN, pygame.mouse.get_pos())
|
|
close.draw(const.SCREEN, pygame.mouse.get_pos())
|
|
tb.draw(const.SCREEN)
|
|
pygame.display.flip()
|
|
|
|
# is_game_over = False
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|