added buddi, started adding buddi animations
authorFrank DeMarco <if.self.end@gmail.com>
Sat, 5 Sep 2020 03:14:46 +0000 (23:14 -0400)
committerFrank DeMarco <if.self.end@gmail.com>
Sat, 5 Sep 2020 03:14:46 +0000 (23:14 -0400)
BuddiSystem.cpp
BuddiSystem.hpp
Makefile
Sea.cpp
Sea.hpp
config.json
lib/sfw

index 5f61ba0..c5cee49 100644 (file)
 #include "filesystem.hpp"
 #include "Color.hpp"
 #include "Scientist.hpp"
-#include "Sea.hpp"
 #include "BuddiSystem.hpp"
 
 BuddiSystem::BuddiSystem()
 {
     // Mix_Music *music = Mix_LoadMUS("resource/bgm/my-piano.ogg");
     // Mix_PlayMusic(music, -1);
-    levels = {new Seafront(this), new Seafloor(this), new Seaside(this)};
+    buddi.set_draw_children_on_frame(false);
+    levels = {new Seafront(this), new Seafloor(this), new Seaside(this), garden_level};
     crew.reserve(6);
     for (const int& index : {3, 5, 4, 1, 0, 2})
     {
@@ -42,7 +42,6 @@ BuddiSystem::BuddiSystem()
     delegate.subscribe(&BuddiSystem::respond, this, SDL_KEYUP);
     reset();
     load_sdl_context();
-    Segment a = {{0, 0}, {5, 5}}, b = {{3, 3}, {4, 3}}, c = {{3, 3}, {2, 3}}, d = {{4, -1}, {5, -2}};
 }
 
 void BuddiSystem::reset()
@@ -81,6 +80,7 @@ void BuddiSystem::load_sdl_context()
     {
         level->load();
     }
+    buddi.load();
     crew[0].select();
 }
 
index 163d343..f0ec441 100644 (file)
@@ -16,7 +16,6 @@
 #include <math.h>
 #include <vector>
 #include <array>
-#include <list>
 #include <cstdlib>
 #include <algorithm>
 #include <string>
@@ -24,6 +23,9 @@
 #include <fstream>
 #include <random>
 
+#include "SDL.h"
+#include "SDL_ttf.h"
+
 #define GLM_ENABLE_EXPERIMENTAL
 #include "glm/gtx/string_cast.hpp"
 #include "glm/gtx/transform.hpp"
@@ -39,6 +41,7 @@
 #include "Select.hpp"
 #include "Beach.hpp"
 #include "Sail.hpp"
+#include "Sea.hpp"
 
 struct Platform;
 
@@ -49,18 +52,20 @@ struct CoralMedia
     std::vector<Platform> platforms;
 };
 
-struct Sea;
 struct Scientist;
 
 struct BuddiSystem : Game
 {
 
+    const std::string CANTARELL_PATH = "resource/Cantarell.ttf";
     SDL_Event event;
     Title title = Title(this);
     Select select = Select(this);
     Beach beach = Beach(this);
     Sail sail = Sail(this);
     Sprite clouds = Sprite(this, "resource/clouds.png"), sun = Sprite(this, "resource/sun.png"), sky = Sprite(this);
+    Buddi buddi = Buddi(this);
+    Sea* garden_level = new Seagarden(this);
     std::vector<Scientist> crew;
     std::vector<Sea*> levels;
     std::size_t current_level_index = 0;
@@ -70,6 +75,8 @@ struct BuddiSystem : Game
     std::random_device random_number_generator;
     std::mt19937 random_number_engine = std::mt19937(random_number_generator());
     std::uniform_real_distribution<> random_distribution = std::uniform_real_distribution<>(0.0f, 1.0f);
+    TTF_Font *font_cantarell_small = TTF_OpenFont(CANTARELL_PATH.c_str(), 14),
+        *font_cantarell_medium = TTF_OpenFont(CANTARELL_PATH.c_str(), 20);
 
     BuddiSystem();
     void reset();
index f4a7141..220f094 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -72,7 +72,7 @@ linux :       LFLAGS = $(shell $(SDLCONFIG) --libs) -lpthread
 linux : $(GLEW_DIR)glew.o $(addprefix $(SDLGFX2_DIR),SDL2_rotozoom.o SDL2_gfxPrimitives.o) \
        $(SFW_O_FILES) $(GAME_O_FILES)
        $(CREATE_FONT_SYMLINK)
-       $(CPPC) $(LFLAGS) -D__LINUX__ -lGL -lSDL2_image -lSDL2_ttf -lSDL2_mixer -lstdc++fs $^ -o buddi
+       $(CPPC) $(LFLAGS) -D__LINUX__ -lGL -lGLESv2 -lSDL2_image -lSDL2_ttf -lSDL2_mixer -lstdc++fs $^ -o buddi
 
 emscripten : CC = $(EMSCRIPTENHOME)/emcc
 emscripten : CPPC = $(EMSCRIPTENHOME)/em++
diff --git a/Sea.cpp b/Sea.cpp
index fd818bd..704d899 100644 (file)
--- a/Sea.cpp
+++ b/Sea.cpp
 #include <string>
 #include <regex>
 
+#include "SDL_ttf.h"
+
 #include "glm/ext/scalar_constants.hpp"
 #include "sdl2-gfx/SDL2_rotozoom.h"
 #include "Scientist.hpp"
 #include "BuddiSystem.hpp"
 #include "Pixels.hpp"
 #include "Segment.hpp"
+#include "Delegate.hpp"
+#include "Input.hpp"
 #include "filesystem.hpp"
 #include "extension.hpp"
 #include "Sea.hpp"
@@ -40,12 +44,14 @@ Sea::Sea(Node* parent) : Node(parent)
     anemone.set_frame_length(750.0f);
     anemone.reverse_wipe_direction();
     home_glow.set_frame_length(200.0f);
+    get_delegate().subscribe(&Sea::respond, this);
 }
 
 void Sea::reset()
 {
     Node::reset();
     recycle.reset();
+    anemone.reset();
     for (Coral& coral : corals)
     {
         coral.reset();
@@ -61,8 +67,10 @@ void Sea::reset()
     {
         jelly.reset();
     }
-    anemone.reset();
     home_glow.hide();
+    root->buddi.reset();
+    root->buddi.hide();
+    peek_buddi_animation.reset();
 }
 
 void Sea::activate()
@@ -165,6 +173,17 @@ void Sea::restart()
     scientist.update();
 }
 
