diff --git a/Thelda/Thelda.py b/Thelda/Thelda.py new file mode 100644 index 00000000..8a777f21 --- /dev/null +++ b/Thelda/Thelda.py @@ -0,0 +1,137 @@ +import thumby +import gc +import json +from sys import path +path.append("/Games/Thelda") +# import thumbyHardware +import fonthandler +from player import Player +gc.collect() +from enemycontroller import EnemyController +gc.collect() +from scenecontroller import SceneController +gc.collect() +from hudcontroller import HudController +gc.collect() + + +# Set framerate +thumby.display.setFPS(20) # set frame rate + +# # Set tiny, almost unreadable font +font_handler = fonthandler.FontHandler() +gc.collect() + +# Create Scene Controller +scene_controller = SceneController() +gc.collect() + +#Create enemy controller +enemy_controller = EnemyController() +gc.collect +# from musicplayer import MusicPlayer + +def loadgame(): + with open("/Games/Thelda/save.json", 'r') as savefile: + thisdata = json.load(savefile) + return thisdata + +title_screen = bytearray([0,252,14,246,26,234,234,234,106,106,106,234,106,234,106,234,106,234,234,234,234,106,234,234,234,106,234,234,234,106,106,234,234,106,234,234,234,106,106,234,234,106,106,234,234,234,106,106,106,234,106,106,106,234,234,234,234,234,234,234,234,234,234,234,234,234,234,26,22,14,252,0, + 0,255,0,255,0,255,255,255,159,164,183,55,244,246,52,55,52,4,5,207,247,52,5,197,63,196,244,53,7,196,13,244,247,20,20,21,7,204,7,244,7,12,253,254,7,247,244,53,52,103,204,30,63,255,7,247,23,23,55,199,15,63,255,255,255,255,255,0,0,0,255,0, + 0,255,0,255,0,255,255,255,207,147,156,159,135,224,248,199,153,158,159,135,227,243,194,146,158,143,129,224,198,152,159,159,145,145,145,128,230,192,158,159,152,152,155,155,131,128,199,158,152,153,152,159,192,224,192,159,156,132,229,228,223,152,128,135,255,255,255,0,0,0,255,0, + 0,255,254,253,251,250,120,184,216,184,120,248,248,248,248,248,248,248,248,248,248,56,184,56,248,56,184,120,248,56,184,184,248,56,184,184,248,56,184,184,248,248,248,248,248,56,248,120,184,120,248,56,248,248,248,248,248,248,248,248,248,120,184,216,184,120,248,248,252,254,255,0, + 0,63,127,119,115,116,118,116,114,116,118,116,115,119,127,127,127,127,127,127,127,120,126,126,127,120,126,121,127,120,122,123,127,122,122,120,127,122,122,120,127,127,127,127,127,127,127,120,126,120,127,127,127,127,127,127,127,127,119,115,116,118,116,114,116,118,116,115,119,127,63,0]) + +gc.collect() + +menu = True +menu2 = False +while menu: + thumby.display.fill(0) + thumby.display.blit(title_screen, 0, 0, 72, 40, -1, 0, 0) + playing = False + start_button_pressed = thumby.buttonA.justPressed() + if start_button_pressed: + # playing = True + menu2 = True + menu = False + arrow_position_y = 19 + gc.collect() + else: menu = True + + thumby.display.update() + +while menu2: + thumby.display.fill(1) + thumby.display.drawText("New Game", 10, 17, 0) + thumby.display.drawText("Load Game", 10, 25, 0) + arrow = bytearray([0,0,5]) + thumby.display.blit(arrow, 6, arrow_position_y, 3, 3, -1, 0, 0) + if arrow_position_y == 19: + if thumby.dpadJustPressed(): + arrow_position_y = 27 + thumby.display.blit(arrow, 6, arrow_position_y, 3, 3, -1, 0, 0) + else: + if arrow_position_y == 27: + if thumby.dpadJustPressed(): + arrow_position_y = 19 + thumby.display.blit(arrow, 6, arrow_position_y, 3, 3, -1, 0, 0) + if thumby.buttonA.justPressed(): + if arrow_position_y == 19: + savedata = [6, 6, 0, 0, 0, True, [], []] + menu2 = False + playing = True + else: + try: + savedata = loadgame() + except: + savedata = [6, 6, 0, 0, 0, True, [], []] + else: + scene_controller.isDangerous = savedata[5] + scene_controller.doors_unlocked = savedata[6] + scene_controller.keys_used = savedata[7] + gc.collect() + menu2 = False + playing = True + print(savedata) + thumby.display.update() + + +my_player = Player(enemy_controller, scene_controller, thumby, savedata) +gc.collect() + +#Create HudController +hud_controller = HudController(my_player) + +gc.collect() + +# music_player = MusicPlayer() +# Begin main game loop that runs for the course of the game +while playing: + # allocmem = gc.mem_alloc() + # freemem = gc.mem_free() + + # music_player.play_song() + thumby.display.fill(1) # Fill canvas to white + scene_controller.build_scene(scene_controller.scene_x, scene_controller.scene_y, font_handler, thumby.display, enemy_controller) + enemy_controller.populate_enemies(scene_controller) + enemy_controller.move_enemies(scene_controller) + enemy_controller.attack(my_player) + enemy_controller.display_loot(my_player, enemy_controller, thumby.display) + if not my_player.swinging: + my_player.move_player(scene_controller, enemy_controller, thumby, json) + my_player.use_item(enemy_controller, thumby) + if not scene_controller.isDangerous: + my_player.swing_sword(enemy_controller, thumby) + hud_controller.display_hearts(my_player) + hud_controller.display_rupees(font_handler, my_player) + hud_controller.display_keys(font_handler, my_player) + hud_controller.display_bombs(font_handler, my_player) + hud_controller.pause_game(font_handler, my_player) + my_player.hit_detection(enemy_controller, thumby) + my_player.death(thumby.display) + # print(f"Memory Allocated: {allocmem}") + # print(f"Memory Free: {freemem}") + # print(f"Keys used: {scene_controller.keys_used}") + thumby.display.update() + \ No newline at end of file diff --git a/Thelda/arcade_description.txt b/Thelda/arcade_description.txt new file mode 100644 index 00000000..dcf63e09 --- /dev/null +++ b/Thelda/arcade_description.txt @@ -0,0 +1,46 @@ +The Legend of Thelda (DEMO) + +This is an ongoing attempt to recreate the NES classic +of a similar title for the Thumby console. + +It's dangerous to go alone! +Don't forget to grab your sword from the cave on the +starting map screen. + +Currently has six unique enemies. + +If you encounter an UNDER CONSTRUCTION screen, +simply return the way you came. + +Access pause menu by pressing "A+B + UP" and exit +with the same. + +Bombs do damage but don't destroy walls yet. +Boomerang works to freeze enemies in place. +Bow is not yet implemented. + +Shield can deflect octorok attacks but not zora attacks, +and only if you're not attacking on impact. + +THIS IS A WORK IN PROGRESS AND IS UNFINISHED + +The world isn't fully populated with enemies, the first +dungeon is still unfinished. There is currently no actual +goal for the player to accomplish. Right now, it's just an +explorable sandbox. + +SOON: The next update should include a larger world map, + three more enemy types, pushable blocks, spike traps, +Dungeon Boss 1 and working bow and arrows. + +FUTURE: Shops, loot changes, more enemies, more items, +music and more sound effects. + + +The current state of this project has been reached without +using any AI assistance, and is a labor of love and obsession. + + +Author: PanduhBeer +Version: 0.3.11 + diff --git a/Thelda/arcade_title_video.webm b/Thelda/arcade_title_video.webm new file mode 100644 index 00000000..6c919fcc Binary files /dev/null and b/Thelda/arcade_title_video.webm differ diff --git a/Thelda/dungeons1.py b/Thelda/dungeons1.py new file mode 100644 index 00000000..651f576d --- /dev/null +++ b/Thelda/dungeons1.py @@ -0,0 +1,279 @@ +from random import randint + +class NSDoorway: + def __init__(self, x, y): + self.doorway = bytearray([31,31,31,31,31,31]) + self.x = x + self.y = y + self.size_x = 6 + + +class EWDoorway: + def __init__(self, x, y): + self.doorway = bytearray([31,31,31,31,31]) + self.x = x + self.y = y + self.size_x = 5 + + +class NSLock: + def __init__(self, x, y, identity): + self.lock = bytearray([0,14,10,10,14,0]) + self.identity = identity + self.x = x + self.y = y + self.size_x = 6 + + +class EWLock: + def __init__(self, x, y, identity): + self.lock = bytearray([0,14,10,14,0]) + self.identity = identity + self.x = x + self.y = y + self.size_x = 5 + + +class Scenes80: + def __init__(self): + + + self.scenes = { + "scene -797,404": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (66, 20), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35), + (33, 5), (33, 35)], + "doorways": [EWDoorway(1, 20)], + "blocks": [(11, 10), (16, 10), (21, 10), (26, 10), (31, 10), (36, 10), (41, 10), (46, 10), (51, 10), (56, 10), + (11, 15), (56, 15), + (11, 20), (56, 20), + (11, 25), (16, 25), (21, 25), (26, 25), (41, 25), (46, 25), (51, 25), (56, 25)], + "bushes": [(26, 15), (41, 15), + (21, 20), (46, 20)] + }, + + "scene -798,403": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (66, 20), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "doorways": [EWDoorway(1, 20), NSDoorway(33, 5)], + "blocks": [(11, 15), (21, 15), (31, 15), (36, 15), (46, 15), (56, 15), + (11, 25), (21, 25), (31, 25), (36, 25), (46, 25), (56, 25)], + }, + + "scene -798,404": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 20), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "doorways": [EWDoorway(66, 20), NSDoorway(33, 35)], + "blocks": [(46, 10), (51, 10), (56, 10), (61, 10), + (56, 15), (61, 15), + (56, 25), (61, 25), + (46, 30), (51, 30), (56, 30), (61, 30)], + }, + + "scene -799,400": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35), + (33, 5), (33, 35), (66, 20)], + "doorways": [EWDoorway(1, 20)], + "blocks": [(16, 15), (21, 15), (46, 15), (51, 15), + (16, 20), (21, 20), (46, 20), (51, 20), + (16, 25), (21, 25), (46, 25), (51, 25)], + "enemies": {"stalfos": [("D1E01"), ("D1E02"), ("D1E03"), ("D1E04")]}, + "keys": [(0, 0, False, "K101", False)], + }, + + "scene -799,402": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (66, 20), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35), + (33, 5), (33, 35), (66, 20)], + "doorways": [EWDoorway(1, 20)], + + "blocks": [(16, 15), (51, 15), (16, 25), (51, 25)], + "enemies": {"keese": [(randint(11, 56), randint(10, 25), "D1E16"), (randint(11, 56), randint(10, 25), "D1E17"), (randint(11, 56), randint(10, 25), "D1E18"), + (randint(11, 56), randint(10, 25), "D1E19"), (randint(11, 56), randint(10, 25), "D1E20")]} + }, + + "scene -799,403": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "doorways": [EWDoorway(1, 20), EWDoorway(66, 20)], + "blocks": [(21, 15), (21, 25), (46, 15), (46, 25)], + }, + + "scene -800,400": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35), ], + "doorways": [NSDoorway(33, 5), NSDoorway(33, 35), EWDoorway(66, 20), EWDoorway(1, 20)], + "locks" : [NSLock(33, 5, "D101")], + "blocks": [(11, 15), (26, 15), (41, 15), (56, 15), (11, 25), (26, 25), (41, 25), (56, 25)] + }, + + "scene -800,401": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35), + (1, 20), (66, 20)], + "doorways": [NSDoorway(33, 5), NSDoorway(33, 35)], + "blocks": [(31, 15), (36, 15), + (31, 20), (36, 20), + (31, 25), (36, 25),], + "enemies": {"stalfos": [("D1E05"), ("D1E06"), ("D1E07")]}, + }, + + "scene -800,402": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "doorways": [EWDoorway(1, 20), EWDoorway(66, 20), NSDoorway(33, 35)], + "blocks": [(21, 15), (21, 25), (46, 15), (46, 25),], + "enemies": {"stalfos": [("D1E08"), ("D1E09"), ("D1E10"), ("D1E11"), ("D1E12")]}, + "keys": [(36, 15, True, "K103", True)], + }, + + "scene -800,403": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35), ], + "doorways": [NSDoorway(33, 5), EWDoorway(66, 20), EWDoorway(1, 20)], + "blocks": [(16, 15), (21, 15), (46, 15), (51, 15), (31, 20), (36, 20), (16, 25), (21, 25), (46, 25), (51, 25)] + }, + + "scene -800,404": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35), + (1, 20), (66, 20)], + "doorways": [NSDoorway(33, 5), NSDoorway(33, 35)], + "bushes": [(6, 10), (11, 10), (16, 10), (21, 10), (26, 10), (41, 10), (46, 10), (51, 10), (56, 10), (61, 10), + (6, 15), (26, 15), (31, 15), (51, 15), + (6, 20), (16, 20), (26, 20), (41, 20), (51, 20), (61, 20), + (16, 25), (36, 25), (41, 25), (61, 25), + (6, 30), (11, 30), (16, 30), (21, 30), (26, 30), (41, 30), (46, 30), (51, 30), (56, 30), (61, 30)], + "enemies": {"stalfos": [("D1E26"), ("D1E27"), ("D1E28")]}, + }, + + "scene -800,405": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35), + (66, 20)], + "doorways": [NSDoorway(33, 35), EWDoorway(1, 20)], + "bushes": [(11, 15), (16, 15), (51, 15), (56, 15), + (11, 20), (26, 20), (31, 20), (36, 20), (41, 20), (56, 20), + (11, 25), (16, 25), (51, 25), (56, 25)], + "enemies": {"stalfos": [("D1E29"), ("D1E30"), ("D1E31")]}, + }, + + "scene -801,402": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35), + (1, 20)], + "doorways": [NSDoorway(33, 5), EWDoorway(66, 20)], + "blocks": [(31, 15), (36, 15), + (31, 20), (36, 20), + (31, 25), (36, 25),], + "locks": [NSLock(33, 5, "D102")], + "enemies": {"keese": [(randint(11, 56), randint(10, 25), "D1E21"), (randint(11, 56), randint(10, 25), "D1E22"), (randint(11, 56), randint(10, 25), "D1E23"), + (randint(11, 56), randint(10, 25), "D1E24"), (randint(11, 56), randint(10, 25), "D1E25")]} + }, + + "scene -801,403": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "doorways": [EWDoorway(1, 20), EWDoorway(66, 20), NSDoorway(33, 35)], + "blocks": [(31, 20)] + }, + + "scene -801,405": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35), + (33, 5), (33, 35), (1, 20)], + "doorways": [EWDoorway(66, 20)], + "blocks": [(36, 15), (31, 20), (41, 20), (36, 25)], + "stairs": [(36, 20)] + }, + + "scene -801,400": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35), + (33, 5), (33, 35), (1, 20)], + "doorways": [EWDoorway(66, 20)], + "keys": [(51, 30, True, "K102", True)], + "enemies": {"keese": [(10, 13, "D1E13"), (18, 18, "D1E14"), (10, 28, "D1E15")]} + }, + + "scene -802,403": { + "barriers": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35), + (33, 5), (33, 35), (1, 20)], + "doorways": [EWDoorway(66, 20)] + } + + } diff --git a/Thelda/enemycontroller.py b/Thelda/enemycontroller.py new file mode 100644 index 00000000..d8eeb144 --- /dev/null +++ b/Thelda/enemycontroller.py @@ -0,0 +1,925 @@ +from thumby import Sprite, display +import gc +from sys import path +path.append("/Games/Thelda") +from random import choice, randrange, randint + +class Octorok: + def __init__(self, x, y, facingDirection, walk_distance, rocks, identity): + self.identity = identity + self.enemy_type = "octorok" + self.x = x + self.y = y + self.damage = 1 + self.starting_health = 1 + self.health = 1 + self.frozen = False + self.freeze_counter = 0 + self.is_dead = False + self.attack_speed = 199 + self.prespawn = True + + self.blank_map = bytearray([31, 31, 31, 31, 31]) + self.prespawn_map = bytearray([25, 5, 14, 20, 19]) + self.enemy_up_map = bytearray([7, 10, 0, 10, 7]) + self.enemy_up_map_2 = bytearray([19, 9, 1, 9, 19]) + self.enemy_right_map = bytearray([0, 10, 17, 27, 17]) + self.enemy_right_map_2 = bytearray([17, 10, 0, 17, 31]) + + self.directions = ["up", "down", "left", "right"] + self.facingDirection = facingDirection + self.colliding_wall = None + self.move_speed = 1 + self.move_buffer = 0 + self.walk_distance = walk_distance + self.distance_count = 0 + self.attack_counter = 0 + self.rocks = rocks + + +class Tektite: + def __init__(self, x, y, identity): + self.identity = identity + self.enemy_type = "tektite" + self.x = x + self.y = y + self.damage = 1 + self.starting_health = 1 + self.health = 1 + self.frozen = False + self.freeze_counter = 0 + self.is_dead = False + self.attack_speed = 199 + self.prespawn = True + self.move_speed = 1 + self.animation_counter = 0 + self.is_jumping = False + self.apex_reached = False + self.jump_counter = 0 + self.jump_direction = "" + self.jump_x = int + self.jump_y = int + self.prejump_x = int + self.prejump_y = int + self.blank_map = bytearray([31, 31, 31, 31, 31]) + self.prespawn_map = bytearray([25, 5, 14, 20, 19]) + self.extended_map = bytearray([5, 26, 24, 26, 5]) + self.crouched_map = bytearray([3, 21, 17, 21, 3]) + + +class Zora: + def __init__(self, x, y, identity): + self.identity = identity + self.enemy_type = "zora" + self.x = x + self.y = y + self.damage = 1 + self.starting_health = 3 + self.health = 3 + self.frozen = False + self.freeze_counter = 0 + self.is_dead = False + self.attack_speed = 199 + self.magic = [] + self.prespawn = True + self.spawn_animation_counter = 0 + self.blank_map = bytearray([31, 31, 31, 31, 31]) + self.prespawn_map = bytearray([25, 5, 14, 20, 19]) + self.surface_map_1 = bytearray([15, 15, 23, 23, 23]) + self.surface_map_2 = bytearray([23, 23, 15, 15, 15]) + self.surface_map_3 = bytearray([23, 15, 15, 23, 23]) + self.attack_map = bytearray([1, 10, 8, 10, 1]) + self.has_fired = False + + +class Leever: + def __init__(self, x, y, identity): + self.identity = identity + self.enemy_type = "leever" + self.x = x + self.y = y + self.damage = 1 + self.starting_health = 3 + self.health = 3 + self.frozen = False + self.freeze_counter = 0 + self.is_dead = False + self.prespawn = True + self.spawn_animation_counter = 0 + self.is_buried = True + + self.directions = ["up", "down", "left", "right"] + self.facingDirection = "" + self.colliding_wall = None + self.move_speed = 1 + self.move_buffer = 0 + self.walk_distance = 5 + self.distance_count = 0 + self.blank_map = bytearray([31, 31, 31, 31, 31]) + self.prespawn_map = bytearray([31, 31, 31, 31, 31]) + self.surface_map_1 = bytearray([15, 31, 15, 31, 15]) + self.surface_map_2 = bytearray([15, 23, 15, 23, 15]) + self.surface_map_3 = bytearray([15, 19, 3, 19, 15]) + self.attacking_map_1 = bytearray([15, 4, 1, 4, 15]) + self.attacking_map_2 = bytearray([14, 5, 0, 5, 14]) + + +class Stalfos: + def __init__(self, x, y, facingDirection, walk_distance, identity): + self.identity = identity + self.enemy_type = "stalfos" + self.x = x + self.y = y + self.damage = 1 + self.health = 2 + self.frozen = False + self.freeze_counter = 0 + self.starting_health = 2 + self.animation_counter = 0 + # BITMAP: width: 7, height: 6 + self.map = bytearray([27,21,16,5,28]) + self.directions = ["up", "down", "left", "right"] + self.prespawn = True + self.prespawn_map = bytearray([25, 5, 14, 20, 19]) + self.facingDirection = facingDirection + self.walk_distance = walk_distance + self.distance_count = 0 + self.move_buffer = 0 + self.is_dead = False + self.move_speed = 1 + self.has_key = False + self.blank_map = bytearray([31, 31, 31, 31, 31]) + + +class Keese: + def __init__(self, x, y, identity): + self.identity = identity + self.enemy_type = "keese" + self.x = x + self.y = y + self.damage = 1 + self.starting_health = 1 + self.health = 1 + self.frozen = False + self.freeze_counter = 0 + self.is_dead = False + self.attack_speed = randrange(20, 60) + self.prespawn = True + self.animation_counter = 0 + self.is_flying = False + self.fly_counter = 0 + self.flight_time = 120 + self.blank_map = bytearray([31, 31, 31, 31, 31]) + self.prespawn_map = bytearray([31,19,25,19,31]) + self.flap1_map = bytearray([25,29,27,29,25]) + self.flap2_map = bytearray([23,19,27,19,23]) + + + +class Rock: + def __init__(self, enemy): + self.parent_enemy = enemy + self.x = enemy.x + 1 + self.y = enemy.y + 1 + self.rock = bytearray([0,2,0]) + self.direction = enemy.facingDirection + self.speed = 2 + self.timer = 0 + self.lifespan = 10 + self.reflected = False + + + def move(self): + if self.direction == "up": + self.y -= self.speed + if self.reflected: + self.x -= self.speed + elif self.direction == "down": + self.y += self.speed + if self.reflected: + self.x += self.speed + elif self.direction == "right": + self.x += self.speed + if self.reflected: + self.y += self.speed + elif self.direction == "left": + self.x -= self.speed + if self.reflected: + self.y -= self.speed + self.timer += 1 + self.rock_sprite = Sprite(3, 3, self.rock, self.x, self.y, key=-1) + + +class Magic: + def __init__(self, enemy, player): + self.enemy = enemy + self.target_x = player.playerSprite.x + 6 + self.target_y = player.playerSprite.y + 6 + self.x = enemy.x + 1 + self.y = enemy.y + 1 + self.dir = (self.target_x - self.x, self.target_y - self.y) + self.length = (abs(self.dir[0]) + abs(self.dir[1])) + self.magic_map = bytearray([0,2,0]) + self.magic_map_flash = bytearray([0,0,0]) + self.animation_counter = 0 + self.speed = 2 + self.reflected = False + self.dir = (self.dir[0] / self.length, self.dir[1] / self.length) + + def move(self): + self.x = self.x + self.dir[0] * self.speed + self.y = self.y + self.dir[1] * self.speed + + if self.animation_counter == 0: + self.magic_sprite = Sprite(3, 3, self.magic_map, self.x, self.y, key=1) + self.animation_counter += 1 + elif self.animation_counter == 1: + self.magic_sprite = Sprite(3, 3, self.magic_map_flash, self.x, self.y, key=1) + self.animation_counter -= 1 + + +class EnemyController: + def __init__(self): + self.enemies = [] + self.loot = [] + self.spawn_counter = 0 + self.spawn_time = 30 + self.enemies_killed = False + self.animation_counter = 0 + self.animation_length = 8 + self.map_to_display = () + self.enemies_used = () + + + def display_death_sprite(self, enemy): + + death_map_1 = bytearray([255,255,255,239,215,239,255,255,255, + 1,1,1,1,1,1,1,1,1]) + death_map_2 = bytearray([255,255,239,215,187,215,239,255,255, + 1,1,1,1,1,1,1,1,1]) + # BITMAP: width: 15, height: 15 + death_map_3 = bytearray([255,239,187,255,125,255,187,239,255, + 1,1,1,1,1,1,1,1,1]) + death_map_4 = bytearray([238,125,255,255,254,255,255,125,238, + 0,1,1,1,0,1,1,1,0]) + + death_sprite = Sprite(9, 9, death_map_1+death_map_1+death_map_2+death_map_2+death_map_3+death_map_3+death_map_4+death_map_4, enemy.x - 2, enemy.y - 2, key=1) + death_sprite.setFrame(self.animation_counter) + display.drawSprite(death_sprite) + self.animation_counter += 1 + + + def check_for_overlap(self, scene_controller, enemy): + elements = scene_controller.walls + scene_controller.bushes + scene_controller.water + scene_controller.trees + scene_controller.barriers + scene_controller.blocks + scene_controller.locks + + while any(enemy.x < element.x + 5 and enemy.x + 5 > element.x and element.y < enemy.y + 5 and element.y + 5 > enemy.y for element in elements): + enemy.x = randrange(11, 56, 5) + enemy.y = randrange(10, 25, 5) + + gc.collect() + + + def populate_enemies(self, scene_controller): + if not self.enemies_killed: + if self.enemies == []: + if "enemies" in scene_controller.this_scene: + for enemy in scene_controller.this_scene["enemies"]: + + if enemy == "octorok": + for octorok in scene_controller.this_scene["enemies"][enemy]: + enemyx = randrange(11, 56, 5) + enemyy = randrange(10, 25, 5) + enemy_facingDirection = choice(["up", "down", "left", "right"]) + enemy_walkDistance = randrange(10, 30) + enemy_rocks = [] + if not octorok in self.enemies_used: + self.enemies.append(Octorok(enemyx, enemyy, enemy_facingDirection, enemy_walkDistance, enemy_rocks, octorok)) + gc.collect() + + if enemy == "tektite": + for tektite in scene_controller.this_scene["enemies"][enemy]: + enemyx = randrange(11, 56, 5) + enemyy = randrange(10, 25, 5) + if not tektite in self.enemies_used: + self.enemies.append(Tektite(enemyx, enemyy, tektite)) + gc.collect() + + if enemy == "leever": + for leever in scene_controller.this_scene["enemies"][enemy]: + enemyx = randrange(11, 56, 5) + enemyy = randrange(10, 25, 5) + if not leever in self.enemies_used: + self.enemies.append(Leever(enemyx, enemyy, leever)) + gc.collect() + + if enemy == "zora": + for zora in scene_controller.this_scene["enemies"][enemy]: + spawn_tile = choice(scene_controller.water) + x = spawn_tile.x + y = spawn_tile.y + if not zora in self.enemies_used: + self.enemies.append(Zora(x, y, zora)) + gc.collect() + + if enemy == "stalfos": + for stalfos in scene_controller.this_scene["enemies"][enemy]: + enemyx = randrange(11, 56, 5) + enemyy = randrange(10, 25, 5) + enemy_facingDirection = choice(["up", "down", "left", "right"]) + enemy_walkDistance = randrange(10, 30) + if not stalfos in self.enemies_used: + self.enemies.append(Stalfos(enemyx, enemyy, enemy_facingDirection, enemy_walkDistance, stalfos)) + gc.collect() + + if enemy == "keese": + for keese in scene_controller.this_scene["enemies"][enemy]: + if not keese[2] in self.enemies_used: + self.enemies.append(Keese(keese[0], keese[1], keese[2])) + gc.collect() + + + if len(self.enemies) > 0: + print(f"Enemies: {len(self.enemies)}") + for enemy in self.enemies: + if not enemy.enemy_type == "zora" and not enemy.enemy_type == "tektite" and not enemy.enemy_type == "keese": + self.check_for_overlap(scene_controller, enemy) + print(enemy.enemy_type) + # gc.collect() + + + def move_enemies(self, scene_controller): + desired_movement_buffer = 1 + self.map_to_display = () + for enemy in self.enemies: + if enemy.frozen: + if enemy.freeze_counter < 40: + enemy.frozen = True + enemy.freeze_counter += 1 + else: + enemy.freeze_counter = 0 + enemy.frozen = False + if self.spawn_counter < self.spawn_time: + enemy.prespawn = True + if enemy.enemy_type == "zora": + if enemy.spawn_animation_counter < 10: + self.map_to_display = (enemy.surface_map_1, 0, 0) + enemy.spawn_animation_counter += 1 + self.spawn_counter += 1 + elif enemy.spawn_animation_counter < 20: + self.map_to_display = (enemy.surface_map_2, 0, 0) + enemy.spawn_animation_counter += 1 + self.spawn_counter += 1 + elif enemy.spawn_animation_counter < 30: + self.map_to_display = (enemy.surface_map_3, 0, 0) + enemy.spawn_animation_counter += 1 + self.spawn_counter += 1 + else: + self.map_to_display = (enemy.attack_map, 0, 0) + enemy.spawn_animation_counter = 0 + self.spawn_counter += 1 + else: + self.map_to_display = (enemy.prespawn_map, 0, 0) + self.spawn_counter += 1 + + if enemy.enemy_type == "leever": + if enemy.spawn_animation_counter < 10: + self.map_to_display = (enemy.surface_map_1, 0, 0) + enemy.spawn_animation_counter += 1 + self.spawn_counter += 1 + elif enemy.spawn_animation_counter < 20: + self.map_to_display = (enemy.surface_map_2, 0, 0) + enemy.spawn_animation_counter += 1 + self.spawn_counter += 1 + elif enemy.spawn_animation_counter < 30: + self.map_to_display = (enemy.surface_map_3, 0, 0) + enemy.spawn_animation_counter += 1 + self.spawn_counter += 1 + else: + self.map_to_display = (enemy.attacking_map_1, 0, 0) + enemy.spawn_animation_counter = 0 + self.spawn_counter += 1 + else: + if not enemy.enemy_type == "zora": + self.map_to_display = (enemy.prespawn_map, 0, 0) + self.spawn_counter += 1 + else: + enemy.prespawn = False + + if enemy.enemy_type == "octorok" or enemy.enemy_type == "stalfos": + if not enemy.frozen: + enemy.walk_distance = randint(15, 25) + if enemy.y % 5 == 0 or enemy.x % 5 == 0: + if enemy.distance_count >= enemy.walk_distance: + enemy.facingDirection = choice(enemy.directions) + enemy.distance_count = 0 + else: + enemy.distance_count += 1 + + def check_for_collisions(scene_controller, mod1, mod2, mod3, mod4): + enemy.isColliding = False + for wall in scene_controller.walls: + if (((enemy.x < wall.x + mod1) and (enemy.x + mod2 > wall.x)) and ((wall.y < enemy.y + mod3) and (wall.y + mod4 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = wall + for bush in scene_controller.bushes: + if (((enemy.x < bush.x + mod1) and (enemy.x + mod2 > bush.x)) and ((bush.y < enemy.y + mod3) and (bush.y + mod4 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = bush + for water in scene_controller.water: + if (((enemy.x < water.x + mod1) and (enemy.x + mod2 > water.x)) and ((water.y < enemy.y + mod3) and (water.y + mod4 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = water + for barrier in scene_controller.barriers: + if (((enemy.x < barrier.x + mod1) and (enemy.x + mod2 > barrier.x)) and ((barrier.y < enemy.y + mod3) and (barrier.y + mod4 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = barrier + for block in scene_controller.blocks: + if (((enemy.x < block.x + mod1) and (enemy.x + mod2 > block.x)) and ((block.y < enemy.y + mod3) and (block.y + mod4 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = block + + if enemy.facingDirection == "up": + check_for_collisions(scene_controller, 5, 5, 5, 6) + if enemy.isColliding: + enemy.y = enemy.colliding_wall.y + 5 + while enemy.facingDirection == "up": + enemy.facingDirection = choice(enemy.directions) + enemy.isColliding = False + + elif enemy.y > 5: + if enemy.move_buffer < desired_movement_buffer: + if not enemy.isColliding: + enemy.y -= enemy.move_speed + enemy.move_buffer += 1 + else: + enemy.move_buffer = 0 + else: + enemy.facingDirection = choice(enemy.directions) + + + elif enemy.facingDirection == "down": + check_for_collisions(scene_controller, 5, 5, 6, 5) + if enemy.isColliding: + enemy.y = enemy.colliding_wall.y - 5 + while enemy.facingDirection == "down": + enemy.facingDirection = choice(enemy.directions) + enemy.isColliding = False + elif enemy.y < 30: + if enemy.move_buffer < desired_movement_buffer: + if not enemy.isColliding: + enemy.y += enemy.move_speed + enemy.move_buffer += 1 + else: + enemy.move_buffer = 0 + else: + enemy.facingDirection = choice(enemy.directions) + + + elif enemy.facingDirection == "right": + check_for_collisions(scene_controller, 5, 6, 5, 5) + if enemy.isColliding: + enemy.x = enemy.colliding_wall.x - 5 + while enemy.facingDirection == "right": + enemy.facingDirection = choice(enemy.directions) + enemy.isColliding = False + elif enemy.x < 61: + if enemy.move_buffer < desired_movement_buffer: + if not enemy.isColliding: + enemy.x += enemy.move_speed + enemy.move_buffer += 1 + else: + enemy.move_buffer = 0 + else: + enemy.facingDirection = choice(enemy.directions) + + + elif enemy.facingDirection == "left": + check_for_collisions(scene_controller, 6, 5, 5, 5) + if enemy.isColliding: + enemy.x = enemy.colliding_wall.x + 5 + while enemy.facingDirection == "left": + enemy.facingDirection = choice(enemy.directions) + enemy.isColliding = False + elif enemy.x > 6: + if enemy.move_buffer < desired_movement_buffer: + if not enemy.isColliding: + enemy.x -= enemy.move_speed + enemy.move_buffer += 1 + else: + enemy.move_buffer = 0 + else: + enemy.facingDirection = choice(enemy.directions) + + if not enemy.is_dead: + if enemy.enemy_type == "stalfos": + if enemy.animation_counter >= 2: + self.map_to_display = (enemy.map, 0, 0) + enemy.animation_counter = 0 + else: + self.map_to_display = (enemy.map, 1, 0) + enemy.animation_counter += 1 + else: + if enemy.facingDirection == "up" and enemy.move_buffer < 1: + self.map_to_display = (enemy.enemy_up_map, 0, 0) + elif enemy.facingDirection == "up" and enemy.move_buffer >= 1: + self.map_to_display = (enemy.enemy_up_map_2, 0, 0) + elif enemy.facingDirection == "right" and enemy.move_buffer < 1: + self.map_to_display = (enemy.enemy_right_map, 0, 0) + elif enemy.facingDirection == "right" and enemy.move_buffer >= 1: + self.map_to_display = (enemy.enemy_right_map_2, 0, 0) + elif enemy.facingDirection == "down" and enemy.move_buffer < 1: + self.map_to_display = (enemy.enemy_up_map, 0, 1) + elif enemy.facingDirection == "down" and enemy.move_buffer >= 1: + self.map_to_display = (enemy.enemy_up_map_2, 0, 1) + elif enemy.facingDirection == "left" and enemy.move_buffer < 1: + self.map_to_display = (enemy.enemy_right_map, 1, 0) + elif enemy.facingDirection == "left" and enemy.move_buffer >= 1: + self.map_to_display = (enemy.enemy_right_map_2, 1, 0) + + display.blit(self.map_to_display[0], enemy.x, enemy.y, 5, 5, 1, self.map_to_display[1], self.map_to_display[2]) + + if enemy.enemy_type == "tektite": + jump_directions = ("left", "right") + if enemy.animation_counter >= 10: + self.map_to_display = (enemy.extended_map, 0, 0) + enemy.animation_counter = 0 + elif enemy.animation_counter <= 5: + self.map_to_display = (enemy.extended_map, 0, 0) + enemy.animation_counter += 1 + else: + self.map_to_display = (enemy.crouched_map, 0, 0) + enemy.animation_counter += 1 + if enemy.is_jumping == False: + enemy.jump_counter = randint(0, 20) + enemy.jump_direction = choice(jump_directions) + + if self.map_to_display == (enemy.extended_map, 0, 0): + if not enemy.frozen: + if enemy.jump_counter == 1 and enemy.is_jumping == False: + # print(f"is jumping {enemy.jump_direction}") + enemy.is_jumping = True + enemy.prejump_x = enemy.x + enemy.prejump_y = enemy.y + enemy.jump_x = randint(7, 14) + enemy.jump_y = randint(0, 7) + + if enemy.is_jumping: + if enemy.jump_direction == "right" and enemy.x >= enemy.prejump_x + enemy.jump_x: + enemy.is_jumping = False + enemy.apex_reached = False + if enemy.jump_direction == "right" and enemy.x < enemy.prejump_x + enemy.jump_x and enemy.x < 66: + enemy.x += 1 + if enemy.x >= 66: + enemy.is_jumping = False + enemy.x -= 1 + if enemy.jump_direction == "left" and enemy.x <= enemy.prejump_x - enemy.jump_x: + enemy.is_jumping = False + enemy.apex_reached = False + if enemy.jump_direction == "left" and enemy.x > enemy.prejump_x - enemy.jump_x and enemy.x > 0: + enemy.x -= 1 + if enemy.x <= 0: + enemy.is_jumping = False + enemy.x += 1 + if enemy.y < enemy.prejump_y - enemy.jump_y or enemy.y <= 5: + enemy.apex_reached = True + if enemy.apex_reached == False: + if enemy.y > 5: + enemy.y -= 1 + elif enemy.apex_reached: + if enemy.y < 35: + enemy.y += 1 + + if enemy.enemy_type == "zora": + if enemy.spawn_animation_counter < 10: + self.map_to_display = (enemy.surface_map_1, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 20: + self.map_to_display = (enemy.surface_map_2, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 30: + self.map_to_display = (enemy.surface_map_3, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 70: + self.map_to_display = (enemy.attack_map, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 80: + self.map_to_display = (enemy.surface_map_3, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 90: + self.map_to_display = (enemy.surface_map_2, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 100: + self.map_to_display = (enemy.surface_map_1, 0, 0) + enemy.spawn_animation_counter += 1 + + if enemy.enemy_type == "leever": + if enemy.is_buried: + if enemy.distance_count >= enemy.walk_distance: + enemy.facingDirection = choice(enemy.directions) + enemy.distance_count = 0 + else: + enemy.distance_count += 1 + if not enemy.is_buried: + if not enemy.frozen: + if enemy.facingDirection == "up": + enemy.isColliding = False + for wall in scene_controller.walls: + if (((enemy.x < wall.x + 5) and (enemy.x + 5 > wall.x)) and ((wall.y < enemy.y + 5) and (wall.y + 6 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = wall + for bush in scene_controller.bushes: + if (((enemy.x < bush.x + 5) and (enemy.x + 5 > bush.x)) and ((bush.y < enemy.y + 5) and (bush.y + 6 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = bush + for water in scene_controller.water: + if (((enemy.x < water.x + 5) and (enemy.x + 5 > water.x)) and ((water.y < enemy.y + 5) and (water.y + 6 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = water + if enemy.isColliding: + enemy.y = enemy.colliding_wall.y + 5 + enemy.facingDirection = "down" + enemy.isColliding = False + + elif enemy.y > 5: + if enemy.move_buffer < desired_movement_buffer: + if not enemy.isColliding: + enemy.y -= enemy.move_speed + enemy.move_buffer += 1 + else: + enemy.move_buffer = 0 + else: + enemy.facingDirection = "down" + + + elif enemy.facingDirection == "down": + enemy.isColliding = False + for wall in scene_controller.walls: + if (((enemy.x < wall.x + 5) and (enemy.x + 5 > wall.x)) and ((wall.y - 1 < enemy.y + 5) and (wall.y + 5 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = wall + for bush in scene_controller.bushes: + if (((enemy.x < bush.x + 5) and (enemy.x + 5 > bush.x)) and ((bush.y - 1 < enemy.y + 5) and (bush.y + 5 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = bush + for water in scene_controller.water: + if (((enemy.x < water.x + 5) and (enemy.x + 5 > water.x)) and ((water.y - 1 < enemy.y + 5) and (water.y + 5 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = water + + if enemy.isColliding: + enemy.y = enemy.colliding_wall.y - 5 + enemy.facingDirection = "up" + enemy.isColliding = False + elif enemy.y < 30: + if enemy.move_buffer < desired_movement_buffer: + if not enemy.isColliding: + enemy.y += enemy.move_speed + enemy.move_buffer += 1 + else: + enemy.move_buffer = 0 + else: + enemy.facingDirection = "up" + + + elif enemy.facingDirection == "right": + enemy.isColliding = False + for wall in scene_controller.walls: + if (((enemy.x < wall.x + 5) and (enemy.x + 5 > wall.x - 1)) and ((wall.y < enemy.y + 5) and (wall.y + 5 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = wall + for bush in scene_controller.bushes: + if (((enemy.x < bush.x + 5) and (enemy.x + 5 > bush.x - 1)) and ((bush.y < enemy.y + 5) and (bush.y + 5 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = bush + for water in scene_controller.water: + if (((enemy.x < water.x + 5) and (enemy.x + 5 > water.x - 1)) and ((water.y < enemy.y + 5) and (water.y + 5 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = water + + if enemy.isColliding: + enemy.x = enemy.colliding_wall.x - 5 + enemy.facingDirection = "left" + enemy.isColliding = False + elif enemy.x < 61: + if enemy.move_buffer < desired_movement_buffer: + if not enemy.isColliding: + enemy.x += enemy.move_speed + enemy.move_buffer += 1 + else: + enemy.move_buffer = 0 + else: + enemy.facingDirection = "left" + + + elif enemy.facingDirection == "left": + enemy.isColliding = False + for wall in scene_controller.walls: + if (((enemy.x < wall.x + 6) and (enemy.x + 5 > wall.x)) and ((wall.y < enemy.y + 5) and (wall.y + 5 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = wall + for bush in scene_controller.bushes: + if (((enemy.x < bush.x + 6) and (enemy.x + 5 > bush.x)) and ((bush.y < enemy.y + 5) and (bush.y + 5 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = bush + for water in scene_controller.water: + if (((enemy.x < water.x + 6) and (enemy.x + 5 > water.x)) and ((water.y < enemy.y + 5) and (water.y + 5 > enemy.y))): + enemy.isColliding = True + enemy.colliding_wall = water + + if enemy.isColliding: + enemy.x = enemy.colliding_wall.x + 5 + enemy.facingDirection = "right" + enemy.isColliding = False + elif enemy.x > 6: + if enemy.move_buffer < desired_movement_buffer: + if not enemy.isColliding: + enemy.x -= enemy.move_speed + enemy.move_buffer += 1 + else: + enemy.move_buffer = 0 + else: + enemy.facingDirection = "right" + + + if enemy.spawn_animation_counter < 10: + self.map_to_display = (enemy.surface_map_1, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 20: + self.map_to_display = (enemy.surface_map_2, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 30: + self.map_to_display = (enemy.surface_map_3, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 40: + enemy.is_buried = False + self.map_to_display = (enemy.attacking_map_1, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 45: + self.map_to_display = (enemy.attacking_map_2, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 50: + self.map_to_display = (enemy.attacking_map_1, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 55: + self.map_to_display = (enemy.attacking_map_2, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 60: + self.map_to_display = (enemy.attacking_map_1, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 65: + self.map_to_display = (enemy.attacking_map_2, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 70: + enemy.is_buried = True + self.map_to_display = (enemy.surface_map_3, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 80: + self.map_to_display = (enemy.surface_map_2, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 90: + self.map_to_display = (enemy.surface_map_1, 0, 0) + enemy.spawn_animation_counter += 1 + elif enemy.spawn_animation_counter < 100: + self.map_to_display = (enemy.prespawn_map, 0, 0) + enemy.spawn_animation_counter += 1 + +#############################################################################TEST############################################################################## + + + + if enemy.enemy_type == "keese": + if enemy.prespawn: + enemy.flight_time = randrange(60, 120) + self.map_to_display = (enemy.prespawn_map, enemy.x, enemy.y) + + if enemy.animation_counter >= enemy.attack_speed: + if not enemy.frozen: + enemy.is_flying = True + enemy.flight_time = randrange(60, 120) + xmod = choice([-1, 0, 1]) + ymod = choice([-1, 0, 1]) + if xmod > 0 and enemy.x < 66: + enemy.x += xmod + elif xmod < 0 and enemy.x > 1: + enemy.x += xmod + if ymod > 0 and enemy.y < 35: + enemy.y += ymod + elif ymod < 0 and enemy.y > 5: + enemy.y += ymod + enemy.animation_counter += 1 + flight_duration = enemy.attack_speed + enemy.flight_time + if enemy.animation_counter >= flight_duration: + enemy.is_flying = False + enemy.animation_counter = 0 + enemy.flight_time = randrange(60, 120) + enemy.attack_speed = randrange(20, 40) + if enemy.fly_counter == 0: + self.map_to_display = (enemy.flap1_map, enemy.x, enemy.y) + enemy.fly_counter = 1 + else: + self.map_to_display = (enemy.flap2_map, enemy.x, enemy.y) + enemy.fly_counter = 0 + + + else: + enemy.animation_counter += 1 + self.map_to_display = (enemy.prespawn_map, enemy.x, enemy.y) + +###############################################################################TEST####################################################################### + + + + + + if enemy.enemy_type == "zora": + if enemy.spawn_animation_counter >= 100: + if not enemy.frozen: + enemy.magic = [] + spawn_tile = choice(scene_controller.water) + enemy.x = spawn_tile.x + enemy.y = spawn_tile.y + enemy.spawn_animation_counter = 0 + enemy.has_fired = False + else: + display.blit(self.map_to_display[0], enemy.x, enemy.y, 5, 5, -1, self.map_to_display[1], self.map_to_display[2]) + if enemy.enemy_type == "leever": + if enemy.spawn_animation_counter >= 100: + if not enemy.frozen: + enemy.x = randrange(11, 56, 5) + enemy.y = randrange(10, 25, 5) + self.check_for_overlap(scene_controller, enemy) + enemy.spawn_animation_counter = 0 + else: + display.blit(self.map_to_display[0], enemy.x, enemy.y, 5, 5, 1, self.map_to_display[1], self.map_to_display[2]) + else: + display.blit(self.map_to_display[0], enemy.x, enemy.y, 5, 5, 1, self.map_to_display[1], self.map_to_display[2]) + + + def attack(self, player): + for enemy in self.enemies: + if enemy.prespawn == False: + if not enemy.frozen: + if enemy.enemy_type == "octorok": + enemy.attack_counter = randint(0, 200) + if enemy.attack_counter >= enemy.attack_speed: + enemy.move_speed = 0 + if enemy.rocks == []: + enemy.rocks.append(Rock(enemy)) + + for rock in enemy.rocks: + rock.move() + display.drawSprite(rock.rock_sprite) + if rock.timer > rock.lifespan: + rock.parent_enemy.move_speed = 1 + rock_index = enemy.rocks.index(rock) + del enemy.rocks[rock_index] + rock.timer = 0 + + if enemy.enemy_type == "zora": + if not enemy.has_fired: + if enemy.spawn_animation_counter >= 40: + if enemy.magic == []: + enemy.magic.append(Magic(enemy, player)) + for magic in enemy.magic: + magic.move() + display.drawSprite(magic.magic_sprite) + + + def display_loot(self, my_player, enemy_controller, display): + for loot in self.loot: + this_loot_index = self.loot.index(loot) + if not loot.destroyed: + loot.display_loot(display) + elif loot.destroyed: + loot.destroyed = False + loot_index = self.loot.index(loot) + del self.loot[loot_index] + if len(self.loot) == 0: + self.loot = [] + + for loot in self.loot: + if (((my_player.playerSprite.x + 4 < loot.x + 5) and (my_player.playerSprite.x + 9 > loot.x)) and ((loot.y < my_player.playerSprite.y + 9) and (loot.y + 5 > my_player.playerSprite.y + 4))): + loot_index = enemy_controller.loot.index(loot) + if loot.loot_type == "heart" and my_player.hearts >= my_player.max_hearts: + del self.loot[loot_index] + if loot.loot_type == "heart" and my_player.hearts == my_player.max_hearts - 1: + del self.loot[loot_index] + my_player.hearts += 1 + if loot.loot_type == "heart" and my_player.hearts <= my_player.max_hearts - 2: + del self.loot[loot_index] + my_player.hearts += 2 + if loot.loot_type == "rupee" and my_player.rupees < 999: + del self.loot[loot_index] + my_player.rupees += 1 + my_player.rupees_text = str(my_player.rupees) + if loot.loot_type == "bigrupee" and my_player.rupees < 994: + del self.loot[loot_index] + my_player.rupees += 5 + my_player.rupees_text = str(my_player.rupees) + # if loot.loot_type == "bomb" and my_player.bombs < 9: + # del self.loot[loot_index] + # my_player.bombs += 1 + # my_player.bombs_text = str(my_player.bombs) + else: + loot.destroyed = True + diff --git a/Thelda/fonthandler.py b/Thelda/fonthandler.py new file mode 100644 index 00000000..dbb48ac8 --- /dev/null +++ b/Thelda/fonthandler.py @@ -0,0 +1,67 @@ +from thumby import display + +class FontHandler: + def __init__(self): + + #Not enough room for 'space' in letters_raw, so I added the byte array for space to it separately. + self.space = bytearray([7,7,7,7])# BITMAP: width: 4, height: 3 + # FONT BITMAP: width: 144, height: 3 + self.letters_white_raw = self.space + bytearray([6,1,6,0,7,7,6,0,2,5,5,0,7,5,2,0,7,6,4,0,7,3,1,0,7,5,6,0,7,2,7,0,0,7,0,0,6,4,7,0,7,2,5,0,7,4,4,0,7,3,7,0,7,1,6,0,2,5,2,0,7,3,3,0,2,5,6,0,7,3,6,0,4,7,1,0,1,7,1,0,7,4,7,0,3,4,3,0,7,6,7,0,5,2,5,0,3,6,3,0,1,7,4,0,7,5,7,0,1,7,0,0,1,7,4,0,1,3,6,0,3,2,7,0,4,7,1,0,7,6,6,0,1,1,7,0,6,7,6,0,3,3,7,0]) + self.letters_raw = self.space + bytearray([1,6,1,7,0,0,1,7,5,2,2,7,0,2,5,7,0,1,3,7,0,4,6,7,0,2,1,7,0,5,0,7,7,0,7,7,1,3,0,7,0,5,2,7,0,3,3,7,0,4,0,7,0,6,1,7,5,2,5,7,0,4,4,7,5,2,1,7,0,4,1,7,3,0,6,7,6,0,6,7,0,3,0,7,4,3,4,7,0,1,0,7,2,5,2,7,4,1,4,7,6,0,3,7,0,2,0,7,6,0,7,7,6,0,3,7,6,4,1,7,4,5,0,7,3,0,6,7,0,1,1,7,6,6,0,7,1,0,1,7,4,4,0,7]) + self.letter_maps = [] # this will hold lists of each letter's byte array values + self.white_letter_maps = [] # this will hold lists of each letter's byte array values + self.chunk_size = 3 + self.count = 0 + self.this_letter_map = [] + self.this_white_letter_map = [] + for number in self.letters_raw: + if self.count < self.chunk_size: + self.this_letter_map.append(number) + self.count += 1 + else: + self.letter_maps.append(self.this_letter_map) + self.this_letter_map = [] + self.count = 0 + + for number in self.letters_white_raw: + if self.count < self.chunk_size: + self.this_white_letter_map.append(number) + self.count += 1 + else: + self.white_letter_maps.append(self.this_white_letter_map) + self.this_white_letter_map = [] + self.count = 0 + + self.font_index = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + + self.letter_dict = dict((char, position) for position, char in enumerate(self.font_index)) + + self.alphabet = {} + self.white_alphabet = {} + + for char in self.letter_dict: + indv_char = self.letter_dict[char] + char_map = self.letter_maps[indv_char] + self.alphabet.update({char:bytearray(char_map)}) + + for char in self.letter_dict: + indv_char = self.letter_dict[char] + char_map = self.white_letter_maps[indv_char] + self.white_alphabet.update({char:bytearray(char_map)}) + + + def write(self, text, x: int, y: int): + text = text.upper() + for character in text: + char_to_print = self.alphabet[character] + display.blit(char_to_print, x, y, 3, 3, 1, 0, 0) + x += 4 + + + def write_white(self, text, x: int, y: int): + text = text.upper() + for character in text: + char_to_print = self.white_alphabet[character] + display.blit(char_to_print, x, y, 3, 3, -1, 0, 0) + x += 4 + diff --git a/Thelda/hudcontroller.py b/Thelda/hudcontroller.py new file mode 100644 index 00000000..47ba8f73 --- /dev/null +++ b/Thelda/hudcontroller.py @@ -0,0 +1,233 @@ +from thumby import buttonA, buttonB, buttonU, buttonL, buttonR, display + +class HudController: + def __init__(self, my_player): + self.rupees = str(my_player.rupees) + self.dash_map = bytearray([1,1]) + self.keys = str(my_player.keys) + self.bombs = str(my_player.bombs) + self.blink_timer = 0 + self.y_height = 1 + self.is_paused = False + self.menu_x = 1 + self.menu_y = -35 + self.deployed = False + self.retracted = True + self.menu_speed = 1 + self.cursor_height = 2 + self.cursor_blink = 0 + self.cursor_x = 44 + self.cursor_y = self.y_height - 34 + self.collected_items = [("boomerang"), ("bombs"), ("bow")] + self.cursor_selection = "" + + + + def display_cursor(self, my_player): + cursor_map = bytearray([99,65,0,0,0,65,99]) + cursor_blink_map = bytearray([0,0,0,0,0,0,0]) + if buttonR.justPressed(): + display.blit(cursor_blink_map, self.cursor_x, self.cursor_height, 7, 7, 1, 0, 0) + if self.cursor_x <= 61: + self.cursor_x += 6 + else: + self.cursor_x = 44 + if self.cursor_height == self.y_height - 34: + self.cursor_height = self.y_height - 28 + else: + self.cursor_height = self.y_height - 34 + elif buttonL.justPressed(): + display.blit(cursor_blink_map, self.cursor_x, self.cursor_height, 7, 7, 1, 0, 0) + if not self.cursor_x <= 44: + self.cursor_x -= 6 + else: + self.cursor_x = 62 + if self.cursor_height == self.y_height - 34: + self.cursor_height = self.y_height - 28 + else: + self.cursor_height = self.y_height - 34 + + if self.cursor_blink >= 20: + self.cursor_blink = 0 + + elif self.cursor_blink > 10: + display.blit(cursor_blink_map, self.cursor_x, self.cursor_height, 7, 7, 1, 0, 0) + self.cursor_blink += 1 + else: + display.blit(cursor_map, self.cursor_x, self.cursor_height, 7, 7, 0, 0, 0) + self.cursor_blink += 1 + cursor_xy = (self.cursor_x, self.cursor_height) + if cursor_xy[1] == (self.y_height - 34): + if cursor_xy[0] == 50: + self.cursor_selection = "bombs" + elif cursor_xy[0] == 44: + self.cursor_selection = "boomerang" + elif cursor_xy[0] == 56: + self.cursor_selection = "bow" + else: + self.cursor_selection = "" + if cursor_xy[1] == (self.y_height - 28): + self.cursor_selection = "" + + if self.cursor_selection in self.collected_items: + my_player.active_item = self.cursor_selection + + + def display_hearts(self, my_player): + display.drawFilledRectangle(0, self.y_height - 1, 71, 5, 0) + heart_map = bytearray([3,6,3]) + blank_map = bytearray([0,0,0]) + + if my_player.hearts <= 3: + if self.blink_timer >= 20: + self.blink_timer = 0 + elif self.blink_timer > 10: + display.blit(heart_map, 51, self.y_height, 3, 3, 1, 0, 0) + self.blink_timer += 1 + else: + display.blit(heart_map, 51, self.y_height, 3, 3, 0, 0, 0) + self.blink_timer += 1 + else: + display.blit(heart_map, 51, self.y_height, 3, 3, 0, 0, 0) + + current_hearts = my_player.hearts / 2 + if current_hearts > 0: + display.setPixel(56, self.y_height, 1) + if current_hearts > 1: + display.setPixel(58, self.y_height, 1) + if current_hearts > 2: + display.setPixel(60, self.y_height, 1) + if current_hearts > 3: + display.setPixel(62, self.y_height, 1) + if current_hearts > 4: + display.setPixel(64, self.y_height, 1) + if current_hearts > 5: + display.setPixel(66, self.y_height, 1) + if current_hearts > 6: + display.setPixel(68, self.y_height, 1) + if current_hearts > 7: + display.setPixel(70, self.y_height, 1) + if current_hearts > 8: + display.setPixel(56, self.y_height, 1) + if current_hearts > 9: + display.setPixel(58, self.y_height + 2, 1) + if current_hearts > 10: + display.setPixel(60, self.y_height + 2, 1) + if current_hearts > 11: + display.setPixel(62, self.y_height + 2, 1) + if current_hearts > 12: + display.setPixel(64, self.y_height + 2, 1) + if current_hearts > 13: + display.setPixel(66, self.y_height + 2, 1) + if current_hearts > 14: + display.setPixel(68, self.y_height + 2, 1) + if current_hearts > 15: + display.setPixel(70, self.y_height + 2, 1) + + def display_rupees(self, font_handler, my_player): + self.rupees = my_player.rupees_text + rupee_map = bytearray([6,7,3]) + display.blit(rupee_map, 1, self.y_height, 3, 3, 0, 0, 0) + display.blit(self.dash_map, 5, self.y_height + 1, 2, 1, 0, 0, 0) + font_handler.write_white(self.rupees, 8, self.y_height) + + def display_keys(self, font_handler, my_player): + self.keys = str(my_player.keys) + key_map = bytearray([6,2,2,5,7]) + display.blit(key_map, 22, self.y_height, 5, 3, 0, 0, 0) + display.blit(self.dash_map, 28, self.y_height + 1, 2, 1, 0, 0, 0) + font_handler.write_white(self.keys, 31, self.y_height) + + def display_bombs(self, font_handler, my_player): + self.bombs = str(my_player.bombs) + bomb_map = bytearray([6,6,1]) + display.blit(bomb_map, 37, self.y_height, 3, 3, 0, 0, 0) + display.blit(self.dash_map, 41, self.y_height + 1, 2, 1, 0, 0, 0) + font_handler.write_white(self.bombs, 44, self.y_height) + + def display_items(self): + for item in self.collected_items: + if item == "boomerang": + display.blit(bytearray([0,4,10,17,0]), 45, self.y_height - 33, 5, 5, -1, 0, 0) + if self.cursor_selection == "boomerang": + display.blit(bytearray([0,8,28,54,34,0,0]), 11, self.y_height - 29, 7, 7, -1, 0, 0) + if item == "bombs": + display.blit(bytearray([0,28,30,29,0]), 51, self.y_height - 33, 5, 5, -1, 0, 0) + if self.cursor_selection == "bombs": + display.blit(bytearray([0,24,60,62,61,24,0]), 11, self.y_height - 29, 7, 7, -1, 0, 0) + if item == "bow": + display.blit(bytearray([0,31,17,14,0]), 57, self.y_height - 33, 5, 5, -1, 0, 0) + if self.cursor_selection == "bow": + display.blit(bytearray([0,0,127,65,34,28,0]), 11, self.y_height - 29, 7, 7, -1, 0, 0) + + if self.cursor_selection == "": + display.blit(bytearray([0,0,0,0,0,0,0]), 11, self.y_height - 29, 7, 7, -1, 0, 0) + + def pause_game(self, font_handler, my_player): + + # BITMAP: width: 70, height: 35 + menu_map = bytearray([0,0,0,10,14,10,0,14,2,140,64,70,72,70,64,78,76,136,0,14,2,12,0,2,14,2,0,14,10,14,0,14,6,12,0,6,12,6,0,0,0,0,252,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,252,0, + 0,0,0,0,0,0,0,0,0,63,64,64,64,64,64,64,64,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,64,32,144,32,64,128,0,0,0,127,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,127,0, + 0,0,0,238,200,238,0,168,238,162,0,46,236,40,0,224,64,224,0,0,0,0,0,0,128,64,32,144,72,36,18,9,4,2,1,0,1,2,4,9,18,36,72,144,32,64,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,14,14,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40,236,42,9,232,106,203,10,170,234,170,10,234,106,42,10,234,170,234,10,234,106,202,10,235,170,168,9,234,204,136,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) + if buttonA.pressed() and buttonB.pressed() and buttonU.pressed(): + self.is_paused = True + print("Paused") + while self.is_paused: + if not self.deployed: + while self.menu_y < 0: + display.fill(0) + self.menu_y += self.menu_speed + self.y_height += self.menu_speed + display.blit(menu_map, self.menu_x, self.menu_y, 70, 35, -1, 0, 0) + display.drawFilledRectangle(0, self.y_height - 1, 71, 5, 0) + self.display_hearts(my_player) + self.display_rupees(font_handler, my_player) + self.display_keys(font_handler, my_player) + self.display_bombs(font_handler, my_player) + # self.display_items(display) + display.update() + else: + self.deployed = True + self.retracted = False + print(self.y_height) + + + if buttonA.pressed() and buttonB.pressed() and buttonU.pressed() and not self.retracted: + if not self.retracted: + while self.menu_y > -35: + display.fill(0) + self.menu_y -= self.menu_speed + self.y_height -= self.menu_speed + display.blit(menu_map, self.menu_x, self.menu_y, 70, 35, -1, 0, 0) + # display.drawLine(44, self.y_height - 35, 69, self.y_height - 35, 1) + # display.drawLine(44, self.y_height - 21, 69, self.y_height - 21, 1) + # display.drawLine(43, self.y_height - 34, 43, self.y_height - 22, 1) + # display.drawLine(70, self.y_height - 34, 70, self.y_height - 22, 1) + display.drawFilledRectangle(0, self.y_height - 1, 71, 5, 0) + self.display_hearts(my_player) + self.display_rupees(font_handler, my_player) + self.display_keys(font_handler, my_player) + self.display_bombs(font_handler, my_player) + # self.display_items(display) + display.update() + else: + self.deployed = False + self.retracted = True + self.is_paused = False + print("Unpaused") + + self.display_hearts(my_player) + self.display_rupees(font_handler, my_player) + self.display_keys(font_handler, my_player) + self.display_bombs(font_handler, my_player) + self.display_cursor(my_player) + self.display_items() + display.update() + + + + + + \ No newline at end of file diff --git a/Thelda/musicplayer.py b/Thelda/musicplayer.py new file mode 100644 index 00000000..4fc420c1 --- /dev/null +++ b/Thelda/musicplayer.py @@ -0,0 +1,34 @@ +from thumby import audio + + +class MusicPlayer: + def __init__(self): + self.song = [(523, 500, 20), (523, 250, 2), (523, 250, 2), (523, 250, 2), (523, 250, 2), (523, 500, 5), (466, 500, 2), (523, 500, 12), + (523, 250, 2), (523, 250, 2), (523, 250, 2), (523, 250, 2), (523, 500, 5), (466, 500, 2), (523, 500, 12), + (523, 250, 2), (523, 250, 2), (523, 250, 2), (523, 250, 2), (523, 500, 5), + (392, 250, 2), (392, 250, 2), (392, 250, 4), (392, 250, 2), (392, 250, 2), (392, 250, 4), (392, 250, 2), (392, 250, 2), (392, 250, 4), (392, 250, 4), + (523, 500, 12), (392, 250, 12), (523, 250, 2), (523, 250, 2), (587, 250, 2), (659, 250, 2), (698, 250, 2), (783, 500, 20), + (783, 250, 2), (783, 250, 2), (831, 250, 2), (932, 250, 2), (1046, 500, 20), + (1046, 250, 2), (1046, 250, 2), (1046, 250, 2), (932, 250, 2), (831, 250, 2), (932, 250, 5), (831, 250, 2), (783, 500, 20)] + self.note_count = 0 + + + self.frequency_count = 0 + self.duration_count = 1 + self.frames_to_play = 2 + + + self.frame_count = 0 + + def play_song(self): + try: + if self.frame_count < self.frames_to_play: + self.frames_to_play = self.song[self.note_count][2] + audio.play(self.song[self.note_count][self.frequency_count], self.song[self.note_count][self.duration_count]) + self.frame_count += 1 + else: + audio.stop() + self.note_count += 1 + self.frame_count = 0 + except IndexError: + self.note_count = 0 diff --git a/Thelda/player.py b/Thelda/player.py new file mode 100644 index 00000000..f61831f4 --- /dev/null +++ b/Thelda/player.py @@ -0,0 +1,952 @@ +from random import randrange +from time import sleep +from sys import path +path.append("/Games/Thelda") + + +class Sword: + def __init__(self, direction, x, y, enemy_controller, thumby): + self.sword = True + self.x = x + self.y = y + self.direction = direction + self.speed = 3 + self.timer = 0 + self.lifespan = 30 + self.interval = 12 + self.dying = False + self.animation_counter = 0 + self.has_hit = False + # BITMAP: width: 5, height: 5 + self.item = bytearray([31,23,0,23,31]) + self.sword_right = bytearray([27,17,27,27,27]) + self.sword_up = bytearray([31,23,0,23,31]) + self.sword_flash = bytearray([31,31,31,31,31]) + + self.death_map_1 = bytearray([255,255,255,255,255,159,223,255,223,159,255,255,255,255,255, + 127,127,127,127,127,124,125,127,125,124,127,127,127,127,127]) + # BITMAP: width: 15, height: 15 + self.death_map_2 = bytearray([255,255,243,251,255,255,255,255,255,255,255,251,243,255,255, + 127,127,103,111,127,127,127,127,127,127,127,111,103,127,127]) + # BITMAP: width: 15, height: 15 + self.death_map_3 = bytearray([252,254,255,255,255,255,255,255,255,255,255,255,255,254,252, + 31,63,127,127,127,127,127,127,127,127,127,127,127,63,31]) + + self.death_sprite = thumby.Sprite(15, 15, self.death_map_1+self.death_map_2+self.death_map_3, self.x - 5, self.y - 5, key=1) + self.sprite = thumby.Sprite(5, 5, self.sword_up, self.x, self.y, key=1) + self.sword_sprite = thumby.Sprite(5, 5, self.sword_up, self.x, self.y, key=1) + + def process_hit(self, enemy, thumby): + thumby.audio.playBlocking(392, 50) + thumby.audio.play(523, 150) + enemy.health -= 1 + self.has_hit = True + self.timer = self.lifespan + + def move(self, enemy_controller, thumby): + if self.direction == "up": + self.sword_sprite = thumby.Sprite(5, 5, self.sword_up+self.sword_flash, self.x, self.y - 4, key=1) + self.sword_sprite.setFrame(self.timer) + thumby.display.drawSprite(self.sword_sprite) + self.y -= self.speed + elif self.direction == "down": + self.sword_sprite = thumby.Sprite(5, 5, self.sword_up+self.sword_flash, self.x, self.y + 4, key=1, mirrorX=0, mirrorY=1) + self.sword_sprite.setFrame(self.timer) + thumby.display.drawSprite(self.sword_sprite) + self.y += self.speed + elif self.direction == "right": + self.sword_sprite = thumby.Sprite(5, 5, self.sword_right+self.sword_flash, self.x + 4, self.y, key=1) + self.sword_sprite.setFrame(self.timer) + thumby.display.drawSprite(self.sword_sprite) + self.x += self.speed + elif self.direction == "left": + self.sword_sprite = thumby.Sprite(5, 5, self.sword_right+self.sword_flash, self.x - 4, self.y, key=1, mirrorX=1, mirrorY=0) + self.sword_sprite.setFrame(self.timer) + thumby.display.drawSprite(self.sword_sprite) + self.x -= self.speed + self.timer += 1 + + for enemy in enemy_controller.enemies: + if not self.has_hit: + if (((self.x < enemy.x + 5) and (self.x + 5 > enemy.x)) and + ((enemy.y < self.y + 5) and (enemy.y + 5 > self.y))): + if enemy.enemy_type == "leever": + if not enemy.is_buried: + self.process_hit(enemy, thumby) + else: + self.process_hit(enemy, thumby) + + + def display_death_sprite(self, thumby): + self.death_sprite = thumby.Sprite(15, 15, self.death_map_1+self.death_map_1+self.death_map_2+self.death_map_2+self.death_map_3+self.death_map_3, self.x -5, self.y - 5, key=1) + self.death_sprite.setFrame(self.animation_counter) + thumby.display.drawSprite(self.death_sprite) + self.animation_counter += 1 + + +class Boomerang: + def __init__(self, playerSprite, direction, display): + self.x = playerSprite.x + 4 + self.y = playerSprite.y + 4 + self.item_type = "boomerang" + self.direction = direction + self.animation_counter = 0 + self.lifespan = 10 + self.lifecounter = 0 + self.playerx = playerSprite.x + 4 + self.playery = playerSprite.y + 4 + self.speed = 2 + + + + def move(self, display, playerSprite, items): + mx = int + my = int + if not self.lifecounter > self.lifespan: + if self.x >= 0 and self.x < 71 and self.y >= 5 and self.y < 40: + # if self.direction == "up" and thumby.buttonR.pressed(): + # self.direction = "NE" + # if self.direction == "up" and thumby.buttonL.pressed(): + # self.direction = "NW" + # if self.direction == "down" and thumby.buttonR.pressed(): + # self.direction = "SE" + # if self.direction == "down" and thumby.buttonR.pressed(): + # self.direction = "SW" + + if self.direction == "up": + mx = 0 + my = -2 + elif self.direction == "down": + mx = 0 + my = 2 + elif self.direction == "right": + mx = 2 + my = 0 + elif self.direction == "left": + mx = -2 + my = 0 + elif self.direction == "NW": + mx = -2 + my = -2 + elif self.direction == "SW": + mx = -2 + my = 2 + elif self.direction == "NE": + mx = 2 + my = -2 + elif self.direction == "SE": + mx = 2 + my = 2 + else: + mx = 0 + my = 0 + self.x += mx + self.y += my + + # else: + # thumby.audio.play(4186, 50) + else: + self.playerx = playerSprite.x + 4 + self.playery = playerSprite.y + 4 + self.dir = (self.playerx - self.x, self.playery - self.y) + self.length = (abs(self.dir[0]) + abs(self.dir[1])) + self.dir = (self.dir[0] / self.length, self.dir[1] / self.length) + self.x = round(self.x + self.dir[0] * self.speed) + self.y = round(self.y + self.dir[1] * self.speed) + + + if self.animation_counter == 0: + display.blit(bytearray([31,17,29,29,31]), self.x, self.y, 5, 5, 1, 0, 0) + self.animation_counter += 1 + elif self.animation_counter == 1: + display.blit(bytearray([31,17,29,29,31]), self.x, self.y, 5, 5, 1, 0, 1) + self.animation_counter += 1 + elif self.animation_counter == 2: + display.blit(bytearray([31,17,29,29,31]), self.x, self.y, 5, 5, 1, 1, 1) + self.animation_counter += 1 + elif self.animation_counter >=3: + display.blit(bytearray([31,17,29,29,31]), self.x, self.y, 5, 5, 1, 1, 0) + self.animation_counter = 0 + + +class Bomb: + def __init__(self, x, y): + self.item_type = "bomb" + self.x = x + self.y = y + self.timer = 0 + self.exploding = False + + def explode(self, display): + self.exploding = True + if self.timer == 40: + display.blit(bytearray([255,255,255,255,143,239,47,191,47,239,143,255,255,255,255, + 127,127,127,127,120,123,122,126,122,123,120,127,127,127,127]), self.x - 5, self.y - 5, 15, 15, 1, 0, 0) + self.timer += 1 + elif self.timer == 41: + display.blit(bytearray([255,225,125,101,245,223,191,231,191,223,245,101,125,225,255, + 127,67,95,83,87,125,126,115,126,125,87,83,95,67,127]), self.x - 5, self.y - 5, 15, 15, 1, 0, 0) + self.timer += 1 + elif self.timer == 42: + display.blit(bytearray([224,126,114,250,238,223,255,249,255,223,238,250,114,126,224, + 3,63,39,47,59,125,127,79,127,125,59,47,39,63,3]), self.x - 5, self.y - 5, 15, 15, 1, 0, 0) + self.timer += 1 + self.exploding = False + + +class Loot: + def __init__(self, x, y, type_of_loot, thumby): + self.x = x + self.y = y + self.loot_type = type_of_loot + self.heart_drop_map = bytearray([31,25,19,25,31]) + self.rupee_drop_map = bytearray([31,17,14,17,31]) + self.bigrupee_drop_map = bytearray([31,17,0,17,31]) + # self.bomb_drop_map = bytearray([31,3,1,2,30]) + self.loot_flash = bytearray([31,31,31,31,31]) + self.timer = 0 + self.lifespan = 100 + self.destroyed = False + self.sprite = thumby.Sprite(5, 5, self.heart_drop_map, self.x, self.y, key=1) + + + if self.loot_type == "none": + self.sprite = thumby.Sprite(5, 5, self.loot_flash, self.x, self.y, key=1) + self.destroyed = True + if self.loot_type == "heart": + self.sprite = thumby.Sprite(5, 5, self.heart_drop_map, self.x, self.y, key=1) + if self.loot_type == "rupee": + self.sprite = thumby.Sprite(5, 5, self.rupee_drop_map, self.x, self.y, key=1) + if self.loot_type == "bigrupee": + self.sprite = thumby.Sprite(5, 5, self.bigrupee_drop_map, self.x, self.y, key=1) + + def display_loot(self, display): + if self.timer < self.lifespan: + display.drawSprite(self.sprite) + self.timer += 1 + else: + self.loot_type = "none" + self.destroyed = True + + +class Player: + + def __init__(self, enemy_controller, scene_controller, thumby, savedata): + self.hearts = savedata[0] + self.rupees = savedata[2] + self.keys = savedata[3] + self.bombs = savedata[4] + self.max_hearts = savedata[1] + self.rupees_text = str(self.rupees) + self.keys_text = str(self.keys) + self.bombs_text = str(self.bombs) + self.loot_types = ["heart", "rupee", "bigrupee", "none"] + self.loot_randomizer = int + self.type_of_loot = int + self.facingDirection = "" + self.isColliding = False + self.colliding_wall = None + self.inCave = False + self.entranceCoords = [0, 0] + self.isTransitioning = False + self.enemyCollision = False + self.enemyCollisionBuffer = 20 + self.swinging = False + self.swing_counter = 0 + self.sword_projectile = [] + self.sword_projectile_timer = 12 + self.sword_projectile_delay = 12 + self.entrance_scene = (0, 0) + self.in_dungeon = False + self.exit_scene = tuple + self.active_item = "" + self.items = [] + + + # Player Sprites width: 13, height: 13 + self.playerFront = bytearray([255,255,255,255,63,15,47,15,191,255,255,255,255, + 31,31,31,31,31,30,31,30,31,31,31,31,31]) + self.playerLeft = bytearray([255,255,255,255,63,15,47,15,255,255,255,255,255, + 31,31,31,31,31,30,31,30,31,31,31,31,31]) + self.playerRight = bytearray([255,255,255,255,255,15,47,15,63,255,255,255,255, + 31,31,31,31,31,30,31,30,31,31,31,31,31]) + + self.playerBack = bytearray([255,255,255,255,191,15,15,15,63,255,255,255,255, + 31,31,31,31,31,30,31,30,31,31,31,31,31]) + self.playerLeftWalk = bytearray([255,255,255,255,63,15,47,15,255,255,255,255,255, + 31,31,31,31,30,31,31,31,30,31,31,31,31]) + self.playerRightWalk = bytearray([255,255,255,255,255,15,47,15,63,255,255,255,255, + 31,31,31,31,30,31,31,31,30,31,31,31,31]) + # BITMAP: width: 13, height: 13 + self.playerFrontWalk1 = bytearray([255,255,255,255,63,15,47,15,191,255,255,255,255, + 31,31,31,31,31,31,31,30,31,31,31,31,31]) + # BITMAP: width: 13, height: 13 + self.playerFrontWalk2 = bytearray([255,255,255,255,63,15,47,15,191,255,255,255,255, + 31,31,31,31,31,30,31,31,31,31,31,31,31]) + self.playerBackWalk1 = bytearray([255,255,255,255,191,15,15,15,63,255,255,255,255, + 31,31,31,31,31,31,31,30,31,31,31,31,31]) + # BITMAP: width: 13, height: 13 + self.playerBackWalk2 = bytearray([255,255,255,255,191,15,15,15,63,255,255,255,255, + 31,31,31,31,31,30,31,31,31,31,31,31,31]) + self.playerLift = bytearray([255,255,255,255,207,15,47,15,207,255,255,255,255, + 31,31,31,31,31,30,31,30,31,31,31,31,31]) + + self.swordRight1 = bytearray([255,255,255,255,191,15,47,15,191,255,255,255,255, + 31,31,31,31,30,31,31,30,31,31,31,31,31]) + self.swordRight2 = bytearray([255,255,255,255,191,15,47,15,191,31,255,255,255, + 31,31,31,31,30,31,31,30,31,31,31,31,31]) + self.swordRight3 = bytearray([255,255,255,255,191,15,47,15,191,31,191,191,255, + 31,31,31,31,30,31,31,30,31,31,31,31,31]) + self.swordRight4 = bytearray([255,255,255,255,191,15,47,15,191,31,191,191,191, + 31,31,31,31,30,31,31,30,31,31,31,31,31]) + + self.swordFront1 = bytearray([255,255,255,255,191,15,47,15,255,255,255,255,255, + 31,31,31,31,31,31,30,30,31,31,31,31,31]) + self.swordFront2 = bytearray([255,255,255,255,191,15,47,15,255,255,255,255,255, + 31,31,31,31,31,29,28,28,31,31,31,31,31]) + self.swordFront3 = bytearray([255,255,255,255,191,15,47,15,255,255,255,255,255, + 31,31,31,31,31,29,16,28,31,31,31,31,31]) + self.swordFront4 = bytearray([255,255,255,255,191,15,47,15,255,255,255,255,255, + 31,31,31,31,31,29,0,28,31,31,31,31,31]) + + self.swordBack1 = bytearray([255,255,255,255,255,15,15,15,191,255,255,255,255, + 31,31,31,31,31,31,31,30,31,31,31,31,31]) + self.swordBack2 = bytearray([255,255,255,255,255,15,7,15,191,255,255,255,255, + 31,31,31,31,31,31,31,30,31,31,31,31,31]) + self.swordBack3 = bytearray([255,255,255,255,255,15,1,15,191,255,255,255,255, + 31,31,31,31,31,31,31,30,31,31,31,31,31]) + self.swordBack4 = bytearray([255,255,255,255,255,7,0,7,191,255,255,255,255, + 31,31,31,31,31,31,31,30,31,31,31,31,31]) + + + self.playerSprite = thumby.Sprite(13, 13, self.playerFront + self.playerBack + self.playerLeft + self.playerRight, self.playerLeft, key=1) + self.playerSprite.x = 29 # Initial placement - middle of screen + self.playerSprite.y = 13 + + self.up_walking_sprite = thumby.Sprite(13, 13, self.playerBack + self.playerBackWalk1 + self.playerBack + self.playerBackWalk2, key=1) + self.down_walking_sprite = thumby.Sprite(13, 13, self.playerFront + self.playerFrontWalk1 + self.playerFront + self.playerFrontWalk2, key=1) + self.left_walking_sprite = thumby.Sprite(13, 13, self.playerLeft + self.playerLeft + self.playerLeftWalk + self.playerLeftWalk, key=1) + self.right_walking_sprite = thumby.Sprite(13, 13, self.playerRight + self.playerRight + self.playerRightWalk + self.playerRightWalk, key=1) + + self.lifting_sprite = thumby.Sprite(13, 13, self.playerLift, key=1) + + # Player movement distance per frame + self.moveNum = 1 + + # Sprite animation counters + self.walkCounter = 0 + self.swordCounter = 0 + + # Bool to determine when using sword + self.swinging = False + + + def death(self, display): + if self.hearts < 1: + display.fill(0) + display.drawText("GAME OVER", 10, 17, 1) + display.update() + sleep(2) + thumbyHardware.reset() + + + def get_collision(self, collider, mod1, mod2, mod3, mod4, mod5, mod6): + if (((self.playerSprite.x + mod1 < collider.x + mod2) and (self.playerSprite.x + mod3 > collider.x)) and + ((collider.y < self.playerSprite.y + mod4) and (collider.y + mod5 > self.playerSprite.y + mod6))): + self.isColliding = True + self.colliding_wall = collider + + + def process_hit(self, direction, enemy, thumby): + if enemy.enemy_type == "leever": + if not enemy.is_buried: + thumby.audio.playBlocking(392, 50) + thumby.audio.play(523, 150) + enemy.health -= 1 + if enemy.facingDirection == "up": + if direction == "down": + enemy.y += 5 + elif enemy.facingDirection == "down": + if direction == "up": + enemy.y -= 5 + elif enemy.facingDirection == "left": + if direction == "right": + enemy.x += 5 + elif enemy.facingDirection == "right": + if direction == "left": + enemy.x -= 5 + if enemy.enemy_type == "stalfos": + thumby.audio.playBlocking(392, 50) + thumby.audio.play(523, 150) + enemy.health -= 1 + if enemy.facingDirection == "up": + if direction == "down": + enemy.y += 5 + elif enemy.facingDirection == "down": + if direction == "up": + enemy.y -= 5 + elif enemy.facingDirection == "left": + if direction == "right": + enemy.x += 5 + elif enemy.facingDirection == "right": + if direction == "left": + enemy.x -= 5 + else: + thumby.audio.playBlocking(392, 50) + thumby.audio.play(523, 150) + enemy.health -= 1 + + + def hit_detection(self, enemy_controller, thumby): + for enemy in enemy_controller.enemies: + if self.facingDirection == "up": + if (((self.playerSprite.x + 6 <= enemy.x + 5) and (self.playerSprite.x + 7 >= enemy.x)) and + ((enemy.y < self.playerSprite.y + 4) and (enemy.y + 5 > self.playerSprite.y))): + if self.swinging: + self.process_hit(self.facingDirection, enemy, thumby) + elif self.facingDirection == "down": + if (((self.playerSprite.x + 6 <= enemy.x + 5) and (self.playerSprite.x + 7 >= enemy.x)) and + ((enemy.y < self.playerSprite.y + 13) and (enemy.y + 5 > self.playerSprite.y + 9))): + if self.swinging: + self.process_hit(self.facingDirection, enemy, thumby) + elif self.facingDirection == "right": + if (((self.playerSprite.x + 6 < enemy.x + 5) and (self.playerSprite.x + 13 > enemy.x)) and + ((enemy.y <= self.playerSprite.y + 7) and (enemy.y + 5 >= self.playerSprite.y + 6))): + if self.swinging: + self.process_hit(self.facingDirection, enemy, thumby) + elif self.facingDirection == "left": + if (((self.playerSprite.x < enemy.x + 5) and (self.playerSprite.x + 4 > enemy.x)) and + ((enemy.y <= self.playerSprite.y + 7) and (enemy.y + 5 >= self.playerSprite.y + 6))): + if self.swinging: + self.process_hit(self.facingDirection, enemy, thumby) + +# TO DO: Put this in the enemy_controller object + if enemy.health < 1: + enemy.is_dead = True + enemy_controller.enemies_used = enemy_controller.enemies_used + (enemy.identity, ) + self.loot_randomizer = randrange(0, 5) + + if self.loot_randomizer == 1: + self.type_of_loot = self.loot_types[0] + elif self.loot_randomizer == 2: + self.type_of_loot = self.loot_types[1] + elif self.loot_randomizer == 3: + self.type_of_loot = self.loot_types[2] + else: + self.type_of_loot = self.loot_types[3] + enemy_controller.loot.append(Loot(enemy.x, enemy.y, self.type_of_loot, thumby)) + + while enemy_controller.animation_counter < enemy_controller.animation_length: + enemy.map_to_display = [enemy.blank_map, 0, 0] + enemy_controller.display_death_sprite(enemy) + + else: + enemy.health = enemy.starting_health + enemy.is_dead = False + enemy_index = enemy_controller.enemies.index(enemy) + # print(enemy_index) + del enemy_controller.enemies[enemy_index] + enemy_controller.animation_counter = 0 + if len(enemy_controller.enemies) == 0: + enemy_controller.enemies_killed = True + + def save_game(self, scene_controller, json): + save_list = [6, self.max_hearts, self.rupees, self.keys, self.bombs, scene_controller.isDangerous, scene_controller.doors_unlocked, scene_controller.keys_used] + with open("/Games/Thelda/save.json", 'w') as savefile: + json.dump(save_list, savefile) + + + # Dpad movement. TO DO: Refactor this monstrosity + def move_player(self, scene_controller, enemy_controller, thumby, json): + + for item in scene_controller.items: + if (((self.playerSprite.x + 4 < item.x + 5) and (self.playerSprite.x + 9 > item.x)) and + ((item.y < self.playerSprite.y + 9) and (item.y + 5 > self.playerSprite.y + 4))): + if scene_controller.isDangerous: + if item.sword: + scene_controller.isDangerous = False + scene_controller.this_scene["items"][0].y -= 40 + + for lock in scene_controller.locks: + if (((self.playerSprite.x + 4 < lock.x + 6) and (self.playerSprite.x + 9 > lock.x - 1)) and + ((lock.y - 1 < self.playerSprite.y + 9) and (lock.y + 6 > self.playerSprite.y + 4))): + if self.keys > 0: + scene_controller.doors_unlocked.append(lock.identity) + scene_controller.locks.remove(lock) + print(scene_controller.doors_unlocked) + self.keys -= 1 + self.keys_text = str(self.keys) + for key in scene_controller.keys: + if not key.carried and key.home_scene == scene_controller.scene_string: + if (((self.playerSprite.x + 4 < key.x + 3) and (self.playerSprite.x + 9 > key.x)) and + ((key.y < self.playerSprite.y + 9) and (key.y + 3 > self.playerSprite.y + 4))): + if not key.conditional: + print(f"keys used: {scene_controller.keys_used}") + print(f"key id: {key.identity}") + if not key.identity in scene_controller.keys_used: + scene_controller.keys_used.append(key.identity) + scene_controller.keys.remove(key) + scene_controller.key_assigned = False + print(scene_controller.keys_used) + self.keys += 1 + self.keys_text = str(self.keys) + else: + if enemy_controller.enemies == []: + print(f"keys used: {scene_controller.keys_used}") + print(f"key id: {key.identity}") + if not key.identity in scene_controller.keys_used: + scene_controller.keys_used.append(key.identity) + scene_controller.keys.remove(key) + scene_controller.key_assigned = False + print(scene_controller.keys_used) + self.keys += 1 + self.keys_text = str(self.keys) + + + for door in scene_controller.doors: + if self.playerSprite.x == door.x - 4 and self.playerSprite.y == door.y - 4: + self.save_game(scene_controller, json) + scene_controller.clear_scene(enemy_controller) + self.entranceCoords = [self.playerSprite.x, self.playerSprite.y + 5] + if scene_controller.is_dungeon: + self.entrance_scene = (scene_controller.scene_x, scene_controller.scene_y) + print(f"Entrance Scene: {self.entrance_scene}") + scene_controller.scene_x *= -100 + scene_controller.scene_y *= 100 + self.exit_scene = (scene_controller.scene_x, scene_controller.scene_y) + print(f"Exit Scene: {self.exit_scene}") + self.in_dungeon = True + scene_controller.in_dungeon = True + self.playerSprite.x = 29 + self.playerSprite.y = 31 + scene_controller.is_dungeon = False + + else: + scene_controller.scene_x *= -1 + scene_controller.scene_y += 1 + print(f"Scene:{scene_controller.scene_x}, {scene_controller.scene_y}") + self.playerSprite.x = 29 + self.playerSprite.y = 31 + self.inCave = True + return + + for enemy in enemy_controller.enemies: + if not enemy.prespawn: + if (((self.playerSprite.x + 4 < enemy.x + 5) and (self.playerSprite.x + 9 > enemy.x)) and + ((enemy.y < self.playerSprite.y + 9) and (enemy.y + 5 > self.playerSprite.y + 4))): + if not self.enemyCollision: + if self.enemyCollisionBuffer >= 20: + # thumby.audio.play(523, 300) + if enemy.enemy_type == "leever": + if not enemy.is_buried: + thumby.audio.playBlocking(523, 50) + thumby.audio.play(392, 200) + self.hearts -= enemy.damage + thumby.display.fill(1) + if enemy.facingDirection == "up": + enemy.facingDirection = "down" + elif enemy.facingDirection == "down": + enemy.facingDirection = "up" + elif enemy.facingDirection == "left": + enemy.facingDirection = "right" + elif enemy.facingDirection == "right": + enemy.facingDirection = "left" + else: + thumby.audio.playBlocking(523, 50) + thumby.audio.play(392, 200) + self.hearts -= enemy.damage + thumby.display.fill(1) + self.enemyCollisionBuffer = 0 + if enemy.enemy_type == "octorok": + for rock in enemy.rocks: + if (((self.playerSprite.x + 4 < rock.x + 3) and (self.playerSprite.x + 9 > rock.x)) and + ((rock.y < self.playerSprite.y + 9) and (rock.y + 3 > self.playerSprite.y + 4))): + # print("hit by rock") + + if self.facingDirection == "up" and rock.direction == "down": + rock.direction = "up" + rock.reflected = True + thumby.audio.play(4186, 50) + elif self.facingDirection == "down" and rock.direction == "up": + rock.direction = "down" + rock.reflected = True + thumby.audio.play(4186, 50) + elif self.facingDirection == "right" and rock.direction == "left": + rock.direction = "right" + rock.reflected = True + thumby.audio.play(4186, 50) + elif self.facingDirection == "left" and rock.direction == "right": + rock.direction = "left" + rock.reflected = True + thumby.audio.play(4186, 50) + else: + thumby.audio.playBlocking(523, 50) + thumby.audio.play(392, 200) + self.hearts -= 1 + thumby.display.fill(1) + rock_index = enemy.rocks.index(rock) + del enemy.rocks[rock_index] + if enemy.enemy_type == "zora": + for magic in enemy.magic: + if (((self.playerSprite.x + 4 < magic.x + 3) and (self.playerSprite.x + 9 > magic.x)) and + ((magic.y < self.playerSprite.y + 9) and (magic.y + 3 > self.playerSprite.y + 4))): + print("hit by magic") + thumby.audio.playBlocking(523, 50) + thumby.audio.play(392, 200) + self.hearts -= 1 + thumby.display.fill(1) + magic_index = enemy.magic.index(magic) + del enemy.magic[magic_index] + enemy.has_fired = True + + + self.enemyCollisionBuffer += 1 + if self.enemyCollisionBuffer > 20: + self.enemyCollision = False + + + if thumby.buttonU.pressed(): + if not self.isTransitioning: + self.isColliding = False + for wall in scene_controller.walls: + self.get_collision(wall, 4, 5, 9, 9, 5, 3) + for bush in scene_controller.bushes: + self.get_collision(bush, 4, 5, 9, 9, 5, 3) + for water in scene_controller.water: + self.get_collision(water, 4, 5, 9, 9, 5, 3) + for barrier in scene_controller.barriers: + self.get_collision(barrier, 4, 5, 9, 9, 5, 3) + for lock in scene_controller.locks: + self.get_collision(lock, 4, 5, 9, 9, 5, 3) + for block in scene_controller.blocks: + self.get_collision(block, 4, 5, 9, 9, 5, 3) + self.facingDirection = "up" + if self.isColliding: + self.playerSprite.y = self.colliding_wall.y + 2 + self.isColliding = False + player_sprite_x = self.playerSprite.x + player_sprite_y = self.playerSprite.y + self.playerSprite = self.up_walking_sprite + self.playerSprite.x = player_sprite_x + self.playerSprite.y = player_sprite_y + self.playerSprite.setFrame(self.walkCounter) + if self.playerSprite.y > 1: + if not self.isColliding: + self.playerSprite.y -= self.moveNum + else: + scene_controller.is_dungeon = False + self.save_game(scene_controller, json) + self.items = [] + scene_controller.clear_scene(enemy_controller) + scene_controller.scene_y += 1 + print(f"Scene:{scene_controller.scene_x}, {scene_controller.scene_y}") + self.playerSprite.y += 30 + self.isTransitioning = True + + + + + if thumby.buttonD.pressed(): + if not self.isTransitioning: + self.isColliding = False + for wall in scene_controller.walls: + self.get_collision(wall, 4, 5, 9, 10, 5, 4) + for bush in scene_controller.bushes: + self.get_collision(bush, 4, 5, 9, 10, 5, 4) + for water in scene_controller.water: + self.get_collision(water, 4, 5, 9, 10, 5, 4) + for barrier in scene_controller.barriers: + self.get_collision(barrier, 4, 5, 9, 10, 5, 4) + for lock in scene_controller.locks: + self.get_collision(lock, 4, 5, 9, 10, 5, 4) + for block in scene_controller.blocks: + self.get_collision(block, 4, 5, 9, 10, 5, 4) + self.facingDirection = "down" + if self.isColliding: + self.playerSprite.y = self.colliding_wall.y - 10 + self.isColliding = False + player_sprite_x = self.playerSprite.x + player_sprite_y = self.playerSprite.y + self.playerSprite = self.down_walking_sprite + self.playerSprite.x = player_sprite_x + self.playerSprite.y = player_sprite_y + self.playerSprite.setFrame(self.walkCounter) + if self.playerSprite.y < 31: + if not self.isColliding: + self.playerSprite.y += self.moveNum + else: + if self.inCave: + self.save_game(scene_controller, json) + self.items = [] + scene_controller.clear_scene(enemy_controller) + scene_controller.scene_x *= -1 + scene_controller.scene_y -= 1 + print(f"Scene:{scene_controller.scene_x}, {scene_controller.scene_y}") + self.playerSprite.x = self.entranceCoords[0] + self.playerSprite.y = self.entranceCoords[1] + self.inCave = False + scene_controller.is_still_here = False + elif self.in_dungeon: + self.save_game(scene_controller, json) + self.items = [] + scene_controller.clear_scene(enemy_controller) + if scene_controller.scene_x == self.exit_scene[0] and scene_controller.scene_y == self.exit_scene[1]: + scene_controller.scene_x = self.entrance_scene[0] + scene_controller.scene_y = self.entrance_scene[1] + self.playerSprite.x = self.entranceCoords[0] + self.playerSprite.y = self.entranceCoords[1] + print(f"Scene:{scene_controller.scene_x}, {scene_controller.scene_y}") + self.in_dungeon = False + scene_controller.in_dungeon = False + enemy_controller.enemies_used = () + else: + self.save_game(scene_controller, json) + self.items = [] + scene_controller.clear_scene(enemy_controller) + scene_controller.scene_y -= 1 + print(f"Scene:{scene_controller.scene_x}, {scene_controller.scene_y}") + self.playerSprite.y -= 30 + self.isTransitioning = True + + + else: + scene_controller.is_dungeon = False + self.save_game(scene_controller, json) + self.items = [] + scene_controller.clear_scene(enemy_controller) + scene_controller.scene_y -= 1 + print(f"Scene:{scene_controller.scene_x}, {scene_controller.scene_y}") + self.playerSprite.y -= 30 + self.isTransitioning = True + + + if thumby.buttonL.pressed(): + if not self.isTransitioning: + self.isColliding = False + for wall in scene_controller.walls: + self.get_collision(wall, 3, 5, 9, 9, 5, 4) + for bush in scene_controller.bushes: + self.get_collision(bush, 3, 5, 9, 9, 5, 4) + for water in scene_controller.water: + self.get_collision(water, 3, 5, 9, 9, 5, 4) + for barrier in scene_controller.barriers: + self.get_collision(barrier, 3, 5, 9, 9, 5, 4) + for lock in scene_controller.locks: + self.get_collision(lock, 3, 5, 9, 9, 5, 4) + for block in scene_controller.blocks: + self.get_collision(block, 3, 5, 9, 9, 5, 4) + self.facingDirection = "left" + if self.isColliding: + self.playerSprite.x = self.colliding_wall.x + 2 + self.isColliding = False + player_sprite_x = self.playerSprite.x + player_sprite_y = self.playerSprite.y + self.playerSprite = self.left_walking_sprite + self.playerSprite.x = player_sprite_x + self.playerSprite.y = player_sprite_y + self.playerSprite.setFrame(self.walkCounter) + if self.playerSprite.x > -4: + if not self.isColliding: + self.playerSprite.x -= self.moveNum + else: + scene_controller.is_dungeon = False + self.save_game(scene_controller, json) + self.items = [] + scene_controller.clear_scene(enemy_controller) + scene_controller.scene_x -= 1 + print(f"Scene:{scene_controller.scene_x}, {scene_controller.scene_y}") + self.playerSprite.x += 67 + self.isTransitioning = True + + if thumby.buttonR.pressed(): + if not self.isTransitioning: + self.isColliding = False + for wall in scene_controller.walls: + self.get_collision(wall, 4, 5, 10, 9, 5, 4) + for bush in scene_controller.bushes: + self.get_collision(bush, 4, 5, 10, 9, 5, 4) + for water in scene_controller.water: + self.get_collision(water, 4, 5, 10, 9, 5, 4) + for barrier in scene_controller.barriers: + self.get_collision(barrier, 4, 5, 10, 9, 5, 4) + for lock in scene_controller.locks: + self.get_collision(lock, 4, 5, 10, 9, 5, 4) + for block in scene_controller.blocks: + self.get_collision(block, 4, 5, 10, 9, 5, 4) + self.facingDirection = "right" + if self.isColliding: + self.playerSprite.x = self.colliding_wall.x - 10 + self.isColliding = False + player_sprite_x = self.playerSprite.x + player_sprite_y = self.playerSprite.y + self.playerSprite = self.right_walking_sprite + self.playerSprite.x = player_sprite_x + self.playerSprite.y = player_sprite_y + self.playerSprite.setFrame(self.walkCounter) + if self.playerSprite.x < 63: + if not self.isColliding: + self.playerSprite.x += self.moveNum + else: + scene_controller.is_dungeon = False + self.save_game(scene_controller, json) + self.items = [] + scene_controller.clear_scene(enemy_controller) + scene_controller.scene_x += 1 + print(f"Scene:{scene_controller.scene_x}, {scene_controller.scene_y}") + self.playerSprite.x -= 67 + self.isTransitioning = True + + if not thumby.dpadPressed(): + self.walkCounter = 0 + self.playerSprite.setFrame(self.walkCounter) + + # Display Sprite + self.walkCounter += 1 + thumby.display.drawSprite(self.playerSprite) + self.isTransitioning = False + + # print(f"{self.isColliding}") + + + def swing_sword(self, enemy_controller, thumby): + if len(self.sword_projectile) >= 1: + for projectile in self.sword_projectile: + if projectile.timer > projectile.lifespan: + projectile.dying = True + if projectile.x < 0 or projectile.x + 2 >= 71 or projectile.y <= 4 or projectile.y + 2 >= 39: # Detects screen edges for sword projectile + projectile.dying = True + if projectile.dying == True: + projectile.display_death_sprite(thumby) + if projectile.animation_counter > 3: + self.sword_projectile = [] + else: + projectile.move(enemy_controller, thumby) + + else: + self.sword_projectile_timer += 1 + + if self.facingDirection == "up" and not thumby.actionPressed(): + self.playerSprite = self.up_walking_sprite + self.swing_counter = 0 + elif self.facingDirection == "down" and not thumby.actionPressed(): + self.playerSprite = self.down_walking_sprite + self.swing_counter = 0 + elif self.facingDirection == "right" and not thumby.actionPressed(): + self.playerSprite = self.right_walking_sprite + self.swing_counter = 0 + elif self.facingDirection == "left" and not thumby.actionPressed(): + self.playerSprite = self.left_walking_sprite + self.swing_counter = 0 + thumby.display.drawSprite(self.playerSprite) + + + if thumby.buttonA.pressed() and self.swing_counter < 5: + if self.hearts == self.max_hearts and self.sword_projectile == []: + if self.sword_projectile_timer > self.sword_projectile_delay: + self.sword_projectile.append(Sword(self.facingDirection, self.playerSprite.x + 4, self.playerSprite.y + 4, enemy_controller, thumby)) + # print(self.sword_projectile) + self.sword_projectile_timer = 0 + self.swinging = True + self.swordCounter = 0 + while self.facingDirection == "right" and self.swordCounter <= 4: + player_sprite_x = self.playerSprite.x + player_sprite_y = self.playerSprite.y + self.playerSprite = thumby.Sprite(13, 13, self.swordRight1+self.swordRight2+self.swordRight3+self.swordRight4, player_sprite_x, player_sprite_y, key=1) + self.playerSprite.setFrame(self.swordCounter) + thumby.display.drawSprite(self.playerSprite) + self.swordCounter += 1 + + while self.facingDirection == "left" and self.swordCounter <= 4: + player_sprite_x = self.playerSprite.x + player_sprite_y = self.playerSprite.y + self.playerSprite = thumby.Sprite(13, 13, self.swordRight1+self.swordRight2+self.swordRight3+self.swordRight4, player_sprite_x, player_sprite_y, key=1, mirrorX=1) + self.playerSprite.setFrame(self.swordCounter) + thumby.display.drawSprite(self.playerSprite) + self.swordCounter += 1 + + while self.facingDirection == "up" and self.swordCounter <= 4: + player_sprite_x = self.playerSprite.x + player_sprite_y = self.playerSprite.y + self.playerSprite = thumby.Sprite(13, 13, self.swordBack1+self.swordBack2+self.swordBack3+self.swordBack4, player_sprite_x, player_sprite_y, key=1) + self.playerSprite.setFrame(self.swordCounter) + thumby.display.drawSprite(self.playerSprite) + self.swordCounter += 1 + + while self.facingDirection == "down" and self.swordCounter <= 4: + player_sprite_x = self.playerSprite.x + player_sprite_y = self.playerSprite.y + self.playerSprite = thumby.Sprite(13, 13, self.swordFront1+self.swordFront2+self.swordFront3+self.swordFront4, player_sprite_x, player_sprite_y, key=1) + self.playerSprite.setFrame(self.swordCounter) + thumby.display.drawSprite(self.playerSprite) + self.swordCounter += 1 + self.swing_counter += 1 + + + else: + self.swinging = False + thumby.display.drawSprite(self.playerSprite) + + + def use_item(self, enemy_controller, thumby): + if thumby.buttonB.pressed(): + if self.active_item == "boomerang": + if self.items == []: + self.items.append(Boomerang(self.playerSprite, self.facingDirection, thumby.display)) + elif self.active_item == "bombs": + if self.items == []: + if self.facingDirection == "up": + bomb_x = self.playerSprite.x + 4 + bomb_y = self.playerSprite.y - 1 + elif self.facingDirection == "down": + bomb_x = self.playerSprite.x + 4 + bomb_y = self.playerSprite.y + 9 + elif self.facingDirection == "right": + bomb_x = self.playerSprite.x + 9 + bomb_y = self.playerSprite.y + 4 + elif self.facingDirection == "left": + bomb_x = self.playerSprite.x + bomb_y = self.playerSprite.y + 4 + else: + bomb_x = playerSprite.x + bomb_y = playerSprite.y + self.items.append(Bomb(bomb_x, bomb_y)) + if not self.items == []: + for item in self.items: + if item.item_type == "boomerang": + item.move(thumby.display, self.playerSprite, self.items) + for enemy in enemy_controller.enemies: + if enemy.x < item.x + 5 and enemy.x + 5 > item.x and item.y < enemy.y + 5 and item.y + 5 > enemy.y: + thumby.audio.play(4186, 50) + item.lifecounter = item.lifespan + if not enemy.frozen: + enemy.frozen = True + + if (((self.playerSprite.x + 4 < item.x + 5) and (self.playerSprite.x + 9 > item.x)) and + ((item.y < self.playerSprite.y + 9) and (item.y + 5 > self.playerSprite.y + 4))) and item.lifecounter >= item.lifespan: + self.items.remove(item) + else: + item.lifecounter += 1 + + elif item.item_type == "bomb": + if item.timer >= 40: + item.explode(thumby.display) + thumby.audio.play(523, 150) + for enemy in enemy_controller.enemies: + if ((enemy.x < item.x + 10) and (enemy.x + 5 > item.x - 5) and + (enemy.y < item.y + 10) and (enemy.y + 5 > item.y - 5)): + enemy.health -= 3 + if item.timer == 42: + if ((self.playerSprite.x - 4 < item.x + 10) and (self.playerSprite.x + 9 > item.x - 5) and + (self.playerSprite.y - 4 < item.y + 10) and (self.playerSprite.y + 9 > item.y - 5)): + thumby.audio.playBlocking(523, 50) + thumby.audio.play(392, 200) + self.hearts -= 2 + thumby.display.fill(1) + + if item.timer >= 43: + self.items.remove(item) + else: + thumby.display.blit(bytearray([31,3,9,2,31]), item.x, item.y, 5, 5, 1, 0, 0) + item.timer += 1 + + \ No newline at end of file diff --git a/Thelda/save.json b/Thelda/save.json new file mode 100644 index 00000000..211af611 --- /dev/null +++ b/Thelda/save.json @@ -0,0 +1 @@ +[6, 6, 0, 0, 0, True, [], []] \ No newline at end of file diff --git a/Thelda/scenecontroller.py b/Thelda/scenecontroller.py new file mode 100644 index 00000000..06b84c91 --- /dev/null +++ b/Thelda/scenecontroller.py @@ -0,0 +1,335 @@ +import gc +from sys import path +path.append("/Games/Thelda") + + +class T: + __slots__ = ("x", "y") + def __init__(self, x, y): + self.x = x + self.y = y + +class Door: + def __init__(self, x, y): + self.x = x + self.y = y + self.cave_door = bytearray([0, 0, 0, 0, 0]) + +class Block: + def __init__(self, x, y): + self.x = x + self.y = y + +class Key: + def __init__(self, x, y, is_solo, identity, scenestring, conditional): + self.key = bytearray([31,13,2,29,31]) + self.identity = identity + self.x = x + self.y = y + self.solo = is_solo + self.carried = False + self.home_scene = scenestring + self.conditional = conditional + + +class SceneController: + def __init__(self): + + self.scene_x = 8 + self.scene_y = 0 + self.wall = bytearray([8,22,5,26,4]) + self.water_tile = bytearray([7,26,31,11,28]) + self.bush = bytearray([17,14,14,4,1]) + self.bridge_tile = bytearray([65,93,65,93,65]) + self.tree_tile = bytearray([30,29,0,0,23]) + self.sand_tile = bytearray([0]) + self.walls = [] + self.water = [] + self.bushes = [] + self.doors = [] + self.sprites = [] + self.items = [] + self.slopes = [] + self.bridges = [] + self.sand = [] + self.trees = [] + self.barriers = [] + self.doorways = [] + self.stairs = [] + self.locks = [] + self.keys = [] + self.blocks = [] + self.frame_timer = 0 + self.frame_delay = 0 + self.is_still_here = False + self.is_dungeon = False + self.in_dungeon = False + self.built = False + self.isDangerous = True + self.doors_unlocked = [] + self.keys_used = [] + self.key_assigned = False + print(f"Items:{len(self.items)}") + + + def build_scene(self, x, y, font_handler, display, enemy_controller): + # BITMAP: width: 35, height: 18 + # BITMAP: width: 35, height: 18 + # self.dungeon_wall = bytearray([0,252,250,246,14,238,238,236,226,238,238,238,238,236,226,238,238,238,238,236,226,238,238,238,238,236,226,238,238,238,236,224,238,238,238, + # 0,158,189,189,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + # 0,3,3,3,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]) + self.dungeon_wall = bytearray([0,252,250,246,14,238,238,236,226,238,238,238,238,236,226,238,238,238,238,236,226,238,238,238,238,236,226,238,238,238,236,226,238,238,238, + 0,222,189,189,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 0,3,3,3,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]) + + if not self.built: + self.scene_string = f"scene {x},{y}" + scene_modules = { + 1: 'scenes1', + 2: 'scenes2', + 3: 'scenes3', + 4: 'scenes4', + 5: 'scenes5', + 6: 'scenes6', + 7: 'scenes7', + 8: 'scenes8', + 9: 'scenes9', + 10: 'scenes10', + 11: 'scenes11', + 12: 'scenes12', + 13: 'scenes13', + } + + abs_x = abs(x) + if abs_x in scene_modules: + module_name = scene_modules[abs_x] + module = __import__(module_name) + scenes_class = getattr(module, f"Scenes{abs_x}") + self.this_scene = scenes_class().scenes[self.scene_string] + elif x < -20: + from dungeons1 import Scenes80 + self.this_scene = Scenes80().scenes[self.scene_string] + + + if "dungeon" in self.this_scene: + self.is_dungeon = True + if self.walls == []: + if "walls" in self.this_scene: + for wall in self.this_scene["walls"]: + self.walls.append(T(wall[0], wall[1])) + if len(self.walls) > 0: + print(f"Walls:{len(self.walls)}") + if self.barriers == []: + if "barriers" in self.this_scene: + for barrier in self.this_scene["barriers"]: + self.barriers.append(T(barrier[0], barrier[1])) + if len(self.barriers) > 0: + print(f"Barriers:{len(self.barriers)}") + if self.water == []: + if "water" in self.this_scene: + for water in self.this_scene["water"]: + self.water.append(T(water[0], water[1])) + if len(self.water) > 0: + print(f"Water:{len(self.water)}") + if self.bridges == []: + if "bridges" in self.this_scene: + for bridge in self.this_scene["bridges"]: + self.bridges.append(T(bridge[0], bridge[1])) + if len(self.bridges) > 0: + print(f"Bridges:{len(self.bridges)}") + if self.sand == []: + if "sand" in self.this_scene: + for sand in self.this_scene["sand"]: + self.sand.append(T(sand[0], sand[1])) + if len(self.sand) > 0: + print(f"Sand:{len(self.sand)}") + if self.doors == []: + if "doors" in self.this_scene: + for door in self.this_scene["doors"]: + self.doors.append(Door(door[0], door[1])) + if len(self.doors) > 0: + print(f"Doors:{len(self.doors)}") + if self.stairs == []: + if "stairs" in self.this_scene: + for stairs in self.this_scene["stairs"]: + self.stairs.append(T(stairs[0], stairs[1])) + if len(self.doors) > 0: + print(f"Doors:{len(self.doors)}") + if self.bushes == []: + if "bushes" in self.this_scene: + for bush in self.this_scene["bushes"]: + self.bushes.append(T(bush[0], bush[1])) + if len(self.bushes) > 0: + print(f"Bushes:{len(self.bushes)}") + if self.sprites == []: + if "sprites" in self.this_scene: + for sprite in self.this_scene["sprites"]: + self.sprites.append(sprite) + if len(self.sprites) > 0: + print(f"Sprites:{len(self.sprites)}") + if self.items == []: + if "items" in self.this_scene: + for item in self.this_scene["items"]: + if not item.item_type == "sword": + self.items.append(item) + else: + if self.isDangerous: + self.items.append(item) + if len(self.items) > 0: + print(f"Items:{len(self.items)}") + if self.trees == []: + if "trees" in self.this_scene: + for tree in self.this_scene["trees"]: + self.trees.append(T(tree[0], tree[1])) + if len(self.trees) > 0: + print(f"Trees:{len(self.trees)}") + if self.doorways == []: + if "doorways" in self.this_scene: + for doorway in self.this_scene["doorways"]: + self.doorways.append(doorway) + if self.locks == []: + if "locks" in self.this_scene: + for lock in self.this_scene["locks"]: + if not lock.identity in self.doors_unlocked: + self.locks.append(lock) + # if self.keys == []: + if "keys" in self.this_scene: + for key in self.this_scene["keys"]: + if not key[3] in self.keys_used: + self.keys.append(Key(key[0], key[1], key[2], key[3], self.scene_string, key[4])) + if self.blocks == []: + if "blocks" in self.this_scene: + for block in self.this_scene["blocks"]: + self.blocks.append(Block(block[0], block[1])) + + gc.collect() + + self.built = True + if "null" in self.this_scene: + font_handler.write("under", 26, 17) + font_handler.write("construction", 11, 22) + + # Top and side black bars. Yes... side. 70px works better than 72 for my 5x5 tiles + display.drawLine(0, 0, 0, 39, 0) + display.drawLine(71, 0, 71, 39, 0) + for wall in self.walls: + display.blit(self.wall, wall.x, wall.y, 5, 5, -1, 0, 0) + for water in self.water: + display.blit(self.water_tile, water.x, water.y, 5, 5, -1, 0, 0) + for bridge in self.bridges: + display.blit(self.bridge_tile, bridge.x, bridge.y - 1, 5, 7, -1, 0, 0) + for sand in self.sand: + display.blit(self.sand_tile, sand.x, sand.y, 1, 1, -1, 0, 0) + for slope in self.slopes: + display.blit(slope.slope, slope.x, slope.y, 5, 5, -1, 0, 0) + for door in self.doors: + display.blit(door.cave_door, door.x, door.y, 5, 5, -1, 0, 0) + for stairs in self.stairs: + display.blit(bytearray([15,0,14,0,12]), stairs.x, stairs.y, 5, 5, -1, 0, 0) + for bush in self.bushes: + if not self.in_dungeon: + display.blit(self.bush, bush.x, bush.y, 5, 5, -1, 0, 0) + else: + display.blit(bytearray([10,21,10,21,10]), bush.x, bush.y, 5, 5, -1, 0, 0) + for item in self.items: + display.blit(item.item, item.x, item.y, 5, 5, -1, 0, 0) + for tree in self.trees: + display.blit(self.tree_tile, tree.x, tree.y, 5, 5, -1, 0, 0) + for key in self.keys: + if key.home_scene == self.scene_string: + if key.solo: + if not key.conditional: + display.blit(key.key, key.x, key.y, 5, 5, -1, 0, 0) + else: + if enemy_controller.enemies == [] and not key.identity in self.keys_used: + display.blit(key.key, key.x, key.y, 5, 5, -1, 0, 0) + else: + if not self.key_assigned: + if not len(enemy_controller.enemies) == 0: + self.keyholder = enemy_controller.enemies[0] + self.key_assigned = True + key.carried = True + else: + key.carried = False + display.blit(key.key, key.x, key.y, 5, 5, -1, 0, 0) + else: + if self.keyholder in enemy_controller.enemies: + key.x = self.keyholder.x + key.y = self.keyholder.y + display.blit(key.key, self.keyholder.x, self.keyholder.y, 5, 5, -1, 0, 0) + else: + key.carried = False + display.blit(key.key, key.x, key.y, 5, 5, -1, 0, 0) + + if self.in_dungeon: + display.blit(self.dungeon_wall, 1, 5, 35, 18, 1, 0, 0) + display.blit(self.dungeon_wall, 36, 5, 35, 18, 1, 1, 0) + display.blit(self.dungeon_wall, 1, 22, 35, 18, 1, 0, 1) + display.blit(self.dungeon_wall, 36, 22, 35, 18, 1, 1, 1) + + for doorway in self.doorways: + display.blit(doorway.doorway, doorway.x, doorway.y, doorway.size_x, 5, 0, 0, 0) + + for lock in self.locks: + display.blit(lock.lock, lock.x, lock.y, lock.size_x, 5, 1, 0, 0) + + for block in self.blocks: + display.blit(bytearray([0,14,6,2,0]), block.x, block.y, 5, 5, 1, 0, 0) + + + for sprite in self.sprites: + if self.scene_x == -7 and self.scene_y == 1 and is_dangerous: + self.is_still_here = True + elif self.scene_x == -7 and self.scene_y == 1 and not is_dangerous: # and not self.is_still_here: # Makes Old Man and text not disappear when sword is taken. Unsure if I like it. + self.this_scene["sprites"][0].y -= 40 + self.this_scene["sprites"][1].y -= 40 + + if self.frame_delay > 10: + sprite.setFrame(self.frame_timer) + display.drawSprite(sprite) + self.frame_timer += 1 + self.frame_delay = 0 + else: + self.frame_delay += 1 + display.drawSprite(sprite) + + def clear_scene(self, enemy_controller): + self.walls = [] + self.water = [] + self.bridges = [] + self.sand = [] + self.bushes = [] + self.doors = [] + self.stairs = [] + self.sprites = [] + self.items = [] + self.slopes = [] + self.barriers = [] + self.trees = [] + self.doorways = [] + self.locks = [] + self.blocks = [] + self.key_assigned = False + for enemy in enemy_controller.enemies: + if enemy.enemy_type == "zora": + for magic in enemy.magic: + enemy.magic.remove(magic) + enemy_controller.enemies = [] + enemy_controller.loot = [] + enemy_controller.spawn_counter = 0 + # if not self.in_dungeon: + enemy_controller.enemies_killed = False + self.this_scene = None + gc.collect() + self.built = False + + +# Full Room Template +# "walls": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), +# (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35), +# (1, 10), (6, 10), (11, 10), (16, 10), (21, 10), (26, 10), (31, 10), (36, 10), (41, 10), (46, 10), (51, 10), (56, 10), (61, 10), (66, 10), +# (1, 15), (6, 15), (11, 15), (16, 15), (21, 15), (26, 15), (31, 15), (36, 15), (41, 15), (46, 15), (51, 15), (56, 15), (61, 15), (66, 15), +# (1, 20), (6, 20), (11, 20), (16, 20), (21, 20), (26, 20), (31, 20), (36, 20), (41, 20), (46, 20), (51, 20), (56, 20), (61, 20), (66, 20), +# (1, 25), (6, 25), (11, 25), (16, 25), (21, 25), (26, 25), (31, 25), (36, 25), (41, 25), (46, 25), (51, 25), (56, 25), (61, 25), (66, 25), +# (1, 30), (6, 30), (11, 30), (16, 30), (21, 30), (26, 30), (31, 30), (36, 30), (41, 30), (46, 30), (51, 30), (56, 30), (61, 30), (66, 30)], + \ No newline at end of file diff --git a/Thelda/scenes1.py b/Thelda/scenes1.py new file mode 100644 index 00000000..04462ddf --- /dev/null +++ b/Thelda/scenes1.py @@ -0,0 +1,14 @@ +class Scenes1: + def __init__(self): + + self.scenes = { + "scene 1,0": {"null": []}, + "scene 1,1": {"null": []}, + "scene 1,2": {"null": []}, + "scene 1,3": {"null": []}, + "scene 1,4": {"null": []}, + "scene 1,5": {"null": []}, + "scene 1,6": {"null": []}, + "scene 1,7": {"null": []} + + } diff --git a/Thelda/scenes10.py b/Thelda/scenes10.py new file mode 100644 index 00000000..0a660b68 --- /dev/null +++ b/Thelda/scenes10.py @@ -0,0 +1,82 @@ +class Scenes10: + def __init__(self): + + self.scenes = { + "scene 10,0": { + "walls": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (6, 10), (11, 10), (16, 10), (51, 10), (56, 10), (61, 10), (66, 10), + (11, 15), (16, 15), (36, 15), (56, 15), (61, 15), (66, 15), + (16, 20), (31, 20), (41, 20), + (36, 25), (56, 25), (61, 25), (66, 25), + (16, 30), (51, 30), (56, 30), (61, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "enemies": {"tektite":[("S10E01"), ("S10E02"), ("S10E03"), ("S10E04")]} + + }, + + "scene 10,1": { + "bushes": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), + (1, 10), + (21, 15), + (11, 20), + (21, 25), + (1, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "water": [(41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (41, 10), (46, 10), (51, 10), (56, 10), (61, 10), (66, 10), + (41, 15), (46, 15), (51, 15), (56, 15), (61, 15), (66, 15)], + "enemies": {"octorok": [("S10E05"), ("S10E06"), ("S10E07")], "zora": [("S10E08")]} + + }, + "scene 10,2": { + "bushes": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (6, 10), (11, 10), (16, 10), (21, 10), (26, 10), (41, 10), (46, 10), (51, 10), (56, 10), (61, 10), (66, 10), + (1, 30), (6, 30), (11, 30), (16, 30), (21, 30), (26, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35)], + "water": [(41, 25), (46, 25), (51, 25), (56, 25), (61, 25), (66, 25), + (41, 30), (46, 30), (51, 30), (56, 30), (61, 30), (66, 30), + (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35),], + "enemies":{"zora": [("S10E09")]} + + }, + "scene 10,3": { + "walls": [(11, 20)], + "bushes": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (21, 10), (26, 10), (41, 10), (46, 10), (51, 10), (56, 10), (61, 10), (66, 10), + (1, 15), + (1, 20), + (1, 25), + (1, 30), (21, 30), (26, 30), (41, 30), (46, 30), (51, 30), (56, 30), (61, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "enemies": {"octorok": [("S10E10"), ("S10E11"), ("S10E12"), ("S10E13"), ("S10E14")]} + + }, + "scene 10,4": { + "walls": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (6, 10), (61, 10), (66, 10), + (1, 15), (66, 15), + (1, 20), (66, 20), + (1, 25), (66, 25), + (1, 30), (6, 30), (61, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "bushes": [(16, 15), (51, 15), + (16, 25), (51, 25)], + "water": [(26, 15), (31, 15), (36, 15), (41, 15), + (26, 20), (31, 20), (36, 20), (41, 20), + ], + + }, + "scene 10,5": { + "walls": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "sand": [(1, 10), (16, 10), (31, 10), (46, 10), (61, 10), + (6, 15), (21, 15), (36, 15), (51, 15), (66, 15), + (11, 20), (26, 20), (41, 20), (56, 20), + (1, 25), (16, 25), (31, 25), (46, 25), (61, 25), + (6, 30), (21, 30), (36, 30), (51, 30), (66, 30)], + }, + "scene 10,6": {"null": []}, + "scene 10,7": {"null": []} + + } + \ No newline at end of file diff --git a/Thelda/scenes11.py b/Thelda/scenes11.py new file mode 100644 index 00000000..e97c0631 --- /dev/null +++ b/Thelda/scenes11.py @@ -0,0 +1,50 @@ +class Scenes11: + def __init__(self): + + self.scenes = { + "scene 11,0": { + "walls": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (6, 10), (11, 10), (16, 10), (21, 10), (41, 10), (46, 10), (51, 10), (56, 10), (61, 10), (66, 10), + (1, 15), (6, 15), (11, 15), (46, 15), (51, 15), (56, 15), (61, 15), (66, 15), + (1, 25), (6, 25), (11, 25), (46, 25), (51, 25), (56, 25), (61, 25), (66, 25), + (1, 30), (6, 30), (11, 30), (16, 30), (21, 30), (41, 30), (46, 30), (51, 30), (56, 30), (61, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)] + + }, + "scene 11,1": { + "bushes": [(46, 5), (51, 5), (56, 5), (66, 5), + (51, 15), + (51, 25), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "water": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), + (1, 10), (6, 10), (11, 10), (16, 10), (21, 10), (26, 10), + (1, 15), (6, 15), (11, 15), (16, 15), (21, 15), (26, 15)] + + }, + "scene 11,2": { + "bushes": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (6, 10), + (56, 15), + (56, 25), + (46, 35), (51, 35), (56, 35), (66, 35)], + "water": [(1, 25), (6, 25), (11, 25), (16, 25), (21, 25), (26, 25), + (1, 30), (6, 30), (11, 30), (16, 30), (21, 30), (26, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35)] + + }, + "scene 11,3": { + "walls": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), (46, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (6, 10), (61, 10), (66, 10), + (1, 30), (6, 30), (61, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "bushes": [(21, 15), (46, 15), (21, 25), (46, 25)], + "doors": [(51, 5)] + + }, + "scene 11,4": {"null": []}, + "scene 11,5": {"null": []}, + "scene 11,6": {"null": []}, + "scene 11,7": {"null": []} + + } + diff --git a/Thelda/scenes12.py b/Thelda/scenes12.py new file mode 100644 index 00000000..b6aec87c --- /dev/null +++ b/Thelda/scenes12.py @@ -0,0 +1,14 @@ +class Scenes12: + def __init__(self): + + self.scenes = { + "scene 12,0": {"null": []}, + "scene 12,1": {"null": []}, + "scene 12,2": {"null": []}, + "scene 12,3": {"null": []}, + "scene 12,4": {"null": []}, + "scene 12,5": {"null": []}, + "scene 12,6": {"null": []}, + "scene 12,7": {"null": []} + + } \ No newline at end of file diff --git a/Thelda/scenes13.py b/Thelda/scenes13.py new file mode 100644 index 00000000..ea48c849 --- /dev/null +++ b/Thelda/scenes13.py @@ -0,0 +1,14 @@ +class Scenes13: + def __init__(self): + + self.scenes = { + "scene 13,0": {"null": []}, + "scene 13,1": {"null": []}, + "scene 13,2": {"null": []}, + "scene 13,3": {"null": []}, + "scene 13,4": {"null": []}, + "scene 13,5": {"null": []}, + "scene 13,6": {"null": []}, + "scene 13,7": {"null": []} + + } \ No newline at end of file diff --git a/Thelda/scenes2.py b/Thelda/scenes2.py new file mode 100644 index 00000000..0dd7a08f --- /dev/null +++ b/Thelda/scenes2.py @@ -0,0 +1,15 @@ +class Scenes2: + def __init__(self): + + self.scenes = { + "scene 2,0": {"null": []}, + "scene 2,1": {"null": []}, + "scene 2,2": {"null": []}, + "scene 2,3": {"null": []}, + "scene 2,4": {"null": []}, + "scene 2,5": {"null": []}, + "scene 2,6": {"null": []}, + "scene 2,7": {"null": []} + + } + diff --git a/Thelda/scenes3.py b/Thelda/scenes3.py new file mode 100644 index 00000000..5c0d2595 --- /dev/null +++ b/Thelda/scenes3.py @@ -0,0 +1,14 @@ +class Scenes3: + def __init__(self): + + self.scenes = { + "scene 3,0": {"null": []}, + "scene 3,1": {"null": []}, + "scene 3,2": {"null": []}, + "scene 3,3": {"null": []}, + "scene 3,4": {"null": []}, + "scene 3,5": {"null": []}, + "scene 3,6": {"null": []}, + "scene 3,7": {"null": []} + + } diff --git a/Thelda/scenes4.py b/Thelda/scenes4.py new file mode 100644 index 00000000..c37643a0 --- /dev/null +++ b/Thelda/scenes4.py @@ -0,0 +1,15 @@ +class Scenes4: + def __init__(self): + + self.scenes = { + "scene 4,0": {"null": []}, + "scene 4,1": {"null": []}, + "scene 4,2": {"null": []}, + "scene 4,3": {"null": []}, + "scene 4,4": {"null": []}, + "scene 4,5": {"null": []}, + "scene 4,6": {"null": []}, + "scene 4,7": {"null": []} + + } + \ No newline at end of file diff --git a/Thelda/scenes5.py b/Thelda/scenes5.py new file mode 100644 index 00000000..be8b810f --- /dev/null +++ b/Thelda/scenes5.py @@ -0,0 +1,14 @@ +class Scenes5: + def __init__(self): + + self.scenes = { + "scene 5,0": {"null": []}, + "scene 5,1": {"null": []}, + "scene 5,2": {"null": []}, + "scene 5,3": {"null": []}, + "scene 5,4": {"null": []}, + "scene 5,5": {"null": []}, + "scene 5,6": {"null": []}, + "scene 5,7": {"null": []} + + } diff --git a/Thelda/scenes6.py b/Thelda/scenes6.py new file mode 100644 index 00000000..a63ab82d --- /dev/null +++ b/Thelda/scenes6.py @@ -0,0 +1,79 @@ +class Scenes6: + def __init__(self): + + self.scenes = { + "scene -6,1": { + "walls": [ + (1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), + (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 20), (66, 20), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), + (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "barriers": [(6, 20), (11, 20), (16, 20), (21, 20), (26, 20), (31, 20), + (36, 20), (41, 20), (46, 20), (51, 20), (56, 20), (61, 20)]}, + "scene 6,0": { + "walls": [ + (1, 5), (11, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), + (56, 5), (61, 5), (66, 5), + (1, 10), + (1, 15), (36, 15), (56, 15), + (1, 20), (11, 20), (46, 20), + (1, 25), (36, 25), (56, 25), + (1, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (31, 35), (36, 35), (41, 35), + (46, 35), (51, 35), (56, 35), (61, 35), (66, 35) + ], + "water": [(21, 5), (26, 5), + (21, 10), (26, 10), + (21, 15), (26, 15), + (21, 20), (26, 20), + (21, 25), (26, 25), + (21, 30), (26, 30), + (21, 35), (26, 35)], + "doors": [(6, 5)], + "enemies": {"zora": [("S6E01")]}}, + + "scene 6,1": { + "walls": [ + (1, 5), (6, 5), (41, 5), (51, 5), (61, 5), (66, 5), + (41, 15), + (51, 20), + (41, 25), + (1, 35), (6, 35), (11, 35), (31, 35), (36, 35), (41, 35), (46, 35), + (51, 35), (56, 35), (61, 35), (66, 35)], + "water": [(21, 5), (26, 5), + (21, 10), (26, 10), + (21, 15), (26, 15), + + (21, 25), (26, 25), + (21, 30), (26, 30), + (21, 35), (26, 35)], + "bridges": [(21, 20), (26, 20)], + "enemies": {"octorok": [("S6E02"), ("S6E03"), ("S6E04")], "zora": [("S6E05")]}}, + + "scene 6,2": { + "walls": [ + (1, 25), (6, 25), (61, 25), (66, 25), + (1, 30), (6, 30), (61, 30), (66, 30), + (1, 35), (6, 35), (41, 35), (51, 35), (61, 35), (66, 35)], + "water": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), + (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (6, 10), (11, 10), (16, 10), (21, 10), (26, 10), + (31, 10), (36, 10), (41, 10), (46, 10), (51, 10), (56, 10), + (61, 10), (66, 10), + (1, 15), (6, 15), (11, 15), (16, 15), (21, 15), (26, 15), + (31, 15), (41, 15), (46, 15), (51, 15), (56, 15), (61, 15), + (66, 15), + (21, 20), (26, 20), + (21, 25), (26, 25), + (21, 30), (26, 30), + (21, 35), (26, 35)], + "bridges": [(36, 15)], + "enemies": {"octorok": [("S6E06")], "zora": [("S6E07")]}}, + } + + \ No newline at end of file diff --git a/Thelda/scenes7.py b/Thelda/scenes7.py new file mode 100644 index 00000000..1db00c13 --- /dev/null +++ b/Thelda/scenes7.py @@ -0,0 +1,92 @@ +from thumby import Sprite + + +class Scenes7: + def __init__(self): + + self.fire_1 = bytearray( + [71, 55, 59, 57, 71, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 71, 55, 59, 57, 71]) + self.fire_2 = bytearray( + [69, 55, 27, 58, 71, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 69, 55, 27, 58, 71]) + self.fire = Sprite(40, 7, self.fire_1 + self.fire_2, 16, 19, key=1) + self.scenes = { + "scene 7,0": { + "walls": [ + (1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), + (36, 5), (41, 5), (46, 5), (51, 5), (66, 5), + (66, 5), + (66, 10), + (41, 15), (66, 15), + (11, 20), (26, 20), (51, 20), + (41, 25), (66, 25), + (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), + (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35) + ], + "enemies": {"tektite": [("S7E01"), ("S7E02"), ("S7E03")]}}, + + "scene -7,2": { + "walls": [ + (1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), + (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 20), (66, 20), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), + (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "barriers": [(6, 20), (11, 20), (16, 20), (21, 20), (26, 20), (31, 20), + (36, 20), (41, 20), (46, 20), (51, 20), (56, 20), (61, 20)], + "sprites": [self.fire]}, + + "scene 7,1": { + "walls": [ + (1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (36, 5), + (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (66, 5), + (66, 10), + (16, 15), (21, 15), (26, 15), (31, 15), + (41, 20), (46, 20), (51, 20), + (16, 25), (21, 25), (26, 25), (31, 25), + (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), + (36, 35), (41, 35), (46, 35), (51, 35), (66, 35) + ], + "doors": [(31, 5)], + "enemies": {"octorok": [("S7E04"), ("S7E05"), ("S7E06")]}}, + "scene 7,2": { + "walls": [(1, 35), + (1, 25), (6, 25), (11, 25), + (1, 30), (6, 30), (11, 30), + (1, 35), (6, 35), (11, 35)], + "water": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), + (1, 10), (6, 10), (11, 10), (16, 10), (21, 10), (26, 10), + (1, 15), (6, 15), (11, 15), (16, 15), (21, 15), (26, 15)], + "bushes": [ + (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (41, 15), (51, 15), (56, 15), + (41, 25), (51, 25), (56, 25), + (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), (41, 35), (46, 35), + (51, 35), (56, 35), (61, 35), (66, 35)], + "enemies": {"octorok": [("S7E07"), ("S7E08"), ("S7E09")], "zora": [("S7E10")]}}, + + "scene 7,3": { + "water": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), + (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (6, 10), (11, 10), (16, 10), (21, 10), (26, 10), + (31, 10), (36, 10), (41, 10), (46, 10), (51, 10), (56, 10), + (61, 10), (66, 10), + (1, 15), (6, 15), (11, 15), (16, 15), (21, 15), (26, 15), + (31, 15), (36, 15), (41, 15), (46, 15), (51, 15), (56, 15), + (61, 15), (66, 15), + (1, 20), (6, 20), (11, 20), (16, 20), (21, 20), (26, 20), + (1, 25), (6, 25), (11, 25), (16, 25), (21, 25), (26, 25), + (1, 30), (6, 30), (11, 30), (16, 30), (21, 30), (26, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35)], + "bushes": [(41, 30), (46, 30), (51, 30), (56, 30), (61, 30), (66, 30), + (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "enemies": {"zora": [("S7E11")]}}, + } \ No newline at end of file diff --git a/Thelda/scenes8.py b/Thelda/scenes8.py new file mode 100644 index 00000000..acfb5321 --- /dev/null +++ b/Thelda/scenes8.py @@ -0,0 +1,155 @@ +from thumby import Sprite + +class Sword: + def __init__(self, direction, x, y): + self.sword = True + self.x = x + self.y = y + self.item_type = "sword" + self.direction = direction + self.item = bytearray([31, 23, 0, 23, 31]) + self.sword_up = bytearray([31, 23, 0, 23, 31]) + self.sprite = Sprite(5, 5, self.sword_up, self.x, self.y, key=1) + self.sword_sprite = Sprite(5, 5, self.sword_up, self.x, self.y, key=1) + + +class Scenes8: + def __init__(self): + # self.nw_slope_map = bytearray([8, 22, 21, 26, 28]) + # # BITMAP: width: 5, height: 5 + # self.ne_slope_map = bytearray([30, 30, 25, 22, 4]) + # # BITMAP: width: 5, height: 5 + # self.se_slope_map = bytearray([15, 23, 7, 27, 4]) + # # BITMAP: width: 5, height: 5 + # self.sw_slope_map = bytearray([8, 22, 5, 27, 7]) + + # BITMAP: width: 60, height: 7 + self.dangerous_map = bytearray( + [127, 10, 40, 26, 127, 94, 40, 94, 127, 126, 27, 104, 30, 127, 15, 56, 58, 125, 95, 41, 94, 121, 15, 104, + 30, 121, 15, 24, 58, 121, 63, 72, 73, 123, 127, 104, 12, 105, 127, 24, 106, 24, 127, 8, 91, 40, 127, 11, + 24, 62, 127, 127, 46, 8, 46, 127, 109, 10, 109, 63]) + self.dangerous = Sprite(60, 7, self.dangerous_map, 6, 11, key=1) + # BITMAP: width: 40, height: 7 + self.dude_1 = bytearray( + [71, 55, 59, 57, 71, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 71, 25, 34, 34, 25, 71, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 71, 55, 59, 57, 71]) + # BITMAP: width: 40, height: 7 + self.dude_2 = bytearray( + [69, 55, 27, 58, 71, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 71, 25, 34, 34, 25, 71, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 69, 55, 27, 58, 71]) + self.dude = Sprite(40, 7, self.dude_1 + self.dude_2, 16, 19, key=1) + + self.fire_1 = bytearray( + [71, 55, 59, 57, 71, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 71, 55, 59, 57, 71]) + self.fire_2 = bytearray( + [69, 55, 27, 58, 71, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 69, 55, 27, 58, 71]) + self.fire = Sprite(40, 7, self.fire_1 + self.fire_2, 16, 19, key=1) + # 15 x 10 + self.dungeon_1_entrance_map = bytearray([254,249,3,252,254,22,22,29,22,22,253,254,1,191,223, + 3,1,0,1,1,0,0,0,0,0,1,1,0,1,3]) + self.dungeon_1_entrance = Sprite(15, 10, self.dungeon_1_entrance_map, 26, 15, key=1) + + + self.scenes = { + + "scene -8,1": { + "walls": [ + (1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), + (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 20), (66, 20), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), + (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "barriers": [(6, 20), (11, 20), (16, 20), (21, 20), (26, 20), (31, 20), + (36, 20), (41, 20), (46, 20), (51, 20), (56, 20), (61, 20)], + "items": [Sword("up", 33, 27)], + "sprites": [self.dangerous, self.dude, self.fire]}, + "scene 8,0": { + "walls": [ + (1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), + (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (6, 10), (11, 10), (21, 10), (41, 10), (46, 10), (51, 10), + (56, 10), (61, 10), (66, 10), + (1, 15), (6, 15), (46, 15), (51, 15), (56, 15), (61, 15), (66, 15), + (1, 25), (61, 25), (66, 25), + (1, 30), (6, 30), (61, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), + (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "doors": [(16, 10)], + # "slopes": [ + # # Slope(self.nw_slope_map, 26, 10), Slope(self.nw_slope_map, 11, 15), Slope(self.ne_slope_map, 41, 15), Slope(self.sw_slope_map, 6, 25) + # ] + }, + "scene 8,1": { + "walls": [ + (1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), + (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (41, 10), (66, 10), + (11, 15), (21, 15), (51, 15), + (11, 25), (21, 25), (51, 25), + (1, 30), (41, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), + (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "enemies": {"octorok": [("S8E01"), ("S8E02"), ("S8E03")]}}, + + "scene 8,2": { + "bushes": [ + (1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), + (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (16, 15), (46, 15), (56, 15), (66, 15), + (26, 20), + (16, 25), (46, 25), (56, 25), (66, 25), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), + (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "enemies": {"octorok": [("S8E04"), ("S8E05")]}}, + "scene 8,3": { + "walls": [(41, 30), (46, 30), (51, 30), (56, 30), (61, 30), (66, 30), + (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "water": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), + (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (1, 10), (6, 10), (11, 10), (16, 10), (21, 10), (26, 10), + (31, 10), (36, 10), (41, 10), (46, 10), (51, 10), (56, 10), + (61, 10), (66, 10), + (1, 15), (6, 15), (11, 15), (16, 15), (21, 15), (26, 15), + (31, 15), (36, 15), (41, 15), (46, 15), (51, 15), (56, 15), + (61, 15), (66, 15)], + "bushes": [(1, 30), (6, 30), (11, 30), (16, 30), (21, 30), (26, 30), + (31, 30), (36, 30), (41, 30), (46, 30), (51, 30), (56, 30), + (61, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), + (31, 35), (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), + (61, 35), (66, 35)], + "enemies": {"zora": [("S8E06")]}}, + + "scene 8,4": { + "dungeon":[], + "walls": [(6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (31, 5), (36, 5), (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (6, 10), (61, 10), + (6, 15), (61, 15), + (6, 20), + (6, 25), (61, 25), + (6, 30), (61, 30), + (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), (41, 35), (46, 35), (51, 35), (56, 35), (61, 35)], + "barriers": [(26, 15), (31, 15), (36, 15), (16, 15), (46, 15), (16, 20), (46, 20), (26, 20), (36, 20)], + "water": [(1, 5), (66, 5), + (1, 10), (66, 10), + (1, 15), (66, 15), + (1, 20), + (1, 25), (66, 25), + (1, 30), (66, 30), + (1, 35), (66, 35), ], + "bridges": [(66, 20)], + "doors": [(31, 20)], + "trees": [(16, 15), (46, 15), + (16, 20), (46, 20)], + "sprites": [self.dungeon_1_entrance], + "enemies" : {"octorok": [("S8E07")]} + } + } + + \ No newline at end of file diff --git a/Thelda/scenes9.py b/Thelda/scenes9.py new file mode 100644 index 00000000..54209439 --- /dev/null +++ b/Thelda/scenes9.py @@ -0,0 +1,81 @@ +class Scenes9: + def __init__(self): + + self.scenes = { + "scene 9,0": { + "walls": [ + (1, 5), + (1, 10), + (1, 15), + (1, 25), + (1, 30), + (1, 35)], + "bushes": [ + (6, 5), (16, 5), (26, 5), (46, 5), (56, 5), (66, 5), + (26, 15), (46, 15), (56, 15), + (16, 20), + (26, 25), (46, 25), (56, 25), + (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (31, 35), (36, 35), + (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "enemies": {"octorok": [("S9E01"), ("S9E02"), ("S9E03")]}}, + "scene 9,1": { + "walls": [ + (1, 5), + (1, 10), + (1, 30), + (1, 35)], + "bushes": [ + (6, 5), (16, 5), (26, 5), (46, 5), (56, 5), (66, 5), + (66, 10), + (16, 15), (46, 15), (56, 15), + (26, 20), + (16, 25), (46, 25), (56, 25), + (66, 30), + (6, 35), (16, 35), (26, 35), (46, 35), (56, 35), (66, 35)], + "enemies": {"octorok": [("S9E04"), ("S9E05")]}}, + "scene 9,2": { + "bushes": [ + (1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), (41, 5), + (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (66, 10), + (1, 15), (16, 15), (46, 15), (56, 15), + (26, 20), + (1, 25), (16, 25), (46, 25), (56, 25), + (66, 30), + (1, 35), (6, 35), (16, 35), (26, 35), (46, 35), (56, 35), (66, 35)], + "enemies": {"octorok": [("S9E06"), ("S9E07")]}}, + + "scene 9,3": { + "water": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), + (1, 10), (6, 10), (11, 10), (16, 10), (21, 10), (26, 10), + (1, 15), (6, 15), (11, 15), (16, 15), (21, 15), (26, 15)], + "bushes": [ + (41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (61, 10), (66, 10), + (61, 15), (66, 15), + (61, 20), (66, 20), + (61, 25), (66, 25), + (1, 30), (6, 30), (61, 30), (66, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35), (41, 35), + (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "enemies": {"leever": [("S9E08"), ("S9E09")], "zora": [("S9E10")]}}, + + "scene 9,4": { + "water": [(1, 5), (6, 5), (11, 5), (16, 5), (21, 5), (26, 5), + (1, 10), (6, 10), (11, 10), (16, 10), (21, 10), (26, 10), + (1, 15), (6, 15), (11, 15), (16, 15), (21, 15), (26, 15), + (1, 25), (6, 25), (11, 25), (16, 25), (21, 25), (26, 25), + (1, 30), (6, 30), (11, 30), (16, 30), (21, 30), (26, 30), + (1, 35), (6, 35), (11, 35), (16, 35), (21, 35), (26, 35)], + "bushes": [(41, 5), (46, 5), (51, 5), (56, 5), (61, 5), (66, 5), + (46, 10), (66, 10), + (56, 15), (66, 15), + (66, 20), + (56, 25), (66, 25), + (46, 30), (66, 30), + (41, 35), (46, 35), (51, 35), (56, 35), (61, 35), (66, 35)], + "bridges": [(1, 20), (6, 20), (11, 20), (16, 20), (21, 20), (26, 20), ], + "enemies": {"octorok": [("S9E11"), ("S9E12"), ("S9E13"), ("S9E14")], "zora": [("S9E15")]}}, + + "scene 9,5": {"null": []} + }