adding files
cc
864
Hashi.py
Normal file
@ -0,0 +1,864 @@
|
|||||||
|
from hashi_functions import *
|
||||||
|
import hashi_generator as hg
|
||||||
|
import hashi_game
|
||||||
|
import assets.palettes.palette_manager as pm
|
||||||
|
from menu_effect import Circle_effect
|
||||||
|
from game_effect import Rectangle_effect
|
||||||
|
from widget_engine import *
|
||||||
|
from s_engine import *
|
||||||
|
import sounds
|
||||||
|
import pygame
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
from pygame.locals import *
|
||||||
|
|
||||||
|
# basic config
|
||||||
|
pygame.mixer.pre_init(48000, -16, 2, 512)
|
||||||
|
pygame.init()
|
||||||
|
pygame.mixer.set_num_channels(16)
|
||||||
|
available = pygame.font.get_fonts()
|
||||||
|
monitor_size = [pygame.display.Info().current_w, pygame.display.Info().current_h]
|
||||||
|
|
||||||
|
font = pygame.font.SysFont('calibri', 60, True)
|
||||||
|
small_font = pygame.font.SysFont('calibri', 40, True)
|
||||||
|
tiny_font = pygame.font.SysFont('calibri', 20, True)
|
||||||
|
|
||||||
|
Window_size = [600, 650]
|
||||||
|
Default_size = Window_size
|
||||||
|
screen = pygame.display.set_mode(Window_size)
|
||||||
|
display = pygame.Surface((600, 650))
|
||||||
|
pygame.display.set_caption("Hashi")
|
||||||
|
pygame.display.set_icon(pygame.image.load("assets/images/general/hashi_logo.png").convert())
|
||||||
|
clock = pygame.time.Clock()
|
||||||
|
|
||||||
|
soundsX = sounds.get_sounds()
|
||||||
|
|
||||||
|
|
||||||
|
def main_menu(screenX, Win_size):
|
||||||
|
# PREP WORK
|
||||||
|
# getting setup
|
||||||
|
with open("assets/saves/setup.json", "r") as f:
|
||||||
|
setup = json.load(f)
|
||||||
|
# game variables
|
||||||
|
game = Game()
|
||||||
|
game.game_flow["ac"] = True
|
||||||
|
game.game_flow["custom_string"] = setup["custom_num"]
|
||||||
|
# next 3 lines for arrow buttons
|
||||||
|
game.game_flow["dfs"] = ["easy", "medium", "hard", "extreme", "custom"]
|
||||||
|
game.game_flow["df"] = setup["difficulty"]
|
||||||
|
game.game_flow["df_change"] = False
|
||||||
|
game.game_flow["dp"] = [0, 0]
|
||||||
|
game.game_flow["back_from_game"] = False
|
||||||
|
game.game_flow["Win_size"] = Win_size
|
||||||
|
game.game_flow["cut_click"] = False
|
||||||
|
game.game_flow["change_fs"] = False
|
||||||
|
|
||||||
|
# mouse
|
||||||
|
mouse = Mouse(pygame.mouse.get_pos())
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
|
||||||
|
# dealing with palettes
|
||||||
|
palette = pm.Palettes("assets/palettes")
|
||||||
|
palette.current_palette = setup["palette"]
|
||||||
|
palette.palette = palette.get_palette()
|
||||||
|
|
||||||
|
menu_objects = []
|
||||||
|
|
||||||
|
# loading images
|
||||||
|
play_images = {"idle": pygame.image.load("assets/images/menu/play.png").convert(),
|
||||||
|
"hover": pygame.image.load("assets/images/menu/play_hover.png").convert()}
|
||||||
|
# size 200
|
||||||
|
|
||||||
|
palette_images = {"idle": pygame.image.load("assets/images/menu/palette.png").convert(),
|
||||||
|
"hover": pygame.image.load("assets/images/menu/palette_hover.png").convert()}
|
||||||
|
# size 140
|
||||||
|
|
||||||
|
new_game_images = {"idle": pygame.image.load("assets/images/menu/new_game.png").convert(),
|
||||||
|
"hover": pygame.image.load("assets/images/menu/new_game_hover.png").convert()}
|
||||||
|
# size 300 150
|
||||||
|
|
||||||
|
difficulty_images = {"idle": pygame.image.load("assets/images/menu/template.png").convert(),
|
||||||
|
"hover": pygame.image.load("assets/images/menu/template_hover.png").convert()}
|
||||||
|
# size 250 100
|
||||||
|
|
||||||
|
right_arrow_images = {"idle": pygame.image.load("assets/images/menu/arrow.png").convert(),
|
||||||
|
"hover": pygame.image.load("assets/images/menu/arrow_hover.png").convert()}
|
||||||
|
left_arrow_images = {"idle": pygame.transform.flip(pygame.image.load("assets/images/menu/arrow.png").convert(),
|
||||||
|
True, False),
|
||||||
|
"hover": pygame.transform.flip(
|
||||||
|
pygame.image.load("assets/images/menu/arrow_hover.png").convert(),
|
||||||
|
True, False)}
|
||||||
|
# size 100 100
|
||||||
|
|
||||||
|
custom_size_images = {"idle": pygame.image.load("assets/images/menu/custom.png").convert(),
|
||||||
|
"hover": pygame.image.load("assets/images/menu/custom_pressed.png").convert()}
|
||||||
|
# size 100 100
|
||||||
|
|
||||||
|
fs_images = {"idle": pygame.image.load("assets/images/menu/fs.png").convert(),
|
||||||
|
"hover": pygame.image.load("assets/images/menu/fs_hover.png").convert()}
|
||||||
|
ms_images = {"idle": pygame.image.load("assets/images/menu/ms.png").convert(),
|
||||||
|
"hover": pygame.image.load("assets/images/menu/ms_hover.png").convert()}
|
||||||
|
# size 60 60
|
||||||
|
|
||||||
|
menu_objects.append(CircleButton(200, [200, 220], play_images, play, [game, palette, mouse]))
|
||||||
|
menu_objects.append(CircleButton(200, [440, 20], palette_images, next_palette, [palette]))
|
||||||
|
menu_objects.append(Button([150, 450], [300, 150], new_game_images, new_game, [game, palette, mouse]))
|
||||||
|
menu_objects.append(Button([20, 20], [250, 100], difficulty_images, play_click_sound, []))
|
||||||
|
menu_objects.append(Button([440, 270], [100, 100], right_arrow_images, right_arrow, [game]))
|
||||||
|
menu_objects.append(Button([60, 270], [100, 100], left_arrow_images, left_arrow, [game]))
|
||||||
|
menu_objects.append(Button([480, 400], [100, 100], custom_size_images, activate_edit_text, [game], False))
|
||||||
|
menu_objects.append(Button([20, 570], [60, 60], fs_images, change_fs, [game]))
|
||||||
|
menu_objects[-1].name = "fs"
|
||||||
|
menu_objects.append(Button([20, 570], [60, 60], ms_images, change_fs, [game], False))
|
||||||
|
menu_objects[-1].name = "ms"
|
||||||
|
difficulty_text = font.render(setup["difficulty"].capitalize(), False, palette.palette["outline-dark"])
|
||||||
|
|
||||||
|
# setting up custom text
|
||||||
|
|
||||||
|
custom_text = font.render(game.game_flow["custom_string"], False, palette.palette["outline-dark"])
|
||||||
|
custom_text_hover = font.render(game.game_flow["custom_string"], False, palette.palette["background"])
|
||||||
|
ct_images = {"idle": create_text_sur(custom_text, [20, 20], [100, 100]),
|
||||||
|
"hover": create_text_sur(custom_text_hover, [20, 20], [100, 100])}
|
||||||
|
menu_objects.append(Button([480, 400], [100, 100], ct_images, activate_edit_text, [game], False))
|
||||||
|
menu_objects[-1].name = "custom_text"
|
||||||
|
|
||||||
|
custom_pointer = palette.swap_image(pygame.image.load("assets/images/menu/writing.png").convert(),
|
||||||
|
"emerald", setup["palette"])
|
||||||
|
custom_pointer.set_colorkey((0, 0, 0))
|
||||||
|
|
||||||
|
# setting up custom
|
||||||
|
|
||||||
|
if setup["difficulty"] == "custom":
|
||||||
|
for item in menu_objects:
|
||||||
|
if item.on_click == activate_edit_text:
|
||||||
|
item.active = True
|
||||||
|
|
||||||
|
# circle effect
|
||||||
|
|
||||||
|
cE = Circle_effect
|
||||||
|
cE.generate_circles(50, [-50, 50])
|
||||||
|
cE.generate_circles(50, [480, 600])
|
||||||
|
|
||||||
|
# last config
|
||||||
|
|
||||||
|
menu_objects, setup = set_palette(setup, palette, setup["palette"], menu_objects, True)
|
||||||
|
|
||||||
|
palette.create_cycle()
|
||||||
|
game.game_flow["setup"] = setup
|
||||||
|
game.game_flow["screen"] = screenX
|
||||||
|
|
||||||
|
# checking tutorial
|
||||||
|
if setup["tutorial"]:
|
||||||
|
run_tutorial(screenX, setup, game, palette, mouse)
|
||||||
|
|
||||||
|
# game loop
|
||||||
|
while game.alive:
|
||||||
|
# checking if returned
|
||||||
|
if game.game_flow["back_from_game"]:
|
||||||
|
game.game_flow["back_from_game"] = False
|
||||||
|
Win_size = game.game_flow["Win_size"]
|
||||||
|
|
||||||
|
with open("assets/saves/setup.json", "r") as f:
|
||||||
|
setup = json.load(f)
|
||||||
|
|
||||||
|
game.game_flow["setup"] = setup
|
||||||
|
|
||||||
|
# background
|
||||||
|
display.fill(palette.palette["background"])
|
||||||
|
pygame.draw.rect(display, palette.palette["outline-shade"], pygame.Rect(180, 0, 240, 650))
|
||||||
|
pygame.draw.rect(display, palette.palette["outline"], pygame.Rect(200, 0, 200, 650))
|
||||||
|
|
||||||
|
# displaying effect
|
||||||
|
|
||||||
|
for circle in cE.circles:
|
||||||
|
circle.move(display, palette)
|
||||||
|
|
||||||
|
if cE.timer == 0:
|
||||||
|
cE.generate_circles(4, [-50, 50])
|
||||||
|
cE.generate_circles(4, [480, 600])
|
||||||
|
cE.timer += 10
|
||||||
|
else:
|
||||||
|
cE.timer -= 1
|
||||||
|
|
||||||
|
# displaying widgets
|
||||||
|
|
||||||
|
for widget in menu_objects:
|
||||||
|
widget.blit(display)
|
||||||
|
|
||||||
|
# dealing with difficulty
|
||||||
|
|
||||||
|
if game.game_flow["df_change"]:
|
||||||
|
game.game_flow["df_change"] = False
|
||||||
|
|
||||||
|
# dealing with json
|
||||||
|
setup["difficulty"] = game.game_flow["df"]
|
||||||
|
with open("assets/saves/setup.json", "w") as f:
|
||||||
|
json.dump(setup, f, indent=4)
|
||||||
|
|
||||||
|
difficulty_text = font.render(setup["difficulty"].capitalize(), False, palette.palette["outline-dark"])
|
||||||
|
|
||||||
|
# changing custom edit text
|
||||||
|
if setup["difficulty"] == "custom":
|
||||||
|
for item in menu_objects:
|
||||||
|
if item.on_click == activate_edit_text:
|
||||||
|
item.active = True
|
||||||
|
else:
|
||||||
|
for item in menu_objects:
|
||||||
|
if item.on_click == activate_edit_text:
|
||||||
|
item.active = False
|
||||||
|
|
||||||
|
display.blit(difficulty_text, [40, 40])
|
||||||
|
|
||||||
|
# checking palette
|
||||||
|
|
||||||
|
if palette.changed:
|
||||||
|
palette.changed = False
|
||||||
|
menu_objects, setup = set_palette(setup, palette, palette.current_palette, menu_objects)
|
||||||
|
difficulty_text = font.render(setup["difficulty"].capitalize(), False, palette.palette["outline-dark"])
|
||||||
|
custom_pointer = palette.swap_image(pygame.image.load("assets/images/menu/writing.png").convert(),
|
||||||
|
"emerald", setup["palette"])
|
||||||
|
custom_pointer.set_colorkey((0, 0, 0))
|
||||||
|
game.game_flow["setup"] = setup
|
||||||
|
|
||||||
|
# custom pointer
|
||||||
|
|
||||||
|
if game.game_flow["ac"] is False:
|
||||||
|
display.blit(custom_pointer, [480, 350])
|
||||||
|
|
||||||
|
# event loop
|
||||||
|
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == QUIT:
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# keydown
|
||||||
|
elif event.type == KEYDOWN:
|
||||||
|
if event.key == K_ESCAPE:
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit(0)
|
||||||
|
elif event.key == K_f:
|
||||||
|
game.fs = not game.fs
|
||||||
|
if game.fs is False:
|
||||||
|
Win_size = Default_size
|
||||||
|
screenX = pygame.display.set_mode(Win_size)
|
||||||
|
game.game_flow["dp"] = [0, 0]
|
||||||
|
mouse.mouse_scroll = game.game_flow["dp"]
|
||||||
|
|
||||||
|
game.game_flow["Win_size"] = Win_size
|
||||||
|
game.game_flow["screen"] = screenX
|
||||||
|
else:
|
||||||
|
screenX = pygame.display.set_mode(monitor_size, pygame.FULLSCREEN)
|
||||||
|
d = screenX
|
||||||
|
ratio = [Default_size[1] / Default_size[0], Default_size[0] / Default_size[1]]
|
||||||
|
# u chose width or height here
|
||||||
|
|
||||||
|
if Default_size[0] > Default_size[1]:
|
||||||
|
Win_size = [d.get_width(), int(d.get_width() * ratio[0])]
|
||||||
|
d = d.get_height()
|
||||||
|
dd = Win_size[1]
|
||||||
|
game.game_flow["dp"][1] = (d - dd) / 2
|
||||||
|
mouse.mouse_scroll = game.game_flow["dp"]
|
||||||
|
else:
|
||||||
|
Win_size = [int(d.get_height() * ratio[1]), d.get_height()]
|
||||||
|
d = pygame.display.get_surface().get_width()
|
||||||
|
dd = Win_size[0]
|
||||||
|
game.game_flow["dp"][0] = (d - dd) / 2
|
||||||
|
mouse.mouse_scroll = game.game_flow["dp"]
|
||||||
|
|
||||||
|
game.game_flow["Win_size"] = Win_size
|
||||||
|
game.game_flow["screen"] = screenX
|
||||||
|
|
||||||
|
if game.game_flow["ac"]:
|
||||||
|
# mouse stuff
|
||||||
|
if event.type == MOUSEMOTION:
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
for widget in menu_objects:
|
||||||
|
widget.hover_check(mouse.mouse_pos)
|
||||||
|
|
||||||
|
# click
|
||||||
|
if event.type == MOUSEBUTTONDOWN:
|
||||||
|
for widget in menu_objects:
|
||||||
|
widget.click_check(mouse.mouse_pos)
|
||||||
|
if game.game_flow["cut_click"]:
|
||||||
|
game.game_flow["cut_click"] = False
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if event.type == MOUSEBUTTONDOWN:
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
game.game_flow["ac"] = True
|
||||||
|
for widget in menu_objects:
|
||||||
|
widget.hover_check(mouse.mouse_pos)
|
||||||
|
soundsX["click"].play()
|
||||||
|
|
||||||
|
# checking if num big enough
|
||||||
|
try:
|
||||||
|
if int(game.game_flow["custom_string"]) < 2 or len(
|
||||||
|
game.game_flow["custom_string"]) == 0:
|
||||||
|
game.game_flow["custom_string"] = "2"
|
||||||
|
except:
|
||||||
|
game.game_flow["custom_string"] = "2"
|
||||||
|
menu_objects, setup = update_text(menu_objects, setup, game, palette)
|
||||||
|
|
||||||
|
if event.type == KEYDOWN:
|
||||||
|
if event.key == K_BACKSPACE:
|
||||||
|
try:
|
||||||
|
game.game_flow["custom_string"] = game.game_flow["custom_string"][:-1]
|
||||||
|
|
||||||
|
menu_objects, setup = update_text(menu_objects, setup, game, palette)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
elif event.key == K_RETURN:
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
game.game_flow["ac"] = True
|
||||||
|
for widget in menu_objects:
|
||||||
|
widget.hover_check(mouse.mouse_pos)
|
||||||
|
soundsX["click"].play()
|
||||||
|
|
||||||
|
# checking if num big enough
|
||||||
|
try:
|
||||||
|
if int(game.game_flow["custom_string"]) < 2 or len(game.game_flow["custom_string"]) == 0:
|
||||||
|
game.game_flow["custom_string"] = "2"
|
||||||
|
except:
|
||||||
|
game.game_flow["custom_string"] = "2"
|
||||||
|
menu_objects, setup = update_text(menu_objects, setup, game, palette)
|
||||||
|
else:
|
||||||
|
if len(game.game_flow["custom_string"]) < 2:
|
||||||
|
try:
|
||||||
|
int(event.unicode)
|
||||||
|
game.game_flow["custom_string"] += event.unicode
|
||||||
|
|
||||||
|
menu_objects, setup = update_text(menu_objects, setup, game, palette)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# checking fs change
|
||||||
|
if game.game_flow["change_fs"]:
|
||||||
|
game.game_flow["change_fs"] = False
|
||||||
|
|
||||||
|
for obj in menu_objects:
|
||||||
|
if obj.name in ["fs", "ms"]:
|
||||||
|
obj.active = not obj.active
|
||||||
|
|
||||||
|
game.fs = not game.fs
|
||||||
|
if game.fs is False:
|
||||||
|
Win_size = Default_size
|
||||||
|
screenX = pygame.display.set_mode(Win_size)
|
||||||
|
game.game_flow["dp"] = [0, 0]
|
||||||
|
mouse.mouse_scroll = game.game_flow["dp"]
|
||||||
|
|
||||||
|
game.game_flow["Win_size"] = Win_size
|
||||||
|
game.game_flow["screen"] = screenX
|
||||||
|
else:
|
||||||
|
screenX = pygame.display.set_mode(monitor_size, pygame.FULLSCREEN)
|
||||||
|
d = screenX
|
||||||
|
ratio = [Default_size[1] / Default_size[0], Default_size[0] / Default_size[1]]
|
||||||
|
# u chose width or height here
|
||||||
|
|
||||||
|
if Default_size[0] > Default_size[1]:
|
||||||
|
Win_size = [d.get_width(), int(d.get_width() * ratio[0])]
|
||||||
|
d = d.get_height()
|
||||||
|
dd = Win_size[1]
|
||||||
|
game.game_flow["dp"][1] = (d - dd) / 2
|
||||||
|
mouse.mouse_scroll = game.game_flow["dp"]
|
||||||
|
else:
|
||||||
|
Win_size = [int(d.get_height() * ratio[1]), d.get_height()]
|
||||||
|
d = pygame.display.get_surface().get_width()
|
||||||
|
dd = Win_size[0]
|
||||||
|
game.game_flow["dp"][0] = (d - dd) / 2
|
||||||
|
mouse.mouse_scroll = game.game_flow["dp"]
|
||||||
|
|
||||||
|
game.game_flow["Win_size"] = Win_size
|
||||||
|
game.game_flow["screen"] = screenX
|
||||||
|
|
||||||
|
# basic loop config
|
||||||
|
|
||||||
|
screenX.blit(pygame.transform.scale(display, Win_size), game.game_flow["dp"])
|
||||||
|
pygame.display.update()
|
||||||
|
clock.tick(60)
|
||||||
|
|
||||||
|
|
||||||
|
# new_game_btn
|
||||||
|
def new_game(args):
|
||||||
|
game = args[0]
|
||||||
|
palette = args[1]
|
||||||
|
mouse = args[2]
|
||||||
|
setup = game.game_flow["setup"]
|
||||||
|
screenX = game.game_flow["screen"]
|
||||||
|
setup[setup["difficulty"]] = True
|
||||||
|
|
||||||
|
if setup["difficulty"] == "easy":
|
||||||
|
hashi = hg.Hashi(5)
|
||||||
|
elif setup["difficulty"] == "medium":
|
||||||
|
hashi = hg.Hashi(10)
|
||||||
|
elif setup["difficulty"] == "hard":
|
||||||
|
hashi = hg.Hashi(15)
|
||||||
|
elif setup["difficulty"] == "extreme":
|
||||||
|
hashi = hg.Hashi(20)
|
||||||
|
elif setup["difficulty"] == "custom":
|
||||||
|
hashi = hg.Hashi(int(setup["custom_num"]))
|
||||||
|
else:
|
||||||
|
sys.exit(55)
|
||||||
|
|
||||||
|
hashi.generate_map()
|
||||||
|
hashi.save(f"assets/maps/{setup['difficulty']}.txt")
|
||||||
|
soundsX["click"].play()
|
||||||
|
|
||||||
|
run_game(screenX, setup, game, palette, mouse, "new")
|
||||||
|
game.game_flow["cut_click"] = True
|
||||||
|
|
||||||
|
|
||||||
|
# play_btn
|
||||||
|
def play(args):
|
||||||
|
game = args[0]
|
||||||
|
palette = args[1]
|
||||||
|
mouse = args[2]
|
||||||
|
setup = game.game_flow["setup"]
|
||||||
|
screenX = game.game_flow["screen"]
|
||||||
|
|
||||||
|
if setup[setup["difficulty"]] is False:
|
||||||
|
new_game(args)
|
||||||
|
else:
|
||||||
|
soundsX["click"].play()
|
||||||
|
run_game(screenX, setup, game, palette, mouse, "continue")
|
||||||
|
game.game_flow["cut_click"] = True
|
||||||
|
|
||||||
|
|
||||||
|
# at this point the whole menu is done and the game is ready to be run so here we go
|
||||||
|
def run_game(screenX, setup, gameMenu, palette, mouse, state):
|
||||||
|
game = Game()
|
||||||
|
game.game_flow["dp"] = gameMenu.game_flow["dp"]
|
||||||
|
game.fs = gameMenu.fs
|
||||||
|
hashi = None
|
||||||
|
Win_size = gameMenu.game_flow["Win_size"]
|
||||||
|
game.game_flow["scroll_length"] = (Win_size[0] - 60) / 2
|
||||||
|
game.game_flow["quit"] = False
|
||||||
|
|
||||||
|
scroll = Scroll([-20, -20])
|
||||||
|
|
||||||
|
mid_point_scroll_mouse = [game.game_flow["dp"][0] + (Win_size[0] / 2),
|
||||||
|
game.game_flow["dp"][1] + (Win_size[1] / 2)]
|
||||||
|
|
||||||
|
back_btn = Button([200, 350], [200, 100], get_back_images(palette), go_back, [game])
|
||||||
|
win_image = get_win_image()
|
||||||
|
|
||||||
|
# initing rectangle effect
|
||||||
|
rE = Rectangle_effect
|
||||||
|
rE.generate_rects()
|
||||||
|
|
||||||
|
# initializing game by state
|
||||||
|
if state == "new":
|
||||||
|
hashi = hashi_game.HashiG("file.txt", f"assets/maps/{setup['difficulty']}.txt", palette, mouse)
|
||||||
|
elif state == "continue":
|
||||||
|
hashi = hashi_game.HashiG("file.json", f"assets/saves/game_saves/{setup['difficulty']}.json", palette, mouse)
|
||||||
|
|
||||||
|
hashi_top_lim = [(hashi.get_length() + 40) - 600, (hashi.get_length() + 40) - 650]
|
||||||
|
|
||||||
|
# pre scrolling
|
||||||
|
scroll.move_scroll_based_on_pos(mouse.get_scrolled(scroll), [600, 650], "both", 40)
|
||||||
|
|
||||||
|
scroll.scroll_lim(scroll, [-40, -40], hashi_top_lim)
|
||||||
|
|
||||||
|
while game.alive:
|
||||||
|
# dealing with hashi locked
|
||||||
|
if hashi.locked:
|
||||||
|
hashi.on_locked(mouse, scroll)
|
||||||
|
|
||||||
|
# background
|
||||||
|
display.fill(palette.palette["background"])
|
||||||
|
|
||||||
|
# dealing with bg effect
|
||||||
|
for item in rE.rects:
|
||||||
|
item.move(display, palette)
|
||||||
|
|
||||||
|
if rE.timer == 0:
|
||||||
|
rE.generate_rects(5, [1, 3])
|
||||||
|
rE.timer = 10
|
||||||
|
else:
|
||||||
|
rE.timer -= 1
|
||||||
|
|
||||||
|
# dealing with scroll
|
||||||
|
# not using mouse.mouse_pos because screen size affects
|
||||||
|
if distance_indicator(pygame.mouse.get_pos(), mid_point_scroll_mouse) > game.game_flow["scroll_length"]:
|
||||||
|
scroll.move_scroll_based_on_pos(mouse.get_scrolled(scroll), [600, 650], "both", 40)
|
||||||
|
|
||||||
|
scroll.scroll_lim(scroll, [-40, -40], hashi_top_lim)
|
||||||
|
|
||||||
|
# game
|
||||||
|
|
||||||
|
hashi.blit(display, palette, scroll)
|
||||||
|
|
||||||
|
# win screen
|
||||||
|
|
||||||
|
if hashi.win:
|
||||||
|
display.blit(win_image, [50, 50])
|
||||||
|
|
||||||
|
back_btn.blit(display)
|
||||||
|
|
||||||
|
setup[setup["difficulty"]] = False
|
||||||
|
|
||||||
|
# event loop
|
||||||
|
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == QUIT:
|
||||||
|
# saving before quiting
|
||||||
|
with open("assets/saves/setup.json", "w") as f:
|
||||||
|
json.dump(setup, f, indent=4)
|
||||||
|
|
||||||
|
if hashi.win is False:
|
||||||
|
hashi.save(setup)
|
||||||
|
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# keydown
|
||||||
|
if event.type == KEYDOWN:
|
||||||
|
if hashi.locked is False:
|
||||||
|
if event.key == K_ESCAPE:
|
||||||
|
gameMenu.fs = game.fs
|
||||||
|
gameMenu.game_flow["dp"] = game.game_flow["dp"]
|
||||||
|
gameMenu.game_flow["back_from_game"] = True
|
||||||
|
gameMenu.game_flow["Win_size"] = Win_size
|
||||||
|
game.alive = False
|
||||||
|
|
||||||
|
with open("assets/saves/setup.json", "w") as f:
|
||||||
|
json.dump(setup, f, indent=4)
|
||||||
|
|
||||||
|
if hashi.win is False:
|
||||||
|
hashi.save(setup)
|
||||||
|
else:
|
||||||
|
if event.key == K_ESCAPE:
|
||||||
|
hashi.locked = False
|
||||||
|
hashi.clear_temp()
|
||||||
|
hashi.clear_temp_remove()
|
||||||
|
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
hashi.hover(mouse, scroll)
|
||||||
|
|
||||||
|
if event.key == K_f:
|
||||||
|
game.fs = not game.fs
|
||||||
|
if game.fs is False:
|
||||||
|
Win_size = Default_size
|
||||||
|
screenX = pygame.display.set_mode(Win_size)
|
||||||
|
game.game_flow["dp"] = [0, 0]
|
||||||
|
mouse.mouse_scroll = game.game_flow["dp"]
|
||||||
|
# specifics
|
||||||
|
mid_point_scroll_mouse = [game.game_flow["dp"][0] + (Win_size[0] / 2),
|
||||||
|
game.game_flow["dp"][1] + (Win_size[1] / 2)]
|
||||||
|
game.game_flow["scroll_length"] = (Win_size[0] - 100) / 2
|
||||||
|
|
||||||
|
else:
|
||||||
|
screenX = pygame.display.set_mode(monitor_size, pygame.FULLSCREEN)
|
||||||
|
d = screenX
|
||||||
|
ratio = [Default_size[1] / Default_size[0], Default_size[0] / Default_size[1]]
|
||||||
|
# u chose width or height here
|
||||||
|
|
||||||
|
if Default_size[0] > Default_size[1]:
|
||||||
|
Win_size = [d.get_width(), int(d.get_width() * ratio[0])]
|
||||||
|
d = d.get_height()
|
||||||
|
dd = Win_size[1]
|
||||||
|
game.game_flow["dp"][1] = (d - dd) / 2
|
||||||
|
else:
|
||||||
|
Win_size = [int(d.get_height() * ratio[1]), d.get_height()]
|
||||||
|
d = pygame.display.get_surface().get_width()
|
||||||
|
dd = Win_size[0]
|
||||||
|
game.game_flow["dp"][0] = (d - dd) / 2
|
||||||
|
|
||||||
|
mouse.mouse_scroll = game.game_flow["dp"]
|
||||||
|
# specifics
|
||||||
|
mid_point_scroll_mouse = [game.game_flow["dp"][0] + (Win_size[0] / 2),
|
||||||
|
game.game_flow["dp"][1] + (Win_size[1] / 2)]
|
||||||
|
game.game_flow["scroll_length"] = (Win_size[0] - 60) / 2
|
||||||
|
|
||||||
|
if hashi.win is False:
|
||||||
|
if hashi.locked is False:
|
||||||
|
# mouse stuff
|
||||||
|
if event.type == MOUSEMOTION:
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
hashi.hover(mouse, scroll)
|
||||||
|
|
||||||
|
# click
|
||||||
|
elif event.type == MOUSEBUTTONDOWN:
|
||||||
|
hashi.click(mouse, scroll)
|
||||||
|
if hashi.locked:
|
||||||
|
soundsX["click"].play()
|
||||||
|
else:
|
||||||
|
if event.type == MOUSEMOTION:
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
|
||||||
|
elif event.type == MOUSEBUTTONDOWN:
|
||||||
|
hashi.locked = False
|
||||||
|
hashi.click_on_locked(mouse, scroll)
|
||||||
|
hashi.check_win()
|
||||||
|
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
hashi.hover(mouse, scroll)
|
||||||
|
else:
|
||||||
|
if event.type == MOUSEMOTION:
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
back_btn.hover_check(mouse.mouse_pos)
|
||||||
|
|
||||||
|
elif event.type == MOUSEBUTTONDOWN:
|
||||||
|
back_btn.click_check(mouse.mouse_pos)
|
||||||
|
|
||||||
|
# quiting on back button (same as esc)
|
||||||
|
|
||||||
|
if game.game_flow["quit"]:
|
||||||
|
gameMenu.fs = game.fs
|
||||||
|
gameMenu.game_flow["dp"] = game.game_flow["dp"]
|
||||||
|
gameMenu.game_flow["back_from_game"] = True
|
||||||
|
gameMenu.game_flow["Win_size"] = Win_size
|
||||||
|
game.alive = False
|
||||||
|
|
||||||
|
with open("assets/saves/setup.json", "w") as f:
|
||||||
|
json.dump(setup, f, indent=4)
|
||||||
|
|
||||||
|
# basic loop config
|
||||||
|
|
||||||
|
screenX.blit(pygame.transform.scale(display, Win_size), game.game_flow["dp"])
|
||||||
|
pygame.display.update()
|
||||||
|
clock.tick(60)
|
||||||
|
|
||||||
|
|
||||||
|
# tutorial
|
||||||
|
def run_tutorial(screenX, setup, gameMenu, palette, mouse):
|
||||||
|
game = Game()
|
||||||
|
game.game_flow["dp"] = gameMenu.game_flow["dp"]
|
||||||
|
game.fs = gameMenu.fs
|
||||||
|
Win_size = gameMenu.game_flow["Win_size"]
|
||||||
|
game.game_flow["scroll_length"] = (Win_size[0] - 60) / 2
|
||||||
|
game.game_flow["quit"] = False
|
||||||
|
game.game_flow["tf"] = False # tutorial forward
|
||||||
|
game.game_flow["t_step"] = 0
|
||||||
|
|
||||||
|
scroll = Scroll([-20, -20])
|
||||||
|
|
||||||
|
mid_point_scroll_mouse = [game.game_flow["dp"][0] + (Win_size[0] / 2),
|
||||||
|
game.game_flow["dp"][1] + (Win_size[1] / 2)]
|
||||||
|
|
||||||
|
back_btn = Button([200, 350], [200, 100], get_back_images(palette), go_back, [game])
|
||||||
|
win_image = get_win_image()
|
||||||
|
|
||||||
|
# initing rectangle effect
|
||||||
|
rE = Rectangle_effect
|
||||||
|
rE.generate_rects()
|
||||||
|
|
||||||
|
# initializing tutorial
|
||||||
|
hashi = hashi_game.HashiG("file.json", f"assets/tutorial/tutorial.json", palette, mouse)
|
||||||
|
|
||||||
|
hashi_top_lim = [(hashi.get_length() + 40) - 600, (hashi.get_length() + 40) - 650]
|
||||||
|
|
||||||
|
# preparing tutorial circle
|
||||||
|
tutorial_circle_images, size = get_tutorial_circle_images(math.sqrt(hashi.indent/hashi.indent_default)**1.5)
|
||||||
|
tutorial_circle = CircleButton(size, [120 - (size/2), 120 - (size/2)],
|
||||||
|
tutorial_circle_images, move_in_tutorial, [game])
|
||||||
|
|
||||||
|
# pre scrolling
|
||||||
|
scroll.move_scroll_based_on_pos(mouse.get_scrolled(scroll), [600, 650], "both", 40)
|
||||||
|
|
||||||
|
scroll.scroll_lim(scroll, [-40, -40], hashi_top_lim)
|
||||||
|
|
||||||
|
while game.alive:
|
||||||
|
# dealing with tutorial
|
||||||
|
if game.game_flow['tf']:
|
||||||
|
game.game_flow["tf"] = False
|
||||||
|
|
||||||
|
if game.game_flow["t_step"] == 0:
|
||||||
|
game.game_flow["t_step"] += 1
|
||||||
|
hashi.click(mouse, scroll)
|
||||||
|
tutorial_circle.move([0, 240])
|
||||||
|
tutorial_circle.hover_check(mouse.get_scrolled(scroll))
|
||||||
|
soundsX["click"].play()
|
||||||
|
|
||||||
|
elif game.game_flow["t_step"] == 1:
|
||||||
|
game.game_flow["t_step"] += 1
|
||||||
|
hashi.locked = False
|
||||||
|
hashi.click_on_locked(mouse, scroll)
|
||||||
|
hashi.check_win()
|
||||||
|
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
hashi.hover(mouse, scroll)
|
||||||
|
|
||||||
|
tutorial_circle.move([240, -240])
|
||||||
|
tutorial_circle.hover_check(mouse.get_scrolled(scroll))
|
||||||
|
soundsX["join"].play()
|
||||||
|
|
||||||
|
elif game.game_flow["t_step"] == 2:
|
||||||
|
game.game_flow["t_step"] += 1
|
||||||
|
hashi.click(mouse, scroll)
|
||||||
|
tutorial_circle.move([0, -60])
|
||||||
|
tutorial_circle.hover_check(mouse.get_scrolled(scroll))
|
||||||
|
soundsX["click"].play()
|
||||||
|
|
||||||
|
elif game.game_flow["t_step"] == 3:
|
||||||
|
game.game_flow["t_step"] += 1
|
||||||
|
hashi.locked = False
|
||||||
|
hashi.click_on_locked(mouse, scroll)
|
||||||
|
hashi.check_win()
|
||||||
|
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
hashi.hover(mouse, scroll)
|
||||||
|
|
||||||
|
tutorial_circle.move([0, -60])
|
||||||
|
tutorial_circle.hover_check(mouse.get_scrolled(scroll))
|
||||||
|
soundsX["join"].play()
|
||||||
|
|
||||||
|
elif game.game_flow["t_step"] == 4:
|
||||||
|
game.game_flow["t_step"] += 1
|
||||||
|
hashi.click(mouse, scroll)
|
||||||
|
tutorial_circle.move([-240, 0])
|
||||||
|
tutorial_circle.hover_check(mouse.get_scrolled(scroll))
|
||||||
|
soundsX["click"].play()
|
||||||
|
|
||||||
|
elif game.game_flow["t_step"] == 5:
|
||||||
|
hashi.locked = False
|
||||||
|
hashi.click_on_locked(mouse, scroll)
|
||||||
|
hashi.check_win()
|
||||||
|
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
hashi.hover(mouse, scroll)
|
||||||
|
soundsX["join"].play()
|
||||||
|
|
||||||
|
tutorial_circle.active = False
|
||||||
|
|
||||||
|
# dealing with hashi locked
|
||||||
|
if hashi.locked:
|
||||||
|
hashi.on_locked(mouse, scroll)
|
||||||
|
|
||||||
|
# background
|
||||||
|
display.fill(palette.palette["background"])
|
||||||
|
|
||||||
|
# dealing with bg effect
|
||||||
|
for item in rE.rects:
|
||||||
|
item.move(display, palette)
|
||||||
|
|
||||||
|
if rE.timer == 0:
|
||||||
|
rE.generate_rects(5, [1, 3])
|
||||||
|
rE.timer = 10
|
||||||
|
else:
|
||||||
|
rE.timer -= 1
|
||||||
|
|
||||||
|
# dealing with scroll
|
||||||
|
# not using mouse.mouse_pos because screen size affects
|
||||||
|
if distance_indicator(pygame.mouse.get_pos(), mid_point_scroll_mouse) > game.game_flow["scroll_length"]:
|
||||||
|
scroll.move_scroll_based_on_pos(mouse.get_scrolled(scroll), [600, 650], "both", 40)
|
||||||
|
|
||||||
|
scroll.scroll_lim(scroll, [-40, -40], hashi_top_lim)
|
||||||
|
|
||||||
|
# game
|
||||||
|
|
||||||
|
hashi.blit(display, palette, scroll)
|
||||||
|
|
||||||
|
# tutorial
|
||||||
|
|
||||||
|
tutorial_circle.blit(display, scroll)
|
||||||
|
|
||||||
|
# win screen
|
||||||
|
|
||||||
|
if hashi.win:
|
||||||
|
display.blit(win_image, [50, 50])
|
||||||
|
|
||||||
|
back_btn.blit(display)
|
||||||
|
|
||||||
|
setup["tutorial"] = False
|
||||||
|
|
||||||
|
# event loop
|
||||||
|
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == QUIT:
|
||||||
|
pygame.quit()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# keydown
|
||||||
|
if event.type == KEYDOWN:
|
||||||
|
if event.key == K_ESCAPE:
|
||||||
|
gameMenu.fs = game.fs
|
||||||
|
gameMenu.game_flow["dp"] = game.game_flow["dp"]
|
||||||
|
gameMenu.game_flow["back_from_game"] = True
|
||||||
|
gameMenu.game_flow["Win_size"] = Win_size
|
||||||
|
game.alive = False
|
||||||
|
|
||||||
|
with open("assets/saves/setup.json", "w") as f:
|
||||||
|
json.dump(setup, f, indent=4)
|
||||||
|
|
||||||
|
if event.key == K_f:
|
||||||
|
game.fs = not game.fs
|
||||||
|
if game.fs is False:
|
||||||
|
Win_size = Default_size
|
||||||
|
screenX = pygame.display.set_mode(Win_size)
|
||||||
|
game.game_flow["dp"] = [0, 0]
|
||||||
|
mouse.mouse_scroll = game.game_flow["dp"]
|
||||||
|
# specifics
|
||||||
|
mid_point_scroll_mouse = [game.game_flow["dp"][0] + (Win_size[0] / 2),
|
||||||
|
game.game_flow["dp"][1] + (Win_size[1] / 2)]
|
||||||
|
game.game_flow["scroll_length"] = (Win_size[0] - 100) / 2
|
||||||
|
|
||||||
|
else:
|
||||||
|
screenX = pygame.display.set_mode(monitor_size, pygame.FULLSCREEN)
|
||||||
|
d = screenX
|
||||||
|
ratio = [Default_size[1] / Default_size[0], Default_size[0] / Default_size[1]]
|
||||||
|
# u chose width or height here
|
||||||
|
|
||||||
|
if Default_size[0] > Default_size[1]:
|
||||||
|
Win_size = [d.get_width(), int(d.get_width() * ratio[0])]
|
||||||
|
d = d.get_height()
|
||||||
|
dd = Win_size[1]
|
||||||
|
game.game_flow["dp"][1] = (d - dd) / 2
|
||||||
|
else:
|
||||||
|
Win_size = [int(d.get_height() * ratio[1]), d.get_height()]
|
||||||
|
d = pygame.display.get_surface().get_width()
|
||||||
|
dd = Win_size[0]
|
||||||
|
game.game_flow["dp"][0] = (d - dd) / 2
|
||||||
|
|
||||||
|
mouse.mouse_scroll = game.game_flow["dp"]
|
||||||
|
# specifics
|
||||||
|
mid_point_scroll_mouse = [game.game_flow["dp"][0] + (Win_size[0] / 2),
|
||||||
|
game.game_flow["dp"][1] + (Win_size[1] / 2)]
|
||||||
|
game.game_flow["scroll_length"] = (Win_size[0] - 60) / 2
|
||||||
|
|
||||||
|
if hashi.win is False:
|
||||||
|
if hashi.locked is False:
|
||||||
|
# mouse stuff
|
||||||
|
if event.type == MOUSEMOTION:
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
hashi.hover(mouse, scroll)
|
||||||
|
tutorial_circle.hover_check(mouse.get_scrolled(scroll))
|
||||||
|
|
||||||
|
# click
|
||||||
|
elif event.type == MOUSEBUTTONDOWN:
|
||||||
|
tutorial_circle.click_check(mouse.get_scrolled(scroll))
|
||||||
|
else:
|
||||||
|
if event.type == MOUSEMOTION:
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
tutorial_circle.hover_check(mouse.get_scrolled(scroll))
|
||||||
|
|
||||||
|
elif event.type == MOUSEBUTTONDOWN:
|
||||||
|
tutorial_circle.click_check(mouse.get_scrolled(scroll))
|
||||||
|
else:
|
||||||
|
if event.type == MOUSEMOTION:
|
||||||
|
mouse.update(Win_size, Default_size)
|
||||||
|
back_btn.hover_check(mouse.mouse_pos)
|
||||||
|
|
||||||
|
elif event.type == MOUSEBUTTONDOWN:
|
||||||
|
back_btn.click_check(mouse.mouse_pos)
|
||||||
|
|
||||||
|
# quiting on back button (same as esc)
|
||||||
|
|
||||||
|
if game.game_flow["quit"]:
|
||||||
|
gameMenu.fs = game.fs
|
||||||
|
gameMenu.game_flow["dp"] = game.game_flow["dp"]
|
||||||
|
gameMenu.game_flow["back_from_game"] = True
|
||||||
|
gameMenu.game_flow["Win_size"] = Win_size
|
||||||
|
game.alive = False
|
||||||
|
|
||||||
|
with open("assets/saves/setup.json", "w") as f:
|
||||||
|
json.dump(setup, f, indent=4)
|
||||||
|
|
||||||
|
# basic loop config
|
||||||
|
|
||||||
|
screenX.blit(pygame.transform.scale(display, Win_size), game.game_flow["dp"])
|
||||||
|
pygame.display.update()
|
||||||
|
clock.tick(60)
|
||||||
|
|
||||||
|
|
||||||
|
main_menu(screen, Window_size)
|
BIN
assets/images/game/back.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
assets/images/game/back_hover.png
Normal file
After Width: | Height: | Size: 731 B |
BIN
assets/images/game/num_circle.png
Normal file
After Width: | Height: | Size: 352 B |
BIN
assets/images/game/num_circle_hover.png
Normal file
After Width: | Height: | Size: 279 B |
BIN
assets/images/game/tutorial_circle.png
Normal file
After Width: | Height: | Size: 281 B |
BIN
assets/images/game/tutorial_circle_hover.png
Normal file
After Width: | Height: | Size: 280 B |
BIN
assets/images/general/hashi_logo.ico
Normal file
After Width: | Height: | Size: 127 KiB |
BIN
assets/images/general/hashi_logo.png
Normal file
After Width: | Height: | Size: 99 KiB |
BIN
assets/images/menu/arrow.png
Normal file
After Width: | Height: | Size: 968 B |
BIN
assets/images/menu/arrow_hover.png
Normal file
After Width: | Height: | Size: 805 B |
BIN
assets/images/menu/continue.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
assets/images/menu/continue_hover.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
assets/images/menu/custom.png
Normal file
After Width: | Height: | Size: 918 B |
BIN
assets/images/menu/custom_pressed.png
Normal file
After Width: | Height: | Size: 522 B |
BIN
assets/images/menu/fs.png
Normal file
After Width: | Height: | Size: 586 B |
BIN
assets/images/menu/fs_hover.png
Normal file
After Width: | Height: | Size: 509 B |
BIN
assets/images/menu/ms.png
Normal file
After Width: | Height: | Size: 590 B |
BIN
assets/images/menu/ms_hover.png
Normal file
After Width: | Height: | Size: 521 B |
BIN
assets/images/menu/new_game.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
assets/images/menu/new_game_hover.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
assets/images/menu/palette.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
assets/images/menu/palette_hover.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
assets/images/menu/play.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
assets/images/menu/play_hover.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
assets/images/menu/template.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/images/menu/template_hover.png
Normal file
After Width: | Height: | Size: 560 B |
BIN
assets/images/menu/writing.png
Normal file
After Width: | Height: | Size: 370 B |
0
assets/maps/custom.txt
Normal file
0
assets/maps/easy.txt
Normal file
0
assets/maps/extreme.txt
Normal file
0
assets/maps/hard.txt
Normal file
0
assets/maps/medium.txt
Normal file
5
assets/maps/tutorial.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
0 1 0 0 0
|
||||||
|
0 0 0 1 0
|
||||||
|
0 0 0 0 0
|
||||||
|
0 3 0 5 1
|
||||||
|
2 0 0 3 0
|
BIN
assets/palettes/__pycache__/palette_manager.cpython-39.pyc
Normal file
6
assets/palettes/aqua.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{"background": "#59bdf7",
|
||||||
|
"backgroundShade": "#81ccf7",
|
||||||
|
"outline": "#268cc7",
|
||||||
|
"outline-shade": "#2ba0e3",
|
||||||
|
"addition": "#1575ad",
|
||||||
|
"outline-dark": "#09517a"}
|
6
assets/palettes/emerald.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{"background": "#75ebc2",
|
||||||
|
"backgroundShade": "#4debb4",
|
||||||
|
"outline": "#9baba5",
|
||||||
|
"outline-shade": "#81a195",
|
||||||
|
"addition": "#07db91",
|
||||||
|
"outline-dark": "#60716a"}
|
6
assets/palettes/lavender.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{"background": "#8818c9",
|
||||||
|
"backgroundShade": "#8425ba",
|
||||||
|
"outline": "#dd26e0",
|
||||||
|
"outline-shade": "#7e38a6",
|
||||||
|
"addition": "#a716fa",
|
||||||
|
"outline-dark": "#5b1485"}
|
71
assets/palettes/palette_manager.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import os
|
||||||
|
import json
|
||||||
|
import pygame
|
||||||
|
from itertools import cycle
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
|
||||||
|
class Palettes:
|
||||||
|
def __init__(self, path):
|
||||||
|
self.path = path
|
||||||
|
self.palettes = {}
|
||||||
|
self.current_palette = "emerald" # set starting palette here
|
||||||
|
self.load_palettes()
|
||||||
|
self.palette = self.get_palette()
|
||||||
|
self.cycle = None
|
||||||
|
self.changed = False
|
||||||
|
|
||||||
|
def load_palettes(self):
|
||||||
|
current_dir = os.getcwd()
|
||||||
|
os.chdir(self.path)
|
||||||
|
files = os.listdir()
|
||||||
|
files.remove('palette_manager.py')
|
||||||
|
try:
|
||||||
|
files.remove("__pycache__")
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
with open(file, "r") as f:
|
||||||
|
fileX = json.load(f)
|
||||||
|
|
||||||
|
for color in fileX.keys():
|
||||||
|
fileX[color] = self.rgb(fileX[color])
|
||||||
|
|
||||||
|
file = "".join(list(file)[:-5])
|
||||||
|
|
||||||
|
self.palettes[file] = fileX
|
||||||
|
|
||||||
|
os.chdir(current_dir)
|
||||||
|
|
||||||
|
def get_palette(self):
|
||||||
|
return self.palettes[self.current_palette]
|
||||||
|
|
||||||
|
def swap_image(self, image, old_p, new_p):
|
||||||
|
for color in self.palettes[old_p].keys():
|
||||||
|
image = swap_color(image, self.palettes[old_p][color], self.palettes[new_p][color])
|
||||||
|
|
||||||
|
return image
|
||||||
|
|
||||||
|
def create_cycle(self):
|
||||||
|
names = self.palettes.keys()
|
||||||
|
self.cycle = cycle(names)
|
||||||
|
while next(self.cycle) != self.current_palette:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def rgb(color):
|
||||||
|
color = color.strip("#")
|
||||||
|
color = [int(color[i:i+2], 16) for i in range(0, 5, 2)]
|
||||||
|
return color
|
||||||
|
|
||||||
|
|
||||||
|
def swap_color(imageX, old, new):
|
||||||
|
image_copy = pygame.Surface(imageX.copy().get_size())
|
||||||
|
image_copy.fill(new)
|
||||||
|
|
||||||
|
imageX.set_colorkey(old)
|
||||||
|
|
||||||
|
image_copy.blit(imageX, [0, 0])
|
||||||
|
|
||||||
|
return image_copy
|
6
assets/palettes/reddish.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{"background": "#c9c5c5",
|
||||||
|
"backgroundShade": "#a3a0a0",
|
||||||
|
"outline": "#9e2929",
|
||||||
|
"outline-shade": "#8f6565",
|
||||||
|
"addition": "#a83939",
|
||||||
|
"outline-dark": "#610e0e"}
|
6
assets/palettes/sakura.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{"background": "#ff87df",
|
||||||
|
"backgroundShade": "#f7b2e5",
|
||||||
|
"outline": "#d94db4",
|
||||||
|
"outline-shade": "#fe75db",
|
||||||
|
"addition": "#eb3bbc",
|
||||||
|
"outline-dark": "#97316b"}
|
6
assets/palettes/vanilla.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{"background": "#faf9de",
|
||||||
|
"backgroundShade": "#f2f2df",
|
||||||
|
"outline": "#c7c689",
|
||||||
|
"outline-shade": "#ccca5e",
|
||||||
|
"addition": "#fffd6e",
|
||||||
|
"outline-dark": "#474731"}
|
11
assets/saves/default.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"difficulty": "easy",
|
||||||
|
"palette": "emerald",
|
||||||
|
"tutorial": true,
|
||||||
|
"easy": false,
|
||||||
|
"medium": false,
|
||||||
|
"hard": false,
|
||||||
|
"extreme": false,
|
||||||
|
"custom": false,
|
||||||
|
"custom_num": "22"
|
||||||
|
}
|
1
assets/saves/game_saves/custom.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
1
assets/saves/game_saves/easy.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
1
assets/saves/game_saves/extreme.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
1
assets/saves/game_saves/hard.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
1
assets/saves/game_saves/medium.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{}
|
11
assets/saves/setup.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"difficulty": "easy",
|
||||||
|
"palette": "emerald",
|
||||||
|
"tutorial": true,
|
||||||
|
"easy": false,
|
||||||
|
"medium": false,
|
||||||
|
"hard": false,
|
||||||
|
"extreme": false,
|
||||||
|
"custom": false,
|
||||||
|
"custom_num": "22"
|
||||||
|
}
|
BIN
assets/sounds/click.wav
Normal file
BIN
assets/sounds/join.wav
Normal file
BIN
assets/sounds/remove.wav
Normal file
239
assets/tutorial/tutorial.json
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
{
|
||||||
|
"difficulty": "tutorial",
|
||||||
|
"connections": [
|
||||||
|
{
|
||||||
|
"pos": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"bridges": [
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 1,
|
||||||
|
"connection": [
|
||||||
|
3,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bridge_occupied": 1,
|
||||||
|
"locked": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pos": [
|
||||||
|
1,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"locked": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pos": [
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"bridges": [
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 2,
|
||||||
|
"connection": [
|
||||||
|
3,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bridge_occupied": 2,
|
||||||
|
"locked": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pos": [
|
||||||
|
1,
|
||||||
|
4
|
||||||
|
],
|
||||||
|
"bridges": [
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bridge_occupied": 0,
|
||||||
|
"locked": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pos": [
|
||||||
|
2,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"locked": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pos": [
|
||||||
|
2,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"locked": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pos": [
|
||||||
|
3,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"bridges": [
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 1,
|
||||||
|
"connection": [
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bridge_occupied": 1,
|
||||||
|
"locked": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pos": [
|
||||||
|
3,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"bridges": [
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 1,
|
||||||
|
"connection": [
|
||||||
|
3,
|
||||||
|
3
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 1,
|
||||||
|
"connection": [
|
||||||
|
4,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 2,
|
||||||
|
"connection": [
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bridge_occupied": 4,
|
||||||
|
"locked": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pos": [
|
||||||
|
3,
|
||||||
|
2
|
||||||
|
],
|
||||||
|
"locked": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pos": [
|
||||||
|
3,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"bridges": [
|
||||||
|
{
|
||||||
|
"bridge_num": 1,
|
||||||
|
"connection": [
|
||||||
|
3,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bridge_occupied": 1,
|
||||||
|
"locked": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pos": [
|
||||||
|
4,
|
||||||
|
1
|
||||||
|
],
|
||||||
|
"bridges": [
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 0,
|
||||||
|
"connection": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"bridge_num": 1,
|
||||||
|
"connection": [
|
||||||
|
3,
|
||||||
|
1
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bridge_occupied": 1,
|
||||||
|
"locked": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
51
game_effect.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import pygame
|
||||||
|
import random
|
||||||
|
|
||||||
|
import pygame
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
class Rectangle_effect:
|
||||||
|
rects = []
|
||||||
|
timer = 0
|
||||||
|
|
||||||
|
def __init__(self, pos, size, speed, dirs):
|
||||||
|
self.pos = pos
|
||||||
|
self.size = size
|
||||||
|
self.speed = speed
|
||||||
|
self.dirs = dirs # True for going up False for down
|
||||||
|
|
||||||
|
def move(self, display, palette):
|
||||||
|
sur = pygame.Surface(self.size)
|
||||||
|
sur.fill(palette.palette["backgroundShade"])
|
||||||
|
sur.set_alpha(random.randint(100, 200))
|
||||||
|
display.blit(sur, self.pos)
|
||||||
|
|
||||||
|
if self.dirs[0]:
|
||||||
|
self.pos[1] -= self.speed
|
||||||
|
elif self.dirs[1]:
|
||||||
|
self.pos[1] += self.speed
|
||||||
|
elif self.dirs[2]:
|
||||||
|
self.pos[0] += self.speed
|
||||||
|
elif self.dirs[3]:
|
||||||
|
self.pos[0] -= self.speed
|
||||||
|
|
||||||
|
if self.pos[1] < -120 or self.pos[0] > 600 or self.pos[1] > 650 or self.pos[0] < -120:
|
||||||
|
self.delete(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def generate_rects(cls, amount=100, speed_range=None):
|
||||||
|
if speed_range is None:
|
||||||
|
speed_range = [1, 4]
|
||||||
|
|
||||||
|
for _ in range(amount):
|
||||||
|
dirs = [0, 0, 0, 0]
|
||||||
|
dirs[random.randint(0, 3)] = 1
|
||||||
|
cls.rects.append(Rectangle_effect([random.randint(0, 600), random.randint(0, 650)],
|
||||||
|
[random.randint(40, 120), random.randint(40, 120)],
|
||||||
|
random.randint(speed_range[0], speed_range[1]),
|
||||||
|
dirs))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def delete(cls, circle):
|
||||||
|
cls.rects.remove(circle)
|
9
garbage.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
def get_result(size):
|
||||||
|
size += 1 # increasing to get away from 0
|
||||||
|
x = [1 for _ in range(size)]
|
||||||
|
for i in range(size - 1): # getting original size
|
||||||
|
x = [sum(x[:i+1]) for i in range(size)]
|
||||||
|
print(x[-1])
|
||||||
|
|
||||||
|
|
||||||
|
get_result(20)
|
229
hashi_functions.py
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
import json
|
||||||
|
import pygame
|
||||||
|
import sounds
|
||||||
|
|
||||||
|
# basic config
|
||||||
|
pygame.mixer.pre_init(48000, -16, 2, 512)
|
||||||
|
pygame.init()
|
||||||
|
pygame.mixer.set_num_channels(16)
|
||||||
|
|
||||||
|
font = pygame.font.SysFont('calibri', 60, True)
|
||||||
|
small_font = pygame.font.SysFont('calibri', 40, True)
|
||||||
|
tiny_font = pygame.font.SysFont('calibri', 20, True)
|
||||||
|
|
||||||
|
soundsX = sounds.get_sounds()
|
||||||
|
|
||||||
|
|
||||||
|
def set_palette(setup, palette, name_of_new_palette, menu_objects, first=False):
|
||||||
|
if first:
|
||||||
|
old_palette = "emerald"
|
||||||
|
else:
|
||||||
|
old_palette = setup["palette"]
|
||||||
|
palette.current_palette = name_of_new_palette
|
||||||
|
palette.palette = palette.get_palette()
|
||||||
|
|
||||||
|
# saving new json
|
||||||
|
setup["palette"] = name_of_new_palette
|
||||||
|
with open("assets/saves/setup.json", "w") as f:
|
||||||
|
json.dump(setup, f, indent=4)
|
||||||
|
|
||||||
|
# iterates over images and sets new palette
|
||||||
|
for obj in range(len(menu_objects)):
|
||||||
|
for img in menu_objects[obj].images.keys():
|
||||||
|
menu_objects[obj].images[img] = palette.swap_image(menu_objects[obj].images[img],
|
||||||
|
old_palette, name_of_new_palette)
|
||||||
|
menu_objects[obj].images[img].set_colorkey((0, 0, 0))
|
||||||
|
menu_objects[obj].display_image = palette.swap_image(menu_objects[obj].display_image,
|
||||||
|
old_palette, name_of_new_palette)
|
||||||
|
menu_objects[obj].display_image.set_colorkey((0, 0, 0))
|
||||||
|
|
||||||
|
return menu_objects, setup
|
||||||
|
|
||||||
|
|
||||||
|
# function for palette btn
|
||||||
|
def next_palette(palette):
|
||||||
|
palette = palette[0]
|
||||||
|
palette.current_palette = next(palette.cycle)
|
||||||
|
palette.changed = True
|
||||||
|
soundsX["click"].play()
|
||||||
|
|
||||||
|
|
||||||
|
# function for right arrow
|
||||||
|
def right_arrow(game):
|
||||||
|
game = game[0]
|
||||||
|
index = game.game_flow["dfs"].index(game.game_flow["df"])
|
||||||
|
if index != len(game.game_flow["dfs"]) - 1:
|
||||||
|
game.game_flow["df"] = game.game_flow["dfs"][index + 1]
|
||||||
|
game.game_flow["df_change"] = True
|
||||||
|
soundsX["click"].play()
|
||||||
|
|
||||||
|
|
||||||
|
# function for left arrow
|
||||||
|
def left_arrow(game):
|
||||||
|
game = game[0]
|
||||||
|
index = game.game_flow["dfs"].index(game.game_flow["df"])
|
||||||
|
if index != 0:
|
||||||
|
game.game_flow["df"] = game.game_flow["dfs"][index - 1]
|
||||||
|
game.game_flow["df_change"] = True
|
||||||
|
soundsX["click"].play()
|
||||||
|
|
||||||
|
|
||||||
|
# input
|
||||||
|
def activate_edit_text(game):
|
||||||
|
game[0].game_flow["ac"] = False
|
||||||
|
soundsX["click"].play()
|
||||||
|
|
||||||
|
|
||||||
|
def update_text(menu_objects, setup, game, palette):
|
||||||
|
custom_text = font.render(game.game_flow["custom_string"], False,
|
||||||
|
palette.palette["outline-dark"])
|
||||||
|
custom_text_hover = font.render(game.game_flow["custom_string"], False,
|
||||||
|
palette.palette["background"])
|
||||||
|
ct_images = {"idle": create_text_sur(custom_text, [20, 20], [100, 100]),
|
||||||
|
"hover": create_text_sur(custom_text_hover, [20, 20], [100, 100])}
|
||||||
|
for image in ct_images.keys():
|
||||||
|
ct_images[image].set_colorkey((0, 0, 0))
|
||||||
|
|
||||||
|
for item in range(len(menu_objects)):
|
||||||
|
if menu_objects[item].on_click == activate_edit_text:
|
||||||
|
if menu_objects[item].name == "custom_text":
|
||||||
|
menu_objects[item].images = ct_images
|
||||||
|
menu_objects[item].display_image = ct_images["hover"]
|
||||||
|
|
||||||
|
# saving json
|
||||||
|
setup["custom_num"] = game.game_flow["custom_string"]
|
||||||
|
with open("assets/saves/setup.json", "w") as f:
|
||||||
|
json.dump(setup, f, indent=4)
|
||||||
|
|
||||||
|
return menu_objects, setup
|
||||||
|
|
||||||
|
|
||||||
|
def create_text_sur(text, pos, size):
|
||||||
|
sur = pygame.Surface(size)
|
||||||
|
sur.fill((0, 0, 0))
|
||||||
|
sur.blit(text, pos)
|
||||||
|
return sur
|
||||||
|
|
||||||
|
|
||||||
|
def get_num_circles(palette, size_multiplier=1):
|
||||||
|
circle_num = pygame.image.load("assets/images/game/num_circle.png").convert()
|
||||||
|
circle_num_hover = pygame.image.load("assets/images/game/num_circle_hover.png").convert()
|
||||||
|
|
||||||
|
circle_num = palette.swap_image(circle_num, "emerald", palette.current_palette)
|
||||||
|
circle_num_hover = palette.swap_image(circle_num_hover, "emerald", palette.current_palette)
|
||||||
|
|
||||||
|
nums = [tiny_font.render(str(num), False, palette.palette["outline-dark"]) for num in range(1, 9)]
|
||||||
|
for i in range(len(nums)):
|
||||||
|
nums[i] = create_text_sur(nums[i], [10, 6], [30, 30])
|
||||||
|
nums[i].set_colorkey((0, 0, 0))
|
||||||
|
|
||||||
|
num_dict = {}
|
||||||
|
|
||||||
|
size = 0
|
||||||
|
for i in range(len(nums)):
|
||||||
|
cn = circle_num.copy()
|
||||||
|
cnh = circle_num_hover.copy()
|
||||||
|
|
||||||
|
cn.blit(nums[i], [0, 0])
|
||||||
|
cnh.blit(nums[i], [0, 0])
|
||||||
|
|
||||||
|
cn.set_colorkey((0, 0, 0))
|
||||||
|
cnh.set_colorkey((0, 0, 0))
|
||||||
|
|
||||||
|
size = int(30 * size_multiplier)
|
||||||
|
cn = pygame.transform.scale(cn, [size for _ in range(2)])
|
||||||
|
cnh = pygame.transform.scale(cnh, [size for _ in range(2)])
|
||||||
|
|
||||||
|
num_dict[str(i + 1)] = {"idle": cn,
|
||||||
|
"hover": cnh}
|
||||||
|
|
||||||
|
return num_dict, size
|
||||||
|
|
||||||
|
|
||||||
|
def get_images(palette, size):
|
||||||
|
circle_num = pygame.image.load("assets/images/game/num_circle.png").convert()
|
||||||
|
circle_num_hover = pygame.image.load("assets/images/game/num_circle_hover.png").convert()
|
||||||
|
|
||||||
|
circle_num = palette.swap_image(circle_num, "emerald", palette.current_palette)
|
||||||
|
circle_num_hover = palette.swap_image(circle_num_hover, "emerald", palette.current_palette)
|
||||||
|
|
||||||
|
nums = [tiny_font.render(str(num), False, palette.palette["backgroundShade"]) for num in range(1, 9)]
|
||||||
|
for i in range(len(nums)):
|
||||||
|
nums[i] = create_text_sur(nums[i], [10, 6], [30, 30])
|
||||||
|
nums[i].set_colorkey((0, 0, 0))
|
||||||
|
|
||||||
|
num_dict = {}
|
||||||
|
|
||||||
|
for i in range(len(nums)):
|
||||||
|
cn = circle_num.copy()
|
||||||
|
cnh = circle_num_hover.copy()
|
||||||
|
|
||||||
|
cn.blit(nums[i], [0, 0])
|
||||||
|
cnh.blit(nums[i], [0, 0])
|
||||||
|
|
||||||
|
cn.set_colorkey((0, 0, 0))
|
||||||
|
cnh.set_colorkey((0, 0, 0))
|
||||||
|
|
||||||
|
cn = pygame.transform.scale(cn, [size for _ in range(2)])
|
||||||
|
cnh = pygame.transform.scale(cnh, [size for _ in range(2)])
|
||||||
|
|
||||||
|
num_dict[str(i + 1)] = {"idle": cn,
|
||||||
|
"hover": cnh}
|
||||||
|
|
||||||
|
return num_dict
|
||||||
|
|
||||||
|
|
||||||
|
def get_back_images(palette):
|
||||||
|
back_images = {"idle": pygame.image.load("assets/images/game/back.png").convert(),
|
||||||
|
"hover": pygame.image.load("assets/images/game/back_hover.png").convert()}
|
||||||
|
|
||||||
|
for image in back_images.keys():
|
||||||
|
back_images[image] = palette.swap_image(back_images[image], "emerald", palette.current_palette)
|
||||||
|
back_images[image].set_colorkey((0, 0, 0))
|
||||||
|
|
||||||
|
return back_images
|
||||||
|
|
||||||
|
|
||||||
|
def get_win_image():
|
||||||
|
surf = pygame.Surface([500, 550])
|
||||||
|
surf.fill((80, 80, 80))
|
||||||
|
surf.set_alpha(180)
|
||||||
|
|
||||||
|
text = font.render("Congratulations!", False, (10, 10, 10))
|
||||||
|
surf.blit(text, [60, 120])
|
||||||
|
|
||||||
|
return surf
|
||||||
|
|
||||||
|
|
||||||
|
def go_back(args):
|
||||||
|
game = args[0]
|
||||||
|
|
||||||
|
game.game_flow["quit"] = True
|
||||||
|
soundsX["click"].play()
|
||||||
|
|
||||||
|
|
||||||
|
def change_fs(args):
|
||||||
|
args[0].game_flow["change_fs"] = True
|
||||||
|
soundsX["click"].play()
|
||||||
|
|
||||||
|
|
||||||
|
def get_tutorial_circle_images(size_multiplier):
|
||||||
|
tutorial_circle_images = {"idle": pygame.image.load("assets/images/game/tutorial_circle.png").convert(),
|
||||||
|
"hover": pygame.image.load("assets/images/game/tutorial_circle_hover.png").convert()}
|
||||||
|
|
||||||
|
size = int(30 * size_multiplier)
|
||||||
|
|
||||||
|
for image in tutorial_circle_images.keys():
|
||||||
|
tutorial_circle_images[image].set_alpha(120)
|
||||||
|
tutorial_circle_images[image].set_colorkey((0, 0, 0))
|
||||||
|
tutorial_circle_images[image] = pygame.transform.scale(tutorial_circle_images[image], [size for _ in range(2)])
|
||||||
|
|
||||||
|
return tutorial_circle_images, size
|
||||||
|
|
||||||
|
|
||||||
|
def move_in_tutorial(args):
|
||||||
|
args[0].game_flow["tf"] = True
|
||||||
|
|
||||||
|
|
||||||
|
def play_click_sound(args):
|
||||||
|
soundsX["click"].play()
|
933
hashi_game.py
Normal file
@ -0,0 +1,933 @@
|
|||||||
|
import json
|
||||||
|
import sounds
|
||||||
|
import widget_engine as wg
|
||||||
|
from hashi_functions import get_num_circles
|
||||||
|
from hashi_functions import get_images
|
||||||
|
import pygame
|
||||||
|
import math
|
||||||
|
import copy
|
||||||
|
|
||||||
|
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
soundsX = sounds.get_sounds()
|
||||||
|
|
||||||
|
|
||||||
|
class HashiG:
|
||||||
|
|
||||||
|
def __init__(self, load_from_where, load_path, palette, mouse):
|
||||||
|
# creating variables
|
||||||
|
self.map = []
|
||||||
|
self.size = None
|
||||||
|
self.indent = 40
|
||||||
|
self.indent_default = 40
|
||||||
|
self.node_count = 0
|
||||||
|
self.win = False
|
||||||
|
|
||||||
|
# for nodes
|
||||||
|
self.locked = False
|
||||||
|
self.c_node = None
|
||||||
|
self.temp_done = [0, 0, 0, 0]
|
||||||
|
self.temp_removed = [0, 0, 0, 0]
|
||||||
|
self.s_node = None
|
||||||
|
|
||||||
|
# loading game
|
||||||
|
if load_from_where == "file.txt":
|
||||||
|
self.load_from_file(load_path, palette)
|
||||||
|
elif load_from_where == "file.json":
|
||||||
|
self.load_game(load_path, palette, mouse)
|
||||||
|
|
||||||
|
self.set_size()
|
||||||
|
self.line_width = int(self.indent / 12) + 1
|
||||||
|
|
||||||
|
def load_from_file(self, path, palette):
|
||||||
|
with open(path, "r") as f:
|
||||||
|
file = f.read()
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
file = file.split("\n")
|
||||||
|
del file[-1]
|
||||||
|
|
||||||
|
# init blank map
|
||||||
|
self.size = len(file)
|
||||||
|
self.map = [[NodeG([x, y]) for y in range(len(file))] for x in range(len(file))]
|
||||||
|
self.set_size()
|
||||||
|
|
||||||
|
# getting images
|
||||||
|
images, widget_size = get_num_circles(palette, math.sqrt(self.indent/self.indent_default)**1.5)
|
||||||
|
switch_images = get_images(palette, widget_size)
|
||||||
|
|
||||||
|
# reversing to get back into our format
|
||||||
|
file = file[::-1]
|
||||||
|
file = [x.split() for x in file]
|
||||||
|
for y in range(len(file)):
|
||||||
|
for x in range(len(file[y])):
|
||||||
|
node = self.map[x][y]
|
||||||
|
node.bridge_num = int(file[y][x])
|
||||||
|
if int(file[y][x]) != 0:
|
||||||
|
# if its node and not blank
|
||||||
|
|
||||||
|
node.locked = True
|
||||||
|
node.widget = wg.CircleButton(widget_size, [0, 0],
|
||||||
|
images[file[y][x]], self.lock, [node])
|
||||||
|
node.widget.switch_images = switch_images[file[y][x]]
|
||||||
|
self.node_count += 1
|
||||||
|
|
||||||
|
def load_game(self, path, palette, mouse):
|
||||||
|
|
||||||
|
with open(path, "r") as f:
|
||||||
|
save = json.load(f)
|
||||||
|
|
||||||
|
self.load_from_file(f"assets/maps/{save['difficulty']}.txt", palette)
|
||||||
|
|
||||||
|
for connection in save["connections"]:
|
||||||
|
# also bridge_occupied
|
||||||
|
if self.map[connection["pos"][0]][connection["pos"][1]].bridge_num != 0:
|
||||||
|
self.map[connection["pos"][0]][connection["pos"][1]].bridges = connection["bridges"]
|
||||||
|
self.map[connection["pos"][0]][connection["pos"][1]].bridge_occupied = connection["bridge_occupied"]
|
||||||
|
self.map[connection["pos"][0]][connection["pos"][1]].locked = connection["locked"]
|
||||||
|
if self.map[connection["pos"][0]][connection["pos"][1]].bridge_occupied == self.map[connection["pos"][0]][connection["pos"][1]].bridge_num:
|
||||||
|
if self.map[connection["pos"][0]][connection["pos"][1]].widget is not None:
|
||||||
|
self.map[connection["pos"][0]][connection["pos"][1]].widget.switch(mouse.mouse_pos)
|
||||||
|
else:
|
||||||
|
self.map[connection["pos"][0]][connection["pos"][1]].locked = connection["locked"]
|
||||||
|
|
||||||
|
def blit(self, display, palette, scroll):
|
||||||
|
# grid
|
||||||
|
for lines in range(self.size):
|
||||||
|
pygame.draw.line(display, palette.palette["outline-shade"],
|
||||||
|
[(lines * self.indent) - scroll.scroll[0],
|
||||||
|
0 - scroll.scroll[1]],
|
||||||
|
[(lines * self.indent) - scroll.scroll[0],
|
||||||
|
((self.size - 1) * self.indent) - scroll.scroll[1]], self.line_width)
|
||||||
|
pygame.draw.line(display, palette.palette["outline-shade"],
|
||||||
|
[0 - scroll.scroll[0],
|
||||||
|
(lines * self.indent) - scroll.scroll[1]],
|
||||||
|
[((self.size - 1) * self.indent) - scroll.scroll[0],
|
||||||
|
(lines * self.indent) - scroll.scroll[1]], self.line_width)
|
||||||
|
|
||||||
|
# connections
|
||||||
|
for x in range(self.size):
|
||||||
|
for y in range(self.size):
|
||||||
|
for connection in self.map[x][y].bridges:
|
||||||
|
if connection["connection"] is not None:
|
||||||
|
if connection["bridge_num"] == 1:
|
||||||
|
node = self.map[x][y]
|
||||||
|
target = self.map[connection["connection"][0]][connection["connection"][1]]
|
||||||
|
pygame.draw.line(display, palette.palette["addition"],
|
||||||
|
[(node.pos[0] * self.indent) - scroll.scroll[0],
|
||||||
|
(node.pos[1] * self.indent) - scroll.scroll[1]],
|
||||||
|
[(target.pos[0] * self.indent) - scroll.scroll[0],
|
||||||
|
(target.pos[1] * self.indent) - scroll.scroll[1]],
|
||||||
|
self.line_width + 1)
|
||||||
|
elif connection["bridge_num"] == 2:
|
||||||
|
node = self.map[x][y]
|
||||||
|
target = self.map[connection["connection"][0]][connection["connection"][1]]
|
||||||
|
pygame.draw.line(display, palette.palette["outline-dark"],
|
||||||
|
[(node.pos[0] * self.indent) - scroll.scroll[0],
|
||||||
|
(node.pos[1] * self.indent) - scroll.scroll[1]],
|
||||||
|
[(target.pos[0] * self.indent) - scroll.scroll[0],
|
||||||
|
(target.pos[1] * self.indent) - scroll.scroll[1]],
|
||||||
|
int((self.line_width * 1.4) + 1))
|
||||||
|
|
||||||
|
# dealing with nodes
|
||||||
|
for x in range(self.size):
|
||||||
|
for y in range(self.size):
|
||||||
|
if self.map[x][y].widget is not None:
|
||||||
|
node = self.map[x][y]
|
||||||
|
node.widget.pos = [(node.pos[0] * self.indent) - node.widget.radius,
|
||||||
|
(node.pos[1] * self.indent) - node.widget.radius]
|
||||||
|
node.widget.center = [node.widget.pos[0] + node.widget.radius,
|
||||||
|
node.widget.pos[1] + node.widget.radius]
|
||||||
|
node.widget.blit(display, scroll)
|
||||||
|
|
||||||
|
def hover(self, mouse, scroll):
|
||||||
|
ms = mouse.get_scrolled(scroll)
|
||||||
|
|
||||||
|
for y in range(self.size):
|
||||||
|
for x in range(self.size):
|
||||||
|
if self.map[x][y].widget is not None:
|
||||||
|
self.map[x][y].widget.hover_check(ms)
|
||||||
|
|
||||||
|
def click(self, mouse, scroll):
|
||||||
|
ms = mouse.get_scrolled(scroll)
|
||||||
|
|
||||||
|
for y in range(self.size):
|
||||||
|
for x in range(self.size):
|
||||||
|
if self.map[x][y].widget is not None:
|
||||||
|
self.map[x][y].widget.click_check(ms)
|
||||||
|
|
||||||
|
def on_locked(self, mouse, scroll):
|
||||||
|
ms = mouse.get_scrolled(scroll)
|
||||||
|
cords = self.c_node.pos
|
||||||
|
|
||||||
|
dists = [ms[0] - self.c_node.widget.center[0],
|
||||||
|
ms[1] - self.c_node.widget.center[1]]
|
||||||
|
da = list(map(abs, dists))
|
||||||
|
self.clear_temp()
|
||||||
|
self.clear_temp_remove()
|
||||||
|
|
||||||
|
# if we still can add bridges
|
||||||
|
if self.c_node.bridge_occupied < self.c_node.bridge_num:
|
||||||
|
|
||||||
|
# if we move out mouse more on x
|
||||||
|
if da[0] > da[1]:
|
||||||
|
if dists[0] > 0:
|
||||||
|
# here we do in case we move right
|
||||||
|
|
||||||
|
self.__right(cords)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# here we do in case we move left
|
||||||
|
|
||||||
|
self.__left(cords)
|
||||||
|
else:
|
||||||
|
|
||||||
|
if dists[1] > 0:
|
||||||
|
# here we do in case we move down
|
||||||
|
|
||||||
|
self.__down(cords)
|
||||||
|
else:
|
||||||
|
# here we do in case we go up
|
||||||
|
|
||||||
|
self.__up(cords)
|
||||||
|
# removing bridges here
|
||||||
|
else:
|
||||||
|
if da[0] > da[1]:
|
||||||
|
if dists[0] > 0:
|
||||||
|
# here we do in case we move right
|
||||||
|
|
||||||
|
if self.c_node.bridges[2]["bridge_num"] != 2:
|
||||||
|
for i in range(1, self.size):
|
||||||
|
if cords[0] + i < self.size:
|
||||||
|
if self.map[cords[0] + i][cords[1]].locked is False:
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.map[cords[0] + i][cords[1]].pos == self.c_node.bridges[2]["connection"]:
|
||||||
|
# connect
|
||||||
|
self.s_node = self.map[cords[0] + i][cords[1]]
|
||||||
|
|
||||||
|
self.c_node.bridges[2]["bridge_num"] -= 1
|
||||||
|
self.s_node.bridges[3]["bridge_num"] -= 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[2]["bridge_num"] == -1:
|
||||||
|
self.c_node.bridges[2]["bridge_num"] = 0
|
||||||
|
self.s_node.bridges[3]["bridge_num"] = 0
|
||||||
|
break
|
||||||
|
|
||||||
|
self.temp_removed[2] = 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[2]["bridge_num"] == 0:
|
||||||
|
self.c_node.bridges[2] = {"bridge_num": 0, "connection": True}
|
||||||
|
self.s_node.bridges[3] = {"bridge_num": 0, "connection": True}
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if self.c_node.bridges[2]["connection"] is not None and self.map[cords[0] + i][cords[1]].bridge_occupied == 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.__right(cords)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# here we do in case we move left
|
||||||
|
|
||||||
|
if self.c_node.bridges[3]["bridge_num"] != 2:
|
||||||
|
for i in range(1, self.size):
|
||||||
|
if cords[0] - i > -1:
|
||||||
|
if self.map[cords[0] - i][cords[1]].locked is False:
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.map[cords[0] - i][cords[1]].pos == self.c_node.bridges[3]["connection"]:
|
||||||
|
# connect
|
||||||
|
self.s_node = self.map[cords[0] - i][cords[1]]
|
||||||
|
|
||||||
|
self.c_node.bridges[3]["bridge_num"] -= 1
|
||||||
|
self.s_node.bridges[2]["bridge_num"] -= 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[3]["bridge_num"] == -1:
|
||||||
|
self.c_node.bridges[3]["bridge_num"] = 0
|
||||||
|
self.s_node.bridges[2]["bridge_num"] = 0
|
||||||
|
break
|
||||||
|
|
||||||
|
self.temp_removed[3] = 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[3]["bridge_num"] == 0:
|
||||||
|
self.c_node.bridges[3] = {"bridge_num": 0, "connection": True}
|
||||||
|
self.s_node.bridges[2] = {"bridge_num": 0, "connection": True}
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if self.c_node.bridges[3]["connection"] is not None and self.map[cords[0] - i][cords[1]].bridge_occupied == 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.__left(cords)
|
||||||
|
else:
|
||||||
|
|
||||||
|
if dists[1] > 0:
|
||||||
|
# here we do in case we move down
|
||||||
|
|
||||||
|
if self.c_node.bridges[1]["bridge_num"] != 2:
|
||||||
|
for i in range(1, self.size):
|
||||||
|
if cords[1] + i < self.size:
|
||||||
|
if self.map[cords[0]][cords[1] + i].locked is False:
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.map[cords[0]][cords[1] + i].pos == self.c_node.bridges[1]["connection"]:
|
||||||
|
# connect
|
||||||
|
self.s_node = self.map[cords[0]][cords[1] + i]
|
||||||
|
|
||||||
|
self.c_node.bridges[1]["bridge_num"] -= 1
|
||||||
|
self.s_node.bridges[0]["bridge_num"] -= 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[1]["bridge_num"] == -1:
|
||||||
|
self.c_node.bridges[1]["bridge_num"] = 0
|
||||||
|
self.s_node.bridges[0]["bridge_num"] = 0
|
||||||
|
break
|
||||||
|
|
||||||
|
self.temp_removed[1] = 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[1]["bridge_num"] == 0:
|
||||||
|
self.c_node.bridges[1] = {"bridge_num": 0, "connection": True}
|
||||||
|
self.s_node.bridges[0] = {"bridge_num": 0, "connection": True}
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if self.c_node.bridges[1]["connection"] is not None and self.map[cords[0]][cords[1] + i].bridge_occupied == 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.__down(cords)
|
||||||
|
else:
|
||||||
|
# here we do in case we go up
|
||||||
|
|
||||||
|
if self.c_node.bridges[0]["bridge_num"] != 2:
|
||||||
|
for i in range(1, self.size):
|
||||||
|
if cords[1] - i > -1:
|
||||||
|
if self.map[cords[0]][cords[1] - i].locked is False:
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.map[cords[0]][cords[1] - i].pos == self.c_node.bridges[0]["connection"]:
|
||||||
|
# connect
|
||||||
|
self.s_node = self.map[cords[0]][cords[1] - i]
|
||||||
|
|
||||||
|
self.c_node.bridges[0]["bridge_num"] -= 1
|
||||||
|
self.s_node.bridges[1]["bridge_num"] -= 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[0]["bridge_num"] == -1:
|
||||||
|
self.c_node.bridges[0]["bridge_num"] -= 1
|
||||||
|
self.s_node.bridges[1]["bridge_num"] -= 1
|
||||||
|
break
|
||||||
|
|
||||||
|
self.temp_removed[0] = 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[0]["bridge_num"] == 0:
|
||||||
|
self.c_node.bridges[0] = {"bridge_num": 0, "connection": True}
|
||||||
|
self.s_node.bridges[1] = {"bridge_num": 0, "connection": True}
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if self.c_node.bridges[0]["connection"] is not None and self.map[cords[0]][cords[1] - i].bridge_occupied == 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
self.__up(cords)
|
||||||
|
|
||||||
|
def clear_temp(self):
|
||||||
|
if self.temp_done.count(1) != 0:
|
||||||
|
i = self.temp_done.index(1)
|
||||||
|
self.temp_done[i] = 0
|
||||||
|
|
||||||
|
if i == 0:
|
||||||
|
self.c_node.bridges[0]["bridge_num"] -= 1
|
||||||
|
self.s_node.bridges[1]["bridge_num"] -= 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[0]["bridge_num"] == 0:
|
||||||
|
self.c_node.bridges[0] = {"bridge_num": 0, "connection": None}
|
||||||
|
self.s_node.bridges[1] = {"bridge_num": 0, "connection": None}
|
||||||
|
elif self.c_node.bridges[0]["bridge_num"] == -1:
|
||||||
|
self.c_node.bridges[0]["bridge_num"] = 2
|
||||||
|
self.s_node.bridges[1]["bridge_num"] = 2
|
||||||
|
|
||||||
|
self.c_node.bridges[0]["connection"] = self.s_node.pos
|
||||||
|
self.s_node.bridges[1]["connection"] = self.c_node.pos
|
||||||
|
elif i == 1:
|
||||||
|
self.c_node.bridges[1]["bridge_num"] -= 1
|
||||||
|
self.s_node.bridges[0]["bridge_num"] -= 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[1]["bridge_num"] == 0:
|
||||||
|
self.c_node.bridges[1] = {"bridge_num": 0, "connection": None}
|
||||||
|
self.s_node.bridges[0] = {"bridge_num": 0, "connection": None}
|
||||||
|
elif self.c_node.bridges[1]["bridge_num"] == -1:
|
||||||
|
self.c_node.bridges[1]["bridge_num"] = 2
|
||||||
|
self.s_node.bridges[0]["bridge_num"] = 2
|
||||||
|
|
||||||
|
self.c_node.bridges[1]["connection"] = self.s_node.pos
|
||||||
|
self.s_node.bridges[0]["connection"] = self.c_node.pos
|
||||||
|
elif i == 2:
|
||||||
|
self.c_node.bridges[2]["bridge_num"] -= 1
|
||||||
|
self.s_node.bridges[3]["bridge_num"] -= 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[2]["bridge_num"] == 0:
|
||||||
|
self.c_node.bridges[2] = {"bridge_num": 0, "connection": None}
|
||||||
|
self.s_node.bridges[3] = {"bridge_num": 0, "connection": None}
|
||||||
|
elif self.c_node.bridges[2]["bridge_num"] == -1:
|
||||||
|
self.c_node.bridges[2]["bridge_num"] = 2
|
||||||
|
self.s_node.bridges[3]["bridge_num"] = 2
|
||||||
|
|
||||||
|
self.c_node.bridges[2]["connection"] = self.s_node.pos
|
||||||
|
self.s_node.bridges[3]["connection"] = self.c_node.pos
|
||||||
|
elif i == 3:
|
||||||
|
self.c_node.bridges[3]["bridge_num"] -= 1
|
||||||
|
self.s_node.bridges[2]["bridge_num"] -= 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[3]["bridge_num"] == 0:
|
||||||
|
self.c_node.bridges[3] = {"bridge_num": 0, "connection": None}
|
||||||
|
self.s_node.bridges[2] = {"bridge_num": 0, "connection": None}
|
||||||
|
elif self.c_node.bridges[3]["bridge_num"] == -1:
|
||||||
|
self.c_node.bridges[3]["bridge_num"] = 2
|
||||||
|
self.s_node.bridges[2]["bridge_num"] = 2
|
||||||
|
|
||||||
|
self.c_node.bridges[3]["connection"] = self.s_node.pos
|
||||||
|
self.s_node.bridges[2]["connection"] = self.c_node.pos
|
||||||
|
|
||||||
|
def clear_temp_remove(self):
|
||||||
|
if self.temp_removed.count(1) != 0:
|
||||||
|
i = self.temp_removed.index(1)
|
||||||
|
self.temp_removed[i] = 0
|
||||||
|
cords = self.c_node.pos
|
||||||
|
|
||||||
|
if i == 0:
|
||||||
|
for i in range(1, self.size):
|
||||||
|
if cords[1] - i > -1:
|
||||||
|
if self.map[cords[0]][cords[1] - i].locked is False:
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.map[cords[0]][cords[1] - i].pos == self.s_node.pos:
|
||||||
|
# connect
|
||||||
|
self.s_node = self.map[cords[0]][cords[1] - i]
|
||||||
|
|
||||||
|
self.c_node.bridges[0]["bridge_num"] += 1
|
||||||
|
self.s_node.bridges[1]["bridge_num"] += 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[0]["bridge_num"] == 3:
|
||||||
|
self.c_node.bridges[0] = {"bridge_num": 0, "connection": None}
|
||||||
|
self.s_node.bridges[1] = {"bridge_num": 0, "connection": None}
|
||||||
|
else:
|
||||||
|
self.c_node.bridges[0]["connection"] = self.s_node.pos
|
||||||
|
self.s_node.bridges[1]["connection"] = self.c_node.pos
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if self.c_node.bridges[0]["connection"] is not None and self.map[cords[0]][cords[1] - i].bridge_occupied == 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
elif i == 1:
|
||||||
|
for i in range(1, self.size):
|
||||||
|
if cords[1] + i < self.size:
|
||||||
|
if self.map[cords[0]][cords[1] + i].locked is False:
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.map[cords[0]][cords[1] + i].pos == self.s_node.pos:
|
||||||
|
# connect
|
||||||
|
self.s_node = self.map[cords[0]][cords[1] + i]
|
||||||
|
|
||||||
|
self.c_node.bridges[1]["bridge_num"] += 1
|
||||||
|
self.s_node.bridges[0]["bridge_num"] += 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[1]["bridge_num"] == 3:
|
||||||
|
self.c_node.bridges[1] = {"bridge_num": 0, "connection": None}
|
||||||
|
self.s_node.bridges[0] = {"bridge_num": 0, "connection": None}
|
||||||
|
else:
|
||||||
|
self.c_node.bridges[1]["connection"] = self.s_node.pos
|
||||||
|
self.s_node.bridges[0]["connection"] = self.c_node.pos
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if self.c_node.bridges[1]["connection"] is not None and self.map[cords[0]][cords[1] + i].bridge_occupied == 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
elif i == 2:
|
||||||
|
for i in range(1, self.size):
|
||||||
|
if cords[0] + i < self.size:
|
||||||
|
if self.map[cords[0] + i][cords[1]].locked is False:
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.map[cords[0] + i][cords[1]].pos == self.s_node.pos:
|
||||||
|
# connect
|
||||||
|
self.s_node = self.map[cords[0] + i][cords[1]]
|
||||||
|
|
||||||
|
self.c_node.bridges[2]["bridge_num"] += 1
|
||||||
|
self.s_node.bridges[3]["bridge_num"] += 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[2]["bridge_num"] == 3:
|
||||||
|
self.c_node.bridges[2] = {"bridge_num": 0, "connection": None}
|
||||||
|
self.s_node.bridges[3] = {"bridge_num": 0, "connection": None}
|
||||||
|
else:
|
||||||
|
self.c_node.bridges[2]["connection"] = self.s_node.pos
|
||||||
|
self.s_node.bridges[3]["connection"] = self.c_node.pos
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if self.c_node.bridges[2]["connection"] is not None and self.map[cords[0] + i][cords[1]].bridge_occupied == 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
elif i == 3:
|
||||||
|
for i in range(1, self.size):
|
||||||
|
if cords[0] - i > -1:
|
||||||
|
if self.map[cords[0] - i][cords[1]].locked is False:
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.map[cords[0] - i][cords[1]].pos == self.s_node.pos:
|
||||||
|
# connect
|
||||||
|
self.s_node = self.map[cords[0] - i][cords[1]]
|
||||||
|
|
||||||
|
self.c_node.bridges[3]["bridge_num"] += 1
|
||||||
|
self.s_node.bridges[2]["bridge_num"] += 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[3]["bridge_num"] == 3:
|
||||||
|
self.c_node.bridges[3] = {"bridge_num": 0, "connection": None}
|
||||||
|
self.s_node.bridges[2] = {"bridge_num": 0, "connection": None}
|
||||||
|
else:
|
||||||
|
self.c_node.bridges[3]["connection"] = self.s_node.pos
|
||||||
|
self.s_node.bridges[2]["connection"] = self.c_node.pos
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if self.c_node.bridges[3]["connection"] is not None and self.map[cords[0] - i][cords[1]].bridge_occupied == 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
def click_on_locked(self, mouse, scroll):
|
||||||
|
c = self.c_node
|
||||||
|
s = self.s_node
|
||||||
|
temp_done = copy.copy(self.temp_done)
|
||||||
|
temp_removed = copy.copy(self.temp_removed)
|
||||||
|
other_removed = self.get_other(temp_removed)
|
||||||
|
other_done = self.get_other(temp_done)
|
||||||
|
self.clear_temp()
|
||||||
|
self.clear_temp_remove()
|
||||||
|
|
||||||
|
if temp_done.count(1) != 0:
|
||||||
|
|
||||||
|
# connecting
|
||||||
|
i1 = temp_done.index(1)
|
||||||
|
i2 = other_done.index(1)
|
||||||
|
|
||||||
|
switch = {"c": False,
|
||||||
|
"s": False}
|
||||||
|
|
||||||
|
if c.bridge_occupied == c.bridge_num:
|
||||||
|
switch["c"] = True
|
||||||
|
if s.bridge_occupied == s.bridge_num:
|
||||||
|
switch["s"] = True
|
||||||
|
|
||||||
|
c.bridges[i1]["bridge_num"] += 1
|
||||||
|
s.bridges[i2]["bridge_num"] += 1
|
||||||
|
c.bridge_occupied += 1
|
||||||
|
s.bridge_occupied += 1
|
||||||
|
|
||||||
|
c.bridges[i1]["connection"] = s.pos
|
||||||
|
s.bridges[i2]["connection"] = c.pos
|
||||||
|
|
||||||
|
if c.bridges[i1]["bridge_num"] > 2:
|
||||||
|
c.bridges[i1] = {"bridge_num": 0, "connection": None}
|
||||||
|
s.bridges[i2] = {"bridge_num": 0, "connection": None}
|
||||||
|
c.bridge_occupied -= 3
|
||||||
|
s.bridge_occupied -= 3
|
||||||
|
|
||||||
|
# playing sound
|
||||||
|
soundsX["remove"].play()
|
||||||
|
else:
|
||||||
|
soundsX["join"].play()
|
||||||
|
|
||||||
|
if c.bridge_occupied == c.bridge_num or switch["c"]:
|
||||||
|
c.widget.switch(mouse.get_scrolled(scroll))
|
||||||
|
if s.bridge_occupied == s.bridge_num or switch["s"]:
|
||||||
|
s.widget.switch(mouse.get_scrolled(scroll))
|
||||||
|
|
||||||
|
# locking
|
||||||
|
if temp_done[1]:
|
||||||
|
for i in range(c.pos[1] + 1, s.pos[1]):
|
||||||
|
if c.bridges[1]["connection"] is not None:
|
||||||
|
self.map[c.pos[0]][i].locked = True
|
||||||
|
else:
|
||||||
|
self.map[c.pos[0]][i].locked = False
|
||||||
|
|
||||||
|
elif temp_done[0]:
|
||||||
|
for i in range(s.pos[1] + 1, c.pos[1]):
|
||||||
|
if c.bridges[0]["connection"] is not None:
|
||||||
|
self.map[s.pos[0]][i].locked = True
|
||||||
|
else:
|
||||||
|
self.map[s.pos[0]][i].locked = False
|
||||||
|
|
||||||
|
elif temp_done[2]:
|
||||||
|
for i in range(c.pos[0] + 1, s.pos[0]):
|
||||||
|
if c.bridges[2]["connection"] is not None:
|
||||||
|
self.map[i][c.pos[1]].locked = True
|
||||||
|
else:
|
||||||
|
self.map[i][c.pos[1]].locked = False
|
||||||
|
|
||||||
|
elif temp_done[3]:
|
||||||
|
for i in range(s.pos[0] + 1, c.pos[0]):
|
||||||
|
if c.bridges[3]["connection"] is not None:
|
||||||
|
self.map[i][s.pos[1]].locked = True
|
||||||
|
else:
|
||||||
|
self.map[i][s.pos[1]].locked = False
|
||||||
|
elif temp_removed.count(1) != 0:
|
||||||
|
# connecting
|
||||||
|
i1 = temp_removed.index(1)
|
||||||
|
i2 = other_removed.index(1)
|
||||||
|
|
||||||
|
switch = {"c": False,
|
||||||
|
"s": False}
|
||||||
|
|
||||||
|
if c.bridge_occupied == c.bridge_num:
|
||||||
|
switch["c"] = True
|
||||||
|
if s.bridge_occupied == s.bridge_num:
|
||||||
|
switch["s"] = True
|
||||||
|
|
||||||
|
c.bridges[i1]["bridge_num"] -= 1
|
||||||
|
s.bridges[i2]["bridge_num"] -= 1
|
||||||
|
c.bridge_occupied -= 1
|
||||||
|
s.bridge_occupied -= 1
|
||||||
|
|
||||||
|
c.bridges[i1]["connection"] = s.pos
|
||||||
|
s.bridges[i2]["connection"] = c.pos
|
||||||
|
|
||||||
|
if c.bridges[i1]["bridge_num"] == 0:
|
||||||
|
c.bridges[i1]["connection"] = None
|
||||||
|
s.bridges[i2]["connection"] = None
|
||||||
|
|
||||||
|
if switch["c"]:
|
||||||
|
c.widget.switch(mouse.get_scrolled(scroll))
|
||||||
|
if switch["s"]:
|
||||||
|
s.widget.switch(mouse.get_scrolled(scroll))
|
||||||
|
|
||||||
|
# locking
|
||||||
|
if temp_removed[1]:
|
||||||
|
for i in range(c.pos[1] + 1, s.pos[1]):
|
||||||
|
if c.bridges[1]["connection"] is not None:
|
||||||
|
self.map[c.pos[0]][i].locked = True
|
||||||
|
else:
|
||||||
|
self.map[c.pos[0]][i].locked = False
|
||||||
|
|
||||||
|
elif temp_removed[0]:
|
||||||
|
for i in range(s.pos[1] + 1, c.pos[1]):
|
||||||
|
if c.bridges[0]["connection"] is not None:
|
||||||
|
self.map[s.pos[0]][i].locked = True
|
||||||
|
else:
|
||||||
|
self.map[s.pos[0]][i].locked = False
|
||||||
|
|
||||||
|
elif temp_removed[2]:
|
||||||
|
for i in range(c.pos[0] + 1, s.pos[0]):
|
||||||
|
if c.bridges[2]["connection"] is not None:
|
||||||
|
self.map[i][c.pos[1]].locked = True
|
||||||
|
else:
|
||||||
|
self.map[i][c.pos[1]].locked = False
|
||||||
|
|
||||||
|
elif temp_removed[3]:
|
||||||
|
for i in range(s.pos[0] + 1, c.pos[0]):
|
||||||
|
if c.bridges[3]["connection"] is not None:
|
||||||
|
self.map[i][s.pos[1]].locked = True
|
||||||
|
else:
|
||||||
|
self.map[i][s.pos[1]].locked = False
|
||||||
|
|
||||||
|
# playing sound
|
||||||
|
soundsX["remove"].play()
|
||||||
|
|
||||||
|
def check_win(self):
|
||||||
|
node_done_count = 0
|
||||||
|
test_node = None
|
||||||
|
for line in self.map:
|
||||||
|
for item in line:
|
||||||
|
if item.bridge_num > 0:
|
||||||
|
if item.bridge_num == item.bridge_occupied:
|
||||||
|
node_done_count += 1
|
||||||
|
test_node = item
|
||||||
|
|
||||||
|
if node_done_count == self.node_count:
|
||||||
|
|
||||||
|
# checking if all connected
|
||||||
|
nodes_to_do = [test_node]
|
||||||
|
nodes_to_remove = []
|
||||||
|
appending = []
|
||||||
|
while len(nodes_to_do) != 0:
|
||||||
|
# making them done
|
||||||
|
for node in nodes_to_do:
|
||||||
|
node.check_for_win = True
|
||||||
|
|
||||||
|
for node in nodes_to_do:
|
||||||
|
for connection in node.bridges:
|
||||||
|
if connection["connection"] is not None:
|
||||||
|
if self.map[connection["connection"][0]][connection["connection"][1]].check_for_win is False:
|
||||||
|
appending.append(self.map[connection["connection"][0]][connection["connection"][1]])
|
||||||
|
nodes_to_remove.append(node)
|
||||||
|
|
||||||
|
for node in appending:
|
||||||
|
nodes_to_do.append(node)
|
||||||
|
appending = []
|
||||||
|
|
||||||
|
for node in nodes_to_remove:
|
||||||
|
nodes_to_do.remove(node)
|
||||||
|
nodes_to_remove = []
|
||||||
|
|
||||||
|
win = True
|
||||||
|
for line in self.map:
|
||||||
|
for item in line:
|
||||||
|
if item.bridge_num > 0:
|
||||||
|
if item.check_for_win is False:
|
||||||
|
win = False
|
||||||
|
|
||||||
|
if win:
|
||||||
|
self.win = True
|
||||||
|
else:
|
||||||
|
for line in self.map:
|
||||||
|
for item in line:
|
||||||
|
item.check_for_win = False
|
||||||
|
|
||||||
|
def save(self, setup):
|
||||||
|
save = {"difficulty": setup["difficulty"]}
|
||||||
|
|
||||||
|
connections = []
|
||||||
|
|
||||||
|
for line in self.map:
|
||||||
|
for node in line:
|
||||||
|
if node.locked is True:
|
||||||
|
if node.bridge_num != 0:
|
||||||
|
connections.append({"pos": node.pos,
|
||||||
|
"bridges": node.bridges,
|
||||||
|
"bridge_occupied": node.bridge_occupied,
|
||||||
|
"locked": node.locked})
|
||||||
|
else:
|
||||||
|
connections.append({"pos": node.pos,
|
||||||
|
"locked": node.locked})
|
||||||
|
save["connections"] = connections
|
||||||
|
|
||||||
|
with open(f"assets/saves/game_saves/{setup['difficulty']}.json", "w") as f:
|
||||||
|
json.dump(save, f, indent=4)
|
||||||
|
|
||||||
|
def print_nodes(self):
|
||||||
|
print("_" * 20)
|
||||||
|
|
||||||
|
for line in self.map:
|
||||||
|
for item in line:
|
||||||
|
if item.bridge_num > 0:
|
||||||
|
print(f"| Node at pos {item.widget.pos}, map pos {item.pos}, bridge_num {item.bridge_num}"
|
||||||
|
f" with {item.bridge_occupied} occupied bridges. |")
|
||||||
|
|
||||||
|
print("_" * 20)
|
||||||
|
|
||||||
|
# technical stuff not used inside class
|
||||||
|
def set_size(self):
|
||||||
|
if self.size <= 15:
|
||||||
|
self.indent = (15 / self.size) * 40
|
||||||
|
|
||||||
|
def get_length(self):
|
||||||
|
return self.indent * (self.size - 1)
|
||||||
|
|
||||||
|
def lock(self, args):
|
||||||
|
self.locked = True
|
||||||
|
self.c_node = args[0]
|
||||||
|
|
||||||
|
# technical stuff used inside class
|
||||||
|
def __down(self, cords):
|
||||||
|
for i in range(1, self.size):
|
||||||
|
if cords[1] + i < self.size:
|
||||||
|
if self.map[cords[0]][cords[1] + i].locked is False:
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.map[cords[0]][cords[1] + i].bridge_occupied < self.map[cords[0]][
|
||||||
|
cords[1] + i].bridge_num or (
|
||||||
|
self.c_node.bridges[1]["bridge_num"] == 2 and self.map[cords[0]][cords[1] + i].pos ==
|
||||||
|
self.c_node.bridges[1]["connection"]):
|
||||||
|
# connect
|
||||||
|
self.s_node = self.map[cords[0]][cords[1] + i]
|
||||||
|
|
||||||
|
self.c_node.bridges[1]["bridge_num"] += 1
|
||||||
|
self.s_node.bridges[0]["bridge_num"] += 1
|
||||||
|
self.temp_done[1] = 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[1]["bridge_num"] == 3:
|
||||||
|
self.c_node.bridges[1] = {"bridge_num": 0, "connection": None}
|
||||||
|
self.s_node.bridges[0] = {"bridge_num": 0, "connection": None}
|
||||||
|
else:
|
||||||
|
self.c_node.bridges[1]["connection"] = self.s_node.pos
|
||||||
|
self.s_node.bridges[0]["connection"] = self.c_node.pos
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if self.c_node.bridges[1]["connection"] is not None and self.map[cords[0]][
|
||||||
|
cords[1] + i].bridge_occupied == 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
def __up(self, cords):
|
||||||
|
for i in range(1, self.size):
|
||||||
|
if cords[1] - i > -1:
|
||||||
|
if self.map[cords[0]][cords[1] - i].locked is False:
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.map[cords[0]][cords[1] - i].bridge_occupied < self.map[cords[0]][
|
||||||
|
cords[1] - i].bridge_num or (
|
||||||
|
self.c_node.bridges[0]["bridge_num"] == 2 and self.map[cords[0]][cords[1] - i].pos ==
|
||||||
|
self.c_node.bridges[0]["connection"]):
|
||||||
|
# connect
|
||||||
|
self.s_node = self.map[cords[0]][cords[1] - i]
|
||||||
|
|
||||||
|
self.c_node.bridges[0]["bridge_num"] += 1
|
||||||
|
self.s_node.bridges[1]["bridge_num"] += 1
|
||||||
|
self.temp_done[0] = 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[0]["bridge_num"] == 3:
|
||||||
|
self.c_node.bridges[0] = {"bridge_num": 0, "connection": None}
|
||||||
|
self.s_node.bridges[1] = {"bridge_num": 0, "connection": None}
|
||||||
|
else:
|
||||||
|
self.c_node.bridges[0]["connection"] = self.s_node.pos
|
||||||
|
self.s_node.bridges[1]["connection"] = self.c_node.pos
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if self.c_node.bridges[0]["connection"] is not None and self.map[cords[0]][
|
||||||
|
cords[1] - i].bridge_occupied == 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
def __right(self, cords):
|
||||||
|
for i in range(1, self.size):
|
||||||
|
if cords[0] + i < self.size:
|
||||||
|
if self.map[cords[0] + i][cords[1]].locked is False:
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.map[cords[0] + i][cords[1]].bridge_occupied < self.map[cords[0] + i][
|
||||||
|
cords[1]].bridge_num or (
|
||||||
|
self.c_node.bridges[2]["bridge_num"] == 2 and self.map[cords[0] + i][cords[1]].pos ==
|
||||||
|
self.c_node.bridges[2]["connection"]):
|
||||||
|
# connect
|
||||||
|
self.s_node = self.map[cords[0] + i][cords[1]]
|
||||||
|
|
||||||
|
self.c_node.bridges[2]["bridge_num"] += 1
|
||||||
|
self.s_node.bridges[3]["bridge_num"] += 1
|
||||||
|
self.temp_done[2] = 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[2]["bridge_num"] == 3:
|
||||||
|
self.c_node.bridges[2] = {"bridge_num": 0, "connection": None}
|
||||||
|
self.s_node.bridges[3] = {"bridge_num": 0, "connection": None}
|
||||||
|
else:
|
||||||
|
self.c_node.bridges[2]["connection"] = self.s_node.pos
|
||||||
|
self.s_node.bridges[3]["connection"] = self.c_node.pos
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if self.c_node.bridges[2]["connection"] is not None and self.map[cords[0] + i][
|
||||||
|
cords[1]].bridge_occupied == 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
def __left(self, cords):
|
||||||
|
for i in range(1, self.size):
|
||||||
|
if cords[0] - i > -1:
|
||||||
|
if self.map[cords[0] - i][cords[1]].locked is False:
|
||||||
|
pass
|
||||||
|
|
||||||
|
else:
|
||||||
|
if self.map[cords[0] - i][cords[1]].bridge_occupied < self.map[cords[0] - i][
|
||||||
|
cords[1]].bridge_num or (
|
||||||
|
self.c_node.bridges[3]["bridge_num"] == 2 and self.map[cords[0] - i][cords[1]].pos ==
|
||||||
|
self.c_node.bridges[3]["connection"]):
|
||||||
|
# connect
|
||||||
|
self.s_node = self.map[cords[0] - i][cords[1]]
|
||||||
|
|
||||||
|
self.c_node.bridges[3]["bridge_num"] += 1
|
||||||
|
self.s_node.bridges[2]["bridge_num"] += 1
|
||||||
|
self.temp_done[3] = 1
|
||||||
|
|
||||||
|
if self.c_node.bridges[3]["bridge_num"] == 3:
|
||||||
|
self.c_node.bridges[3] = {"bridge_num": 0, "connection": None}
|
||||||
|
self.s_node.bridges[2] = {"bridge_num": 0, "connection": None}
|
||||||
|
else:
|
||||||
|
self.c_node.bridges[3]["connection"] = self.s_node.pos
|
||||||
|
self.s_node.bridges[2]["connection"] = self.c_node.pos
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if self.c_node.bridges[3]["connection"] is not None and self.map[cords[0] - i][
|
||||||
|
cords[1]].bridge_occupied == 0:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_other(temp):
|
||||||
|
second = [0, 0, 0, 0]
|
||||||
|
|
||||||
|
if temp[0]:
|
||||||
|
second[1] = 1
|
||||||
|
elif temp[1]:
|
||||||
|
second[0] = 1
|
||||||
|
elif temp[2]:
|
||||||
|
second[3] = 1
|
||||||
|
elif temp[3]:
|
||||||
|
second[2] = 1
|
||||||
|
|
||||||
|
return second
|
||||||
|
|
||||||
|
|
||||||
|
class NodeG:
|
||||||
|
|
||||||
|
def __init__(self, pos, bridge_num=0):
|
||||||
|
self.pos = pos
|
||||||
|
self.bridge_occupied = 0
|
||||||
|
self.bridge_num = bridge_num
|
||||||
|
self.locked = False
|
||||||
|
self.widget = None
|
||||||
|
self.check_for_win = False
|
||||||
|
|
||||||
|
self.bridges = [{"bridge_num": 0, "connection": None} for _ in range(4)] # down, up, right, left
|
232
hashi_generator.py
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
class Hashi:
|
||||||
|
|
||||||
|
def __init__(self, size):
|
||||||
|
if size < 2:
|
||||||
|
size = 2
|
||||||
|
print("Size cant be 1 or lower.")
|
||||||
|
self.size = size
|
||||||
|
self.node_limit_lower = size # lower limit
|
||||||
|
self.node_upper_limit = int(size ** 1.4) + 1 # upper limit
|
||||||
|
self.node_count = 0
|
||||||
|
self.low_lim = 0
|
||||||
|
self.high_lim = size
|
||||||
|
|
||||||
|
self.map = [[Node([x, y]) for y in range(size)] for x in range(size)]
|
||||||
|
|
||||||
|
def generate_map(self):
|
||||||
|
# down, up, right, left
|
||||||
|
first = [random.randint(0, self.size-1), random.randint(0, self.size-1)]
|
||||||
|
self.node_count += 1
|
||||||
|
|
||||||
|
node = self.get_node(first)
|
||||||
|
self.write_node(node)
|
||||||
|
nodes_to_do = self.get_new_nodes(node)
|
||||||
|
while len(nodes_to_do) != 0:
|
||||||
|
for n in nodes_to_do:
|
||||||
|
node = self.get_node(n)
|
||||||
|
self.write_node(node)
|
||||||
|
nodes_to_do = nodes_to_do + self.get_new_nodes(node)
|
||||||
|
nodes_to_do.remove(n)
|
||||||
|
|
||||||
|
def get_node(self, cords):
|
||||||
|
ways = [0, 0, 0, 0] # down, up, right, left
|
||||||
|
possibilities = 0
|
||||||
|
|
||||||
|
if self.node_count >= self.node_upper_limit:
|
||||||
|
node = {"ways": [0, 0, 0, 0],
|
||||||
|
"num_of_bridges": [random.randint(1, 2) for _ in range(4)],
|
||||||
|
"pos": cords}
|
||||||
|
|
||||||
|
return node
|
||||||
|
|
||||||
|
if cords[1] - 1 > -1 and self.map[cords[0]][cords[1] - 1].locked is False:
|
||||||
|
ways[0] += 1
|
||||||
|
possibilities += 1
|
||||||
|
|
||||||
|
if cords[1] + 1 < self.size and self.map[cords[0]][cords[1] + 1].locked is False:
|
||||||
|
ways[1] += 1
|
||||||
|
possibilities += 1
|
||||||
|
|
||||||
|
if cords[0] + 1 < self.size and self.map[cords[0] + 1][cords[1]].locked is False:
|
||||||
|
ways[2] += 1
|
||||||
|
possibilities += 1
|
||||||
|
|
||||||
|
if cords[0] - 1 > -1 and self.map[cords[0] - 1][cords[1]].locked is False:
|
||||||
|
ways[3] += 1
|
||||||
|
possibilities += 1
|
||||||
|
|
||||||
|
if possibilities:
|
||||||
|
attempts = [x+1 if random.randint(0, 1) == 0 else x for x in ways]
|
||||||
|
|
||||||
|
# making the puzzle forcefully bigger
|
||||||
|
if self.node_count < self.node_limit_lower:
|
||||||
|
while 2 not in attempts:
|
||||||
|
attempts = [x + 1 if random.randint(0, 1) == 0 else x for x in ways]
|
||||||
|
|
||||||
|
# getting the starting distances
|
||||||
|
distances = [1 if x > 1 else 0 for x in attempts]
|
||||||
|
|
||||||
|
# getting possible distance up to 6
|
||||||
|
if attempts[0] > 1:
|
||||||
|
for i in range(2, self.size):
|
||||||
|
if cords[1] - i > -1 and self.map[cords[0]][cords[1] - i].locked is False:
|
||||||
|
distances[0] += 1
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
if attempts[1] > 1:
|
||||||
|
for i in range(2, self.size):
|
||||||
|
if cords[1]+i < self.size and self.map[cords[0]][cords[1]+i].locked is False:
|
||||||
|
distances[1] += 1
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
if attempts[2] > 1:
|
||||||
|
for i in range(2, self.size):
|
||||||
|
if cords[0] + i < self.size and self.map[cords[0]+i][cords[1]].locked is False:
|
||||||
|
distances[2] += 1
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
if attempts[3] > 1:
|
||||||
|
for i in range(2, self.size):
|
||||||
|
if cords[0] - i > -1 and self.map[cords[0] - i][cords[1]].locked is False:
|
||||||
|
distances[3] += 1
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
final_decision = [random.randint(1, x)if x != 0 else 0 for x in distances]
|
||||||
|
|
||||||
|
node = {"ways": final_decision,
|
||||||
|
"num_of_bridges": [random.randint(1, 2) for _ in range(4)],
|
||||||
|
"pos": cords}
|
||||||
|
|
||||||
|
return node
|
||||||
|
|
||||||
|
else:
|
||||||
|
node = {"ways": [0, 0, 0, 0],
|
||||||
|
"num_of_bridges": [random.randint(1, 2) for _ in range(4)],
|
||||||
|
"pos": cords}
|
||||||
|
|
||||||
|
return node
|
||||||
|
|
||||||
|
def write_node(self, node):
|
||||||
|
pos = node["pos"]
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
sum_of_bridges = 0
|
||||||
|
for item in node["ways"]:
|
||||||
|
if item != 0:
|
||||||
|
sum_of_bridges += node["num_of_bridges"][i]
|
||||||
|
|
||||||
|
# adding the bridges to new nodes
|
||||||
|
if i == 0:
|
||||||
|
self.map[pos[0]][pos[1] - item].bridge_num += node["num_of_bridges"][i]
|
||||||
|
elif i == 1:
|
||||||
|
self.map[pos[0]][pos[1] + item].bridge_num += node["num_of_bridges"][i]
|
||||||
|
elif i == 2:
|
||||||
|
self.map[pos[0] + item][pos[1]].bridge_num += node["num_of_bridges"][i]
|
||||||
|
elif i == 3:
|
||||||
|
self.map[pos[0] - item][pos[1]].bridge_num += node["num_of_bridges"][i]
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
self.map[pos[0]][pos[1]].locked = True
|
||||||
|
self.map[pos[0]][pos[1]].bridge_num += sum_of_bridges
|
||||||
|
|
||||||
|
def get_new_nodes(self, node):
|
||||||
|
pos = node["pos"]
|
||||||
|
# down, up, right, left
|
||||||
|
nodes_to_send = []
|
||||||
|
|
||||||
|
for nodeX in range(1, node["ways"][0]+1):
|
||||||
|
self.map[pos[0]][pos[1] - nodeX].locked = True
|
||||||
|
|
||||||
|
if nodeX == node["ways"][0]:
|
||||||
|
nodes_to_send.append(self.map[pos[0]][pos[1] - nodeX].pos)
|
||||||
|
|
||||||
|
for nodeX in range(1, node["ways"][1]+1):
|
||||||
|
self.map[pos[0]][pos[1] + nodeX].locked = True
|
||||||
|
|
||||||
|
if nodeX == node["ways"][1]:
|
||||||
|
nodes_to_send.append(self.map[pos[0]][pos[1] + nodeX].pos)
|
||||||
|
|
||||||
|
for nodeX in range(1, node["ways"][2]+1):
|
||||||
|
self.map[pos[0] + nodeX][pos[1]].locked = True
|
||||||
|
|
||||||
|
if nodeX == node["ways"][2]:
|
||||||
|
nodes_to_send.append(self.map[pos[0] + nodeX][pos[1]].pos)
|
||||||
|
|
||||||
|
for nodeX in range(1, node["ways"][3]+1):
|
||||||
|
self.map[pos[0] - nodeX][pos[1]].locked = True
|
||||||
|
|
||||||
|
if nodeX == node["ways"][3]:
|
||||||
|
nodes_to_send.append(self.map[pos[0] - nodeX][pos[1]].pos)
|
||||||
|
|
||||||
|
self.node_count += len(nodes_to_send)
|
||||||
|
|
||||||
|
return nodes_to_send
|
||||||
|
|
||||||
|
def save(self, path):
|
||||||
|
final_string = ""
|
||||||
|
|
||||||
|
for y in range(self.size):
|
||||||
|
|
||||||
|
for x in range(self.size):
|
||||||
|
final_string += str(self.map[x][y].bridge_num) + " "
|
||||||
|
|
||||||
|
final_string += "\n"
|
||||||
|
|
||||||
|
with open(path, "w") as f:
|
||||||
|
f.write(final_string)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
def print(self, bridges=False):
|
||||||
|
final_string = "_" * ((self.size * 2) + 3) + "\n"
|
||||||
|
|
||||||
|
for y in range(self.size):
|
||||||
|
final_string += "| "
|
||||||
|
|
||||||
|
for x in range(self.size):
|
||||||
|
if bridges is False:
|
||||||
|
final_string += str(self.map[x][y].bridge_num) + " "
|
||||||
|
else:
|
||||||
|
final_string += f" |* {self.map[x][y].bridge_num} *,{str(self.map[x][y].locked)[0]}| "
|
||||||
|
|
||||||
|
final_string += "|\n"
|
||||||
|
|
||||||
|
final_string += "¯" * ((self.size * 2) + 3)
|
||||||
|
|
||||||
|
print(final_string)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return self.node_count
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
final_string = "_" * ((self.size*2)+3) + "\n"
|
||||||
|
|
||||||
|
for y in range(self.size):
|
||||||
|
final_string += "| "
|
||||||
|
|
||||||
|
for x in range(self.size):
|
||||||
|
final_string += str(self.map[x][y].bridge_num) + " "
|
||||||
|
|
||||||
|
final_string += "|\n"
|
||||||
|
|
||||||
|
final_string += "¯" * ((self.size*2)+3)
|
||||||
|
|
||||||
|
return final_string
|
||||||
|
|
||||||
|
def __add__(self, other):
|
||||||
|
return self.node_count + other.node_count
|
||||||
|
|
||||||
|
|
||||||
|
class Node:
|
||||||
|
|
||||||
|
def __init__(self, pos, bridge_num=0):
|
||||||
|
self.pos = pos
|
||||||
|
self.bridge_num = bridge_num
|
||||||
|
self.locked = False
|
50
menu_effect.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import pygame
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
class Circle_effect:
|
||||||
|
|
||||||
|
circles = []
|
||||||
|
timer = 0
|
||||||
|
|
||||||
|
def __init__(self, pos, radius, speed, vertical):
|
||||||
|
self.pos = pos
|
||||||
|
self.radius = radius
|
||||||
|
self.speed = speed
|
||||||
|
self.vertical = vertical # True for going up False for down
|
||||||
|
|
||||||
|
def move(self, display, palette, horizontal=False):
|
||||||
|
sur = pygame.Surface((self.radius * 2, self.radius * 2))
|
||||||
|
pygame.draw.circle(sur, palette.palette["addition"], [self.radius, self.radius], self.radius)
|
||||||
|
sur.set_alpha(random.randint(100, 200))
|
||||||
|
sur.set_colorkey((0, 0, 0))
|
||||||
|
display.blit(sur, self.pos)
|
||||||
|
|
||||||
|
if self.vertical:
|
||||||
|
if horizontal:
|
||||||
|
self.pos[0] -= self.speed
|
||||||
|
else:
|
||||||
|
self.pos[1] -= self.speed
|
||||||
|
else:
|
||||||
|
if horizontal:
|
||||||
|
self.pos[0] += self.speed
|
||||||
|
else:
|
||||||
|
self.pos[1] += self.speed
|
||||||
|
|
||||||
|
if self.pos[1] < -100 or self.pos[0] > 700 or self.pos[1] > 700 or self.pos[0] < -100:
|
||||||
|
self.delete(self)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def generate_circles(cls, amount=100, y_lim=None):
|
||||||
|
if y_lim is None:
|
||||||
|
y_lim = [0, 100]
|
||||||
|
|
||||||
|
for _ in range(amount):
|
||||||
|
cls.circles.append(Circle_effect([random.randint(y_lim[0], y_lim[1]), random.randint(0, 650)],
|
||||||
|
random.randint(20, 50), random.randint(1, 4),
|
||||||
|
[True if x == 1 else False for x in [random.randint(0, 1)]][0]))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def delete(cls, circle):
|
||||||
|
cls.circles.remove(circle)
|
||||||
|
|
527
s_engine.py
Normal file
@ -0,0 +1,527 @@
|
|||||||
|
import pygame
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
import math
|
||||||
|
import copy
|
||||||
|
from pygame.locals import *
|
||||||
|
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
|
||||||
|
# has attributes for basic thing in game
|
||||||
|
class Game:
|
||||||
|
def __init__(self, game_maps=None):
|
||||||
|
self.alive = True
|
||||||
|
# fs = fullscreen
|
||||||
|
self.fs = False
|
||||||
|
self.custom_id_giver = 0
|
||||||
|
|
||||||
|
self.game_flow = {}
|
||||||
|
|
||||||
|
self.game_maps = None
|
||||||
|
# checks if there are any maps if there are puts them in self.game_maps
|
||||||
|
if game_maps is not None:
|
||||||
|
self.game_maps = game_maps
|
||||||
|
|
||||||
|
|
||||||
|
# stores objects in a sorted way
|
||||||
|
class Objects:
|
||||||
|
def __init__(self):
|
||||||
|
self.game_objects = []
|
||||||
|
self.collision_objects = []
|
||||||
|
self.moving_objects = []
|
||||||
|
|
||||||
|
# dunno if next att will be useful
|
||||||
|
# u add ids of objects u want to delete there is no func to delete for now
|
||||||
|
|
||||||
|
self.objects_to_delete = []
|
||||||
|
|
||||||
|
self.values = {
|
||||||
|
"pos_to_del": []
|
||||||
|
}
|
||||||
|
|
||||||
|
def do_collisions(self, objects):
|
||||||
|
for obj in self.collision_objects:
|
||||||
|
collision(obj, objects)
|
||||||
|
|
||||||
|
def take_out_trash(self, ids):
|
||||||
|
for trash in self.objects_to_delete:
|
||||||
|
ids.ids_to_remove.append(trash)
|
||||||
|
self.objects_to_delete = []
|
||||||
|
|
||||||
|
|
||||||
|
# Id class just stores all ids of all objects
|
||||||
|
class Id:
|
||||||
|
all_ids = []
|
||||||
|
ids_to_remove = []
|
||||||
|
|
||||||
|
def remove_by_id(self, objects):
|
||||||
|
for item in self.ids_to_remove:
|
||||||
|
for obj in objects.game_objects:
|
||||||
|
if obj.object_id == item:
|
||||||
|
g_index = objects.game_objects.index(obj)
|
||||||
|
if obj.moving:
|
||||||
|
m_index = objects.moving_objects.index(obj)
|
||||||
|
if obj.move.collisions:
|
||||||
|
c_index = objects.collision_objects.index(obj)
|
||||||
|
|
||||||
|
del objects.collision_objects[c_index]
|
||||||
|
|
||||||
|
del objects.moving_objects[m_index]
|
||||||
|
|
||||||
|
del objects.game_objects[g_index]
|
||||||
|
|
||||||
|
self.ids_to_remove = []
|
||||||
|
|
||||||
|
|
||||||
|
class Scroll:
|
||||||
|
def __init__(self, scroll):
|
||||||
|
self.scroll = scroll
|
||||||
|
self.fade = 20
|
||||||
|
self.safe_fade = 20
|
||||||
|
self.in_progress = False
|
||||||
|
self.save_scroll = self.scroll
|
||||||
|
|
||||||
|
def move_scroll(self, player, screen, which, space=20):
|
||||||
|
if which == "y" or which == "both":
|
||||||
|
self.scroll[1] += (player.rect.y - self.scroll[1] - (screen[1] / 2) + (player.size[1] / 2)) / space
|
||||||
|
self.scroll[1] = int(self.scroll[1])
|
||||||
|
if which == "x" or which == "both":
|
||||||
|
self.scroll[0] += (player.rect.x - self.scroll[0] - (screen[0] / 2) + (player.size[0] / 2)) / space
|
||||||
|
self.scroll[0] = int(self.scroll[0])
|
||||||
|
|
||||||
|
def add_scroll(self, which, how_much, fade=None):
|
||||||
|
if fade is not None:
|
||||||
|
self.safe_fade = fade
|
||||||
|
if self.in_progress is False:
|
||||||
|
self.load_safe_fade()
|
||||||
|
self.save_scroll = self.scroll
|
||||||
|
self.in_progress = True
|
||||||
|
how_much[0] /= self.fade
|
||||||
|
how_much[1] /= self.fade
|
||||||
|
self.fade += 0.01 * self.fade
|
||||||
|
|
||||||
|
if which == "x" or which == "both":
|
||||||
|
self.scroll[0] += how_much[0]
|
||||||
|
self.scroll[0] = round(self.scroll[0])
|
||||||
|
|
||||||
|
if which == "y" or which == "both":
|
||||||
|
self.scroll[1] += how_much[1]
|
||||||
|
self.scroll[1] = round(self.scroll[1])
|
||||||
|
|
||||||
|
def load_safe_fade(self):
|
||||||
|
self.fade = self.safe_fade
|
||||||
|
self.in_progress = False
|
||||||
|
|
||||||
|
# next function is used for mouse scrolling mainly
|
||||||
|
def move_scroll_based_on_pos(self, pos, screen, which, space=20):
|
||||||
|
# id used for mouse u can first check mouse pos from mid to create non moving bubble in middle
|
||||||
|
if which == "y" or which == "both":
|
||||||
|
self.scroll[1] += (pos[1] - self.scroll[1] - (screen[1] / 2)) / space
|
||||||
|
self.scroll[1] = int(self.scroll[1])
|
||||||
|
if which == "x" or which == "both":
|
||||||
|
self.scroll[0] += (pos[0] - self.scroll[0] - (screen[0] / 2)) / space
|
||||||
|
self.scroll[0] = int(self.scroll[0])
|
||||||
|
|
||||||
|
# for limiting scroll
|
||||||
|
@staticmethod
|
||||||
|
def scroll_lim(scroll, lim_min, lim_max):
|
||||||
|
# min lim has priority
|
||||||
|
|
||||||
|
if lim_min[0] < lim_max[0]:
|
||||||
|
|
||||||
|
if scroll.scroll[0] < lim_min[0]:
|
||||||
|
scroll.scroll[0] = lim_min[0]
|
||||||
|
|
||||||
|
if scroll.scroll[0] > lim_max[0]:
|
||||||
|
scroll.scroll[0] = lim_max[0]
|
||||||
|
else:
|
||||||
|
scroll.scroll[0] = lim_min[0]
|
||||||
|
|
||||||
|
if lim_min[1] < lim_max[1]:
|
||||||
|
if scroll.scroll[1] < lim_min[1]:
|
||||||
|
scroll.scroll[1] = lim_min[1]
|
||||||
|
|
||||||
|
if scroll.scroll[1] > lim_max[1]:
|
||||||
|
scroll.scroll[1] = lim_max[1]
|
||||||
|
else:
|
||||||
|
scroll.scroll[1] = lim_min[1]
|
||||||
|
|
||||||
|
|
||||||
|
class Special:
|
||||||
|
def __init__(self, object_id):
|
||||||
|
self.object_id = object_id
|
||||||
|
self.stage = ""
|
||||||
|
self.attribute = ""
|
||||||
|
self.images = []
|
||||||
|
self.attribute_0 = 0
|
||||||
|
self.attribute_1 = 0
|
||||||
|
self.attribute_2 = 0
|
||||||
|
self.color_r = [0, 0, 0]
|
||||||
|
self.boolean_attribute = False
|
||||||
|
self.height = 0
|
||||||
|
self.power = 0
|
||||||
|
self.flip = False
|
||||||
|
self.scroll = False
|
||||||
|
self.fixed = False
|
||||||
|
|
||||||
|
|
||||||
|
# collisions class take care of collision funcs
|
||||||
|
# !!!!!!!!!! holds init for Object !!!!!!!!!!!!!!!!!!!
|
||||||
|
# class purely for inheritance
|
||||||
|
class Collisions(Id):
|
||||||
|
|
||||||
|
def __init__(self, typeX, object_id, x_y, movement, direction, moving, size, special=None):
|
||||||
|
self.type = typeX
|
||||||
|
self.object_id = object_id
|
||||||
|
self.object_pos = x_y
|
||||||
|
self.movement = movement
|
||||||
|
self.direction = direction
|
||||||
|
self.moving = moving
|
||||||
|
self.size = size
|
||||||
|
self.dir_movement = [0.0, 0.0]
|
||||||
|
self.memory = []
|
||||||
|
self.special = special
|
||||||
|
if self.object_id != self.all_ids:
|
||||||
|
self.all_ids.append(self.object_id)
|
||||||
|
else:
|
||||||
|
print("duplicate/ linked object")
|
||||||
|
|
||||||
|
# giving it bonus classes
|
||||||
|
|
||||||
|
if self.moving:
|
||||||
|
self.move = Moving_Object()
|
||||||
|
if self.special:
|
||||||
|
self.specific = Special(self.object_id)
|
||||||
|
|
||||||
|
self.rect = pygame.Rect(self.object_pos[0], self.object_pos[1], self.size[0], self.size[1])
|
||||||
|
|
||||||
|
# theres a function for every type of collisions
|
||||||
|
# edit collisions here (I added some basic ones just so u can see)
|
||||||
|
# self if objects that it hit and obj is the object that hit smt
|
||||||
|
|
||||||
|
# always add both side of collisions (ask who collided with whom)
|
||||||
|
|
||||||
|
def hit_bottom(self, obj, objects):
|
||||||
|
if self.type == "solid":
|
||||||
|
if obj.type == "player":
|
||||||
|
obj.rect.bottom = self.rect.top
|
||||||
|
obj.object_pos = [obj.rect.x, obj.rect.y]
|
||||||
|
self.memory[0] -= 1
|
||||||
|
if self.memory[0] == 0:
|
||||||
|
objects.objects_to_delete.append(self.object_id)
|
||||||
|
|
||||||
|
opposite = obj.move.get_final_vector()
|
||||||
|
opp = [-opposite[0] * 0.4, -opposite[1] * 0.8]
|
||||||
|
obj.move.vectors.append(opp)
|
||||||
|
|
||||||
|
def hit_top(self, obj, objects):
|
||||||
|
if self.type == "solid":
|
||||||
|
if obj.type == "player":
|
||||||
|
obj.rect.top = self.rect.bottom
|
||||||
|
obj.object_pos = [obj.rect.x, obj.rect.y]
|
||||||
|
self.memory[0] -= 1
|
||||||
|
if self.memory[0] == 0:
|
||||||
|
objects.objects_to_delete.append(self.object_id)
|
||||||
|
|
||||||
|
opposite = obj.move.get_final_vector()
|
||||||
|
opp = [-opposite[0] * 0.4, -opposite[1] * 0.8]
|
||||||
|
obj.move.vectors.append(opp)
|
||||||
|
|
||||||
|
def hit_left(self, obj, objects):
|
||||||
|
if self.type == "solid":
|
||||||
|
if obj.type == "player":
|
||||||
|
obj.rect.left = self.rect.right
|
||||||
|
obj.object_pos = [obj.rect.x, obj.rect.y]
|
||||||
|
self.memory[0] -= 1
|
||||||
|
if self.memory[0] == 0:
|
||||||
|
objects.objects_to_delete.append(self.object_id)
|
||||||
|
|
||||||
|
opposite = obj.move.get_final_vector()
|
||||||
|
opp = [-opposite[0] * 0.4, -opposite[1] * 0.8]
|
||||||
|
obj.move.vectors.append(opp)
|
||||||
|
|
||||||
|
def hit_right(self, obj, objects):
|
||||||
|
if self.type == "solid":
|
||||||
|
if obj.type == "player":
|
||||||
|
obj.rect.right = self.rect.left
|
||||||
|
obj.object_pos = [obj.rect.x, obj.rect.y]
|
||||||
|
self.memory[0] -= 1
|
||||||
|
if self.memory[0] == 0:
|
||||||
|
objects.objects_to_delete.append(self.object_id)
|
||||||
|
|
||||||
|
opposite = obj.move.get_final_vector()
|
||||||
|
opp = [-opposite[0] * 0.4, -opposite[1] * 0.8]
|
||||||
|
obj.move.vectors.append(opp)
|
||||||
|
|
||||||
|
|
||||||
|
# next 2 classes are for object class
|
||||||
|
class Moving_Object:
|
||||||
|
def __init__(self):
|
||||||
|
# consts
|
||||||
|
self.degree = 0.0174533
|
||||||
|
self.pi = math.pi
|
||||||
|
self.half_pi = round(math.pi / 2, 6)
|
||||||
|
self.two_pi = round(math.pi * 2, 6)
|
||||||
|
self.three_halves_pi = round(3 * (math.pi / 2), 6)
|
||||||
|
self.speed = 1
|
||||||
|
self.force = 3
|
||||||
|
self.offset = 0
|
||||||
|
self.vectors = []
|
||||||
|
|
||||||
|
self.forward = False
|
||||||
|
self.backwards = False
|
||||||
|
self.left = False
|
||||||
|
self.right = False
|
||||||
|
|
||||||
|
self.collisions = False
|
||||||
|
|
||||||
|
def move(self, dir_movement):
|
||||||
|
|
||||||
|
movement = dir_movement
|
||||||
|
|
||||||
|
return movement
|
||||||
|
|
||||||
|
# dir is the angle the player is facing
|
||||||
|
def change_dir(self, direction, angle):
|
||||||
|
|
||||||
|
new_vector = [0, 0]
|
||||||
|
|
||||||
|
if self.left:
|
||||||
|
direction -= angle
|
||||||
|
if direction < 0:
|
||||||
|
direction += self.two_pi
|
||||||
|
new_vector[0] = round(math.cos(direction) * self.speed, 2)
|
||||||
|
new_vector[1] = round(math.sin(direction) * self.speed, 2)
|
||||||
|
self.vectors.append(new_vector)
|
||||||
|
elif self.right:
|
||||||
|
direction += angle
|
||||||
|
if direction > self.two_pi:
|
||||||
|
direction -= self.two_pi
|
||||||
|
new_vector[0] = round(math.cos(direction) * self.speed, 2)
|
||||||
|
new_vector[1] = round(math.sin(direction) * self.speed, 2)
|
||||||
|
self.vectors.append(new_vector)
|
||||||
|
elif self.forward:
|
||||||
|
new_vector[0] = round(math.cos(direction) * self.speed, 2)
|
||||||
|
new_vector[1] = round(math.sin(direction) * self.speed, 2)
|
||||||
|
self.vectors.append(new_vector)
|
||||||
|
|
||||||
|
return direction, self.get_final_vector()
|
||||||
|
|
||||||
|
# used for setting things before game loop
|
||||||
|
def set_start_dir_movement(self, direction, dir_movement):
|
||||||
|
dir_movement[0] = round(math.cos(direction + (self.offset * self.degree)) * self.speed, 2)
|
||||||
|
dir_movement[1] = round(math.sin(direction + (self.offset * self.degree)) * self.speed, 2)
|
||||||
|
return dir_movement
|
||||||
|
|
||||||
|
def get_final_vector(self):
|
||||||
|
to_remove = []
|
||||||
|
for i in range(len(self.vectors)-1):
|
||||||
|
self.vectors[i][0] *= 0.96
|
||||||
|
self.vectors[i][1] *= 0.96
|
||||||
|
if abs(self.vectors[i][0]) < 0.2 and abs(self.vectors[i][1]) < 0.2:
|
||||||
|
to_remove.append(self.vectors[i])
|
||||||
|
|
||||||
|
for item in to_remove:
|
||||||
|
self.vectors.remove(item)
|
||||||
|
|
||||||
|
final_vector = [0, 0]
|
||||||
|
|
||||||
|
for vector in self.vectors:
|
||||||
|
final_vector[0] += vector[0]
|
||||||
|
final_vector[1] += vector[1]
|
||||||
|
|
||||||
|
return final_vector
|
||||||
|
|
||||||
|
|
||||||
|
class Object(Collisions):
|
||||||
|
def __init__(self, typeX, object_id, x_y, movement, direction, moving, size, special=None):
|
||||||
|
super().__init__(typeX, object_id, x_y, movement, direction, moving, size, special)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.type
|
||||||
|
|
||||||
|
# changes position along with the rect
|
||||||
|
def change_pos(self, x_y):
|
||||||
|
self.object_pos = x_y
|
||||||
|
self.rect = pygame.Rect(self.object_pos[0], self.object_pos[1], self.size[0], self.size[1])
|
||||||
|
|
||||||
|
|
||||||
|
class Mouse:
|
||||||
|
|
||||||
|
points = 0
|
||||||
|
|
||||||
|
def __init__(self, mouse_pos):
|
||||||
|
self.mouse_pos = mouse_pos
|
||||||
|
self.mouse_scroll = [0, 0]
|
||||||
|
|
||||||
|
def update(self, Win_size, Default_size):
|
||||||
|
self.mouse_pos = pygame.mouse.get_pos()
|
||||||
|
self.mouse_pos = [((self.mouse_pos[0] - self.mouse_scroll[0]) * (Default_size[0] / Win_size[0])),
|
||||||
|
((self.mouse_pos[1] - self.mouse_scroll[1]) * (Default_size[1] / Win_size[1]))]
|
||||||
|
|
||||||
|
def get_scrolled(self, scroll):
|
||||||
|
scrolled_pos = [self.mouse_pos[0] + scroll.scroll[0],
|
||||||
|
self.mouse_pos[1] + scroll.scroll[1]]
|
||||||
|
return scrolled_pos
|
||||||
|
|
||||||
|
|
||||||
|
def distance_indicator(coords1, coords2):
|
||||||
|
x_distance = abs(coords1[0] - coords2[0])
|
||||||
|
y_distance = abs(coords1[1] - coords2[1])
|
||||||
|
distance = math.sqrt((x_distance ** 2) + (y_distance ** 2))
|
||||||
|
return round(distance, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def load_images(path, name, number_of_images, file_type=".png"):
|
||||||
|
images = []
|
||||||
|
for i in range(number_of_images):
|
||||||
|
images.append(pygame.image.load("{}/{}{}{}".format(path, name, i, file_type)).convert())
|
||||||
|
return images
|
||||||
|
|
||||||
|
|
||||||
|
def load_map(path):
|
||||||
|
f = open(path, "r")
|
||||||
|
data = f.read()
|
||||||
|
f.close()
|
||||||
|
data = data.split('\n')
|
||||||
|
product = []
|
||||||
|
for line in data:
|
||||||
|
product.append(list(line))
|
||||||
|
return product
|
||||||
|
|
||||||
|
|
||||||
|
# next func sorts object into objects class so the objects is stored where it should be
|
||||||
|
def sort(obj, objects):
|
||||||
|
objects.game_objects.append(obj)
|
||||||
|
|
||||||
|
if obj.moving:
|
||||||
|
objects.moving_objects.append(obj)
|
||||||
|
|
||||||
|
if obj.move.collisions:
|
||||||
|
objects.collision_objects.append(obj)
|
||||||
|
|
||||||
|
|
||||||
|
def find_collisions(obj, objects):
|
||||||
|
hit_list = []
|
||||||
|
for element in objects.game_objects:
|
||||||
|
if element.object_id != obj.object_id:
|
||||||
|
if element.rect.colliderect(obj.rect):
|
||||||
|
hit_list.append(element)
|
||||||
|
return hit_list
|
||||||
|
|
||||||
|
|
||||||
|
def collision(obj, objects):
|
||||||
|
# collisions for left/right
|
||||||
|
obj.change_pos([obj.object_pos[0] + obj.movement[0], obj.object_pos[1]])
|
||||||
|
hit_list = find_collisions(obj, objects)
|
||||||
|
for item in hit_list:
|
||||||
|
if obj.movement[0] > 0:
|
||||||
|
item.hit_right(obj, objects)
|
||||||
|
elif obj.movement[0] < 0:
|
||||||
|
item.hit_left(obj, objects)
|
||||||
|
|
||||||
|
# collisions for top/bottom
|
||||||
|
obj.change_pos([obj.object_pos[0], obj.object_pos[1] + obj.movement[1]])
|
||||||
|
hit_list = find_collisions(obj, objects)
|
||||||
|
for item in hit_list:
|
||||||
|
if obj.movement[1] > 0:
|
||||||
|
item.hit_bottom(obj, objects)
|
||||||
|
elif obj.movement[1] < 0:
|
||||||
|
item.hit_top(obj, objects)
|
||||||
|
|
||||||
|
|
||||||
|
# !!!!!!!!!!! config this function for every program !!!!!!!!!!
|
||||||
|
def load_objects(game_map, width, height, objects, game):
|
||||||
|
x, y = 0, 0
|
||||||
|
for line in game_map:
|
||||||
|
for obj in line:
|
||||||
|
# this is just to be efficient normaly u can use elif and put another obj to another num
|
||||||
|
if obj == "1":
|
||||||
|
obj = Object("solid", game.custom_id_giver, [x, y], [0, 0], 0, False, [width, height])
|
||||||
|
obj.memory.append(3)
|
||||||
|
sort(obj, objects)
|
||||||
|
game.custom_id_giver += 1
|
||||||
|
x += width
|
||||||
|
y += height
|
||||||
|
x = 0
|
||||||
|
|
||||||
|
|
||||||
|
def load_textures(objects, dictionary, display, scroll):
|
||||||
|
for object in objects.game_objects:
|
||||||
|
if object.special:
|
||||||
|
display.blit(object.specific.images[object.specific.attribute_0],
|
||||||
|
[object.object_pos[0] - scroll.scroll[0], object.object_pos[1] - scroll.scroll[1]])
|
||||||
|
else:
|
||||||
|
display.blit(dictionary["{}".format(object.type)],
|
||||||
|
[object.object_pos[0] - scroll.scroll[0], object.object_pos[1] - scroll.scroll[1]])
|
||||||
|
|
||||||
|
|
||||||
|
def load_sp_texture(objects, type_x, image):
|
||||||
|
for object in objects.special_objects:
|
||||||
|
if object.type == type_x:
|
||||||
|
object.attributes.images.append(image)
|
||||||
|
|
||||||
|
|
||||||
|
def load_bg(image, y_x, width, height, display):
|
||||||
|
pos = [0, 0]
|
||||||
|
for i in range(y_x[0]):
|
||||||
|
for j in range(y_x[1]):
|
||||||
|
display.blit(image, pos)
|
||||||
|
pos[0] += width
|
||||||
|
pos[0] = 0
|
||||||
|
pos[1] += height
|
||||||
|
|
||||||
|
|
||||||
|
def find_angle_between_points(center, point):
|
||||||
|
dists = distances(center, point)
|
||||||
|
try:
|
||||||
|
angle = math.atan(dists[1] / dists[0])
|
||||||
|
|
||||||
|
if point[0] < center[0]:
|
||||||
|
if point[1] < center[1]:
|
||||||
|
return angle + math.pi
|
||||||
|
else:
|
||||||
|
return (math.pi / 2 - angle) + (math.pi / 2)
|
||||||
|
else:
|
||||||
|
if point[1] < center[1]:
|
||||||
|
return (math.pi / 2 - angle) + 3 * (math.pi / 2)
|
||||||
|
else:
|
||||||
|
return angle
|
||||||
|
except ZeroDivisionError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def distances(cords1, cords2):
|
||||||
|
return [abs(cords1[0] - cords2[0]), abs(cords1[1] - cords2[1])]
|
||||||
|
|
||||||
|
|
||||||
|
def average(*args):
|
||||||
|
sumX = 0
|
||||||
|
for item in args:
|
||||||
|
sumX += item
|
||||||
|
return sumX/len(args)
|
||||||
|
|
||||||
|
|
||||||
|
def area_intersection_of_circles(points, radius_list):
|
||||||
|
try:
|
||||||
|
dist = distance_indicator(points[0], points[1])
|
||||||
|
|
||||||
|
alpha_cos = (pow(radius_list[1], 2) + pow(dist, 2) - pow(radius_list[0], 2)) / (2 * radius_list[1] * dist)
|
||||||
|
|
||||||
|
alpha = math.acos(alpha_cos)
|
||||||
|
|
||||||
|
beta_cos = (dist - alpha_cos * radius_list[1]) / radius_list[0]
|
||||||
|
|
||||||
|
beta = math.acos(beta_cos)
|
||||||
|
|
||||||
|
triangles = (alpha_cos * pow(radius_list[1], 2) * math.sin(alpha)) + (
|
||||||
|
beta_cos * pow(radius_list[0], 2) * math.sin(beta))
|
||||||
|
|
||||||
|
arcs = ((math.pi * pow(radius_list[0], 2) * beta * 2) / math.tau) + (
|
||||||
|
(math.pi * pow(radius_list[1], 2) * alpha * 2) / math.tau)
|
||||||
|
|
||||||
|
return arcs - triangles
|
||||||
|
except:
|
||||||
|
return False
|
12
sounds.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import pygame
|
||||||
|
from pygame.locals import *
|
||||||
|
|
||||||
|
pygame.init()
|
||||||
|
|
||||||
|
|
||||||
|
def get_sounds():
|
||||||
|
sounds = {"click": pygame.mixer.Sound("assets/sounds/click.wav"),
|
||||||
|
"remove": pygame.mixer.Sound("assets/sounds/remove.wav"),
|
||||||
|
"join": pygame.mixer.Sound("assets/sounds/join.wav")}
|
||||||
|
|
||||||
|
return sounds
|
99
widget_engine.py
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import pygame
|
||||||
|
import math
|
||||||
|
|
||||||
|
|
||||||
|
class Button:
|
||||||
|
|
||||||
|
def __init__(self, pos, size, images, onclick=None, onclick_args=None, active=True):
|
||||||
|
self.pos = pos
|
||||||
|
self.size = size
|
||||||
|
self.rect = pygame.Rect(pos[0], pos[1], size[0], size[1])
|
||||||
|
self.images = images
|
||||||
|
self.display_image = images["idle"]
|
||||||
|
self.on_click = onclick
|
||||||
|
self.oc_args = onclick_args
|
||||||
|
self.active = active
|
||||||
|
self.switch_images = None
|
||||||
|
self.name = ""
|
||||||
|
|
||||||
|
def hover_check(self, mouse_pos):
|
||||||
|
if self.active:
|
||||||
|
if self.rect.collidepoint(mouse_pos):
|
||||||
|
self.display_image = self.images["hover"]
|
||||||
|
else:
|
||||||
|
self.display_image = self.images["idle"]
|
||||||
|
|
||||||
|
def click_check(self, mouse_pos):
|
||||||
|
if self.active:
|
||||||
|
if self.rect.collidepoint(mouse_pos):
|
||||||
|
if self.on_click is not None:
|
||||||
|
self.on_click(self.oc_args)
|
||||||
|
|
||||||
|
def blit(self, display, scroll=None):
|
||||||
|
if self.active:
|
||||||
|
if scroll is None:
|
||||||
|
display.blit(self.display_image, self.pos)
|
||||||
|
else:
|
||||||
|
display.blit(self.display_image, [self.pos[0] - scroll.scroll[0],
|
||||||
|
self.pos[1] - scroll.scroll[1]])
|
||||||
|
|
||||||
|
def switch(self, mouse_pos):
|
||||||
|
self.switch_images, self.images = self.images, self.switch_images
|
||||||
|
self.hover_check(mouse_pos)
|
||||||
|
|
||||||
|
def move(self, movement):
|
||||||
|
self.pos = [self.pos[0] + movement[0],
|
||||||
|
self.pos[1] + movement[1]]
|
||||||
|
self.rect = pygame.Rect(self.pos[0], self.pos[1], self.size[0], self.size[1])
|
||||||
|
|
||||||
|
|
||||||
|
class CircleButton:
|
||||||
|
def __init__(self, size, pos, images, onclick=None, onclick_args=None, active=True):
|
||||||
|
self.pos = pos
|
||||||
|
self.size = size
|
||||||
|
self.center = [pos[0] + (size/2), pos[1] + (size/2)]
|
||||||
|
self.radius = size/2
|
||||||
|
self.images = images
|
||||||
|
self.display_image = images["idle"]
|
||||||
|
self.on_click = onclick
|
||||||
|
self.oc_args = onclick_args
|
||||||
|
self.active = active
|
||||||
|
self.switch_images = None
|
||||||
|
self.name = ""
|
||||||
|
|
||||||
|
def hover_check(self, mouse_pos):
|
||||||
|
if self.active:
|
||||||
|
if distance_indicator(self.center, mouse_pos) <= self.radius:
|
||||||
|
self.display_image = self.images["hover"]
|
||||||
|
else:
|
||||||
|
self.display_image = self.images["idle"]
|
||||||
|
|
||||||
|
def click_check(self, mouse_pos):
|
||||||
|
if self.active:
|
||||||
|
if distance_indicator(self.center, mouse_pos) <= self.radius:
|
||||||
|
if self.on_click is not None:
|
||||||
|
self.on_click(self.oc_args)
|
||||||
|
|
||||||
|
def blit(self, display, scroll=None):
|
||||||
|
if self.active:
|
||||||
|
if scroll is None:
|
||||||
|
display.blit(self.display_image, self.pos)
|
||||||
|
else:
|
||||||
|
display.blit(self.display_image, [self.pos[0] - scroll.scroll[0],
|
||||||
|
self.pos[1] - scroll.scroll[1]])
|
||||||
|
|
||||||
|
def switch(self, mouse_pos):
|
||||||
|
self.switch_images, self.images = self.images, self.switch_images
|
||||||
|
self.hover_check(mouse_pos)
|
||||||
|
|
||||||
|
def move(self, movement):
|
||||||
|
self.pos = [self.pos[0] + movement[0],
|
||||||
|
self.pos[1] + movement[1]]
|
||||||
|
self.center = [self.pos[0] + (self.size / 2), self.pos[1] + (self.size / 2)]
|
||||||
|
|
||||||
|
|
||||||
|
def distance_indicator(cords1, cords2):
|
||||||
|
x_distance = abs(cords1[0] - cords2[0])
|
||||||
|
y_distance = abs(cords1[1] - cords2[1])
|
||||||
|
distance = round(math.sqrt((x_distance**2) + (y_distance**2)))
|
||||||
|
return distance
|