- add arcade mode and arcade-only configuration option
- scoreboard and name entry for arcade mode - separate save data for quest and arcade modes
This commit is contained in:
parent
8d9ec69656
commit
18fb61c236
4
Makefile
4
Makefile
|
@ -301,7 +301,7 @@ WINDOWS_OBJ := $(addprefix $(WINDOWS_BUILD_DIR)/, glew.o SDL2_rotozoom.o SDL2_gf
|
|||
|
||||
Cakefoot-win32.exe: CC = i686-w64-mingw32-gcc-posix
|
||||
Cakefoot-win32.exe: CXX = i686-w64-mingw32-g++-posix
|
||||
Cakefoot-win32.exe: CFLAGS = -Wall -Wextra -g -O0 -c -I$(SB_LIB_DIR) -I$(SB_SRC_DIR) -DGLEW_STATIC \
|
||||
Cakefoot-win32.exe: CFLAGS = -Wall -Wextra -O3 -c -I$(SB_LIB_DIR) -I$(SB_SRC_DIR) -DGLEW_STATIC \
|
||||
-I$(SDL_MINGW)/include/SDL2 -I$(SDL_IMG_MINGW)/include/SDL2 -I$(SDL_TTF_MINGW)/include/SDL2 -I$(SDL_MIXER_MINGW)/include/SDL2
|
||||
Cakefoot-win32.exe: CXXFLAGS = $(CFLAGS) --std=c++17
|
||||
Cakefoot-win32.exe: LFLAGS = -lpthread -lstdc++fs \
|
||||
|
@ -314,7 +314,7 @@ Cakefoot-win32.exe: $(WINDOWS_OBJ) config.json
|
|||
mkdir ${basename $@}
|
||||
cp $(SDL_MINGW)/bin/*.dll $(SDL_IMG_MINGW)/bin/*.dll $(SDL_TTF_MINGW)/bin/*.dll $(SDL_MIXER_MINGW)/bin/*.dll ${basename $@}
|
||||
cp /usr/i686-w64-mingw32/lib/libwinpthread-1.dll ${basename $@}
|
||||
rsync -arR resource/ src/shaders/ config.json ${basename $@}
|
||||
rsync -arRL resource/ src/shaders/ config.json BPmono.ttf ${basename $@}
|
||||
cp $(WINDOWS_BUILD_DIR)/$@ ${basename $@}
|
||||
zip -r ${@:exe=zip} ${basename $@}
|
||||
mv ${basename $@} /tmp
|
||||
|
|
132
config.json
132
config.json
|
@ -2,12 +2,13 @@
|
|||
"display":
|
||||
{
|
||||
"dimensions": [864, 486],
|
||||
"title": "Microsoft Windows 11 Home Edition",
|
||||
"title": "c a k e f o o t",
|
||||
"debug": false,
|
||||
"render driver": "opengl",
|
||||
"show-cursor": true,
|
||||
"fluid resize": true,
|
||||
"fps": false,
|
||||
"fullscreen": false,
|
||||
"clear color": [0.0, 0.0, 0.0, 1.0],
|
||||
"playing field aspect": 1.7777777,
|
||||
"playing field color": [0.2, 0.2, 0.2, 1.0],
|
||||
|
@ -24,7 +25,33 @@
|
|||
"level hud foreground": [255.0, 255.0, 255.0, 255.0],
|
||||
"level hud background": [0.0, 0.0, 0.0, 60.0],
|
||||
"hitbox": false,
|
||||
"use play button": true
|
||||
"use play button": false,
|
||||
"arcade only": false,
|
||||
"use arcade prompt": false,
|
||||
"game over text": "GAME OVER",
|
||||
"game over display time": 2.5,
|
||||
"game over foreground": [255.0, 255.0, 255.0, 255.0],
|
||||
"game over background": [0.0, 0.0, 0.0, 255.0],
|
||||
"game over translation": [0.0, 0.0],
|
||||
"game over scale": [0.25, 0.05],
|
||||
"arcade rank scale": [0.4, 0.1],
|
||||
"arcade rank dimensions": [300.0, 80.0],
|
||||
"arcade rank translation": [-1.2, 0.5],
|
||||
"arcade distance scale": [0.4, 0.1],
|
||||
"arcade distance dimensions": [300.0, 80.0],
|
||||
"arcade distance translation": [0.0, 0.5],
|
||||
"arcade time remaining scale": [0.4, 0.1],
|
||||
"arcade time remaining translation": [1.2, 0.5],
|
||||
"scoreboard foreground": [155.0, 155.0, 155.0, 255.0],
|
||||
"scoreboard background": [0.0, 0.0, 0.0, 0.0],
|
||||
"scoreboard translation": [-0.38, 0.845],
|
||||
"scoreboard scale": [1.4, 0.15],
|
||||
"scoreboard translation": [-0.45, 0.865],
|
||||
"scoreboard scale": [1.35, 0.14],
|
||||
"qr texture": "resource/qr.png",
|
||||
"qr translation": [1.49, -0.7],
|
||||
"qr scale": [0.205, 0.225],
|
||||
"end screen timeout": 40.0
|
||||
},
|
||||
|
||||
"configuration":
|
||||
|
@ -47,7 +74,7 @@
|
|||
"input":
|
||||
{
|
||||
"suppress any key on mods": true,
|
||||
"any key ignore commands": ["left", "right"]
|
||||
"any key ignore commands": ["left", "right", "up", "down"]
|
||||
},
|
||||
|
||||
"keys":
|
||||
|
@ -136,35 +163,69 @@
|
|||
"text foreground": [200.0, 200.0, 200.0, 255.0],
|
||||
"text background": [60.0, 60.0, 60.0, 190.0],
|
||||
"start text": "PLAY",
|
||||
"start translation": [0.0, -0.45],
|
||||
"start translation": [0.0, -0.4],
|
||||
"start alt texture": "resource/press_button_to_start.png",
|
||||
"start alt translation": [0.0, -0.5],
|
||||
"start alt scale": [0.5787, 0.91],
|
||||
"resume text": "RESUME",
|
||||
"resume translation": [0.0, 0.25],
|
||||
"reset text": "RESET",
|
||||
"reset translation": [0.0, -0.25],
|
||||
"level decrement translation": [-0.65, -0.675],
|
||||
"level decrement translation": [-0.67, -0.6],
|
||||
"level decrement text": "<",
|
||||
"level decrement dimensions": [40.0, 40.0],
|
||||
"level increment translation": [0.65, -0.675],
|
||||
"level increment translation": [0.67, -0.6],
|
||||
"level increment text": ">",
|
||||
"level select translation": [0.0, -0.675],
|
||||
"level select dimensions": [350.0, 28.0],
|
||||
"level select scale": [0.6, 0.06],
|
||||
"level select translation": [0.0, -0.6],
|
||||
"level select dimensions": [350.0, 22.0],
|
||||
"level select scale": [0.63, 0.04],
|
||||
"level select text": "LEVEL ",
|
||||
"profile translation": [0.0, -0.83],
|
||||
"profile dimensions": [320.0, 28.0],
|
||||
"profile scale": [0.6, 0.06],
|
||||
"profile translation": [0.0, -0.71],
|
||||
"profile dimensions": [320.0, 22.0],
|
||||
"profile scale": [0.63, 0.04],
|
||||
"profile text": "DIFFICULTY: ",
|
||||
"profile decrement text": "<",
|
||||
"profile decrement translation": [-0.65, -0.83],
|
||||
"profile decrement translation": [-0.67, -0.71],
|
||||
"profile increment text": ">",
|
||||
"profile increment translation": [0.65, -0.83],
|
||||
"profile increment translation": [0.67, -0.71],
|
||||
"challenge text": "CHALLENGE: ",
|
||||
"challenge translation": [0.0, -0.82],
|
||||
"challenge dimensions": [320.0, 22.0],
|
||||
"challenge scale": [0.63, 0.04],
|
||||
"challenge decrement text": "<",
|
||||
"challenge decrement translation": [-0.67, -0.82],
|
||||
"challenge increment text": ">",
|
||||
"challenge increment translation": [0.67, -0.82],
|
||||
"view text": "VIEW: ",
|
||||
"view translation": [0.0, -0.925],
|
||||
"view dimensions": [320.0, 22.0],
|
||||
"view scale": [0.63, 0.04],
|
||||
"view decrement text": "<",
|
||||
"view decrement translation": [-0.67, -0.925],
|
||||
"view increment text": ">",
|
||||
"view increment translation": [0.67, -0.925],
|
||||
"volume on texture": "resource/vol.png",
|
||||
"volume off texture": "resource/vol_off.png",
|
||||
"volume translation": [-1.65, -0.85],
|
||||
"volume scale": 0.08,
|
||||
"play texture": "resource/Play_Button.png",
|
||||
"play translation": [0.0, 0.0],
|
||||
"play scale": 0.6
|
||||
"play scale": 0.6,
|
||||
"name":
|
||||
{
|
||||
"arrow dimensions": [80.0, 40.0],
|
||||
"arrow scale": [0.3, 0.15],
|
||||
"arrow increment y": -0.25,
|
||||
"arrow decrement y": -0.76,
|
||||
"character 1 x": -0.4,
|
||||
"character 2 x": 0.0,
|
||||
"character 3 x": 0.4,
|
||||
"arrow increment texture": "resource/up_arrow.png",
|
||||
"arrow decrement texture": "resource/down_arrow.png",
|
||||
"character dimensions": [60.0, 80.0],
|
||||
"character scale": [0.2, 0.15],
|
||||
"character y": -0.5
|
||||
}
|
||||
},
|
||||
|
||||
"world": [
|
||||
|
@ -186,7 +247,46 @@
|
|||
}
|
||||
],
|
||||
|
||||
"audio": {
|
||||
"challenge": [
|
||||
{
|
||||
"name": "RESUME QUEST"
|
||||
},
|
||||
{
|
||||
"name": "NEW QUEST"
|
||||
},
|
||||
{
|
||||
"name": "LEVEL SELECT"
|
||||
},
|
||||
{
|
||||
"name": "RESUME ARCADE",
|
||||
"time limit": 30.0,
|
||||
"checkpoint addition": 10.0,
|
||||
"level addition": 20.0,
|
||||
"bank bonus": 5.0
|
||||
},
|
||||
{
|
||||
"name": "ARCADE",
|
||||
"time limit": 30.0,
|
||||
"checkpoint addition": 10.0,
|
||||
"level addition": 20.0,
|
||||
"bank bonus": 5.0
|
||||
}
|
||||
],
|
||||
|
||||
"view": [
|
||||
{
|
||||
"name": "ORIGINAL"
|
||||
},
|
||||
{
|
||||
"name": "MIRROR"
|
||||
},
|
||||
{
|
||||
"name": "WARPED"
|
||||
}
|
||||
],
|
||||
|
||||
"audio":
|
||||
{
|
||||
"files":
|
||||
{
|
||||
"restart": "resource/no.ogg",
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
{
|
||||
"display":
|
||||
{
|
||||
"render driver": "opengles2",
|
||||
"fluid resize": false
|
||||
},
|
||||
"display":
|
||||
{
|
||||
"render driver": "opengles2",
|
||||
"fluid resize": false,
|
||||
"use play button": true
|
||||
},
|
||||
|
||||
"recording":
|
||||
{
|
||||
"enabled": false
|
||||
},
|
||||
"recording":
|
||||
{
|
||||
"enabled": false
|
||||
},
|
||||
|
||||
"log":
|
||||
{
|
||||
"enabled": false
|
||||
},
|
||||
"log":
|
||||
{
|
||||
"enabled": false
|
||||
},
|
||||
|
||||
"configuration":
|
||||
{
|
||||
"auto-refresh": false
|
||||
}
|
||||
"configuration":
|
||||
{
|
||||
"auto-refresh": false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
return response.json();
|
||||
}
|
||||
}).then((response) => {
|
||||
document.getElementById("session").innerHTML = "Progress is automatically saved to your browswer (session ID: " + response["id"] + ")";
|
||||
document.getElementById("session").innerHTML = "Progress is automatically saved to your browser (session ID: " + response["id"] + ")";
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
2
lib/sb
2
lib/sb
|
@ -1 +1 @@
|
|||
Subproject commit e168844fc5310581da43b32ac7ba8b2c2007a6e3
|
||||
Subproject commit a91bc4b773a0938f4f3984ce78d48d9ba70dec73
|
|
@ -957,7 +957,7 @@
|
|||
|
||||
{
|
||||
"curve": [
|
||||
[80, 244], [80, 244], [784, 244], [784, 244]
|
||||
[280, 244], [280, 244], [584, 244], [584, 244]
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
1130
src/Cakefoot.cpp
1130
src/Cakefoot.cpp
File diff suppressed because it is too large
Load Diff
250
src/Cakefoot.hpp
250
src/Cakefoot.hpp
|
@ -1,4 +1,8 @@
|
|||
/* >> Cakefoot << */
|
||||
/* _ _
|
||||
* c/a`k-e'f`o^o~t-, | a single-button action game | by @ooofoam
|
||||
* / _< | wow a living cake the sweet | play online: https://shampoo.ooo/cakefoot
|
||||
* _> `~_/ | taste of victory | open source: https://open.shampoo.ooo/shampoo/cakefoot
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -14,6 +18,8 @@
|
|||
#include <memory>
|
||||
#include <functional>
|
||||
#include <malloc.h>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
|
||||
/* Include Game.hpp before any other SDL-related headers because it defines SDL_MAIN_HANDLED */
|
||||
#include "Game.hpp"
|
||||
|
@ -53,6 +59,108 @@
|
|||
#include "Curve.hpp"
|
||||
#include "Enemy.hpp"
|
||||
|
||||
/*!
|
||||
* Container for a list of arcade scores that keeps scores sorted as they are added.
|
||||
*/
|
||||
class ArcadeScores
|
||||
{
|
||||
public:
|
||||
|
||||
struct Score
|
||||
{
|
||||
float time = 0.0f;
|
||||
int distance = 0;
|
||||
std::string name = "";
|
||||
std::time_t date;
|
||||
|
||||
Score(float time, int distance, const std::string& name = "") : time(time), distance(distance), name(name), date(std::time(nullptr)) {};
|
||||
Score() : Score(0.0f, 0) {};
|
||||
|
||||
bool operator >(const Score& other) const
|
||||
{
|
||||
return time > other.time || (time == other.time && distance > other.distance);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
std::vector<Score> scores;
|
||||
|
||||
public:
|
||||
|
||||
void add(const Score& incoming)
|
||||
{
|
||||
auto score = scores.begin();
|
||||
for (; score != scores.end(); score++) if (incoming > *score) break;
|
||||
scores.insert(score, incoming);
|
||||
}
|
||||
|
||||
int rank(const Score& other) const
|
||||
{
|
||||
std::size_t index = 0;
|
||||
for (; index < scores.size() && scores[index] > other; index++);
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
nlohmann::json json(const std::string& date_format) const
|
||||
{
|
||||
nlohmann::json json;
|
||||
for (const ArcadeScores::Score& score : scores)
|
||||
{
|
||||
std::ostringstream date;
|
||||
date << std::put_time(std::localtime(&score.date), date_format.c_str());
|
||||
|
||||
nlohmann::json entry = {
|
||||
{"name", score.name},
|
||||
{"time", score.time},
|
||||
{"distance", score.distance},
|
||||
{"date", date.str()}
|
||||
};
|
||||
|
||||
json.push_back(entry);
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
std::string formatted(int rows, int cols) const
|
||||
{
|
||||
std::size_t index = 0;
|
||||
std::string name;
|
||||
std::ostringstream text;
|
||||
for (int row = 0; row < rows; row++)
|
||||
{
|
||||
for (int col = 0; col < cols; col++)
|
||||
{
|
||||
std::ostringstream score;
|
||||
index = cols * col + row;
|
||||
if (index >= scores.size())
|
||||
{
|
||||
name = "---";
|
||||
score << "";
|
||||
}
|
||||
else
|
||||
{
|
||||
name = scores[index].name;
|
||||
if (scores[index].time > 0.0f)
|
||||
{
|
||||
score << std::setprecision(1) << std::fixed << scores[index].time;
|
||||
}
|
||||
else
|
||||
{
|
||||
score << scores[index].distance << "m";
|
||||
}
|
||||
}
|
||||
text << std::setw(2) << index + 1 << ". " << name << " " << std::setw(6) << score.str() << " ";
|
||||
if (col == cols - 1)
|
||||
{
|
||||
text << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
return text.str();
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* The main game object. There is currently only support for one of these to exist at a time.
|
||||
*
|
||||
|
@ -75,12 +183,16 @@ private:
|
|||
typedef sb::Game super;
|
||||
|
||||
/* Static members */
|
||||
inline static std::string reset_command_name = "reset";
|
||||
const inline static std::string progress_file_path = "storage/cakefoot_progress.json";
|
||||
const inline static std::string reset_command_name = "reset";
|
||||
const inline static fs::path progress_file_path = "storage/cakefoot_progress.json";
|
||||
const inline static fs::path arcade_scores_file_path = "storage/cakefoot_arcade_scores.json";
|
||||
const inline static fs::path levels_file_path = "resource/levels.json";
|
||||
const inline static std::string date_format = "%Y/%m/%d %H:%M";
|
||||
|
||||
/* Member vars */
|
||||
std::shared_ptr<SDL_Cursor> poke, grab;
|
||||
int previous_frames_per_second = 0, curve_index = 0, curve_byte_count = 0, level_index = 0, level_select_index = 1, profile_index = 0;
|
||||
int previous_frames_per_second = 0, curve_index = 0, curve_byte_count = 0, level_index = 0, level_select_index = 1, profile_index = 0,
|
||||
challenge_index = 0, view_index = 0, name_entry_index = 0;
|
||||
std::map<std::string, GLuint> uniform;
|
||||
GLuint shader_program;
|
||||
glm::mat4 view {1.0f}, projection {1.0f};
|
||||
|
@ -96,16 +208,36 @@ private:
|
|||
{"profile increment", sb::Pad<>()},
|
||||
{"profile decrement", sb::Pad<>()},
|
||||
{"volume", sb::Pad<>()},
|
||||
{"play", sb::Pad<>()}
|
||||
{"play", sb::Pad<>()},
|
||||
{"challenge increment", sb::Pad<>()},
|
||||
{"challenge decrement", sb::Pad<>()},
|
||||
{"view increment", sb::Pad<>()},
|
||||
{"view decrement", sb::Pad<>()},
|
||||
{"name 1", sb::Pad<>()},
|
||||
{"name 1 increment", sb::Pad<>()},
|
||||
{"name 1 decrement", sb::Pad<>()},
|
||||
{"name 2", sb::Pad<>()},
|
||||
{"name 2 increment", sb::Pad<>()},
|
||||
{"name 2 decrement", sb::Pad<>()},
|
||||
{"name 3", sb::Pad<>()},
|
||||
{"name 3 increment", sb::Pad<>()},
|
||||
{"name 3 decrement", sb::Pad<>()}
|
||||
};
|
||||
std::shared_ptr<TTF_Font> large_font {font(configuration()("display", "default font path").get<std::string>(), 72)},
|
||||
small_font {font(configuration()("display", "default font path").get<std::string>(), 12)};
|
||||
std::map<std::string, sb::Text> label = {
|
||||
{"fps", sb::Text(font())},
|
||||
{"clock", sb::Text(font())},
|
||||
{"level", sb::Text(font())},
|
||||
{"level select", sb::Text(font())},
|
||||
{"profile", sb::Text(font())}
|
||||
{"profile", sb::Text(font())},
|
||||
{"challenge", sb::Text(font())},
|
||||
{"view", sb::Text(font())},
|
||||
{"game over", sb::Text(font())},
|
||||
{"arcade rank", sb::Text(large_font)},
|
||||
{"arcade distance", sb::Text(large_font)}
|
||||
};
|
||||
sb::Sprite playing_field, checkpoint_on, checkpoint_off, coin {"resource/coin/coin-0.png", glm::vec2{12.0f / 486.0f}};
|
||||
sb::Sprite playing_field, checkpoint_on, checkpoint_off, coin {"resource/coin/coin-0.png", glm::vec2{12.0f / 486.0f}}, qr_code;
|
||||
sb::Timer on_timer, run_timer, unpaused_timer;
|
||||
glm::vec3 camera_position {0.0f, 0.0f, 2.0f}, subject_position {0.0f, 0.0f, 0.0f};
|
||||
float zoom = 0.0f;
|
||||
|
@ -116,7 +248,11 @@ private:
|
|||
std::map<std::string, std::shared_ptr<TTF_Font>> fonts;
|
||||
std::map<std::string, sb::audio::Chunk> audio;
|
||||
Character character {_configuration, audio};
|
||||
bool use_play_button = false;
|
||||
bool use_play_button = false, coin_collected = false;
|
||||
ArcadeScores arcade_scores;
|
||||
ArcadeScores::Score arcade_score;
|
||||
std::string name_entry = "AAA";
|
||||
sb::Text scoreboard {large_font};
|
||||
|
||||
/*!
|
||||
* Load sound effects and music into objects that can be used by the SDL mixer library. Use chunk objects for background music instead of
|
||||
|
@ -140,6 +276,11 @@ private:
|
|||
*/
|
||||
void set_up_buttons();
|
||||
|
||||
/*!
|
||||
* Respond to a change in index in the challenge spinner.
|
||||
*/
|
||||
void toggle_challenge();
|
||||
|
||||
/*!
|
||||
* Style the HUD elements based on the configuration settings. This can be re-run to apply changes made in the configuration.
|
||||
*/
|
||||
|
@ -151,10 +292,15 @@ private:
|
|||
void load_vbo();
|
||||
|
||||
/*!
|
||||
* @return the currently active curve
|
||||
* @return The current level's curve
|
||||
*/
|
||||
Curve& curve();
|
||||
|
||||
/*!
|
||||
* @return The current level's curve
|
||||
*/
|
||||
const Curve& curve() const;
|
||||
|
||||
/*!
|
||||
* Change the level to the given index. Load enemies, update the curve index.
|
||||
*
|
||||
|
@ -166,12 +312,94 @@ private:
|
|||
* Save the JSON in the `progress` field of Game::configuration to storage at Cakefoot::progress_file_path.
|
||||
*
|
||||
* For PC builds, the folder `storage/` will be created in the current working directory if it doesn't exist already. The user must have
|
||||
* permission to create folders in the directory. The file `progress.json` will also be created if necessary.
|
||||
* permission to create folders in the directory. The file `cakefoot_progress.json` will also be created if necessary.
|
||||
*
|
||||
* For web builds, Emscripten is used to abstract this function so that writing to a browser's Indexed DB is done automatically. The folder
|
||||
* `storage/` must have been mounted already using Emscripten's FS module.
|
||||
*/
|
||||
void write_progress();
|
||||
void write_progress() const;
|
||||
|
||||
/*!
|
||||
* Use the same procedure as Cakefoot::write_progress() to write arcade scores to a JSON file in `storage/cakefoot_arcade_scores.json`.
|
||||
*
|
||||
* @see Cakefoot::write_progress()
|
||||
*/
|
||||
void write_scores() const;
|
||||
|
||||
/*!
|
||||
* @return Sum of the lengths of all curves on all regular levels.
|
||||
*/
|
||||
int length() const;
|
||||
|
||||
/*!
|
||||
* @return The character's current distance from the beginning of the first level.
|
||||
*/
|
||||
int distance() const;
|
||||
|
||||
/*!
|
||||
* @return The time limit of the current run. Combines the challenge mode's initial limit with added time for completed levels and checkpoints.
|
||||
*/
|
||||
float limit() const;
|
||||
|
||||
/*!
|
||||
* @return True if arcade is the current mode
|
||||
*/
|
||||
bool arcade() const;
|
||||
|
||||
/*!
|
||||
* @return True if quest is the current mode
|
||||
*/
|
||||
bool quest() const;
|
||||
|
||||
/*!
|
||||
* @return True if level select is the current mode
|
||||
*/
|
||||
bool level_select() const;
|
||||
|
||||
/*!
|
||||
* Remove coin from the enemy and the level. If quest or arcade mode is active and flag is not set, add the coin to the appropriate bank.
|
||||
*
|
||||
* @param add_to_bank flag to either add to the bank or not
|
||||
*/
|
||||
void collect_coin(bool add_to_bank = true);
|
||||
|
||||
/*!
|
||||
* Move the level index to the end level, causing the game over state to end.
|
||||
*/
|
||||
void end_game_over_display();
|
||||
|
||||
/* This animation can be used to end the game over state after the time limit is reached. Play once with a delay to let the game over screen
|
||||
* display temporarily before being ended by this animation. */
|
||||
Animation game_over_animation {sb::Animation(std::bind(&Cakefoot::end_game_over_display, this))};
|
||||
|
||||
/*!
|
||||
* Write score, refresh scoreboard, and load the title screen
|
||||
*/
|
||||
void submit_score();
|
||||
|
||||
/* Can be used to time out the name entry screen */
|
||||
Animation submit_score_animation {sb::Animation(std::bind(&Cakefoot::submit_score, this))};
|
||||
|
||||
/*!
|
||||
* Get the arcade time as the amount of time remaining before the limit is reached.
|
||||
*
|
||||
* @param limit Time limit of arcade mode
|
||||
* @return Amount of time remaining in seconds
|
||||
*/
|
||||
float arcade_time_remaining(float limit) const;
|
||||
|
||||
/*!
|
||||
* Convert an amount of seconds to MMM:SS.sss format. The amount of minute digits will be as many as necessary.
|
||||
*
|
||||
* @param amount Amount in seconds to convert
|
||||
* @return String formatted to MMM:SS.sss
|
||||
*/
|
||||
static std::string format_clock(float amount);
|
||||
|
||||
/*!
|
||||
* Build a texture displaying the top 25 scores and assign the texture to the scoreboard sprite.
|
||||
*/
|
||||
void refresh_scoreboard();
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -33,7 +33,10 @@ bool Enemy::collide_coin(sb::Box box, const glm::vec3& clip_lower, const glm::ve
|
|||
|
||||
void Enemy::take_coin()
|
||||
{
|
||||
_coin_taken = true;
|
||||
if (_coin.has_value())
|
||||
{
|
||||
_coin_taken = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Enemy::coin_taken() const
|
||||
|
@ -43,7 +46,10 @@ bool Enemy::coin_taken() const
|
|||
|
||||
void Enemy::collect_coin()
|
||||
{
|
||||
coin_collected = true;
|
||||
if (_coin.has_value())
|
||||
{
|
||||
coin_collected = true;
|
||||
}
|
||||
}
|
||||
|
||||
Slicer::Slicer(const Curve& curve, float relative, float speed, float stray) : curve(curve), relative(relative), speed(speed), stray(stray)
|
||||
|
@ -304,7 +310,7 @@ bool Projectile::coinified() const
|
|||
return _coin.has_value();
|
||||
}
|
||||
|
||||
Projector::Projector(const Character& character, const glm::vec3& position, float speed, float rate, const double& release_delay) :
|
||||
Projector::Projector(const Character& character, const glm::vec3& position, float speed, float rate, float release_delay) :
|
||||
character(character), position(position), speed(speed), rate(rate), release_delay(release_delay)
|
||||
{
|
||||
animation_charge.frame_length(rate);
|
||||
|
|
|
@ -293,7 +293,7 @@ private:
|
|||
const Character& character;
|
||||
glm::vec3 position = glm::vec3{0.0f};
|
||||
float speed = 0.0f, rate = 0.0f;
|
||||
const double& release_delay;
|
||||
float release_delay;
|
||||
sb::Sprite sprite;
|
||||
sb::Animation animation_charge = sb::Animation(std::bind(&Projector::charge, this)),
|
||||
animation_release = sb::Animation(std::bind(&Projector::release, this));
|
||||
|
@ -316,7 +316,7 @@ public:
|
|||
* @param rate amount of seconds between each projectile
|
||||
* @param release_delay amount in seconds between charge and release
|
||||
*/
|
||||
Projector(const Character& character, const glm::vec3& position, float speed = 0.51440329f, float rate = 3.0f, const double& release_delay = 0.3);
|
||||
Projector(const Character& character, const glm::vec3& position, float speed = 0.51440329f, float rate = 3.0f, float release_delay = 0.3f);
|
||||
|
||||
/*!
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue