diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index a80832e4..0f2b9164 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -387,6 +387,14 @@ void Game::init(void) languagepage = 0; setdefaultcontrollerbuttons(); + + tutorial_mode = false; + tutorial_state = 0; + tutorial_timer = 0; + + tutorial_screen_pos = 0; + tutorial_touch_timer = 0; + tutorial_flip = 0; } void Game::setdefaultcontrollerbuttons(void) diff --git a/desktop_version/src/Game.h b/desktop_version/src/Game.h index aa5ad4ea..a28f0cba 100644 --- a/desktop_version/src/Game.h +++ b/desktop_version/src/Game.h @@ -612,6 +612,14 @@ public: bool screenshot_saved_success; int languagepage; + + bool tutorial_mode; + int tutorial_state; + int tutorial_timer; + + int tutorial_screen_pos; + int tutorial_touch_timer; + int tutorial_flip; }; #ifndef GAME_DEFINITION diff --git a/desktop_version/src/GraphicsResources.cpp b/desktop_version/src/GraphicsResources.cpp index 1a364f0b..1a352c16 100644 --- a/desktop_version/src/GraphicsResources.cpp +++ b/desktop_version/src/GraphicsResources.cpp @@ -434,6 +434,18 @@ void GraphicsResources::init(void) im_button_map = LoadImage("graphics/buttons/button_map.png"); im_button_globe = LoadImage("graphics/buttons/button_globe.png"); + im_tutorial_lefthand_far = LoadImage("graphics/tutorial/lefthand_far.png"); + im_tutorial_lefthand_near = LoadImage("graphics/tutorial/lefthand_near.png"); + im_tutorial_lefthand_off = LoadImage("graphics/tutorial/lefthand_off.png"); + im_tutorial_righthand_far = LoadImage("graphics/tutorial/righthand_far.png"); + im_tutorial_righthand_near = LoadImage("graphics/tutorial/righthand_near.png"); + im_tutorial_righthand_off = LoadImage("graphics/tutorial/righthand_off.png"); + + im_tutorial_arrowleft = LoadImage("graphics/tutorial/arrowleft.png"); + im_tutorial_arrowright = LoadImage("graphics/tutorial/arrowright.png"); + + im_tutorial_screen = LoadImage("graphics/tutorial/touchscreen.png"); + im_sprites_translated = NULL; im_flipsprites_translated = NULL; @@ -486,6 +498,18 @@ void GraphicsResources::destroy(void) CLEAR(im_button_right); CLEAR(im_button_map); CLEAR(im_button_globe); + + CLEAR(im_tutorial_lefthand_far); + CLEAR(im_tutorial_lefthand_near); + CLEAR(im_tutorial_lefthand_off); + CLEAR(im_tutorial_righthand_far); + CLEAR(im_tutorial_righthand_near); + CLEAR(im_tutorial_righthand_off); + + CLEAR(im_tutorial_arrowleft); + CLEAR(im_tutorial_arrowright); + + CLEAR(im_tutorial_screen); #undef CLEAR VVV_freefunc(SDL_FreeSurface, im_sprites_surf); diff --git a/desktop_version/src/GraphicsResources.h b/desktop_version/src/GraphicsResources.h index 5938cc46..9d080a51 100644 --- a/desktop_version/src/GraphicsResources.h +++ b/desktop_version/src/GraphicsResources.h @@ -54,6 +54,18 @@ public: SDL_Texture* im_button_right; SDL_Texture* im_button_map; SDL_Texture* im_button_globe; + + SDL_Texture* im_tutorial_lefthand_far; + SDL_Texture* im_tutorial_lefthand_near; + SDL_Texture* im_tutorial_lefthand_off; + SDL_Texture* im_tutorial_righthand_far; + SDL_Texture* im_tutorial_righthand_near; + SDL_Texture* im_tutorial_righthand_off; + + SDL_Texture* im_tutorial_arrowleft; + SDL_Texture* im_tutorial_arrowright; + + SDL_Texture* im_tutorial_screen; }; SDL_Surface* LoadImageSurface(const char* filename); diff --git a/desktop_version/src/Input.cpp b/desktop_version/src/Input.cpp index 70cad6e2..ff362c46 100644 --- a/desktop_version/src/Input.cpp +++ b/desktop_version/src/Input.cpp @@ -2907,6 +2907,13 @@ void gameinput(void) bool enter_pressed = game.press_map && !game.mapheld; bool enter_already_processed = false; bool interact_pressed; + + bool should_move = true; + if (game.tutorial_mode) + { + should_move = game.tutorial_touch_timer >= 8; + } + if (game.separate_interact) { interact_pressed = game.press_interact && !game.interactheld; @@ -3011,15 +3018,25 @@ void gameinput(void) } } - if(game.press_left) + if (game.press_left) { - obj.entities[ie].ax = -3; - obj.entities[ie].dir = 0; + if (should_move) + { + obj.entities[ie].ax = -3; + obj.entities[ie].dir = 0; + } } else if (game.press_right) { - obj.entities[ie].ax = 3; - obj.entities[ie].dir = 1; + if (should_move) + { + obj.entities[ie].ax = 3; + obj.entities[ie].dir = 1; + } + } + else + { + game.tutorial_touch_timer = 0; } } } @@ -3030,6 +3047,10 @@ void gameinput(void) if (game.press_left) { game.tapleft++; + if (game.tutorial_mode) + { + game.tutorial_touch_timer++; + } } else { @@ -3051,6 +3072,10 @@ void gameinput(void) if (game.press_right) { game.tapright++; + if (game.tutorial_mode) + { + game.tutorial_touch_timer++; + } } else { @@ -3222,6 +3247,15 @@ void gameinput(void) { game.deathseq = 30; } + + if (game.tutorial_mode && game.tutorial_state >= 13) + { + if (key.isDown(KEYBOARD_z) || key.isDown(KEYBOARD_v) || key.isDown(KEYBOARD_ENTER) || key.isDown(KEYBOARD_UP) || key.isDown(KEYBOARD_DOWN) || touch::screen_down()) + { + music.playef(11); + game.tutorial_mode = false; + } + } } void mapinput(void) diff --git a/desktop_version/src/Logic.cpp b/desktop_version/src/Logic.cpp index 67dd637a..2bc6f05a 100644 --- a/desktop_version/src/Logic.cpp +++ b/desktop_version/src/Logic.cpp @@ -1483,5 +1483,173 @@ void gamelogic(void) #undef gotoroom #undef GOTOROOM + if (game.tutorial_mode) + { + game.tutorial_timer++; + + if (game.tutorial_flip > 0) + { + game.tutorial_flip--; + } + + switch (game.tutorial_state) + { + case 0: + if (game.tutorial_timer > 10) + { + game.tutorial_state = 1; + game.tutorial_timer = 0; + } + break; + case 1: + game.tutorial_screen_pos += 5; + if (game.tutorial_screen_pos >= 100) + { + game.tutorial_screen_pos = 100; + game.tutorial_state = 2; + game.tutorial_timer = 0; + } + break; + case 2: + if (game.tutorial_timer > 30) + { + game.tutorial_timer = 0; + game.tutorial_state = 3; + } + break; + case 3: + game.press_right = true; + if (game.tutorial_timer > 60) + { + game.tutorial_timer = 0; + game.tutorial_state = 4; + } + break; + case 4: + game.press_right = false; + if (game.tutorial_timer > 30) + { + game.tutorial_timer = 0; + game.tutorial_state = 5; + } + break; + case 5: + game.press_left = true; + if (game.tutorial_timer > 60) + { + game.tutorial_timer = 0; + game.tutorial_state = 6; + } + break; + case 6: + game.press_left = false; + if (game.tutorial_timer > 30) + { + game.tutorial_timer = 0; + game.tutorial_state = 7; + } + break; + case 7: + if (game.tutorial_timer > 5) + { + game.tutorial_timer = 0; + game.tutorial_state = 8; + } + break; + case 8: + game.jumppressed = 5; + game.jumpheld = true; + game.press_action = true; + game.tutorial_state = 9; + game.tutorial_flip = 10; + game.tutorial_timer = 0; + break; + case 9: + if (game.tutorial_timer > 45) + { + game.tutorial_timer = 0; + game.tutorial_state = 10; + } + break; + case 10: + game.jumppressed = 5; + game.jumpheld = true; + game.press_action = true; + game.tutorial_state = 11; + game.tutorial_flip = 10; + game.tutorial_timer = 0; + break; + case 11: + if (game.tutorial_timer > 45) + { + game.tutorial_timer = 0; + game.tutorial_state++; + } + break; + case 12: + game.press_left = false; + game.press_right = true; + if (game.tutorial_timer > 28) + { + game.tutorial_timer = 0; + game.tutorial_state++; + } + break; + case 13: + game.press_left = true; + game.press_right = false; + if (game.tutorial_timer == 30) + { + game.jumppressed = 5; + game.jumpheld = true; + game.press_action = true; + game.tutorial_flip = 10; + } + if (game.tutorial_timer > 45) + { + game.tutorial_timer = 0; + game.tutorial_state++; + } + break; + case 14: + game.press_left = false; + game.press_right = true; + if (game.tutorial_timer == 30) + { + if (fRandom() * 100 > 50) + { + game.jumppressed = 5; + game.jumpheld = true; + game.press_action = true; + game.tutorial_flip = 10; + } + } + if (game.tutorial_timer > 45) + { + game.tutorial_timer = 0; + game.tutorial_state++; + } + break; + case 15: + game.press_left = true; + game.press_right = false; + if (game.tutorial_timer == 30) + { + if (fRandom() * 100 > 50) + { + game.jumppressed = 5; + game.jumpheld = true; + game.tutorial_flip = 10; + } + } + if (game.tutorial_timer > 45) + { + game.tutorial_timer = 0; + game.tutorial_state = 14; + } + break; + } + } + level_debugger::logic(); } diff --git a/desktop_version/src/Render.cpp b/desktop_version/src/Render.cpp index 4a5f9cca..5ab3e133 100644 --- a/desktop_version/src/Render.cpp +++ b/desktop_version/src/Render.cpp @@ -2466,7 +2466,7 @@ void gamerender(void) } graphics.drawtowermap(); } - else + else if (!game.tutorial_mode) { if(!game.colourblindmode) { @@ -2485,7 +2485,10 @@ void gamerender(void) graphics.drawmap(); } } - + else if (game.tutorial_mode) + { + graphics.fill_rect(10, 24, 26); + } graphics.drawentities(); if (map.towermode) @@ -2906,6 +2909,117 @@ void gamerender(void) graphics.drawtrophytext(); } + if (game.tutorial_mode) + { + int screen_off = (100 - game.tutorial_screen_pos) * 3; + + font::print_wrap(PR_CEN, -1, 10, loc::gettext("-= TOUCHSCREEN CONTROLS =-"), 200 - help.glow, 220 - help.glow, 255 - help.glow / 2); + + if (game.tutorial_state >= 3 && game.tutorial_state <= 6) + { + font::print_wrap(PR_CEN, -1, 203, "Swipe and hold on the left side of the screen to move", 200 - help.glow, 220 - help.glow, 255 - help.glow / 2, -1, SCREEN_WIDTH_PIXELS / 3 * 2); + } + + if (game.tutorial_state >= 7 && game.tutorial_state <= 11) + { + font::print_wrap(PR_CEN, -1, 203, "Tap on the right to flip", 200 - help.glow, 220 - help.glow, 255 - help.glow / 2, -1, SCREEN_WIDTH_PIXELS / 3 * 2); + } + + if (game.tutorial_state >= 13) + { + font::print_wrap(PR_CEN, -1, 203, "Tap to start", 200 - help.glow, 220 - help.glow, 255 - help.glow / 2, -1, SCREEN_WIDTH_PIXELS / 3 * 2); + } + + graphics.draw_texture(graphics.grphx.im_tutorial_screen, 80, 70 + screen_off); + + // Touchpoints! + if (!game.press_left && !game.press_right) + { + // Left hand off + graphics.draw_texture(graphics.grphx.im_tutorial_lefthand_off, 56, 106 + screen_off); + } + else if (game.press_left) + { + // Left hand moving left + if (game.tutorial_touch_timer <= 8) + { + if (help.slowsine % 16 > 8) + { + graphics.draw_rect(116, 120, 16, 16, 255, 255, 255); + } + else + { + graphics.draw_rect(118, 122, 12, 12, 255, 255, 255); + } + graphics.draw_texture(graphics.grphx.im_tutorial_lefthand_far, 56, 106 + screen_off); + graphics.draw_texture(graphics.grphx.im_tutorial_arrowleft, 136, 120); + } + else + { + if (help.slowsine % 16 > 8) + { + graphics.draw_rect(104, 118, 16, 16, 255, 255, 255); + } + else + { + graphics.draw_rect(106, 120, 12, 12, 255, 255, 255); + } + graphics.draw_texture(graphics.grphx.im_tutorial_lefthand_near, 56, 106 + screen_off); + graphics.draw_texture(graphics.grphx.im_tutorial_arrowleft, 124, 120); + } + } + else if (game.press_right) + { + // Left hand moving right + if (game.tutorial_touch_timer <= 8) + { + if (help.slowsine % 16 > 8) + { + graphics.draw_rect(104, 118, 16, 16, 255, 255, 255); + } + else + { + graphics.draw_rect(106, 120, 12, 12, 255, 255, 255); + } + graphics.draw_texture(graphics.grphx.im_tutorial_lefthand_near, 56, 106 + screen_off); + graphics.draw_texture(graphics.grphx.im_tutorial_arrowright, 124, 120); + } + else + { + if (help.slowsine % 16 > 8) + { + graphics.draw_rect(116, 120, 16, 16, 255, 255, 255); + } + else + { + graphics.draw_rect(118, 122, 12, 12, 255, 255, 255); + } + graphics.draw_texture(graphics.grphx.im_tutorial_lefthand_far, 56, 106 + screen_off); + graphics.draw_texture(graphics.grphx.im_tutorial_arrowright, 136, 120); + } + } + + if (game.tutorial_state >= 7) + { + if (game.tutorial_flip > 0) + { + if (help.slowsine % 16 > 8) + { + graphics.draw_rect(188, 120, 16, 16, 255, 255, 255); + } + else + { + graphics.draw_rect(190, 122, 12, 12, 255, 255, 255); + } + graphics.draw_texture(graphics.grphx.im_tutorial_righthand_far, 193, 106); + } + else + { + graphics.draw_texture(graphics.grphx.im_tutorial_righthand_off, 193, 106 + screen_off); + } + } + } + level_debugger::render(); graphics.renderwithscreeneffects(); diff --git a/desktop_version/src/Script.cpp b/desktop_version/src/Script.cpp index 9f1dd8bc..bf1ae6a7 100644 --- a/desktop_version/src/Script.cpp +++ b/desktop_version/src/Script.cpp @@ -198,10 +198,13 @@ void scriptclass::run(void) tokenize(commands[position]); //For script assisted input - game.press_left = false; - game.press_right = false; - game.press_action = false; - game.press_map = false; + if (!game.tutorial_mode) + { + game.press_left = false; + game.press_right = false; + game.press_action = false; + game.press_map = false; + } //Ok, now we run a command based on that string if (words[0] == "moveplayer") @@ -1418,6 +1421,11 @@ void scriptclass::run(void) graphics.setfade(0); graphics.fademode = FADE_NONE; } + else if (words[0] == "befadeout") + { + graphics.setfade(416); + graphics.fademode = FADE_FULLY_BLACK; + } else if (words[0] == "fadein") { graphics.fademode = FADE_START_FADEIN; @@ -2514,6 +2522,33 @@ void scriptclass::run(void) } } } + else if (words[0] == "settile") + { + map.settile(ss_toi(words[1]), ss_toi(words[2]), ss_toi(words[3])); + graphics.foregrounddrawn = false; + } + else if (words[0] == "controls") + { + game.tutorial_mode = true; + game.tutorial_state = 0; + game.tutorial_timer = 0; + + game.tutorial_screen_pos = 0; + game.tutorial_touch_timer = 0; + game.tutorial_flip = 0; + } + else if (words[0] == "untilcontrols") + { + if (game.tutorial_mode) + { + scriptdelay = 1; + position--; + } + } + else if (words[0] == "setbars") + { + graphics.setbars(ss_toi(words[1])); + } position++; } @@ -3223,6 +3258,14 @@ void scriptclass::hardreset(void) game.ingame_titlemode = false; + game.tutorial_mode = false; + game.tutorial_state = 0; + game.tutorial_timer = 0; + + game.tutorial_screen_pos = 0; + game.tutorial_touch_timer = 0; + game.tutorial_flip = 0; + //dwgraphicsclass graphics.backgrounddrawn = false; graphics.textboxes.clear(); diff --git a/desktop_version/src/Scripts.cpp b/desktop_version/src/Scripts.cpp index 18f1984c..7b68fcdc 100644 --- a/desktop_version/src/Scripts.cpp +++ b/desktop_version/src/Scripts.cpp @@ -188,14 +188,54 @@ bool scriptclass::load(const std::string& name) "changemood(player,0)", "changedir(player,1)", - "delay(100)", + //"delay(100)", + "delay(5)", + "gotoroom(7,10)", + "gotoposition(148,32,0)", + "warpdir(8,11,3)", + "settile(25,8,495)", + "settile(26,8,495)", + "settile(34,8,495)", + "settile(35,8,495)", + "settile(36,4,0)", + "settile(37,4,0)", + "settile(38,4,0)", + "settile(39,4,0)", + "settile(36,5,0)", + "settile(37,5,0)", + "settile(38,5,0)", + "settile(39,5,0)", + "settile(36,6,0)", + "settile(37,6,0)", + "settile(38,6,0)", + "settile(39,6,0)", + "settile(36,7,0)", + "settile(37,7,0)", + "settile(38,7,0)", + "settile(39,7,0)", + "delay(50)", "blackon()", + "endcutscene()", + "setbars(0)", + "changemood(player,0)", + "changedir(player,0)", + "controls()", + "untilcontrols()", + "befadeout()", + "cutscene()", + "setbars(320)", + "delay(45)", // 100 frames total + + "changemood(player,1)", + "befadein()", "shake(20)", "playef(10)", //Finally, appear at the start of the game: "gotoroom(13,5)", "gotoposition(80,96,0)", + "hidecoordinates(7,10)", // Hide coordinates where the touch tutorial took place + "warpdir(8,11,0)", "walk(right,20)", //"delay(45)",