From 3d1ecf99f5a004d7d350287234d261f7d045917d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20W=C3=A4chter?= Date: Wed, 29 Mar 2023 10:30:27 +0200 Subject: [PATCH 1/4] cave Blocks working --- project/data/sprites/cave_block_bottom.png | Bin 614 -> 833 bytes project/data/sprites/cave_block_full.png | Bin 616 -> 823 bytes project/data/sprites/cave_block_left.png | Bin 628 -> 817 bytes project/data/sprites/cave_block_right.png | Bin 620 -> 798 bytes project/data/sprites/cave_block_top.png | Bin 634 -> 821 bytes project/data/sprites/cave_block_top_left.png | Bin 610 -> 651 bytes project/data/sprites/cave_block_top_right.png | Bin 618 -> 661 bytes project/data/sprites/sprites.json | 96 ++++++++++++++++++ 8 files changed, 96 insertions(+) diff --git a/project/data/sprites/cave_block_bottom.png b/project/data/sprites/cave_block_bottom.png index 5353e7b9c14f5d76f24c629caf8e059833e8a010..68ea4e5d90a6ba8c736217b83962d6f5bb52775a 100644 GIT binary patch delta 823 zcmV-71IYa51i=Q77k?xO1^@s6y^7ns0004QX+uL$X=7sm04R}lkvmHRK@^2Q6D8sU z3oS$xwonmN2nu2;5wuZ@7{OPwyV)c{vM#$DL~I2c3&BFP@m2T_v=wX>1VIr*?CgCt z64pCLNRVWf+52&3&SmBdgr>4)&Z~_=&i38-WK5f1Skxk~gn#KGLO)^M^qlG0i3C;0 z*F80=-VLf=)%R5#jY-Qhp{8DV#B^L=cuaU|&36=U3%8jWJt=%7JmAU!g|C%v6!}GQ zy2u}j-9&sGLaL{hE@PvN&5WB9?i23LW%K6WdDKmsEPHNNYKP2DJmO3eL&G4?3R!#x zrP`8NWnc8yH-E#bcue^_tmBF!O-8%}qUNQmB{e0wC0~|xmHYoZz0~kfv3pYt>Yjt( zy$2$@P}m8A@8cjSoIv;qF71+kRdO2r6n&?pbss{@CY)cDG-D4gwxIpd(Ovyl3d;Hh`oM`33W0z^ z2;SpcX-><@MlQfB+1$;|>>qn%<2e2WXI{eX>ju zAWzeD;D6P1ZF}KFwg{d~SfvC}WO+KI1o`=V+L=Ubv?kTudlwlJIEE8UqQZwfE7nx| zUoNEpd1UWXWDnPBP&YimuOZ8dPc`^@AgiXVEK7USO3l}y$Ou$x6aao>@l8XPck-C|7ZQH^; z&+)ges}%~?G);KDUg0oH68b3V+S;lPaY*4<+ExSizqhk=*49G}x7$sQ>`C54CwJ8s zM?;& z7BCp|G7N*Q{ai6inx{A#y0@wcl`z)AqX6(5`v+jJRRg}a?Tr8c002ovPDHLkV1fzi BdM*F} delta 602 zcmV-g0;T=I2Id5i7k>;01^@s6R&`wG0004QX+uL$X=7sm04R}lkvU5PQ51#0B#NSu z6k3Q{L{PCXAPS%36i|w&HXs*o=Nst-QZtNFc#t8*i6YT#%Wp3-z9FD%m#+{){U_k?@2RCGi5M0m`Q0flds9<%vP zanj~5#YQAF2Ts+~o2=tl9cw8gBRncRlt~w~>OAU8-0|#ESZbf_0Zc*!@Z%*$flbon z@kz}}W{rL06@T9%Iq_)n)+u6$BS}iUW1<$MYg}qV^te1}iYoX2d76pI3A?-753R43 z^*Ib}`%o@f*6*ohmCwNS0@vA^KPNd&e~VtKX+y{0*@4TOnie~Nt6k`Q)}uzWBDrKc z6AAdZfUXtjzK4!AJFDtB=T8vXmS1!Shet3X_dV->ZGT>9JeEa0sQ>@~32;bRa{vHb zMgRa@MgbI*LqPxl0G>%iK~yLejgiR>!yptyzY(QS2_3l-iZN#zp_qh+HPPhYD04t8 zv;47->$+ZHIL|X$YjzW{I5EbEIcFq);Q=6eLe_&^bVgKb-ACL(@BL12GO-#7qR3mZ zmamZ@<5L18@;#}^-9?6^KA5;Dd*rXOTeX(t(Ok+=dryVCJLqe82j3$W@>2(QhOACU oDP{j@jpjX+j6hvK0xti-8@Og_Du?G`t^fc407*qoM6N<$f|6_yc>n+a diff --git a/project/data/sprites/cave_block_full.png b/project/data/sprites/cave_block_full.png index 4e3c5241aae3ab1f5debf5c7d6bbaed7f1a43763..64003d2561ff82f55a8fcd49b5f60d0493db8fe2 100644 GIT binary patch delta 813 zcmV+|1JeBH1h)o|7k?xO1^@s6y^7ns0004QX+uL$X=7sm04R}lkvmHRK@^2Q6D8sU z3oS$xwonmN2nu2;5wuZ@7{OPwyV)c{vM#$DL~I2c3&BFP@m2T_v=wX>1VIr*?CgCt z64pCLNRVWf+52&3&SmBdgr>4)&Z~_=&i38-WK5f1Skxk~gn#KGLO)^M^qlG0i3C;0 z*F80=-VLf=)%R5#jY-Qhp{8DV#B^L=cuaU|&36=U3%8jWJt=%7JmAU!g|C%v6!}GQ zy2u}j-9&sGLaL{hE@PvN&5WB9?i23LW%K6WdDKmsEPHNNYKP2DJmO3eL&G4?3R!#x zrP`8NWnc8yH-E#bcue^_tmBF!O-8%}qUNQmB{e0wC0~|xmHYoZz0~kfv3pYt>Yjt( zy$2$@P}m8A@8cjSoIv;qF71+kRdO2r6n&?pbss{@CY)cDG-D4gwxIpd(Ovyl3d;=x;U=ayE8Eggw0}c*}U=Rof zqDOkvaA<8AnyTd=)6>7_*r@OOEjVl2HgsL*ZbH~GVVb5e&vS^qM-G{SezODzESwco zRh1pZE`J+_;rj&-*0V?w5U@q;pOYkk#Udj}d)>?QYV6qooA>7f2?Pn*3rvMRB^~WA z+{%iCq9_h&kXe-^%Nx=p)5BoUn&M}P89%n<&OS)$aE`f-+gSqZXPA|Y0i zSM34fi?0`Q2&kXR=qo0y4WAh4Buq3{&DkJ4&z0DGg0?-e@dd2>tbkqays+U1G@b!T7!aDe!tdY_eK500000NkvXXu0mjf-N9?6 delta 604 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 SHw{Yw0000WNFg? delta 608 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 kDeA!vFvP07*qoM6N<$f-=$$RR910 diff --git a/project/data/sprites/cave_block_top_right.png b/project/data/sprites/cave_block_top_right.png index 02a47d50b48a46805eded69b21fae9375ddec25d..7a5d9ffa0307f57655a55571061f282154c5dc99 100644 GIT binary patch delta 650 zcmV;50(JfB1eFDl7k?xO1^@s6y^7ns0004QX+uL$X=7sm04R}lkvmHRK@^2Q6D8sU z3oS$xwonmN2nu2;5wuZ@7{OPwyV)c{vM#$DL~I2c3&BFP@m2T_v=wX>1VIr*?CgCt z64pCLNRVWf+52&3&SmBdgr>4)&Z~_=&i38-WK5f1Skxk~gn#KGLO)^M^qlG0i3C;0 z*F80=-VLf=)%R5#jY-Qhp{8DV#B^L=cuaU|&36=U3%8jWJt=%7JmAU!g|C%v6!}GQ zy2u}j-9&sGLaL{hE@PvN&5WB9?i23LW%K6WdDKmsEPHNNYKP2DJmO3eL&G4?3R!#x zrP`8NWnc8yH-E#bcue^_tmBF!O-8%}qUNQmB{e0wC0~|xmHYoZz0~kfv3pYt>Yjt( zy$2$@P}m8A@8cjSoIv;qF71+kRdO2r6n&?pbss{@CY)cDG-D4gwxIpd(Ovyl3d;Zz(90r+q4KkD-(MqS zf+|$@ETy~R_$^vVx*44bf$uJZCJ?~rBFCA(-k~S->(NWxh#t~!$FcSf4*IJj9KH0k k@c5U!MbuA@{beuRr6?iQpKM}000000NkvXXt^-0~f}htXqW}N^ delta 606 zcmV-k0-^nt1?mKl7k>;01^@s6R&`wG0004QX+uL$X=7sm04R}lkvU5PQ51#0B#NSu z6k3Q{L{PCXAPS%36i|w&HXs*o=Nst-QZtNFc#t8*i6YT#%Wp3-z9FD%m#+{){U_k?@2RCGi5M0m`Q0flds9<%vP zanj~5#YQAF2Ts+~o2=tl9cw8gBRncRlt~w~>OAU8-0|#ESZbf_0Zc*!@Z%*$flbon z@kz}}W{rL06@T9%Iq_)n)+u6$BS}iUW1<$MYg}qV^te1}iYoX2d76pI3A?-753R43 z^*Ib}`%o@f*6*ohmCwNS0@vA^KPNd&e~VtKX+y{0*@4TOnie~Nt6k`Q)}uzWBDrKc z6AAdZfUXtjzK4!AJFDtB=T8vXmS1!Shet3X_dV->ZGT>9JeEa0sQ>@~32;bRa{vHb zMgRa@MgbI*LqPxl0HR4mK~yLem5{*=Lm>=90sT>65$+7bBn$&*7GapS56LK^>Y=$L zB(~$=V~j8NNBG|R7va-$b56I`+EQbToolTw+~NYOFRaH(*1m zSjaiMQdi0*@P4SINDY`x3T`1pdH_p_fdJGB+uIu$*rv6`3_;C Date: Wed, 29 Mar 2023 10:30:41 +0200 Subject: [PATCH 2/4] cave Blocks working --- project/data/levels/levels.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/data/levels/levels.json b/project/data/levels/levels.json index 4da65a4..8b300ce 100644 --- a/project/data/levels/levels.json +++ b/project/data/levels/levels.json @@ -1,7 +1,7 @@ -[ + [ { "name": "0-tutorial", - "theme": "tutorial", + "theme": "cave", "abilities": [ ], "file": "0-tutorial.csv" From e50d280afa54497be184d7f6fa4bfacf41b7f802 Mon Sep 17 00:00:00 2001 From: Skyball2000 Date: Wed, 29 Mar 2023 10:45:48 +0200 Subject: [PATCH 3/4] Introduced screen layouts and game states --- project/data/levels/level-01.csv | 4 +- project/data/levels/levels.json | 2 +- project/data/sprites/sprites.json | 21 ++ project/level/LevelManager.py | 10 + .../selection}/LevelMenu.py | 24 +- project/level/selection/LevelScreenManager.py | 16 + .../selection/LevelSelectionScreenManager.py | 79 +++++ .../level/selection/MainMenuScreenManager.py | 16 + project/level/selection/ScreenManager.py | 26 ++ project/main.py | 295 +++++++----------- project/sprite/BoundingBox.py | 5 + ...ground.py => ColoredRectangleUiElement.py} | 20 +- 12 files changed, 311 insertions(+), 207 deletions(-) rename project/{ui_elements => level/selection}/LevelMenu.py (60%) create mode 100644 project/level/selection/LevelScreenManager.py create mode 100644 project/level/selection/LevelSelectionScreenManager.py create mode 100644 project/level/selection/MainMenuScreenManager.py create mode 100644 project/level/selection/ScreenManager.py rename project/ui_elements/{Background.py => ColoredRectangleUiElement.py} (64%) diff --git a/project/data/levels/level-01.csv b/project/data/levels/level-01.csv index eb4a382..f87f64e 100644 --- a/project/data/levels/level-01.csv +++ b/project/data/levels/level-01.csv @@ -5,13 +5,13 @@ #,#,S,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,# #,#,S,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,# #,#,S,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,# -#,#,S,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,L,,,,,,,,,,,,,,,,,,,,,,,,C,,,# +#,#,S,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,L,,,,,M,M,,,,,,,,,,,,,,,,,,C,,,# #,#,S,,,,,,,,,,,,,,,,,,,+,+,+,+,S,S,S,S,S,+,+,+,+,+,S,S,S,S,S,+,+,+,+,+,S,S,S,S,S,+,+,+,+,+,+,+,+,+,# #,#,S,,,,,,,,,,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,# #,#,S,,,,,,,,,,,,,,,,,,,,,#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,# #,#,S,,,,,,,,,,,,,,,,,,,,,#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,# #,#,,,,,,,,,,,,,,,,,,,,,,G,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,# -#,,,,,,,,,,,,,,,M,,,M,M,,M,,,,,,,,,,,,,,,,,M,,,,,,M,,,,,,,,,,,,,,,# +#,,,,,,,,,,,,,,,M,,,,,,M,,,,,,,,,,,,,,,,,M,,,,,,M,,,,,,,,,,,,,,,# #,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,# #,,,,,,,,,,,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,# #,L,,,,,,,,,,#,#,#,#,#,#,#,#,#,#,#,#,#,#,#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,# diff --git a/project/data/levels/levels.json b/project/data/levels/levels.json index 4da65a4..186d256 100644 --- a/project/data/levels/levels.json +++ b/project/data/levels/levels.json @@ -15,7 +15,7 @@ }, { "name": "level-02", - "theme": "castle", + "theme": "cave", "abilities": [ ], "file": "level-02.csv" diff --git a/project/data/sprites/sprites.json b/project/data/sprites/sprites.json index fa8c061..fc2a709 100644 --- a/project/data/sprites/sprites.json +++ b/project/data/sprites/sprites.json @@ -834,5 +834,26 @@ "height": 36 } ] + }, + { + "id": "ui_arrow", + "subsheets": [ + { + "id": "left", + "delays": [ + 1 + ], + "width": 12, + "height": 12 + }, + { + "id": "right", + "delays": [ + 1 + ], + "width": 12, + "height": 12 + } + ] } ] \ No newline at end of file diff --git a/project/level/LevelManager.py b/project/level/LevelManager.py index 0c1b878..9069e29 100644 --- a/project/level/LevelManager.py +++ b/project/level/LevelManager.py @@ -25,3 +25,13 @@ class LevelManager: filtered_row = list(map(lambda x: x.replace('\n', ''), split_row)) csv_array.append(filtered_row) return csv_array + + def get_levels_by_theme(self) -> dict[str, list[Level]]: + levels_by_theme = {} + for level in self.levels: + if level.theme not in levels_by_theme: + levels_by_theme[level.theme] = [] + levels_by_theme[level.theme].append(level) + return levels_by_theme + + diff --git a/project/ui_elements/LevelMenu.py b/project/level/selection/LevelMenu.py similarity index 60% rename from project/ui_elements/LevelMenu.py rename to project/level/selection/LevelMenu.py index b1de9f8..599dbed 100644 --- a/project/ui_elements/LevelMenu.py +++ b/project/level/selection/LevelMenu.py @@ -1,7 +1,7 @@ import pygame from level.Level import Level -from ui_elements.Background import Background +from ui_elements.ColoredRectangleUiElement import ColoredRectangleUiElement from ui_elements.ClickEvent import ClickEvent from ui_elements.TextLabel import TextLabel @@ -11,23 +11,27 @@ class LevelMenu: def __init__(self, levels: [Level], x_pos: float, y_pos: float, width: float, height: float, column_count: int): super().__init__() self.levels = levels - self.x_pos = x_pos - self.y_pos = y_pos self.level_select_listener = lambda selected_level: None self.level_text_labels = [] self.width = width self.height = height self.column_count = column_count + self.position = (x_pos, y_pos) + self.create_level_text_labels() - self.background = Background(self.x_pos, self.y_pos, self.width, self.height, (100, 100, 100, 180)) + self.background = ColoredRectangleUiElement(self.width, self.height, (100, 100, 100, 180)) + self.background.position_scale.position = self.position def create_level_text_labels(self): - current_text_label_x = self.x_pos - current_text_label_y = self.y_pos + current_text_label_position = [self.position[0], self.position[1]] for index, level in enumerate(self.levels): - text_label = TextLabel(level.name, current_text_label_x, current_text_label_y, 60) + text_label = TextLabel(level.name, + current_text_label_position[0], + current_text_label_position[1], + 60) + text_label.position_scale.scale = (0.5, 0.5) text_label.add_click_listener( lambda click_event, selected_level=level: @@ -36,10 +40,10 @@ class LevelMenu: self.level_text_labels.append(text_label) if (index + 1) % self.column_count == 0: - current_text_label_y += self.height / (len(self.levels) / self.column_count) - current_text_label_x = self.x_pos + current_text_label_position[0] = self.position[0] + current_text_label_position[1] += self.height / (len(self.levels) / self.column_count) else: - current_text_label_x += self.width / self.column_count + current_text_label_position[0] += self.width / self.column_count def handle_level_text_label_click(self, click_event: ClickEvent, level: Level): if click_event.event.type == pygame.MOUSEBUTTONUP: diff --git a/project/level/selection/LevelScreenManager.py b/project/level/selection/LevelScreenManager.py new file mode 100644 index 0000000..f86d1ae --- /dev/null +++ b/project/level/selection/LevelScreenManager.py @@ -0,0 +1,16 @@ +from abc import abstractmethod + +from level.selection.ScreenManager import ScreenManager +from physics.SpriteManager import SpriteManager +from sprite.SpritesheetManager import SpritesheetManager + + +class LevelScreenManager(ScreenManager): + def __init__(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager, main_loop): + super().__init__(sprite_manager, spritesheet_manager, main_loop) + + def initialize(self): + pass + + def destroy(self): + super().destroy() diff --git a/project/level/selection/LevelSelectionScreenManager.py b/project/level/selection/LevelSelectionScreenManager.py new file mode 100644 index 0000000..b789be6 --- /dev/null +++ b/project/level/selection/LevelSelectionScreenManager.py @@ -0,0 +1,79 @@ +from abc import abstractmethod + +from level.Level import Level +from level.LevelManager import LevelManager +from level.selection.ScreenManager import ScreenManager +from physics.SpriteManager import SpriteManager, DrawLayers +from sprite.PositionScale import PositionScale +from sprite.SpritesheetManager import SpritesheetManager +from sprite.StaticSprite import StaticSprite +from ui_elements.ClickEvent import ClickEvent +from ui_elements.TextLabel import TextLabel + +LABEL_COUNT = 10 +OFFSET = (50, 20) + + +class LevelSelectionScreenManager(ScreenManager): + def __init__(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager, main_loop, + level_manager: LevelManager): + super().__init__(sprite_manager, spritesheet_manager, main_loop) + + self.level_manager = level_manager + self.levels_by_theme = self.level_manager.get_levels_by_theme() + self.themes = ['tutorial', 'cave', 'castle'] + + self.level_labels: list[TextLabel] = [] + + self.selected_theme = self.themes[0] + + def select_next_theme(self, click: ClickEvent): + if click.is_click_down(ClickEvent.CLICK_LEFT): + index = (self.themes.index(self.selected_theme) + 1) % len(self.themes) + self.select_theme(self.themes[index]) + + def select_prev_theme(self, click): + if click.is_click_down(ClickEvent.CLICK_LEFT): + index = self.themes.index(self.selected_theme) - 1 + if index < 0: + index = len(self.themes) - 1 + self.select_theme(self.themes[index]) + + def select_level(self, click: ClickEvent, level: Level): + if click.is_click_down(ClickEvent.CLICK_LEFT): + self.main_loop.select_level(level) + + def initialize(self): + arrow_left = StaticSprite(self.spritesheet_manager.get_sheet('ui_arrow')) + arrow_left.set_animation_state('left') + arrow_left.position_scale = PositionScale((OFFSET[0], OFFSET[1]), (3, 3)) + arrow_left.add_click_listener(self.select_prev_theme) + self.add_element(DrawLayers.UI, arrow_left) + + arrow_right = StaticSprite(self.spritesheet_manager.get_sheet('ui_arrow')) + arrow_right.set_animation_state('right') + arrow_right.position_scale = PositionScale((OFFSET[0] + 50, OFFSET[1]), (3, 3)) + arrow_right.add_click_listener(self.select_next_theme) + self.add_element(DrawLayers.UI, arrow_right) + + for i in range(0, LABEL_COUNT): + label = TextLabel(str(i), OFFSET[0] + 30, OFFSET[1] + 60 + i * 50, font_size=65) + label.position_scale.scale = (0.5, 0.5) + self.level_labels.append(label) + self.add_element(DrawLayers.UI, label) + + self.select_theme(self.selected_theme) + + def select_theme(self, theme: str): + self.selected_theme = theme + + for label in self.level_labels: + label.set_text('') + label.click_listeners = [] + + for id, level in enumerate(self.levels_by_theme[self.selected_theme]): + self.level_labels[id].set_text(level.name) + self.level_labels[id].add_click_listener(lambda click: self.select_level(click, level)) + + def destroy(self): + super().destroy() diff --git a/project/level/selection/MainMenuScreenManager.py b/project/level/selection/MainMenuScreenManager.py new file mode 100644 index 0000000..726e599 --- /dev/null +++ b/project/level/selection/MainMenuScreenManager.py @@ -0,0 +1,16 @@ +from abc import abstractmethod + +from level.selection.ScreenManager import ScreenManager +from physics.SpriteManager import SpriteManager +from sprite.SpritesheetManager import SpritesheetManager + + +class MainMenuScreenManager(ScreenManager): + def __init__(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager,main_loop): + super().__init__(sprite_manager, spritesheet_manager, main_loop) + + def initialize(self): + pass + + def destroy(self): + super().destroy() diff --git a/project/level/selection/ScreenManager.py b/project/level/selection/ScreenManager.py new file mode 100644 index 0000000..29c9322 --- /dev/null +++ b/project/level/selection/ScreenManager.py @@ -0,0 +1,26 @@ +from abc import abstractmethod + +from physics.SpriteManager import SpriteManager +from sprite.SpritesheetManager import SpritesheetManager +from ui_elements.UiElement import UiElement + + +class ScreenManager: + def __init__(self, sprite_manager: SpriteManager, spritesheet_manager: SpritesheetManager, main_loop): + self.sprite_manager = sprite_manager + self.spritesheet_manager = spritesheet_manager + self.main_loop = main_loop + + self.elements: list[UiElement] = [] + + def add_element(self, layer: str, ui_element: UiElement): + self.elements.append(ui_element) + self.sprite_manager.add_ui_element(layer, ui_element) + + @abstractmethod + def initialize(self): + pass + + def destroy(self): + for element in self.elements: + self.sprite_manager.remove_ui_element(element) diff --git a/project/main.py b/project/main.py index 8e3f3d8..404ebf2 100644 --- a/project/main.py +++ b/project/main.py @@ -1,221 +1,146 @@ -import random +from typing import Optional import pygame +from level.Level import Level from level.LevelManager import LevelManager from level.elements.LoadedLevel import LoadedLevel +from level.selection.LevelScreenManager import LevelScreenManager +from level.selection.LevelSelectionScreenManager import LevelSelectionScreenManager +from level.selection.MainMenuScreenManager import MainMenuScreenManager +from level.selection.ScreenManager import ScreenManager from physics import ConstantsParser -from physics.SpriteManager import SpriteManager, DrawLayers +from physics.SpriteManager import SpriteManager from physics.TickData import TickData -from physics.sprites.PlayerSprite import PlayerSprite from sprite.PositionScale import PositionScale -from sprite.Sprite import Sprite from sprite.SpritesheetManager import SpritesheetManager -from sprite.StaticSprite import StaticSprite from ui_elements.ClickEvent import ClickEvent from ui_elements.KeyManager import KeyManager -from ui_elements.LevelMenu import LevelMenu -from ui_elements.TextLabel import TextLabel what_to_run = 'level' -WIDTH = 12 * 71 * 1.5 -HEIGHT = 12 * 40 * 1.5 +DEPRECATED_WIDTH = 12 * 71 * 1.5 +DEPRECATED_HEIGHT = 12 * 40 * 1.5 # Background to test for level design -test_background_castle = pygame.transform.scale(pygame.image.load('data/sprites/castle_bg.png'), (WIDTH, HEIGHT)) -# test_background_cave = pygame.transform.scale(pygame.image.load('data/sprites/cave_bg.png'), (WIDTH, HEIGHT)) -# test_background_tutorial = pygame.transform.scale(pygame.image.load('data/sprites/tutorial_bg.png'), (WIDTH, HEIGHT)) +test_background_castle = pygame.transform.scale(pygame.image.load('data/sprites/castle_bg.png'), + (DEPRECATED_WIDTH, DEPRECATED_HEIGHT)) +# test_background_castle = pygame.transform.scale(pygame.image.load('data/sprites/cave_bg.png'), (DEPRECATED_WIDTH, DEPRECATED_WIDTH)) +# test_background_tutorial = pygame.transform.scale(pygame.image.load('data/sprites/tutorial_bg.png'), (DEPRECATED_WIDTH, DEPRECATED_WIDTH)) -def apply_frame_rate(number: float): + +def apply_frame_rate(number: float, frame_rate: float = 30): """ this function calculates a factor that will be multiplied with the physics of the game to provide a constant speed + :param frame_rate: the frame rate of the game :param number: The number to scale by the factor :return: The scaled number """ return number / (frame_rate / 30) -if what_to_run == 'menu': - screen_transform = PositionScale((0, 0), (1.5, 1.5)) +class MainLoop: + def __init__(self): + self.GAME_STATE_MENU = 'main_menu' + self.GAME_STATE_LEVEL_SELECTION = 'level_selection' + self.GAME_STATE_LEVEL = 'level' - screen_height = 12 * 40 * 1.5 - screen_width = 12 * 71 * 1.5 + self.screen_transform: PositionScale = PositionScale((0, 0), (1.5, 1.5)) + self.window_size: tuple[float, float] = (1, 1) - pygame.init() - screen = pygame.display.set_mode((screen_width, screen_height)) - pygame.display.set_caption("PM GAME") - clock = pygame.time.Clock() - frame_rate = 30 + pygame.init() + pygame.display.set_caption("PM GAME") - spritesheet_manager = SpritesheetManager("data/sprites", "data/sprites/sprites.json") - sprite_manager = SpriteManager() - key_manager = KeyManager() + self.update_position_scale(self.screen_transform) - parsed_levels_manager = LevelManager('data/levels') - parsed_levels_manager.load_from_config('data/levels/levels.json') + self.screen = self.screen + self.clock = pygame.time.Clock() + self.frame_rate = 30 - generated_level = LoadedLevel(sprite_manager, spritesheet_manager) + self.spritesheet_manager = SpritesheetManager("data/sprites", "data/sprites/sprites.json") + self.sprite_manager = SpriteManager() + self.key_manager = KeyManager() - level_menu_width = screen_width / 2 - level_menu_height = screen_height / 2 - level_menu = LevelMenu(parsed_levels_manager.levels, 0, 0, level_menu_width, level_menu_height, 3) - show_menu = False + self.parsed_levels_manager = LevelManager('data/levels') + self.parsed_levels_manager.load_from_config('data/levels/levels.json') + + self.screen_manager: Optional[ScreenManager] = None + self.game_state = self.GAME_STATE_MENU + self.set_game_state(self.GAME_STATE_LEVEL_SELECTION) + + def update_position_scale(self, position_scale: PositionScale): + self.screen_transform = position_scale + self.window_size = ( + self.screen_transform.scale[0] * ConstantsParser.CONFIG.block_size[0] * + ConstantsParser.CONFIG.level_size[0], + self.screen_transform.scale[1] * ConstantsParser.CONFIG.block_size[1] * + ConstantsParser.CONFIG.level_size[1] + ) + + self.screen = pygame.display.set_mode((self.window_size[0], self.window_size[1])) + + def select_level(self, level: Level): + print(level.name) + self.set_game_state(self.GAME_STATE_LEVEL) + + def set_game_state(self, game_state: str): + self.game_state = game_state + + if self.screen_manager is not None: + self.screen_manager.destroy() + + if self.game_state == self.GAME_STATE_MENU: + self.screen_manager = MainMenuScreenManager( + self.sprite_manager, self.spritesheet_manager, self + ) + elif self.game_state == self.GAME_STATE_LEVEL: + self.screen_manager = LevelScreenManager( + self.sprite_manager, self.spritesheet_manager, self + ) + elif self.game_state == self.GAME_STATE_LEVEL_SELECTION: + self.screen_manager = LevelSelectionScreenManager( + self.sprite_manager, self.spritesheet_manager, self, self.parsed_levels_manager + ) + else: + print('Invalid game state', self.game_state) + + if self.screen_manager is not None: + self.screen_manager.initialize() + + def main_loop(self): + while True: + self.clock.tick(self.frame_rate) + + pygame_events: list[pygame.event.Event] = pygame.event.get() + self.key_manager.update_key_events(pygame_events) + click_events: list[ClickEvent] = ClickEvent.create_events(pygame_events, self.screen_transform) + + for event in click_events: + for layer in self.sprite_manager.layers: + for sprite in self.sprite_manager.layers[layer]: + if sprite.get_bounding_box().contains_point(event.world_position): + sprite.click(event) + + for event in pygame_events: + if event.type == pygame.QUIT: + pygame.quit() + quit() + + self.screen.fill((0, 0, 0)) + self.sprite_manager.tick( + TickData(apply_frame_rate(1, self.frame_rate), + pygame_events, + self.key_manager, + click_events, + self.screen_transform) + ) + self.sprite_manager.draw(self.screen, self.screen_transform) + + pygame.display.update() - def load_next_level(selected_level): - global show_menu - generated_level.destroy_level() - generated_level.load_level(selected_level) - destroy_menu() - show_menu = False - - - def destroy_menu(): - global level_text_label - for level_text_label in level_menu.level_text_labels: - sprite_manager.remove_ui_element(level_text_label) - sprite_manager.remove_ui_element(level_menu.background) - - - level_menu.level_select_listener = lambda selected_level: load_next_level(selected_level) - - while True: - clock.tick(frame_rate) - - pygame_events: list[pygame.event.Event] = pygame.event.get() - key_manager.update_key_events(pygame_events) - click_events: list[ClickEvent] = ClickEvent.create_events(pygame_events, screen_transform) - - for event in click_events: - for layer in sprite_manager.layers: - for sprite in sprite_manager.layers[layer]: - if sprite.get_bounding_box().contains_point(event.world_position): - sprite.click(event) - - for event in pygame_events: - if event.type == pygame.QUIT: - pygame.quit() - quit() - if key_manager.is_keymap_down(KeyManager.KEY_ESCAPE): - if show_menu: - show_menu = False - destroy_menu() - else: - show_menu = True - sprite_manager.add_ui_element(DrawLayers.UI, level_menu.background) - for level_text_label in level_menu.level_text_labels: - sprite_manager.add_ui_element(DrawLayers.UI, level_text_label) - - screen.fill((0, 0, 0)) - sprite_manager.tick(TickData(apply_frame_rate(1), pygame_events, key_manager, click_events, screen_transform)) - sprite_manager.draw(screen, screen_transform) - - pygame.display.update() - -elif what_to_run == 'level': - screen_transform = PositionScale((0, 0), (1.5, 1.5)) - - pygame.init() - screen = pygame.display.set_mode((12 * ConstantsParser.CONFIG.level_size[0] * screen_transform.scale[0], - 12 * ConstantsParser.CONFIG.level_size[1] * screen_transform.scale[1]), - flags=pygame.HWSURFACE | pygame.DOUBLEBUF, - vsync=1, - depth=1) - - pygame.display.set_caption("PM GAME") - clock = pygame.time.Clock() - frame_rate = 30 - - spritesheet_manager = SpritesheetManager("data/sprites", "data/sprites/sprites.json") - sprite_manager = SpriteManager() - key_manager = KeyManager() - - parsed_levels_manager = LevelManager('data/levels') - parsed_levels_manager.load_from_config('data/levels/levels.json') - - generated_level = LoadedLevel(sprite_manager, spritesheet_manager) - generated_level.load_level(parsed_levels_manager.levels[1]) - ghost_character = PlayerSprite(spritesheet_manager.get_sheet("ghost_character")) - ghost_character.position_scale = PositionScale((90, 50), (1, 1)) - sprite_manager.add_ui_element(DrawLayers.OBJECTS, ghost_character) - - calculated_frame_rate_text = TextLabel("0 FPS", 2, 2, 70, alignment="left") - calculated_frame_rate_text.position_scale.scale = (0.3, 0.3) - sprite_manager.add_ui_element(DrawLayers.UI, calculated_frame_rate_text) - - left_sprite = None - right_sprite = None - - while True: - clock.tick(frame_rate) - - calculated_frame_rate_text.text = f"{round(clock.get_fps())} FPS" - - pygame_events: list[pygame.event.Event] = pygame.event.get() - key_manager.update_key_events(pygame_events) - click_events: list[ClickEvent] = ClickEvent.create_events(pygame_events, screen_transform) - - for event in pygame_events: - if event.type == pygame.QUIT: - pygame.quit() - quit() - - for event in click_events: - for layer in sprite_manager.layers: - for sprite in sprite_manager.layers[layer]: - if sprite.get_bounding_box().contains_point(event.world_position): - if event.is_click_down(ClickEvent.CLICK_LEFT): - left_sprite = sprite - if event.is_click_down(ClickEvent.CLICK_RIGHT): - right_sprite = sprite - - if left_sprite is not None and right_sprite is not None: - print(left_sprite.get_bounding_box().distance(right_sprite.get_bounding_box())) - left_sprite = None - right_sprite = None - - screen.fill((0, 0, 0)) - # Playground to test background on any level - screen.blit(test_background_castle, (0, 0)) - - sprite_manager.tick(TickData(apply_frame_rate(1), pygame_events, key_manager, click_events, screen_transform)) - sprite_manager.draw(screen, screen_transform) - pygame.display.update() - - -elif what_to_run == 'textlabel': - screen_transform = PositionScale((0, 0), (4, 4)) - - pygame.init() - screen = pygame.display.set_mode((800, 800)) - pygame.display.set_caption("PM GAME") - clock = pygame.time.Clock() - - test1 = TextLabel("Das ist ein Test", 100, 0, 50, alignment="left") - test2 = TextLabel("Das ist ein Test", 100, 50, 50, alignment="left") - test3 = TextLabel("Das ist ein Test", 100, 20, 50, alignment="left") - - test1.position_scale.scale = (0.2, 0.2) - test2.position_scale.scale = (0.4, 0.4) - test3.position_scale.scale = (0.2, 0.2) - - test3.visible = False - - while True: - clock.tick(5) - - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - - screen.fill((0, 0, 110)) - - test1.draw(screen, screen_transform) - test2.draw(screen, screen_transform) - test3.draw(screen, screen_transform) - - pygame.display.update() +main_loop: MainLoop = MainLoop() +main_loop.main_loop() diff --git a/project/sprite/BoundingBox.py b/project/sprite/BoundingBox.py index 8ff3ccb..e5236f1 100644 --- a/project/sprite/BoundingBox.py +++ b/project/sprite/BoundingBox.py @@ -1,5 +1,7 @@ import math +import pygame + class BoundingBox: def __init__(self, x, y, width, height): @@ -46,3 +48,6 @@ class BoundingBox: """ return self.x < bounding_box.x + bounding_box.width and self.x + self.width > bounding_box.x and \ self.y < bounding_box.y + bounding_box.height and self.y + self.height > bounding_box.y + + def get_rect(self) -> pygame.Rect: + return pygame.Rect(self.x, self.y, self.width, self.height) diff --git a/project/ui_elements/Background.py b/project/ui_elements/ColoredRectangleUiElement.py similarity index 64% rename from project/ui_elements/Background.py rename to project/ui_elements/ColoredRectangleUiElement.py index 17deaaf..3be76dd 100644 --- a/project/ui_elements/Background.py +++ b/project/ui_elements/ColoredRectangleUiElement.py @@ -8,24 +8,26 @@ from sprite.BoundingBox import BoundingBox from ui_elements.UiElement import UiElement -class Background(UiElement): +class ColoredRectangleUiElement(UiElement): - def __init__(self, x_pos: float, y_pos: float, width: float, height: float, color: tuple): + def __init__(self, width: float, height: float, color: tuple): super().__init__() - self.x_pos = x_pos - self.y_pos = y_pos + self.width = width self.height = height self.color = color - def tick(self, tick_data: TickData): - pass - def render_sprite_image(self) -> Optional[Surface]: + bounding_box = self.get_bounding_box() + background_rect = bounding_box.get_rect() + surface = pygame.Surface((self.width, self.height), pygame.SRCALPHA) - background_rect = pygame.Rect(self.x_pos, self.y_pos, self.width, self.height) pygame.draw.rect(surface, self.color, background_rect) return surface def get_bounding_box(self) -> BoundingBox: - return BoundingBox(-1, -1, 0, 0) + return BoundingBox(self.position_scale.position[0], self.position_scale.position[1], + self.width, self.height) + + def tick(self, tick_data: TickData): + pass From 8f72869e7349f93e91455f0cdb174fc0530ac980 Mon Sep 17 00:00:00 2001 From: Skyball2000 Date: Wed, 29 Mar 2023 10:58:11 +0200 Subject: [PATCH 4/4] Added ui arrow texture --- project/data/sprites/ui_arrow.png | Bin 0 -> 877 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 project/data/sprites/ui_arrow.png diff --git a/project/data/sprites/ui_arrow.png b/project/data/sprites/ui_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..23c2292cc2f5f32b068a38fdf84b2b23ab56141d GIT binary patch literal 877 zcmV-z1CsoSP)4Tx04UFukvmHRK@^2Q6GhQT3N1t}BB)px5CzdrBA6yxBoTZy$(V<*8<*V# z3ATcbMZiL|@m2T_v=wX>1VIr*?CgCtBI_L^B#0KyGJ8MH?77@I3!aFfOs94X%v|1% zhC_jw*||XdBVIc2(Zy&&Io4!sBF>-d?V1{0uY$T4|65IqDMvv~gYdAj?7Xl{Lu4gy zY2FZSRoTR%@SbqLEdvUlYdu-!2hEu>zi77O(Q&z(?it8bak7e4);5Lvgu6|npuXqP zH}R!%(=n;-vO95z5++1|Bn6f*$P<*Blgxhi4Se~gSQd|xw?z?K92v6W?H9EmT~kui zqNn6BDC*pQ=INw|2Fu-jA*j1|-RB;t--M5n>%Q;1?#BUm@8C37@h?kGBd?;DDq8n0 z_}Ae0tfD2i;A9=zZmoo!_>#P`J?S(&9YOOfv|K{td^xM{a}IAHzAC@y0=9RcSHAZz zd;)D=Xgp8qMOgp<010qNS#tmYTtxr?Ttxx7En+MH00EszL_t(IPkoayEQ3K9hOg3u zLBc>7x-l>a34@V|*<>)7bTL#AN(>?*g4AH?RHKcdiLu=bIv6aXiItG(AW;e7dGG&E zuI=Bx$&>H9%lG|v_x^V=(?Z#7c7kvOQ+5JHHc&W7*n@dHVN34m$KR@&C~Ewk8Pje*tv9DjdQo zyhGC;H%5?ivv$H5tzun_Y;dAcS0V%YfK|-xEz}*zgd%&l6ZP_K)v}{dfNO0FG+!gX zVHkGd6K3ERax^9UMt@5&ZG&+ixt!9KkyBqFm*iH(U%`r|7g!=4fh%Z-O?ZM-LxU4d z4=_hM4L8sQnWhb%Izz0q$4GIOae{lE`d@M}-Oxbc0Kq*^73yN1z%f*PmwI6f-1Gba z_dMU^pyaRc2s)U)YM&>RU7?fTpet^lCzR?70~zxN)$4#deapwi00000NkvXXu0mjf DZBB@b literal 0 HcmV?d00001