diff --git a/source/core/assets/configs/text.json b/source/core/assets/configs/text.json new file mode 100644 index 000000000..721a313dc --- /dev/null +++ b/source/core/assets/configs/text.json @@ -0,0 +1,7 @@ +{ + "com.badlogic.gdx.graphics.g2d.BitmapFont": { + "default": { + "file": "images/ui/font.fnt" + } + } +} diff --git a/source/core/assets/images/background/HelpScreenBG.png b/source/core/assets/images/background/HelpScreenBG.png new file mode 100644 index 000000000..6e52bb314 Binary files /dev/null and b/source/core/assets/images/background/HelpScreenBG.png differ diff --git a/source/core/assets/images/background/main_menu/MM_Objects/MM_Galaxy1.png b/source/core/assets/images/background/main_menu/MM_Objects/MM_Galaxy1.png new file mode 100644 index 000000000..fa987fd6d Binary files /dev/null and b/source/core/assets/images/background/main_menu/MM_Objects/MM_Galaxy1.png differ diff --git a/source/core/assets/images/background/main_menu/MM_Objects/MM_MonitorFace1.png b/source/core/assets/images/background/main_menu/MM_Objects/MM_MonitorFace1.png new file mode 100644 index 000000000..da0f66bab Binary files /dev/null and b/source/core/assets/images/background/main_menu/MM_Objects/MM_MonitorFace1.png differ diff --git a/source/core/assets/images/background/main_menu/MM_Objects/MM_Planet1.png b/source/core/assets/images/background/main_menu/MM_Objects/MM_Planet1.png new file mode 100644 index 000000000..ca9729755 Binary files /dev/null and b/source/core/assets/images/background/main_menu/MM_Objects/MM_Planet1.png differ diff --git a/source/core/assets/images/background/main_menu/MM_Objects/MM_Planet2.png b/source/core/assets/images/background/main_menu/MM_Objects/MM_Planet2.png new file mode 100644 index 000000000..24c6bd1b9 Binary files /dev/null and b/source/core/assets/images/background/main_menu/MM_Objects/MM_Planet2.png differ diff --git a/source/core/assets/images/background/main_menu/MM_Objects/MM_Planet3.png b/source/core/assets/images/background/main_menu/MM_Objects/MM_Planet3.png new file mode 100644 index 000000000..23a503af6 Binary files /dev/null and b/source/core/assets/images/background/main_menu/MM_Objects/MM_Planet3.png differ diff --git a/source/core/assets/images/background/main_menu/MM_Objects/MM_Star1.png b/source/core/assets/images/background/main_menu/MM_Objects/MM_Star1.png new file mode 100644 index 000000000..8eb76f991 Binary files /dev/null and b/source/core/assets/images/background/main_menu/MM_Objects/MM_Star1.png differ diff --git a/source/core/assets/images/background/main_menu/main_menu_bg.png b/source/core/assets/images/background/main_menu/main_menu_bg.png new file mode 100644 index 000000000..8fc9e4556 Binary files /dev/null and b/source/core/assets/images/background/main_menu/main_menu_bg.png differ diff --git a/source/core/assets/images/background/settings/settings_bg.png b/source/core/assets/images/background/settings/settings_bg.png new file mode 100644 index 000000000..f0a0c5064 Binary files /dev/null and b/source/core/assets/images/background/settings/settings_bg.png differ diff --git a/source/core/assets/images/ui/font.fnt b/source/core/assets/images/ui/font.fnt new file mode 100644 index 000000000..1c8e0fa9d --- /dev/null +++ b/source/core/assets/images/ui/font.fnt @@ -0,0 +1,99 @@ +info face="Times New Roman" size=-32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=0 aa=1 padding=0,0,0,0 spacing=0,0 outline=0 +common lineHeight=37 base=29 scaleW=256 scaleH=128 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4 +page id=0 file="font.png" +chars count=95 +char id=32 x=0 y=0 width=0 height=0 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15 +char id=33 x=251 y=20 width=4 height=23 xoffset=4 yoffset=6 xadvance=12 page=0 chnl=15 +char id=34 x=47 y=96 width=9 height=10 xoffset=2 yoffset=6 xadvance=13 page=0 chnl=15 +char id=35 x=151 y=15 width=15 height=23 xoffset=1 yoffset=6 xadvance=17 page=0 chnl=15 +char id=36 x=169 y=77 width=13 height=26 xoffset=2 yoffset=5 xadvance=17 page=0 chnl=15 +char id=37 x=0 y=82 width=25 height=24 xoffset=1 yoffset=6 xadvance=27 page=0 chnl=15 +char id=38 x=21 y=53 width=23 height=24 xoffset=1 yoffset=6 xadvance=25 page=0 chnl=15 +char id=39 x=61 y=96 width=3 height=10 xoffset=1 yoffset=6 xadvance=5 page=0 chnl=15 +char id=40 x=218 y=37 width=9 height=30 xoffset=1 yoffset=6 xadvance=10 page=0 chnl=15 +char id=41 x=225 y=67 width=9 height=30 xoffset=0 yoffset=6 xadvance=10 page=0 chnl=15 +char id=42 x=232 y=0 width=11 height=13 xoffset=2 yoffset=6 xadvance=15 page=0 chnl=15 +char id=43 x=155 y=105 width=17 height=18 xoffset=1 yoffset=10 xadvance=19 page=0 chnl=15 +char id=44 x=56 y=96 width=5 height=9 xoffset=1 yoffset=25 xadvance=8 page=0 chnl=15 +char id=45 x=52 y=24 width=8 height=3 xoffset=1 yoffset=20 xadvance=10 page=0 chnl=15 +char id=46 x=38 y=77 width=3 height=4 xoffset=2 yoffset=25 xadvance=7 page=0 chnl=15 +char id=47 x=198 y=100 width=9 height=23 xoffset=0 yoffset=6 xadvance=9 page=0 chnl=15 +char id=48 x=166 y=15 width=14 height=23 xoffset=1 yoffset=6 xadvance=16 page=0 chnl=15 +char id=49 x=206 y=15 width=10 height=22 xoffset=3 yoffset=7 xadvance=16 page=0 chnl=15 +char id=50 x=141 y=82 width=15 height=23 xoffset=1 yoffset=6 xadvance=16 page=0 chnl=15 +char id=51 x=156 y=82 width=13 height=23 xoffset=1 yoffset=6 xadvance=16 page=0 chnl=15 +char id=52 x=160 y=38 width=14 height=22 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=15 +char id=53 x=184 y=55 width=13 height=22 xoffset=2 yoffset=7 xadvance=16 page=0 chnl=15 +char id=54 x=180 y=15 width=13 height=23 xoffset=1 yoffset=6 xadvance=16 page=0 chnl=15 +char id=55 x=141 y=105 width=14 height=22 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=15 +char id=56 x=186 y=100 width=12 height=23 xoffset=2 yoffset=6 xadvance=16 page=0 chnl=15 +char id=57 x=182 y=77 width=13 height=23 xoffset=1 yoffset=6 xadvance=16 page=0 chnl=15 +char id=58 x=236 y=13 width=3 height=15 xoffset=3 yoffset=14 xadvance=9 page=0 chnl=15 +char id=59 x=251 y=0 width=5 height=20 xoffset=2 yoffset=14 xadvance=9 page=0 chnl=15 +char id=60 x=167 y=60 width=17 height=17 xoffset=1 yoffset=10 xadvance=19 page=0 chnl=15 +char id=61 x=29 y=22 width=17 height=7 xoffset=1 yoffset=15 xadvance=19 page=0 chnl=15 +char id=62 x=174 y=38 width=17 height=17 xoffset=1 yoffset=10 xadvance=19 page=0 chnl=15 +char id=63 x=195 y=77 width=12 height=23 xoffset=1 yoffset=6 xadvance=14 page=0 chnl=15 +char id=64 x=0 y=0 width=29 height=30 xoffset=1 yoffset=6 xadvance=30 page=0 chnl=15 +char id=65 x=0 y=106 width=24 height=22 xoffset=-1 yoffset=7 xadvance=23 page=0 chnl=15 +char id=66 x=71 y=95 width=20 height=22 xoffset=0 yoffset=7 xadvance=22 page=0 chnl=15 +char id=67 x=70 y=71 width=20 height=24 xoffset=1 yoffset=6 xadvance=21 page=0 chnl=15 +char id=68 x=47 y=74 width=23 height=22 xoffset=0 yoffset=7 xadvance=24 page=0 chnl=15 +char id=69 x=90 y=71 width=20 height=22 xoffset=0 yoffset=7 xadvance=20 page=0 chnl=15 +char id=70 x=111 y=44 width=17 height=22 xoffset=0 yoffset=7 xadvance=18 page=0 chnl=15 +char id=71 x=25 y=82 width=22 height=24 xoffset=1 yoffset=6 xadvance=23 page=0 chnl=15 +char id=72 x=48 y=106 width=23 height=22 xoffset=0 yoffset=7 xadvance=24 page=0 chnl=15 +char id=73 x=216 y=15 width=10 height=22 xoffset=0 yoffset=7 xadvance=11 page=0 chnl=15 +char id=74 x=197 y=53 width=12 height=23 xoffset=0 yoffset=7 xadvance=12 page=0 chnl=15 +char id=75 x=24 y=106 width=24 height=22 xoffset=0 yoffset=7 xadvance=24 page=0 chnl=15 +char id=76 x=91 y=46 width=20 height=22 xoffset=0 yoffset=7 xadvance=20 page=0 chnl=15 +char id=77 x=29 y=0 width=28 height=22 xoffset=0 yoffset=7 xadvance=29 page=0 chnl=15 +char id=78 x=57 y=0 width=24 height=22 xoffset=-1 yoffset=7 xadvance=23 page=0 chnl=15 +char id=79 x=78 y=22 width=21 height=24 xoffset=1 yoffset=6 xadvance=23 page=0 chnl=15 +char id=80 x=118 y=22 width=17 height=22 xoffset=0 yoffset=7 xadvance=18 page=0 chnl=15 +char id=81 x=0 y=53 width=21 height=29 xoffset=1 yoffset=6 xadvance=23 page=0 chnl=15 +char id=82 x=81 y=0 width=22 height=22 xoffset=0 yoffset=7 xadvance=21 page=0 chnl=15 +char id=83 x=172 y=103 width=14 height=24 xoffset=2 yoffset=6 xadvance=18 page=0 chnl=15 +char id=84 x=103 y=0 width=18 height=22 xoffset=1 yoffset=7 xadvance=19 page=0 chnl=15 +char id=85 x=30 y=29 width=24 height=23 xoffset=-1 yoffset=7 xadvance=22 page=0 chnl=15 +char id=86 x=44 y=52 width=24 height=22 xoffset=0 yoffset=7 xadvance=24 page=0 chnl=15 +char id=87 x=0 y=30 width=30 height=23 xoffset=0 yoffset=7 xadvance=30 page=0 chnl=15 +char id=88 x=54 y=27 width=24 height=22 xoffset=0 yoffset=7 xadvance=24 page=0 chnl=15 +char id=89 x=68 y=49 width=23 height=22 xoffset=0 yoffset=7 xadvance=23 page=0 chnl=15 +char id=90 x=99 y=22 width=19 height=22 xoffset=0 yoffset=7 xadvance=20 page=0 chnl=15 +char id=91 x=227 y=30 width=8 height=29 xoffset=3 yoffset=7 xadvance=12 page=0 chnl=15 +char id=92 x=209 y=53 width=9 height=23 xoffset=0 yoffset=6 xadvance=9 page=0 chnl=15 +char id=93 x=234 y=59 width=8 height=29 xoffset=1 yoffset=7 xadvance=12 page=0 chnl=15 +char id=94 x=91 y=116 width=15 height=12 xoffset=0 yoffset=6 xadvance=15 page=0 chnl=15 +char id=95 x=52 y=22 width=17 height=2 xoffset=0 yoffset=35 xadvance=17 page=0 chnl=15 +char id=96 x=46 y=22 width=6 height=6 xoffset=1 yoffset=6 xadvance=11 page=0 chnl=15 +char id=97 x=195 y=0 width=13 height=15 xoffset=1 yoffset=14 xadvance=15 page=0 chnl=15 +char id=98 x=128 y=44 width=16 height=23 xoffset=-1 yoffset=6 xadvance=16 page=0 chnl=15 +char id=99 x=208 y=0 width=12 height=15 xoffset=1 yoffset=14 xadvance=14 page=0 chnl=15 +char id=100 x=135 y=15 width=16 height=23 xoffset=1 yoffset=6 xadvance=16 page=0 chnl=15 +char id=101 x=220 y=0 width=12 height=15 xoffset=1 yoffset=14 xadvance=14 page=0 chnl=15 +char id=102 x=193 y=15 width=13 height=23 xoffset=1 yoffset=6 xadvance=10 page=0 chnl=15 +char id=103 x=152 y=60 width=15 height=22 xoffset=1 yoffset=14 xadvance=16 page=0 chnl=15 +char id=104 x=91 y=93 width=17 height=23 xoffset=0 yoffset=6 xadvance=16 page=0 chnl=15 +char id=105 x=243 y=0 width=8 height=23 xoffset=0 yoffset=6 xadvance=9 page=0 chnl=15 +char id=106 x=229 y=97 width=9 height=30 xoffset=-3 yoffset=6 xadvance=9 page=0 chnl=15 +char id=107 x=108 y=93 width=17 height=23 xoffset=0 yoffset=6 xadvance=16 page=0 chnl=15 +char id=108 x=235 y=30 width=9 height=23 xoffset=0 yoffset=6 xadvance=9 page=0 chnl=15 +char id=109 x=110 y=68 width=25 height=15 xoffset=0 yoffset=14 xadvance=24 page=0 chnl=15 +char id=110 x=145 y=0 width=17 height=15 xoffset=0 yoffset=14 xadvance=16 page=0 chnl=15 +char id=111 x=191 y=38 width=14 height=15 xoffset=1 yoffset=14 xadvance=16 page=0 chnl=15 +char id=112 x=125 y=83 width=16 height=22 xoffset=-1 yoffset=14 xadvance=16 page=0 chnl=15 +char id=113 x=125 y=105 width=16 height=22 xoffset=1 yoffset=14 xadvance=16 page=0 chnl=15 +char id=114 x=217 y=107 width=12 height=15 xoffset=0 yoffset=14 xadvance=11 page=0 chnl=15 +char id=115 x=226 y=15 width=10 height=15 xoffset=2 yoffset=14 xadvance=13 page=0 chnl=15 +char id=116 x=207 y=107 width=10 height=20 xoffset=0 yoffset=9 xadvance=10 page=0 chnl=15 +char id=117 x=135 y=67 width=17 height=15 xoffset=-1 yoffset=14 xadvance=15 page=0 chnl=15 +char id=118 x=162 y=0 width=17 height=15 xoffset=-1 yoffset=14 xadvance=16 page=0 chnl=15 +char id=119 x=121 y=0 width=24 height=15 xoffset=0 yoffset=14 xadvance=23 page=0 chnl=15 +char id=120 x=179 y=0 width=16 height=15 xoffset=0 yoffset=14 xadvance=16 page=0 chnl=15 +char id=121 x=144 y=38 width=16 height=22 xoffset=0 yoffset=14 xadvance=16 page=0 chnl=15 +char id=122 x=205 y=38 width=13 height=15 xoffset=1 yoffset=14 xadvance=15 page=0 chnl=15 +char id=123 x=207 y=76 width=9 height=31 xoffset=4 yoffset=6 xadvance=15 page=0 chnl=15 +char id=124 x=238 y=88 width=2 height=30 xoffset=2 yoffset=6 xadvance=7 page=0 chnl=15 +char id=125 x=216 y=76 width=9 height=31 xoffset=3 yoffset=6 xadvance=16 page=0 chnl=15 +char id=126 x=21 y=77 width=17 height=5 xoffset=1 yoffset=18 xadvance=18 page=0 chnl=15 diff --git a/source/core/assets/images/ui/font.png b/source/core/assets/images/ui/font.png new file mode 100644 index 000000000..628b02462 Binary files /dev/null and b/source/core/assets/images/ui/font.png differ diff --git a/source/core/assets/images/ui/game screen/1 earth before.png b/source/core/assets/images/ui/game screen/1 earth before.png new file mode 100644 index 000000000..c4233d125 Binary files /dev/null and b/source/core/assets/images/ui/game screen/1 earth before.png differ diff --git a/source/core/assets/images/ui/game screen/1.1 earth before.png b/source/core/assets/images/ui/game screen/1.1 earth before.png new file mode 100644 index 000000000..5bed55ad9 Binary files /dev/null and b/source/core/assets/images/ui/game screen/1.1 earth before.png differ diff --git a/source/core/assets/images/ui/game screen/2.0 earth dying.png b/source/core/assets/images/ui/game screen/2.0 earth dying.png new file mode 100644 index 000000000..162af4008 Binary files /dev/null and b/source/core/assets/images/ui/game screen/2.0 earth dying.png differ diff --git a/source/core/assets/images/ui/game screen/2.1 earth dying.png b/source/core/assets/images/ui/game screen/2.1 earth dying.png new file mode 100644 index 000000000..c2e54ef5c Binary files /dev/null and b/source/core/assets/images/ui/game screen/2.1 earth dying.png differ diff --git a/source/core/assets/images/ui/game screen/3. meeting.png b/source/core/assets/images/ui/game screen/3. meeting.png new file mode 100644 index 000000000..e91965704 Binary files /dev/null and b/source/core/assets/images/ui/game screen/3. meeting.png differ diff --git a/source/core/assets/images/ui/game screen/3.1 meeting turret.png b/source/core/assets/images/ui/game screen/3.1 meeting turret.png new file mode 100644 index 000000000..6669cedb4 Binary files /dev/null and b/source/core/assets/images/ui/game screen/3.1 meeting turret.png differ diff --git a/source/core/assets/images/ui/game screen/4.0 spaceship built.png b/source/core/assets/images/ui/game screen/4.0 spaceship built.png new file mode 100644 index 000000000..0baad28ac Binary files /dev/null and b/source/core/assets/images/ui/game screen/4.0 spaceship built.png differ diff --git a/source/core/assets/images/ui/game screen/4.1 spaceship leaving.png b/source/core/assets/images/ui/game screen/4.1 spaceship leaving.png new file mode 100644 index 000000000..10761bfb8 Binary files /dev/null and b/source/core/assets/images/ui/game screen/4.1 spaceship leaving.png differ diff --git a/source/core/assets/images/ui/game screen/5 arrival.png b/source/core/assets/images/ui/game screen/5 arrival.png new file mode 100644 index 000000000..31369d500 Binary files /dev/null and b/source/core/assets/images/ui/game screen/5 arrival.png differ diff --git a/source/core/assets/images/ui/game screen/5.1 arrival.png b/source/core/assets/images/ui/game screen/5.1 arrival.png new file mode 100644 index 000000000..f718a06f8 Binary files /dev/null and b/source/core/assets/images/ui/game screen/5.1 arrival.png differ diff --git a/source/core/assets/images/ui/game screen/6.0 survey.png b/source/core/assets/images/ui/game screen/6.0 survey.png new file mode 100644 index 000000000..ecce5abc5 Binary files /dev/null and b/source/core/assets/images/ui/game screen/6.0 survey.png differ diff --git a/source/core/assets/images/ui/game screen/6.1 survey.png b/source/core/assets/images/ui/game screen/6.1 survey.png new file mode 100644 index 000000000..22606d09e Binary files /dev/null and b/source/core/assets/images/ui/game screen/6.1 survey.png differ diff --git a/source/core/assets/images/ui/mouse_effect.png b/source/core/assets/images/ui/mouse_effect.png new file mode 100644 index 000000000..74d1ebce2 Binary files /dev/null and b/source/core/assets/images/ui/mouse_effect.png differ diff --git a/source/core/assets/sounds/Modern4.ogg b/source/core/assets/sounds/Modern4.ogg new file mode 100644 index 000000000..9288e95db Binary files /dev/null and b/source/core/assets/sounds/Modern4.ogg differ diff --git a/source/core/src/main/com/csse3200/game/GdxGame.java b/source/core/src/main/com/csse3200/game/GdxGame.java index 8cbb484cb..903f443d3 100644 --- a/source/core/src/main/com/csse3200/game/GdxGame.java +++ b/source/core/src/main/com/csse3200/game/GdxGame.java @@ -78,13 +78,15 @@ private Screen newScreen(ScreenType screenType) { return new LosingScreen(this); case TURRET_SELECTION: return new TurretSelectionScreen(this); + case HELP_SCREEN: + return new HelpScreen(this); default: return null; } } public enum ScreenType { - MAIN_MENU, MAIN_GAME, SETTINGS, STORY_SCREEN, LEVEL_SELECT, TURRET_SELECTION, LOSING_SCREEN + MAIN_MENU, MAIN_GAME, SETTINGS, STORY_SCREEN, LEVEL_SELECT, TURRET_SELECTION, LOSING_SCREEN, HELP_SCREEN } /** diff --git a/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuActions.java b/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuActions.java index 6907caf67..28aaeb805 100644 --- a/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuActions.java +++ b/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuActions.java @@ -2,6 +2,7 @@ import com.csse3200.game.GdxGame; import com.csse3200.game.components.Component; +import com.csse3200.game.screens.HelpScreen; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,7 +21,7 @@ public MainMenuActions(GdxGame game) { @Override public void create() { entity.getEvents().addListener("start", this::onStart); - entity.getEvents().addListener("load", this::onLoad); + entity.getEvents().addListener("help", this::onHelp); entity.getEvents().addListener("exit", this::onExit); entity.getEvents().addListener("settings", this::onSettings); } @@ -34,12 +35,9 @@ private void onStart() { // game.setScreen(GdxGame.ScreenType.LEVEL_SELECT); } - /** - * Intended for loading a saved game state. - * Load functionality is not actually implemented. - */ - private void onLoad() { - logger.info("Load game"); + private void onHelp() { + logger.info("Help Menu"); + game.setScreen(GdxGame.ScreenType.HELP_SCREEN); } /** diff --git a/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuDisplay.java b/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuDisplay.java index ab941a70a..89f005390 100644 --- a/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuDisplay.java +++ b/source/core/src/main/com/csse3200/game/components/mainmenu/MainMenuDisplay.java @@ -1,6 +1,9 @@ package com.csse3200.game.components.mainmenu; import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.audio.Sound; +import com.badlogic.gdx.graphics.Cursor; +import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.scenes.scene2d.Actor; @@ -9,50 +12,71 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener; import com.csse3200.game.services.ServiceLocator; +import com.csse3200.game.ui.ButtonFactory; import com.csse3200.game.ui.UIComponent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -/** - * A ui component for displaying the Main menu. - */ public class MainMenuDisplay extends UIComponent { private static final Logger logger = LoggerFactory.getLogger(MainMenuDisplay.class); private static final float Z_INDEX = 2f; private Table table; private Table table1; - - - + private Sound clickSound; @Override public void create() { super.create(); addActors(); + loadSounds(); + } + private void loadSounds() { + clickSound = Gdx.audio.newSound(Gdx.files.internal("sounds/Modern4.ogg")); } - private void addActors() { + /** + * Loads a custom cursor image and sets it as the system cursor. + * + * This method loads an image file named "mouse_effect.png" from the "images/ui" directory + * and sets it as the system cursor. After setting the custom cursor, it disposes of the + * Pixmap object used for loading the cursor image to release system resources. + * + * @param none + * @return none + */ + // Load the custom cursor image + Pixmap cursorPixmap = new Pixmap(Gdx.files.internal("images/ui/mouse_effect.png")); + Cursor customCursor = Gdx.graphics.newCursor(cursorPixmap, 0, 0); + Gdx.graphics.setCursor(customCursor); + cursorPixmap.dispose(); // Dispose of the Pixmap to release resources + table = new Table(); - table1=new Table(); + table1 = new Table(); table.setFillParent(true); table1.setFillParent(true); + Image title = new Image( ServiceLocator.getResourceService() - .getAsset("images/background/background1.png", Texture.class)); + .getAsset("images/background/main_menu/main_menu_bg.png", Texture.class)); title.setWidth(Gdx.graphics.getWidth()); title.setHeight(Gdx.graphics.getHeight()); - title.setPosition(0,0); + title.setPosition(0, 0); + +// Create a "Start" TextButton using the default style + TextButton startBtn = ButtonFactory.createButton("Start"); +// Create a "Help" TextButton using the default style + TextButton helpBtn = ButtonFactory.createButton("Help"); +// Create a "Settings" TextButton with a custom image + TextButton settingsBtn =ButtonFactory.createButton("Settings"); +// Create a "Quit" TextButton with a custom image + TextButton exitBtn = ButtonFactory.createButton("Quit"); - TextButton startBtn = new TextButton("Start", skin); - TextButton loadBtn = new TextButton("Help", skin); - TextButton settingsBtn = new TextButton("Settings", skin); - TextButton exitBtn = new TextButton("Quit", skin); // Triggers an event when the button is pressed startBtn.addListener( @@ -61,15 +85,17 @@ private void addActors() { public void changed(ChangeEvent changeEvent, Actor actor) { logger.debug("Start button clicked"); entity.getEvents().trigger("start"); + clickSound.play(); } }); - loadBtn.addListener( + helpBtn.addListener( new ChangeListener() { @Override public void changed(ChangeEvent changeEvent, Actor actor) { - logger.debug("Load button clicked"); - entity.getEvents().trigger("load"); + logger.debug("Help button clicked"); + entity.getEvents().trigger("help"); + clickSound.play(); } }); @@ -79,6 +105,7 @@ public void changed(ChangeEvent changeEvent, Actor actor) { public void changed(ChangeEvent changeEvent, Actor actor) { logger.debug("Settings button clicked"); entity.getEvents().trigger("settings"); + clickSound.play(); } }); @@ -86,28 +113,34 @@ public void changed(ChangeEvent changeEvent, Actor actor) { new ChangeListener() { @Override public void changed(ChangeEvent changeEvent, Actor actor) { - logger.debug("Exit button clicked"); entity.getEvents().trigger("exit"); + clickSound.play(); } }); + // Proportional padding values based on original screen or background dimensions + float originalScreenWidth = 1920; // Replace with the original width if different + float originalScreenHeight = 1080; // Replace with the original height if different + + float padTopStartBtn = 260f / originalScreenHeight * Gdx.graphics.getHeight(); + float padTopOtherBtns = 15f / originalScreenHeight * Gdx.graphics.getHeight(); + table.add(title); table1.row(); - table1.add(startBtn).padTop(30f); + table1.add(startBtn).padTop(padTopStartBtn); table1.row(); - table1.add(loadBtn).padTop(15f); + table1.add(helpBtn).padTop(padTopOtherBtns); table1.row(); - table1.add(settingsBtn).padTop(15f); + table1.add(settingsBtn).padTop(padTopOtherBtns); table1.row(); - table1.add(exitBtn).padTop(15f); + table1.add(exitBtn).padTop(padTopOtherBtns); stage.addActor(table); stage.addActor(table1); } - @Override public void draw(SpriteBatch batch) { // draw is handled by the stage @@ -122,5 +155,6 @@ public float getZIndex() { public void dispose() { table.clear(); super.dispose(); + clickSound.dispose(); } -} \ No newline at end of file +} diff --git a/source/core/src/main/com/csse3200/game/components/settingsmenu/SettingsMenuDisplay.java b/source/core/src/main/com/csse3200/game/components/settingsmenu/SettingsMenuDisplay.java index 43f1ca961..90936f942 100644 --- a/source/core/src/main/com/csse3200/game/components/settingsmenu/SettingsMenuDisplay.java +++ b/source/core/src/main/com/csse3200/game/components/settingsmenu/SettingsMenuDisplay.java @@ -16,6 +16,11 @@ import com.csse3200.game.services.ServiceLocator; import com.csse3200.game.ui.UIComponent; import com.csse3200.game.utils.StringDecorator; +import com.badlogic.gdx.graphics.Cursor; +import com.badlogic.gdx.graphics.Pixmap; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.utils.Scaling; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,7 +50,22 @@ public void create() { addActors(); } + /** + * Adds various actors to the stage for the settings screen. + * This method sets up and adds elements such as a custom cursor, background image, title label, settings table, and menu buttons. + */ private void addActors() { + // Load the custom cursor image + Pixmap cursorPixmap = new Pixmap(Gdx.files.internal("images/ui/mouse_effect.png")); + Cursor customCursor = Gdx.graphics.newCursor(cursorPixmap, 0, 0); + Gdx.graphics.setCursor(customCursor); + cursorPixmap.dispose(); + + Image background = new Image(ServiceLocator.getResourceService() + .getAsset("images/background/settings/settings_bg.png", Texture.class)); + background.setScaling(Scaling.stretch); + background.setFillParent(true); + Label title = new Label("Settings", skin, "title"); Table settingsTable = makeSettingsTable(); Table menuBtns = makeMenuBtns(); @@ -61,6 +81,7 @@ private void addActors() { rootTable.row(); rootTable.add(menuBtns).fillX(); + stage.addActor(background); stage.addActor(rootTable); } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/MobMeleeAttackTask.java b/source/core/src/main/com/csse3200/game/components/tasks/MobMeleeAttackTask.java index 461428870..3ac8c6c3c 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/MobMeleeAttackTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/MobMeleeAttackTask.java @@ -208,7 +208,7 @@ private int getInactivePriority() { * @return true if a target is visible, false otherwise */ private boolean isTargetVisible() { - Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 10f, owner.getEntity().getPosition().y - 2f); + Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 100f, owner.getEntity().getPosition().y - 2f); return physics.raycast(owner.getEntity().getPosition(), newVector, TARGET, hit); } @@ -236,7 +236,7 @@ private Weapon meleeOrProjectile() { } private void setTarget() { - Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 10f, owner.getEntity().getPosition().y - 2f); + Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 100f, owner.getEntity().getPosition().y - 2f); target = physics.raycastGetHit(owner.getEntity().getPosition(), newVector, TARGET); } } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/MobRangedAttackTask.java b/source/core/src/main/com/csse3200/game/components/tasks/MobRangedAttackTask.java index e3885ae8b..b10dad91f 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/MobRangedAttackTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/MobRangedAttackTask.java @@ -214,7 +214,7 @@ private int getInactivePriority() { * @return true if a target is visible, false otherwise */ private boolean isTargetVisible() { - Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 10f, owner.getEntity().getPosition().y - 2f); + Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 100f, owner.getEntity().getPosition().y - 2f); return physics.raycast(owner.getEntity().getPosition(), newVector, TARGET, hit); } @@ -242,7 +242,7 @@ private Weapon meleeOrProjectile() { } private void setTarget() { - Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 10f, owner.getEntity().getPosition().y - 2f); + Vector2 newVector = new Vector2(owner.getEntity().getPosition().x - 100f, owner.getEntity().getPosition().y - 2f); target = physics.raycastGetHit(owner.getEntity().getPosition(), newVector, TARGET); } } diff --git a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/DemonBossTask.java b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/DemonBossTask.java index e9fc0e514..6349e51ab 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/DemonBossTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/DemonBossTask.java @@ -123,6 +123,10 @@ public void run() { */ @Override public void update() { + // * Don't know if this is actually needed. + if(ServiceLocator.getGameEndService().hasGameEnded()) { + stop(); + } // give game time to load in then start if (!startFlag) { return; @@ -381,6 +385,11 @@ private void fireBreath() { Timer.schedule(new Timer.Task() { @Override public void run() { + // service locator getting a service could be anything here. + if(ServiceLocator.getTimeSource() == null) { + stop(); + return; // prevent current iteration from running. + } Entity projectile = ProjectileFactory.createEffectProjectile(PhysicsLayer.HUMANS, destination, new Vector2(2, 2), effect, aoe); projectile.setPosition(demon.getPosition().x, demon.getPosition().y); diff --git a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/IceBabyTask.java b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/IceBabyTask.java index 31f61136c..f89f12ed0 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/IceBabyTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/IceBabyTask.java @@ -124,7 +124,10 @@ public void update() { } if (health <= 0) { changeState(STATE.DEATH); - iceBaby.setFlagForDelete(true); + animate(); + if (animation.isFinished()) { + iceBaby.setFlagForDelete(true); + } } switch (iceBabyState) { diff --git a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/PatrickTask.java b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/PatrickTask.java index 9e41941dd..ee06a9d44 100644 --- a/source/core/src/main/com/csse3200/game/components/tasks/bosstask/PatrickTask.java +++ b/source/core/src/main/com/csse3200/game/components/tasks/bosstask/PatrickTask.java @@ -251,6 +251,10 @@ private void meleeAttack() { initialPos = patrick.getPosition(); meleeTarget = ServiceLocator.getEntityService().getClosestEntityOfLayer( patrick, PhysicsLayer.HUMANS); + // check if melee target exists + if (meleeTarget == null) { + return; + } teleport(meleeTarget.getPosition()); meleeFlag = true; } diff --git a/source/core/src/main/com/csse3200/game/entities/factories/WaveFactory.java b/source/core/src/main/com/csse3200/game/entities/factories/WaveFactory.java index b6615c42a..0c7bac198 100644 --- a/source/core/src/main/com/csse3200/game/entities/factories/WaveFactory.java +++ b/source/core/src/main/com/csse3200/game/entities/factories/WaveFactory.java @@ -98,9 +98,9 @@ public static LevelWaves createLevel(int maxDiff, int maxWaves, int chosenLevel) String boss1 = "IceBoss"; // String boss1 = "PatrickBoss"; String boss2 = "PatrickBoss"; - String boss3 = "IceBoss"; - //TODO change this to a fire boss in sprint 4 -// String boss3 = "FireBoss"; + //String boss3 = "IceBoss"; + + String boss3 = "FireBoss"; int spawnDelay = 5; diff --git a/source/core/src/main/com/csse3200/game/screens/AssetLoader.java b/source/core/src/main/com/csse3200/game/screens/AssetLoader.java new file mode 100644 index 000000000..4c0ec4738 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/screens/AssetLoader.java @@ -0,0 +1,167 @@ +package com.csse3200.game.screens; +import com.badlogic.gdx.audio.Music; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.audio.Sound; +import com.csse3200.game.areas.ForestGameArea; +import com.csse3200.game.services.ResourceService; +import com.csse3200.game.services.ServiceLocator; + +public class AssetLoader { + // Define your asset file paths here + public static final String[] textures = { + "images/desert_bg.png", + "images/ice_bg.png", + "images/lava_bg.png", + "images/projectiles/projectile.png", + "images/ingamebg.png", + "images/box_boy_leaf.png", + "images/background/building1.png", + "images/ghost_1.png", + "images/grass_2.png", + "images/grass_3.png", + "images/hex_grass_1.png", + "images/background/mountain.png", + "images/ghost_king.png", + "images/ghost_1.png", + "images/terrain 2 normal.png", + "images/terrain 2 hex.png", + "images/hex_grass_2.png", + "images/hex_grass_3.png", + "images/iso_grass_1.png", + "images/iso_grass_2.png", + "images/iso_grass_3.png", + "images/towers/turret.png", + "images/towers/turret01.png", + "images/towers/turret_deployed.png", + "images/towers/fire_tower_atlas.png", + "images/towers/stun_tower.png", + "images/background/building2.png", + "images/mobs/robot.png", + "images/mobs/boss2.png", + "images/mobs/Attack_1.png", + "images/mobs/Attack_2.png", + "images/mobs/Charge_1.png", + "images/mobs/Charge_2.png", + "images/mobs/Dead.png", + "images/mobs/Enabling-5.png", + "images/mobs/satyr.png", + "images/mobs/Hurt.png", + "images/mobs/Idle.png", + "images/mobs/rangeBossRight.png", + "images/towers/wallTower.png", + "images/background/building2.png", + "images/iso_grass_3.png", + "images/terrain_use.png", + "images/Dusty_MoonBG.png", + "images/economy/scrap.png", + "images/economy/crystal.png", + "images/economy/econ-tower.png", + "images/projectiles/bossProjectile.png", + "images/towers/mine_tower.png", + "images/towers/TNTTower.png", + "images/towers/DroidTower.png", + "images/projectiles/basic_projectile.png", + "images/projectiles/mobProjectile.png", + "images/projectiles/engineer_projectile.png", + "images/projectiles/mobKing_projectile.png", + "images/projectiles/snow_ball.png", + "images/projectiles/burn_effect.png", + "images/projectiles/stun_effect.png", + "images/projectiles/firework_anim.png", + "images/projectiles/pierce_anim.png", + "images/projectiles/snow_ball.png" + }; + + public static final String[] textureAtlases = { + "images/economy/econ-tower.atlas", + "images/terrain_iso_grass.atlas", + "images/ghost.atlas", + "images/mobs/boss2.atlas", + "images/ghostKing.atlas", + "images/towers/turret.atlas", + "images/towers/turret01.atlas", + "images/mobs/xenoGrunt.atlas", + "images/towers/fire_tower_atlas.atlas", + "images/towers/stun_tower.atlas", + "images/mobs/xenoGruntRunning.atlas", + "images/xenoGrunt.atlas", + "images/mobs/robot.atlas", + "images/mobs/rangeBossRight.atlas", + "images/towers/DroidTower.atlas", + "images/mobs/robot.atlas", + "images/mobs/rangeBossRight.atlas", + "images/towers/TNTTower.atlas", + "images/projectiles/basic_projectile.atlas", + "images/projectiles/bossProjectile.atlas", + "images/projectiles/mobProjectile.atlas", + "images/projectiles/mobProjectile.atlas", + "images/projectiles/engineer_projectile.atlas", + "images/projectiles/mobKing_projectile.atlas", + "images/projectiles/snow_ball.atlas", + "images/projectiles/pierce_anim.atlas", + "images/projectiles/burn_effect.atlas", + "images/projectiles/firework_anim.atlas", + "images/projectiles/mobProjectile.atlas", + "images/projectiles/stun_effect.atlas" + }; + + + public static final String[] music = { + "sounds/background/Sci-Fi1.ogg" + }; + + public static final String[] Sounds = { + "sounds/Impact4.ogg", + "sounds/economy/click.wav", + "sounds/economy/click_1.wav", + "sounds/towers/gun_shot_trimmed.mp3", + "sounds/towers/deploy.mp3", + "sounds/towers/stow.mp3", + "sounds/engineers/firing_auto.mp3", + "sounds/engineers/firing_single.mp3", + "sounds/projectiles/on_collision.mp3", + "sounds/projectiles/explosion.mp3", + }; + + + public static void loadAllAssets() { + ResourceService resourceService = ServiceLocator.getResourceService(); + + resourceService.loadTextures(textures); + resourceService.loadTextureAtlases(textureAtlases); + resourceService.loadSounds(Sounds); + resourceService.loadMusic(music); + + // Wait for the assets to finish loading (you can implement a loading screen) + while (!resourceService.loadForMillis(10)) { + // Display loading progress if needed + } + } + + public static void unloadAllAssets() { + ResourceService resourceService = ServiceLocator.getResourceService(); + + resourceService.unloadAssets(textures); + resourceService.unloadAssets(textureAtlases); + resourceService.unloadAssets(Sounds); + resourceService.unloadAssets(music); + } + + public static Texture getTexture(String assetPath) { + return ServiceLocator.getResourceService().getAsset(assetPath, Texture.class); + } + + public static TextureAtlas getTextureAtlas(String assetPath) { + return ServiceLocator.getResourceService().getAsset(assetPath, TextureAtlas.class); + } + + public static Sound getSound(String assetPath) { + return ServiceLocator.getResourceService().getAsset(assetPath, Sound.class); + } + + public static Music getMusic(String assetPath) { + return ServiceLocator.getResourceService().getAsset(assetPath, Music.class); + } +} + diff --git a/source/core/src/main/com/csse3200/game/screens/HelpScreen.java b/source/core/src/main/com/csse3200/game/screens/HelpScreen.java new file mode 100644 index 000000000..4798205c4 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/screens/HelpScreen.java @@ -0,0 +1,85 @@ +package com.csse3200.game.screens; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.ScreenAdapter; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Image; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.csse3200.game.GdxGame; + +public class HelpScreen extends ScreenAdapter { + private final GdxGame game; + private Stage stage; + private SpriteBatch spriteBatch; + + + public HelpScreen(GdxGame game) { + this.game = game; + stage = new Stage(new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight())); + spriteBatch = new SpriteBatch(); + + // Create a table to organize the image placeholder + Table table = new Table(); + table.setFillParent(true); // Makes the table the size of the stage + + // Create one image placeholder + Image image = new Image(new Texture("images/background/HelpScreenBG.png")); + + // Add the image placeholder to the table + table.add(image).expand().fill(); + + // Add the table to the stage + stage.addActor(table); + + Skin skin = new Skin(Gdx.files.internal("flat-earth/skin/flat-earth-ui.json")); + TextButton BackButton = new TextButton("Back", skin); + BackButton.addListener(new ClickListener() { + @Override + public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) { + game.setScreen(GdxGame.ScreenType.MAIN_MENU); + + } + }); + Table buttonTable = new Table(); + buttonTable.add(BackButton).padRight(10); + Table table1 = new Table(); + table1.setFillParent(true); + table1.top().right(); // Align to the top-right corner + table1.pad(20); // Add padding to the top-right corner + table1.add(buttonTable).row(); // Add button table and move to the next row + stage.addActor(table1); + } + @Override + public void show() { + // Set this screen as the input processor + Gdx.input.setInputProcessor(stage); + } + + @Override + public void render(float delta) { + // Clear the screen + spriteBatch.begin(); + spriteBatch.end(); + + // Draw the stage + stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); + stage.draw(); + } + + @Override + public void resize(int width, int height) { + stage.getViewport().update(width, height, true); + } + + @Override + public void dispose() { + stage.dispose(); + spriteBatch.dispose(); + } +} \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java b/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java index bf2de6a5c..b4738a456 100644 --- a/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/LevelSelectScreen.java @@ -9,12 +9,26 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector3; +import com.badlogic.gdx.scenes.scene2d.Stage; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.Table; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.TimeUtils; +import com.badlogic.gdx.utils.viewport.FitViewport; import com.csse3200.game.GdxGame; +import com.csse3200.game.components.mainmenu.MainMenuDisplay; +import com.csse3200.game.entities.factories.RenderFactory; +import com.csse3200.game.rendering.Renderer; import com.csse3200.game.screens.text.AnimatedText; +import com.csse3200.game.screens.Planets; import com.csse3200.game.services.GameEndService; import com.csse3200.game.services.ServiceLocator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.w3c.dom.Text; + +import static com.badlogic.gdx.scenes.scene2d.ui.Table.Debug.table; /** * The game screen where you can choose a planet to play on. @@ -26,7 +40,7 @@ public class LevelSelectScreen extends ScreenAdapter { private int selectedLevel = -1; private static final String INTRO_TEXT = "Select a Planet for Conquest"; - + private Stage stage; private AnimatedText text; private BitmapFont font; @@ -42,6 +56,27 @@ public LevelSelectScreen(GdxGame game) { font = new BitmapFont(); text = new AnimatedText(INTRO_TEXT, font, 0.05f); this.game = game; + + stage = new Stage(new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight())); + + Skin skin = new Skin(Gdx.files.internal("flat-earth/skin/flat-earth-ui.json")); + TextButton BackButton = new TextButton("Back", skin); // Universal Skip button + BackButton.addListener(new ClickListener() { + @Override + public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) { + game.setScreen(GdxGame.ScreenType.MAIN_MENU); + + + } + }); + Table buttonTable = new Table(); + buttonTable.add(BackButton).padRight(10); + Table table1 = new Table(); + table1.setFillParent(true); + table1.top().right(); // Align to the top-right corner + table1.pad(20); // Add padding to the top-right corner + table1.add(buttonTable).row(); // Add button table and move to the next row + stage.addActor(table1); } @Override @@ -49,6 +84,7 @@ public void show() { batch = new SpriteBatch(); background = new Sprite(new Texture(BG_PATH)); ServiceLocator.registerGameEndService(new GameEndService()); + Gdx.input.setInputProcessor(stage); } /** @@ -103,11 +139,12 @@ private void spawnPlanetBorders() { dispose(); logger.info("Loading level {}", planet[4]); GameLevelData.setSelectedLevel(planet[4]); - game.setScreen(new TurretSelectionScreen(game)); + game.setScreen(new TurretSelectionScreen(game)); + } } } } - } + // TODO: Make it display information about the planet @@ -126,10 +163,16 @@ public void render(float delta) { text.update(); text.draw(batch, 100, 700); // Adjust the position batch.end(); + stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); + stage.draw(); + } + public void resize(int width, int height) { + stage.getViewport().update(width, height, true); } @Override public void dispose() { + stage.dispose(); batch.dispose(); } -} +} \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/screens/LoadingScreen.java b/source/core/src/main/com/csse3200/game/screens/LoadingScreen.java new file mode 100644 index 000000000..6df900616 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/screens/LoadingScreen.java @@ -0,0 +1,52 @@ +package com.csse3200.game.screens; +import com.csse3200.game.GdxGame; +import com.csse3200.game.screens.MainGameScreen; +//TODO make the loading animation fit in with all aspects +//public class LoadingScreen { +// Object monitor = new Object(); +//GdxGame game; +//TurretSelectionScreen turretSelectionScreen; +//public void Loading(GdxGame game, TurretSelectionScreen turretSelectionScreen) { +// Create a shared monitor object +// this.game=game; +//this.turretSelectionScreen = turretSelectionScreen; +// First thread +//Thread thread1 = new Thread(new Runnable() { +// @Override +// public void run() { +// synchronized (monitor) { +// try { +// turretSelectionScreen.toggleLoadingCircle(true); +// monitor.wait(); // Wait for a signal from thread 2 +//} catch (InterruptedException e) { +// e.printStackTrace(); +//} + +// game.setScreen(GdxGame.ScreenType.MAIN_GAME); +// } +//} +//}); + +// Second thread +//Thread thread2 = new Thread(new Runnable() { +// @Override +//public void run() { +//System.out.println("Thread 2 is running."); +// try { +// Simulate some work +// Thread.sleep(2000); +//} catch (InterruptedException e) { +// e.printStackTrace(); +//} +//synchronized (monitor) { +// MainGameScreen.loadAssets(); +//monitor.notify(); // Notify thread 1 that it can proceed +// } +// } +//}); + +// Start both threads +//thread1.start(); +//thread2.start();// +// } +//} \ No newline at end of file diff --git a/source/core/src/main/com/csse3200/game/screens/MainMenuScreen.java b/source/core/src/main/com/csse3200/game/screens/MainMenuScreen.java index 18246be53..6b2de82e9 100644 --- a/source/core/src/main/com/csse3200/game/screens/MainMenuScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/MainMenuScreen.java @@ -16,6 +16,8 @@ import com.csse3200.game.rendering.Renderer; import com.csse3200.game.services.ResourceService; import com.csse3200.game.services.ServiceLocator; +import com.badlogic.gdx.graphics.g2d.Animation; +import com.badlogic.gdx.graphics.g2d.TextureRegion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.badlogic.gdx.graphics.Texture; @@ -31,7 +33,33 @@ public class MainMenuScreen extends ScreenAdapter { private final Renderer renderer; private Texture backgroundTexture; private final SpriteBatch batch; - private static final String[] mainMenuTextures = {"images/background/background1.png"}; + private Animation MM_Star1_animation; + private Animation MM_Galaxy1_animation; + private Animation MM_Planet1_animation; + private Animation MM_Planet2_animation; + private Animation MM_Planet3_animation; +// private Animation MM_MonitorFace1_animation; + private Texture MM_Star1_Texture; + private Texture MM_Galaxy1_Texture; + private Texture MM_Planet1_Texture; + private Texture MM_Planet2_Texture; + private Texture MM_Planet3_Texture; +// private Texture MM_MonitorFace1_Texture; + private float elapsedTime = 0; + private int MM_Star1_frameWidth; + private int MM_Star1_frameHeight; + private int MM_Galaxy1_frameWidth; + private int MM_Galaxy1_frameHeight; + private int MM_Planet1_frameWidth; + private int MM_Planet1_frameHeight; + private int MM_Planet2_frameWidth; + private int MM_Planet2_frameHeight; + private int MM_Planet3_frameWidth; + private int MM_Planet3_frameHeight; + +// private int MM_MonitorFace1_frameWidth; +// private int MM_MonitorFace1_frameHeight; + private static final String[] mainMenuTextures = {"images/background/main_menu/main_menu_bg.png"}; public MainMenuScreen(GdxGame game) { this.game = game; @@ -51,17 +79,98 @@ public MainMenuScreen(GdxGame game) { createUI(); } + /** + * Loads the assets required for the main menu screen, including textures and animations. + * This method initializes and loads sprite sheets for various celestial objects like stars, planets, and galaxies. + * Each sprite sheet is divided into individual frames for animation purposes. + */ @Override public void render(float delta) { Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); ServiceLocator.getEntityService().update(); + float screenWidth = Gdx.graphics.getWidth(); + float screenHeight = Gdx.graphics.getHeight(); + // Draw the background image batch.begin(); - batch.draw(backgroundTexture, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + batch.draw(backgroundTexture, 0, 0, screenWidth, screenHeight); batch.end(); renderer.render(); + + batch.begin(); + elapsedTime += delta; + + // MM_Star1 + // Determine the proportional offset of the MM_Star1 sprite + float MM_Star1_proportionalOffsetX = 830f / backgroundTexture.getWidth(); + float MM_Star1_proportionalOffsetY = 650f / backgroundTexture.getHeight(); + // Calculate the scaling factor based on how the background is stretched to fit the screen + float scaleX = screenWidth / backgroundTexture.getWidth(); + float scaleY = screenHeight / backgroundTexture.getHeight(); + // Calculate the position of the MM_Star1 sprite on the screen + float MM_Star1_spriteX = MM_Star1_proportionalOffsetX * screenWidth; + float MM_Star1_spriteY = MM_Star1_proportionalOffsetY * screenHeight; + // Size adjustments + float MM_Star1_ScaleFactor = 0.3f; + float MM_Star1_Width = MM_Star1_frameWidth * MM_Star1_ScaleFactor; + float MM_Star1_Height = MM_Star1_frameHeight * MM_Star1_ScaleFactor; + batch.draw(MM_Star1_animation.getKeyFrame(elapsedTime, true), MM_Star1_spriteX, MM_Star1_spriteY, MM_Star1_Width, MM_Star1_Height); + + // MM_Galaxy1 + // Determine the proportional offset of the MM_Star1 sprite + float MM_Galaxy1_proportionalOffsetX = 2000f / backgroundTexture.getWidth(); + float MM_Galaxy1_proportionalOffsetY = 1075f / backgroundTexture.getHeight(); + // Calculate the position of the MM_Star1 sprite on the screen + float MM_Galaxy1_spriteX = MM_Galaxy1_proportionalOffsetX * screenWidth; + float MM_Galaxy1_spriteY = MM_Galaxy1_proportionalOffsetY * screenHeight; + // Size adjustments + float MM_Galaxy1_ScaleFactor = 0.95f; + float MM_Galaxy1_Width = MM_Galaxy1_frameWidth * MM_Galaxy1_ScaleFactor; + float MM_Galaxy1_Height = MM_Galaxy1_frameHeight * MM_Galaxy1_ScaleFactor; + batch.draw(MM_Galaxy1_animation.getKeyFrame(elapsedTime, true), MM_Galaxy1_spriteX, MM_Galaxy1_spriteY, MM_Galaxy1_Width, MM_Galaxy1_Height); + + // MM_Planet1 + // Determine the proportional offset of the MM_Star1 sprite + float MM_Planet1_proportionalOffsetX = 1630f / backgroundTexture.getWidth(); + float MM_Planet1_proportionalOffsetY = 800f / backgroundTexture.getHeight(); + // Calculate the position of the MM_Star1 sprite on the screen + float MM_Planet1_spriteX = MM_Planet1_proportionalOffsetX * screenWidth; + float MM_Planet1_spriteY = MM_Planet1_proportionalOffsetY * screenHeight; + // Size adjustments + float MM_Planet1_ScaleFactor = 0.5f; + float MM_Planet1_Width = MM_Planet1_frameWidth * MM_Planet1_ScaleFactor; + float MM_Planet1_Height = MM_Planet1_frameHeight * MM_Planet1_ScaleFactor; + batch.draw(MM_Planet1_animation.getKeyFrame(elapsedTime, true), MM_Planet1_spriteX, MM_Planet1_spriteY, MM_Planet1_Width, MM_Planet1_Height); + + // MM_Planet2 + // Determine the proportional offset of the MM_Star1 sprite + float MM_Planet2_proportionalOffsetX = 1290f / backgroundTexture.getWidth(); + float MM_Planet2_proportionalOffsetY = 1200f / backgroundTexture.getHeight(); + // Calculate the position of the MM_Star1 sprite on the screen + float MM_Planet2_spriteX = MM_Planet2_proportionalOffsetX * screenWidth; + float MM_Planet2_spriteY = MM_Planet2_proportionalOffsetY * screenHeight; + // Size adjustments + float MM_Planet2_ScaleFactor = 0.7f; + float MM_Planet2_Width = MM_Planet2_frameWidth * MM_Planet2_ScaleFactor; + float MM_Planet2_Height = MM_Planet2_frameHeight * MM_Planet2_ScaleFactor; + batch.draw(MM_Planet2_animation.getKeyFrame(elapsedTime, true), MM_Planet2_spriteX, MM_Planet2_spriteY, MM_Planet2_Width, MM_Planet2_Height); + + // MM_Planet3 + // Determine the proportional offset of the MM_Star1 sprite + float MM_Planet3_proportionalOffsetX = 420f / backgroundTexture.getWidth(); + float MM_Planet3_proportionalOffsetY = 990f / backgroundTexture.getHeight(); + // Calculate the position of the MM_Star1 sprite on the screen + float MM_Planet3_spriteX = MM_Planet3_proportionalOffsetX * screenWidth; + float MM_Planet3_spriteY = MM_Planet3_proportionalOffsetY * screenHeight; + // Size adjustments + float MM_Planet3_ScaleFactor = 0.65f; + float MM_Planet3_Width = MM_Planet3_frameWidth * MM_Planet3_ScaleFactor; + float MM_Planet3_Height = MM_Planet3_frameHeight * MM_Planet3_ScaleFactor; + batch.draw(MM_Planet3_animation.getKeyFrame(elapsedTime, true), MM_Planet3_spriteX, MM_Planet3_spriteY, MM_Planet3_Width, MM_Planet3_Height); + + batch.end(); } @Override @@ -93,18 +202,117 @@ public void dispose() { ServiceLocator.clear(); } + /** + * Loads the assets required for the main menu screen, including textures and animations. + * This method initializes and loads sprite sheets for various celestial objects such as stars, galaxies, and planets. + * Each sprite sheet is divided into individual frames for animation purposes. + */ private void loadAssets() { logger.debug("Loading assets"); ResourceService resourceService = ServiceLocator.getResourceService(); resourceService.loadTextures(mainMenuTextures); - backgroundTexture = new Texture("images/background/background1.png"); + backgroundTexture = new Texture("images/background/main_menu/main_menu_bg.png"); + + // MM_Star1 + MM_Star1_Texture = new Texture(Gdx.files.internal("images/background/main_menu/MM_Objects/MM_Star1.png")); + + int MM_Star1_totalColumns=60; + MM_Star1_frameWidth = MM_Star1_Texture.getWidth() / MM_Star1_totalColumns; // totalColumns = no. of columns in MM_Star1 sprite sheet + int MM_Star1_totalRows=1; + MM_Star1_frameHeight = MM_Star1_Texture.getHeight() / MM_Star1_totalRows; // totalRows = no. of rows in MM_Star1 sprite sheet + + TextureRegion[][] MM_Star1_Frames = TextureRegion.split(MM_Star1_Texture, MM_Star1_frameWidth, MM_Star1_frameHeight); + + TextureRegion[] MM_Star1_animationFrames = new TextureRegion[MM_Star1_totalColumns]; + + System.arraycopy(MM_Star1_Frames[0], 0, MM_Star1_animationFrames, 0, MM_Star1_totalColumns); + + MM_Star1_animation = new Animation<>(0.17f, MM_Star1_animationFrames); + + + // MM_Galaxy1 + MM_Galaxy1_Texture = new Texture(Gdx.files.internal("images/background/main_menu/MM_Objects/MM_Galaxy1.png")); + + int MM_Galaxy1_totalColumns=60; + MM_Galaxy1_frameWidth = MM_Galaxy1_Texture.getWidth() / MM_Galaxy1_totalColumns; // totalColumns = no. of columns in MM_Star1 sprite sheet + int MM_Galaxy1_totalRows=1; + MM_Galaxy1_frameHeight = MM_Galaxy1_Texture.getHeight() / MM_Galaxy1_totalRows; // totalRows = no. of rows in MM_Star1 sprite sheet + + TextureRegion[][] MM_Galaxy1_Frames = TextureRegion.split(MM_Galaxy1_Texture, MM_Galaxy1_frameWidth, MM_Galaxy1_frameHeight); + + TextureRegion[] MM_Galaxy1_animationFrames = new TextureRegion[MM_Galaxy1_totalColumns]; + + System.arraycopy(MM_Galaxy1_Frames[0], 0, MM_Galaxy1_animationFrames, 0, MM_Galaxy1_totalColumns); + + MM_Galaxy1_animation = new Animation<>(0.17f, MM_Galaxy1_animationFrames); + + + // MM_Planet1 + MM_Planet1_Texture = new Texture(Gdx.files.internal("images/background/main_menu/MM_Objects/MM_Planet1.png")); + + int MM_Planet1_totalColumns=60; + MM_Planet1_frameWidth = MM_Planet1_Texture.getWidth() / MM_Planet1_totalColumns; // totalColumns = no. of columns in MM_Star1 sprite sheet + int MM_Planet1_totalRows=1; + MM_Planet1_frameHeight = MM_Planet1_Texture.getHeight() / MM_Planet1_totalRows; // totalRows = no. of rows in MM_Star1 sprite sheet + + TextureRegion[][] MM_Planet1_Frames = TextureRegion.split(MM_Planet1_Texture, MM_Planet1_frameWidth, MM_Planet1_frameHeight); + + TextureRegion[] MM_Planet1_animationFrames = new TextureRegion[MM_Planet1_totalColumns]; + + System.arraycopy(MM_Planet1_Frames[0], 0, MM_Planet1_animationFrames, 0, MM_Planet1_totalColumns); + + MM_Planet1_animation = new Animation<>(0.17f, MM_Planet1_animationFrames); + + + // MM_Planet2 + MM_Planet2_Texture = new Texture(Gdx.files.internal("images/background/main_menu/MM_Objects/MM_Planet2.png")); + + int MM_Planet2_totalColumns=60; + MM_Planet2_frameWidth = MM_Planet2_Texture.getWidth() / MM_Planet2_totalColumns; // totalColumns = no. of columns in MM_Star1 sprite sheet + int MM_Planet2_totalRows=1; + MM_Planet2_frameHeight = MM_Planet2_Texture.getHeight() / MM_Planet2_totalRows; // totalRows = no. of rows in MM_Star1 sprite sheet + + TextureRegion[][] MM_Planet2_Frames = TextureRegion.split(MM_Planet2_Texture, MM_Planet2_frameWidth, MM_Planet2_frameHeight); + + TextureRegion[] MM_Planet2_animationFrames = new TextureRegion[MM_Planet2_totalColumns]; + + System.arraycopy(MM_Planet2_Frames[0], 0, MM_Planet2_animationFrames, 0, MM_Planet2_totalColumns); + + MM_Planet2_animation = new Animation<>(0.17f, MM_Planet2_animationFrames); + + + // MM_Planet3 + MM_Planet3_Texture = new Texture(Gdx.files.internal("images/background/main_menu/MM_Objects/MM_Planet3.png")); + + int MM_Planet3_totalColumns=54; + MM_Planet3_frameWidth = MM_Planet3_Texture.getWidth() / MM_Planet3_totalColumns; // totalColumns = no. of columns in MM_Star1 sprite sheet + int MM_Planet3_totalRows=1; + MM_Planet3_frameHeight = MM_Planet3_Texture.getHeight() / MM_Planet3_totalRows; // totalRows = no. of rows in MM_Star1 sprite sheet + + TextureRegion[][] MM_Planet3_Frames = TextureRegion.split(MM_Planet3_Texture, MM_Planet3_frameWidth, MM_Planet3_frameHeight); + + TextureRegion[] MM_Planet3_animationFrames = new TextureRegion[MM_Planet3_totalColumns]; + + System.arraycopy(MM_Planet3_Frames[0], 0, MM_Planet3_animationFrames, 0, MM_Planet3_totalColumns); + + MM_Planet3_animation = new Animation<>(0.17f, MM_Planet3_animationFrames); + ServiceLocator.getResourceService().loadAll(); } + /** + * Unloads the assets that were previously loaded for the main menu screen. + * This method disposes of textures and sprite sheets used for celestial objects such as stars, galaxies, and planets. + */ private void unloadAssets() { logger.debug("Unloading assets"); ResourceService resourceService = ServiceLocator.getResourceService(); resourceService.unloadAssets(mainMenuTextures); + MM_Star1_Texture.dispose(); + MM_Galaxy1_Texture.dispose(); + MM_Planet1_Texture.dispose(); + MM_Planet2_Texture.dispose(); + MM_Planet3_Texture.dispose(); } /** diff --git a/source/core/src/main/com/csse3200/game/screens/SettingsScreen.java b/source/core/src/main/com/csse3200/game/screens/SettingsScreen.java index c436df417..4fa46c738 100644 --- a/source/core/src/main/com/csse3200/game/screens/SettingsScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/SettingsScreen.java @@ -14,6 +14,10 @@ import com.csse3200.game.services.GameTime; import com.csse3200.game.services.ResourceService; import com.csse3200.game.services.ServiceLocator; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.GL20; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.SpriteBatch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,9 +27,14 @@ public class SettingsScreen extends ScreenAdapter { private final GdxGame game; private final Renderer renderer; + private Texture backgroundTexture; + private final SpriteBatch batch; + private static final String[] SettingsTextures = {"images/background/settings/settings_bg.png"}; public SettingsScreen(GdxGame game) { this.game = game; + this.batch = new SpriteBatch(); + backgroundTexture = new Texture("images/background/settings/settings_bg.png"); logger.debug("Initialising settings screen services"); ServiceLocator.registerInputService(new InputService()); @@ -37,29 +46,85 @@ public SettingsScreen(GdxGame game) { renderer = RenderFactory.createRenderer(); renderer.getCamera().getEntity().setPosition(5f, 5f); + loadAssets(); createUI(); } + /** + * Renders the main gameplay screen. + * + * @param delta The time elapsed since the last frame in seconds. + */ @Override public void render(float delta) { + Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); ServiceLocator.getEntityService().update(); + + // Render the background + float screenWidth = Gdx.graphics.getWidth(); + float screenHeight = Gdx.graphics.getHeight(); + + batch.begin(); + batch.draw(backgroundTexture, 0, 0, screenWidth, screenHeight); + batch.end(); + renderer.render(); } + /** + * Called when the game window is resized. + * + * @param width The new width of the window. + * @param height The new height of the window. + */ @Override public void resize(int width, int height) { renderer.resize(width, height); + // Add the below line to update the stage's viewport + ServiceLocator.getRenderService().getStage().getViewport().update(width, height, true); + logger.trace("Resized renderer: ({} x {})", width, height); + renderer.resize(width, height); } + /** + * Disposes of resources and services associated with the main menu screen. + * This method performs cleanup tasks such as disposing of the renderer, unloading assets, disposing of the render service, + * disposing of the entity service, disposing of the batch, and clearing the service locator. + */ @Override public void dispose() { + logger.debug("Disposing main menu screen"); renderer.dispose(); + unloadAssets(); ServiceLocator.getRenderService().dispose(); ServiceLocator.getEntityService().dispose(); + batch.dispose(); ServiceLocator.clear(); } + /** + * Loads the assets required for the settings screen. + * This method initializes and loads textures, including the background texture and any other assets specified in SettingsTextures. + */ + private void loadAssets() { + logger.debug("Loading assets"); + ResourceService resourceService = ServiceLocator.getResourceService(); + resourceService.loadTextures(SettingsTextures); + backgroundTexture = new Texture("images/background/settings/settings_bg.png"); + ServiceLocator.getResourceService().loadAll(); + } + + /** + * Unloads the assets that were previously loaded for the settings screen. + * This method disposes of textures and assets specified in SettingsTextures to release resources. + */ + private void unloadAssets() { + logger.debug("Unloading assets"); + ResourceService resourceService = ServiceLocator.getResourceService(); + resourceService.unloadAssets(SettingsTextures); + } + /** * Creates the setting screen's ui including components for rendering ui elements to the screen * and capturing and handling ui input. diff --git a/source/core/src/main/com/csse3200/game/screens/StoryScreen.java b/source/core/src/main/com/csse3200/game/screens/StoryScreen.java index 838401cdd..98adfb109 100644 --- a/source/core/src/main/com/csse3200/game/screens/StoryScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/StoryScreen.java @@ -5,94 +5,185 @@ import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.BitmapFont; -import com.badlogic.gdx.graphics.g2d.Sprite; +import com.badlogic.gdx.graphics.g2d.GlyphLayout; import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.scenes.scene2d.InputEvent; -import com.badlogic.gdx.utils.viewport.ScreenViewport; -import com.csse3200.game.GdxGame; -import com.csse3200.game.screens.text.AnimatedText; +import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer; +import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; import com.badlogic.gdx.scenes.scene2d.Stage; import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.scenes.scene2d.ui.TextButton; import com.badlogic.gdx.scenes.scene2d.ui.Table; import com.badlogic.gdx.scenes.scene2d.utils.ClickListener; +import com.badlogic.gdx.utils.viewport.FitViewport; +import com.csse3200.game.GdxGame; - +/** + * Screen that displays a story with images and text. + */ public class StoryScreen extends ScreenAdapter { private final GdxGame game; private SpriteBatch batch; - private Texture introImage; - private Sprite introSprite; - - private static final String TEXTURE = "planets/background.png"; - private static final String INTRO_TEXT = """ - More than 100 years ago, the world was at peace.\s - The people lived in harmony with nature, and the\s - world was full of life. However, the people grew\s - greedy and wanted more. They began to take more\s - than they needed, and the world began to suffer.\s - The people began to fight over the remaining\s - resources, and the world was plunged into chaos.\s - With nothing left to fight over, the people began\s - to fight for resources that were not theirs.\s - This is where our story begins.\s - """; - + private Texture[] images; + private String[] texts; + private int currentIndex; + private float imageDuration; + private float elapsedTime; private BitmapFont font; - private AnimatedText text; + private BitmapFont boldFont; private Stage stage; private TextButton continueButton; + private TextButton skipButton; // Universal Skip button + private ShapeRenderer shapeRenderer; + // Image file paths + private static final String[] IMAGE_PATHS = { + "images/ui/game screen/1 earth before.png", + "images/ui/game screen/1.1 earth before.png", + "images/ui/game screen/2.0 earth dying.png", + "images/ui/game screen/2.1 earth dying.png", + "images/ui/game screen/3. meeting.png", + "images/ui/game screen/3.1 meeting turret.png", + "images/ui/game screen/4.0 spaceship built.png", + "images/ui/game screen/4.1 spaceship leaving.png", + "images/ui/game screen/5.1 arrival.png", + "images/ui/game screen/5.1 arrival.png", + "images/ui/game screen/6.0 survey.png", + "images/ui/game screen/6.1 survey.png", + // Add more image paths as needed + }; + // Texts to display + private static final String[] TEXTS = { + "Over a century ago, a tranquil world basked in an era of serenity. ", + "Nature's embrace cradled humanity, and life flourished abundantly. ", + "However, this harmony soon succumbed to the relentless grip of human greed. ", + "As desires grew insatiable, the delicate balance fractured, and the world's vitality waned", + "as everything was about to be lost a group of people cam together to save humanity and an idea was born", + "to set out towards the stars and conquer planets", + "humanity pooled its resources together and made giant ships called ARKs that would carry us onto the stars", + "we set out with our iron will and firm resolve to not fade away ", + "we arrived at planets and built outposts that would help us survive this harsh environment ", + "we terraformed and procured resources that would help the future generations survive ", + "the brightest and best began researching anf evaluating the newly found planets", + "all seems perfect until we picked up on a looming threat that maybe we aren't alone......", + // Add more text as needed + }; + /** + * Creates a new StoryScreen. + * + * @param game The game instance + */ public StoryScreen(GdxGame game) { this.game = game; - font = new BitmapFont(); - text = new AnimatedText(INTRO_TEXT, font, 0.05f); + this.images = new Texture[IMAGE_PATHS.length]; + this.texts = TEXTS; + this.currentIndex = 0; + this.imageDuration = 2.0f; // Time (in seconds) per image + this.elapsedTime = 0f; + + for (int i = 0; i < IMAGE_PATHS.length; i++) { + images[i] = new Texture(IMAGE_PATHS[i]); + } } @Override public void show() { + // Initialize assets batch = new SpriteBatch(); - introImage = new Texture(TEXTURE); - introSprite = new Sprite(introImage); - introSprite.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); - - stage = new Stage(new ScreenViewport()); + font = new BitmapFont(); + boldFont = new BitmapFont(); + boldFont.getData().setScale(1.5f); // Set the font scale for bold text + boldFont.setColor(Color.WHITE); // Set the font color to white for bold text + stage = new Stage(new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight())); Gdx.input.setInputProcessor(stage); + shapeRenderer = new ShapeRenderer(); + // Create UI Skin skin = new Skin(Gdx.files.internal("flat-earth/skin/flat-earth-ui.json")); continueButton = new TextButton("Continue", skin); continueButton.addListener(new ClickListener() { @Override - public void clicked(InputEvent event, float x, float y) { - game.setScreen(GdxGame.ScreenType.LEVEL_SELECT); + public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) { + next(); } + }); + skipButton = new TextButton("Skip", skin); // Universal Skip button + skipButton.addListener(new ClickListener() { + @Override + public void clicked(com.badlogic.gdx.scenes.scene2d.InputEvent event, float x, float y) { + currentIndex = images.length; // Skip to the end + next(); + } }); + // Add buttons to table + Table buttonTable = new Table(); + buttonTable.add(continueButton).padRight(10); // Add Continue button + buttonTable.add(skipButton); // Add Universal Skip button Table table = new Table(); table.setFillParent(true); - table.add(continueButton).padBottom(-400).row(); + table.top().right(); // Align to the top-right corner + table.pad(20); // Add padding to the top-right corner + table.add(buttonTable).row(); // Add button table and move to the next row stage.addActor(table); } @Override public void render(float delta) { - Gdx.gl.glClearColor(0, 0, 0, 1); + // Clear the screen outside the loop + Gdx.gl.glClearColor(0, 0, 0, 1F); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); + elapsedTime += delta; + batch.begin(); - introSprite.draw(batch); - text.update(); - text.draw(batch, 400, 500); // Adjust the position + + if (currentIndex < images.length) { + // Display the current image + batch.draw(images[currentIndex], 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); + + // Display text if enough time has passed + if (elapsedTime >= imageDuration) { + float textX = 100; + float textY = 100; + float padding = 10; // Padding around the text + + // Calculate the text bounds for box size + GlyphLayout glyphLayout = new GlyphLayout(boldFont, texts[currentIndex]); + float boxWidth = glyphLayout.width + 2 * padding; + float boxHeight = glyphLayout.height + 2 * padding; + + // Draw a black background box + shapeRenderer.begin(ShapeType.Filled); + shapeRenderer.setColor(Color.BLACK); + shapeRenderer.rect(textX - padding, textY - padding, boxWidth, boxHeight); + shapeRenderer.end(); + + // Draw the text in white + batch.setShader(null); // Reset the shader + boldFont.setColor(Color.WHITE); + boldFont.draw(batch, texts[currentIndex], textX, textY + glyphLayout.height); // Adjust text position + } + } + batch.end(); + // Draw UI + stage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); stage.draw(); } - /** - * Fixes the - * @param width - * @param height + * Advances to next image/text. */ + private void next() { + currentIndex++; + if (currentIndex < images.length) { + elapsedTime = 0; + } else { + game.setScreen(GdxGame.ScreenType.LEVEL_SELECT); + } + } + @Override public void resize(int width, int height) { stage.getViewport().update(width, height, true); @@ -101,7 +192,12 @@ public void resize(int width, int height) { @Override public void dispose() { batch.dispose(); - introImage.dispose(); + for (Texture texture : images) { + texture.dispose(); + } + font.dispose(); + boldFont.dispose(); stage.dispose(); + shapeRenderer.dispose(); } } diff --git a/source/core/src/main/com/csse3200/game/screens/TurretSelectionScreen.java b/source/core/src/main/com/csse3200/game/screens/TurretSelectionScreen.java index a679dd30c..48cfee714 100644 --- a/source/core/src/main/com/csse3200/game/screens/TurretSelectionScreen.java +++ b/source/core/src/main/com/csse3200/game/screens/TurretSelectionScreen.java @@ -56,7 +56,7 @@ public class TurretSelectionScreen extends ScreenAdapter { private TextButton descriptionLabel; private static final String TEXTURE = "planets/background.png"; private Set selectedTurrets = new HashSet<>(); - + private TextButton backButton; private static final Logger logger = LoggerFactory.getLogger(MainMenuScreen.class); public TurretSelectionScreen(GdxGame game) { @@ -77,6 +77,20 @@ public TurretSelectionScreen(GdxGame game) { // Restrictions can be added to the arrays i.e. map == "Forest" && level == 1 using for loop Skin skin = new Skin(Gdx.files.internal("flat-earth/skin/flat-earth-ui.json")); + backButton = new TextButton("Back", skin); + backButton.addListener(new ClickListener() { + @Override + public void clicked(InputEvent event, float x, float y) { + // Handle the "back" action, e.g., return to the previous screen + game.setScreen(GdxGame.ScreenType.MAIN_MENU); // Replace PREVIOUS_SCREEN with the appropriate screen type + } + }); + Table topRightTable = new Table(); + topRightTable.top().right(); + topRightTable.add(backButton).pad(10); + + stage.addActor(topRightTable); + message = new Label("Select your turrets", skin); confirmButton = createButton("images/turret-select/imageedit_4_5616741474.png", @@ -131,7 +145,7 @@ public void clicked(InputEvent event, float x, float y) { TextButton button = createButton(turret.getDefaultImage(), turret.getClickedImage(), turret.getPrice(), turret.getTowerName(), turret.getDescription()); - + button.pad(103, 15, 0, 0); button.addListener(new ClickListener() { diff --git a/source/core/src/main/com/csse3200/game/ui/ButtonFactory.java b/source/core/src/main/com/csse3200/game/ui/ButtonFactory.java new file mode 100644 index 000000000..67fafb0c0 --- /dev/null +++ b/source/core/src/main/com/csse3200/game/ui/ButtonFactory.java @@ -0,0 +1,90 @@ +package com.csse3200.game.ui; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Texture; +import com.badlogic.gdx.graphics.g2d.TextureAtlas; +import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.badlogic.gdx.scenes.scene2d.ui.Skin; +import com.badlogic.gdx.scenes.scene2d.ui.TextButton; +import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; + +/** + * This class provides static methods for creating various types of TextButtons with different styles. + */ +public class ButtonFactory { + private static Skin defaultSkin; + + // Static initializer block to initialize the default skin + static { + defaultSkin = createDefaultSkin(); + } + + private static Skin createDefaultSkin() { + Skin skin = new Skin(Gdx.files.internal("configs/text.json")); + + // Define the button style with the background image + TextButton.TextButtonStyle style = new TextButton.TextButtonStyle(); + style.font = skin.getFont("default"); + style.up = new TextureRegionDrawable(new TextureRegion(new Texture("images/ui/Sprites/UI_Glass_Button_Large_Lock_01a1.png"))); // Set the button background to the loaded image + + skin.add("default", style); + return skin; + } + + /** + * Creates a TextButton with the specified text using the default skin. + * + * @param text The text to display on the button. + * @return The created TextButton. + */ + public static TextButton createButton(String text) { + TextButton button = new TextButton(text, defaultSkin); + button.getLabel().setFontScale(0.8f); // Adjust text size + button.pad(10f); // Adjust padding + return button; + } + + /** + * Creates a custom TextButton with the specified text and a custom image. + * + * @param text The text to display on the button. + * @param customImagePath The path to the custom image for the button. + * @return The created custom TextButton. + */ + public static TextButton createCustomButton(String text, String customImagePath) { + // Create a custom button with a PNG image + Texture customTexture = new Texture(Gdx.files.internal(customImagePath)); + TextureRegionDrawable customDrawable = new TextureRegionDrawable(customTexture); + + TextButton.TextButtonStyle style = new TextButton.TextButtonStyle(); + style.font = defaultSkin.getFont("default"); + style.up = customDrawable; + + TextButton button = new TextButton(text, style); + button.getLabel().setFontScale(0.8f); // Adjust text size + button.pad(10f); // Adjust padding + + return button; + } + + /** + * Creates a custom TextButton with the specified text and an image from a TextureAtlas. + * + * @param text The text to display on the button. + * @param atlasPath The path to the TextureAtlas containing the button image. + * @return The created custom TextButton. + */ + public static TextButton createCustomButtonWithAtlas(String text, String atlasPath) { + // Create a custom button with a TextureAtlas + TextureAtlas atlas = new TextureAtlas(Gdx.files.internal(atlasPath)); + Skin customSkin = new Skin(atlas); + + TextButton.TextButtonStyle style = new TextButton.TextButtonStyle(); + style.font = defaultSkin.getFont("default"); // Use the default font + TextButton button = new TextButton(text, style); + button.getLabel().setFontScale(0.8f); // Adjust text size + button.pad(10f); // Adjust padding + + return button; + } +} \ No newline at end of file diff --git a/source/core/src/test/com/csse3200/game/entities/factories/WaveFactoryTest.java b/source/core/src/test/com/csse3200/game/entities/factories/WaveFactoryTest.java index f806a8ae1..7b45d6c87 100644 --- a/source/core/src/test/com/csse3200/game/entities/factories/WaveFactoryTest.java +++ b/source/core/src/test/com/csse3200/game/entities/factories/WaveFactoryTest.java @@ -60,7 +60,7 @@ class WaveFactoryTest { private final int LVL3_WAVES = 15; private final int LVL3_CHOSEN_LVL = 2; private final ArrayList LVL3_MOBS = new ArrayList<>(Arrays.asList("Xeno", "DodgingDragon", "FireWorm")); - private final String LVL3_BOSS = "IceBoss"; + private final String LVL3_BOSS = "FireBoss"; // private final String LVL3_BOSS = "FireBoss"; //TODO: make this a fire boss in sprint 4