+void Sea::respond(SDL_Event& event)
+{
+    if (get_delegate().compare(event, {Input::any, "up", "right", "down", "left"}))
+    {
+        if (peek_buddi_animation.is_playing())
+        {
+            end_peek_buddi();
+        }
+    }
+}
+
 void Sea::place_cans(const std::vector<glm::vec2>& positions)
 {
     for (std::size_t ii = 0; ii < positions.size(); ii++)
@@ -262,6 +281,42 @@ void Sea::finish_level()
     clownfish.at_home = true;
     home_glow.set_center(anemone.get_center());
     home_glow.unhide();
+    suppress_input_temporarily();
+    if (this == root->garden_level)
+    {
+    }
+    else
+    {
+        Buddi& buddi = root->buddi;
+        buddi.set_frameset("scanner");
+        buddi.unhide();
+        Box window_box = get_window_box();
+        buddi.set_south({anemone.get_center_x(), window_box.get_top()});
+        if (buddi.get_left() < window_box.get_left())
+        {
+            buddi.set_left(window_box.get_left());
+        }
+        else if (buddi.get_right() > window_box.get_right())
+        {
+            buddi.set_right(window_box.get_right());
+        }
+        peek_buddi_animation.play();
+    }
+}
+
+void Sea::peek_buddi()
+{
+    root->buddi.move({0, 1});
+    if (root->buddi.get_bottom() - get_window_box().get_top() > BUDDI_PEEK)
+    {
+        end_peek_buddi();
+    }
+}
+
+void Sea::end_peek_buddi()
+{
+    root->buddi.set_bottom(get_window_box().get_top() + BUDDI_PEEK);
+    peek_buddi_animation.reset();
 }
 
 void Sea::update()
@@ -270,6 +325,7 @@ void Sea::update()
     {
         Scientist& scientist = get_root<BuddiSystem>()->get_selected_scientist();
         restore_background_animation.update();
+        peek_buddi_animation.update();
         if (is_cleaned() && !clownfish_hit && !clownfish.at_home)
         {
             Segment distance = {clownfish.get_center(), scientist.get_center()};
@@ -445,6 +501,7 @@ void Sea::update()
                         jelly.update();
                     }
                 }
+                root->buddi.update();
                 seaweed.update();
             }
         }
@@ -664,6 +721,82 @@ void Seaside::update()
     }
 }
 
+Seagarden::Seagarden(Node* parent) : Sea(parent) {}
+
+Buddi::Buddi(Node* parent) : Sprite(parent)
+{
+    Frameset &scanner_frameset = add_frameset("scanner"), &monitor_frameset = add_frameset("monitor");
+    scanner_frameset.set_frame_length(100.0f);
+    monitor_frameset.set_frame_length(200.0f);
+    associate("resource/buddi_screen");
+    std::size_t scanner_frame_count = frame_paths.size();
+    scanner_frameset.add_frame_indicies(sfw::range(scanner_frame_count));
+    associate("resource/buddi_monitor");
+    monitor_frameset.add_frame_indicies(sfw::range(scanner_frame_count, frame_paths.size()));
+    Sprite& shell = insert_child("shell");
+    shell.associate("resource/buddi_case.png");
+    set_frameset("scanner");
+}
+
+void Buddi::reset()
+{
+    Sprite::reset();
+    remove_child("scan");
+    remove_child("info");
+}
+
+Sprite& Buddi::set_scan(Coral& coral)
+{
+    Sprite& scan = insert_child("scan", 0);
+    scan.get_current_frameset().set_frame_length(300.0f);
+    SDL_Texture* frame = sfw::duplicate_texture(
+        get_renderer(), coral.get_current_frame(), sfw::fit_and_preserve_aspect(SCREEN_SIZE, coral.get_size()));
+    scan.add_frames(frame);
+    scan.set_south(CORAL_SOUTH);
+    return scan;
+}
+
+Sprite& Buddi::set_info(Coral& coral)
+{
+    Sprite& info = insert_child("info", 0);
+    std::stringstream text;
+    text << coral.name << std::endl << "(" << coral.scientific_name << ")";
+    SDL_Surface* text_surface = TTF_RenderText_Blended_Wrapped(
+        root->font_cantarell_medium, text.str().c_str(), {0, 0, 0, 255}, SCREEN_SIZE.x - 26);
+    SDL_Texture* frame = SDL_CreateTextureFromSurface(get_renderer(), text_surface);
+    info.add_frames(frame);
+    info.set_north(INFO_NORTH);
+    SDL_FreeSurface(text_surface);
+    return info;
+}
+
+Frameset& Buddi::set_frameset(std::string name)
+{
+    Frameset& frameset = Sprite::set_frameset(name);
+    if (name == "scanner")
+    {
+        get_child("shell").unhide();
+    }
+    else if (name == "monitor")
+    {
+        get_child("shell").hide();
+        wipe_animation.reset();
+        if (has_child("scan"))
+        {
+            Sprite& scan = get_child("scan");
+            scan.hide();
+            scan.blink_animation.reset();
+        }
+        if (has_child("info"))
+        {
+            Sprite& info = get_child("info");
+            info.hide();
+            info.toggle_hidden_animation.reset();
+        }
+    }
+    return frameset;
+}
+
 Jellyfish::Jellyfish(Sea* parent, glm::vec2 frame_size, int z_index, const Color& body_color, const Color& eye_color) :
     Sprite(parent), frame_size(frame_size), z_index(z_index), body_color(body_color), eye_color(eye_color)
 {
@@ -970,6 +1103,7 @@ void Coral::load()
 
 void Coral::reset()
 {
+    Sprite::reset();
     enable_platforms();
     bleach.unhide();
 }
diff --git a/Sea.hpp b/Sea.hpp
index 2cdafbe..f29ded4 100644 (file)
--- a/Sea.hpp
+++ b/Sea.hpp
@@ -19,6 +19,7 @@
 #include "Sprite.hpp"
 #include "Platform.hpp"
 #include "Color.hpp"
+#include "Node.hpp"
 
 struct Sea;
 
@@ -105,6 +106,21 @@ struct Coral : Sprite
 
 };
 
+struct Buddi : Sprite
+{
+
+    const glm::vec2 SCREEN_SIZE = {142, 119}, CORAL_SOUTH = {102, 138}, INFO_NORTH = {100, 20};
+    const int FONT_SIZE = 18;
+    BuddiSystem* root = get_root<BuddiSystem>();
+
+    Buddi(Node*);
+    void reset();
+    Sprite& set_scan(Coral&);
+    Sprite& set_info(Coral&);
+    Frameset& set_frameset(std::string);
+
+};
+
 #include "Recycle.hpp"
 #include "Animation.hpp"
 
@@ -121,7 +137,8 @@ struct Sea : Node
     };
     bool restarting = false, display_fill_animation = false, clownfish_hit = false, touching_clownfish = false;
     float background_offset = 0.0f, previous_scientist_x = 0.0f, carried_can_x = 0.0f;
-    Animation restore_background_animation = Animation(&Sea::restore_background, this);
+    Animation restore_background_animation = Animation(&Sea::restore_background, this),
+        peek_buddi_animation = Animation(&Sea::peek_buddi, this);
     Sprite seafloor = Sprite(this, "resource/seafloor.png"), background = Sprite(this),
         seaweed = Sprite(this, "resource/seaweed.png"), anemone = Sprite(this, "resource/anemone"),
         home_glow = Sprite(this);
@@ -143,6 +160,7 @@ struct Sea : Node
     virtual void activate();
     virtual void load();
     virtual void restart();
+    void respond(SDL_Event&);
     void place_cans(const std::vector<glm::vec2>&);
     void paint_background();
     void restore_background();
@@ -150,6 +168,8 @@ struct Sea : Node
     bool is_cleaned();
     void transition_to_cleaned();
     void finish_level();
+    void peek_buddi();
+    void end_peek_buddi();
     virtual void update();
 
 };
@@ -195,4 +215,11 @@ struct Seaside : Sea
 
 };
 
+struct Seagarden : Sea
+{
+
+    Seagarden(Node*);
+
+};
+
 #endif
index 697006d..bc027cf 100644 (file)
@@ -2,7 +2,7 @@
     "display":
     {
         "dimensions": [720, 405],
-        "framerate": 60,
+        "framerate": 30,
         "title": "B.U.D.D.I.",
         "debug": false,
         "render-test-spacing": 2,
diff --git a/lib/sfw b/lib/sfw
index 877d63c..0e6e506 160000 (submodule)
--- a/lib/sfw
+++ b/lib/sfw
@@ -1 +1 @@
-Subproject commit 877d63cf4e9c6f7798bfbf3ee71d187430376aea
+Subproject commit 0e6e506c680b313cd2f772deacc4841764c1f578