integrate ads API on coolmath builds, add loading message
This commit is contained in:
parent
63336a3126
commit
9fa8051b06
9
Makefile
9
Makefile
|
@ -138,7 +138,7 @@ $(addsuffix /Attributes.o, $(BUILD_DIRS)): $(addprefix $(SB_SRC_DIR)/, Attribute
|
|||
$(addsuffix /Model.o, $(BUILD_DIRS)): $(addprefix $(SB_SRC_DIR)/, Model.cpp Model.hpp extension.hpp Attributes.hpp Texture.hpp Carousel.hpp) | $(BUILD_DIRS)
|
||||
$(CXX) $(CXXFLAGS) $< -c -o $@
|
||||
|
||||
$(addsuffix /Text.o, $(BUILD_DIRS)): $(addprefix $(SB_SRC_DIR)/, Text.cpp Text.hpp Model.hpp Color.hpp Log.hpp) | $(BUILD_DIRS)
|
||||
$(addsuffix /Text.o, $(BUILD_DIRS)): $(addprefix $(SB_SRC_DIR)/, Text.cpp Text.hpp Model.hpp Color.hpp Log.hpp Texture.hpp) | $(BUILD_DIRS)
|
||||
$(CXX) $(CXXFLAGS) $< -c -o $@
|
||||
|
||||
$(addsuffix /Color.o, $(BUILD_DIRS)): $(addprefix $(SB_SRC_DIR)/, Color.cpp Color.hpp) | $(BUILD_DIRS)
|
||||
|
@ -199,8 +199,8 @@ Cakefoot-linux_debug.x86_64 : $(LINUX_DEBUG_OBJ)
|
|||
EMSCRIPTENHOME = $(HOME)/ext/software/emsdk/upstream/emscripten
|
||||
EMSCRIPTEN_CFLAGS = -Oz -Wall -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS="['png', 'jpg']" -s USE_SDL_TTF=2 -s USE_SDL_MIXER=2 \
|
||||
-I $(SB_LIB_DIR) -I $(SB_SRC_DIR)
|
||||
EMSCRIPTEN_LFLAGS = -s MIN_WEBGL_VERSION=2 -s EXPORTED_FUNCTIONS="['_main', '_malloc']" -s LLD_REPORT_UNDEFINED -s NO_DISABLE_EXCEPTION_CATCHING \
|
||||
-s FULL_ES3=1 -lidbfs.js -s ALLOW_MEMORY_GROWTH=1
|
||||
EMSCRIPTEN_LFLAGS = -s MIN_WEBGL_VERSION=2 -s EXPORTED_FUNCTIONS="['_main', '_malloc', '_pause_for_ads', '_unpause_for_ads']" -s LLD_REPORT_UNDEFINED \
|
||||
-s NO_DISABLE_EXCEPTION_CATCHING -s FULL_ES3=1 -lidbfs.js -s ALLOW_MEMORY_GROWTH=1
|
||||
EMSCRIPTEN_PRELOADS = --preload-file "config.json" --preload-file "resource/" --preload-file "src/shaders/" --preload-file "src/config_wasm.json" \
|
||||
--pre-js "src/pre_js.js"
|
||||
EMSCRIPTEN_GAME_CONFIGS = config.json src/config_wasm.json resource/levels.json
|
||||
|
@ -230,6 +230,9 @@ cakefoot_coolmath.js : $(addprefix $(WASM_COOLMATH_BUILD_DIR)/, SDL2_rotozoom.o
|
|||
$(CXX) $(filter-out $(EMSCRIPTEN_GAME_CONFIGS), $^) $(CXXFLAGS) $(EMSCRIPTEN_LFLAGS) -D__COOLMATH__ $(EMSCRIPTEN_PRELOADS) \
|
||||
--preload-file "src/config_coolmath.json" -o $(WASM_COOLMATH_BUILD_DIR)/$@
|
||||
cp src/index_coolmath.html $(WASM_COOLMATH_BUILD_DIR)/index.html
|
||||
cd $(WASM_COOLMATH_BUILD_DIR) && \
|
||||
zip -r Cakefoot_coolmath.zip cakefoot_coolmath.data cakefoot_coolmath.js cakefoot_coolmath.wasm index.html && \
|
||||
rm cakefoot_coolmath.data cakefoot_coolmath.js cakefoot_coolmath.wasm index.html && cd -
|
||||
|
||||
#################
|
||||
# Android build #
|
||||
|
|
|
@ -70,10 +70,19 @@
|
|||
padding: 0% 1%;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
p#loading
|
||||
{
|
||||
font-size: 72px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p id="loading">
|
||||
Loading...
|
||||
</p>
|
||||
|
||||
<!-- Emscripten's module object will update this canvas with WebGL content. -->
|
||||
<canvas id="canvas"></canvas>
|
||||
|
||||
|
|
2
lib/sb
2
lib/sb
|
@ -1 +1 @@
|
|||
Subproject commit 11c8abcc5441db15dbdcbb9cce8c42fc37803607
|
||||
Subproject commit 1fff973b46684277e34c2a78ab857fa4766ca5e5
|
109
src/Cakefoot.cpp
109
src/Cakefoot.cpp
|
@ -140,8 +140,8 @@ Cakefoot::Cakefoot(std::initializer_list<std::string> configuration_merge) : Gam
|
|||
character.profile(configuration()("character", "profile", profile_index, "name"));
|
||||
|
||||
/* Set up checkpoint on and off sprites */
|
||||
checkpoint_on = sb::Sprite {"resource/checkpoint/on.png", glm::vec2(12.0f / 486.0f)};
|
||||
checkpoint_off = sb::Sprite {"resource/checkpoint/off.png", glm::vec2(12.0f / 486.0f)};
|
||||
checkpoint_on = sb::Sprite {"resource/checkpoint/on.png", glm::vec2(12.0f / 486.0f), GL_LINEAR};
|
||||
checkpoint_off = sb::Sprite {"resource/checkpoint/off.png", glm::vec2(12.0f / 486.0f), GL_LINEAR};
|
||||
|
||||
/* Set hitbox */
|
||||
character.box_size(configuration()("character", "hitbox").get<float>());
|
||||
|
@ -439,6 +439,10 @@ void Cakefoot::set_up_buttons()
|
|||
challenge_index = 3;
|
||||
configuration()["progress"]["current challenge"] = challenge_index;
|
||||
}
|
||||
#if defined(__COOLMATH__)
|
||||
/* Coolmath API */
|
||||
EM_ASM( if (parent.cmgGameEvent !== undefined) { console.log("cmgGameEvent start"); parent.cmgGameEvent("start"); } );
|
||||
#endif
|
||||
load_level(level_select_index);
|
||||
});
|
||||
button.at("resume").on_state_change([&](bool state){
|
||||
|
@ -1366,6 +1370,21 @@ void Cakefoot::load_level(int index)
|
|||
|
||||
/* Flash the screen at the start of a level */
|
||||
flash_animation.play_once(configuration()("display", "flash length"));
|
||||
|
||||
#if defined(__COOLMATH__)
|
||||
/* Send a game event to the Coolmath API if it's a regular level. */
|
||||
if (index > 0 && static_cast<std::size_t>(index) < configuration()("levels").size() - 1)
|
||||
{
|
||||
EM_ASM(
|
||||
{
|
||||
if (parent.cmgGameEvent !== undefined)
|
||||
{
|
||||
console.log("cmgGameEvent start " + $0);
|
||||
parent.cmgGameEvent("start", $0);
|
||||
}
|
||||
}, index);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Cakefoot::write_progress() const
|
||||
|
@ -2082,6 +2101,55 @@ void Cakefoot::respond(SDL_Event& event)
|
|||
}
|
||||
}
|
||||
|
||||
else if (sb::Delegate::compare(event, "pause for ads"))
|
||||
{
|
||||
/* Store current volume to be restored when returning from ads by looking at the state of the button. */
|
||||
if (button.at("volume").pressed())
|
||||
{
|
||||
pre_ad_volume = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
pre_ad_volume = 0.0f;
|
||||
}
|
||||
std::ostringstream message;
|
||||
message << "Pre-ad volume registered as " << pre_ad_volume.value();
|
||||
sb::Log::log(message);
|
||||
|
||||
/* Mute without changing the state of the button to avoid losing the original state if this event is fired twice in a row. */
|
||||
Mix_Volume(-1, 0);
|
||||
|
||||
if (level_index > 0 && static_cast<std::size_t>(level_index) <= configuration()("levels").size() - 2)
|
||||
{
|
||||
/* Pause game */
|
||||
unpaused_timer.off();
|
||||
run_timer.off();
|
||||
}
|
||||
}
|
||||
|
||||
else if (sb::Delegate::compare(event, "unpause for ads"))
|
||||
{
|
||||
/* Restore volume to the volume of the mixer before the ads started */
|
||||
std::ostringstream message;
|
||||
if (pre_ad_volume.has_value())
|
||||
{
|
||||
Mix_Volume(-1, sb::audio::convert_volume(pre_ad_volume.value()));
|
||||
message << "Restoring volume to " << pre_ad_volume.value();
|
||||
}
|
||||
else
|
||||
{
|
||||
message << "Not restoring volume because pre-ad value was not registered";
|
||||
}
|
||||
sb::Log::log(message);
|
||||
|
||||
if (level_index > 0 && static_cast<std::size_t>(level_index) <= configuration()("levels").size() - 2)
|
||||
{
|
||||
/* Unpause game */
|
||||
unpaused_timer.on();
|
||||
run_timer.on();
|
||||
}
|
||||
}
|
||||
|
||||
else if (sb::Delegate::compare(event, "reconfig"))
|
||||
{
|
||||
load_curves();
|
||||
|
@ -2353,6 +2421,14 @@ void Cakefoot::update(float timestamp)
|
|||
/* Load next level, or reload current level if in level select mode or on title screen */
|
||||
audio.at("teleport").play();
|
||||
load_level(level_select() || level_index == 0 ? level_index : level_index + 1);
|
||||
|
||||
#if defined(__COOLMATH__)
|
||||
/* Trigger an ad when a level is beaten */
|
||||
if (level_index > 0 && static_cast<std::size_t>(level_index) < configuration()("levels").size() - 1)
|
||||
{
|
||||
EM_ASM(cmgAdBreak());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2380,9 +2456,7 @@ void Cakefoot::update(float timestamp)
|
|||
configuration()["progress"]["quest checkpoint"] = character.checkpoint();
|
||||
}
|
||||
write_progress();
|
||||
}
|
||||
}
|
||||
}
|
||||
} } }
|
||||
|
||||
/* Collide with enemies and challenge coins */
|
||||
bool enemy_collision = false;
|
||||
|
@ -2398,8 +2472,7 @@ void Cakefoot::update(float timestamp)
|
|||
{
|
||||
audio.at("take").play();
|
||||
enemy->take_coin();
|
||||
}
|
||||
}
|
||||
} }
|
||||
|
||||
/* Collide with ending screen coins */
|
||||
if (end_screen())
|
||||
|
@ -2433,9 +2506,7 @@ void Cakefoot::update(float timestamp)
|
|||
/* Record a death */
|
||||
configuration()["progress"]["deaths"].get_ref<nlohmann::json::number_integer_t&>()++;
|
||||
write_progress();
|
||||
}
|
||||
}
|
||||
}
|
||||
} } }
|
||||
|
||||
/* Plane position vertices will be used for everything before the curve */
|
||||
sb::Plane::position->bind("vertex_position", shader_program);
|
||||
|
@ -2729,8 +2800,7 @@ void Cakefoot::update(float timestamp)
|
|||
y += configuration()("ending", "messages margin").get<float>();
|
||||
}
|
||||
y += configuration()("ending", "messages step").get<float>();
|
||||
}
|
||||
}
|
||||
} }
|
||||
|
||||
/* Update FPS indicator display to the current FPS count and draw. */
|
||||
if (configuration()["display"]["fps"])
|
||||
|
@ -2800,6 +2870,21 @@ EM_BOOL respond_to_gamepad_connected(int event_type, const EmscriptenGamepadEven
|
|||
game->open_game_controller();
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
void pause_for_ads()
|
||||
{
|
||||
sb::Delegate::post("pause for ads", false);
|
||||
}
|
||||
|
||||
void unpause_for_ads()
|
||||
{
|
||||
sb::Delegate::post("unpause for ads", false);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
int main()
|
||||
|
|
|
@ -244,7 +244,7 @@ private:
|
|||
{"arcade distance", sb::Text(fonts.at("large"))},
|
||||
{"quest best", sb::Text(fonts.at("glyph"))}
|
||||
};
|
||||
sb::Sprite playing_field, checkpoint_on, checkpoint_off, coin {"resource/coin/coin-0.png", glm::vec2{12.0f / 486.0f}}, qr_code, qr_code_bg, social;
|
||||
sb::Sprite playing_field, checkpoint_on, checkpoint_off, coin {"resource/coin/coin-0.png", glm::vec2{12.0f / 486.0f}, GL_LINEAR}, qr_code, qr_code_bg, social;
|
||||
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;
|
||||
|
@ -264,6 +264,7 @@ private:
|
|||
std::vector<sb::Text> ending_messages;
|
||||
std::optional<std::string> selected;
|
||||
std::shared_ptr<SDL_GameController> controller = nullptr;
|
||||
std::optional<float> pre_ad_volume = std::nullopt;
|
||||
|
||||
/*!
|
||||
* Load sound effects and music into objects that can be used by the SDL mixer library. Use chunk objects for background music instead of
|
||||
|
@ -547,6 +548,24 @@ EM_BOOL respond_to_visibility_change(int event_type, const EmscriptenVisibilityC
|
|||
* @return True to indicate that the event was consumed by the handler
|
||||
*/
|
||||
EM_BOOL respond_to_gamepad_connected(int event_type, const EmscriptenGamepadEvent* gamepad_event, void* user_data);
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
* Custom pause event for use with ad APIs that posts a "pause for ads" event using sb::Delegate::post(const std::string&, bool). This function will
|
||||
* be exported for use in the JavaScript code in* a web build and is not available in other types of builds.
|
||||
*/
|
||||
void pause_for_ads();
|
||||
|
||||
/*!
|
||||
* Custom pause event for use with ad APIs that posts a "unpause for ads" event using sb::Delegate::post(const std::string&, bool). This function will
|
||||
* be exported for use in the JavaScript code in a web build and is not available in other types of builds.
|
||||
*/
|
||||
void unpause_for_ads();
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
|
|
|
@ -15,9 +15,9 @@ void Character::profile(const std::string& name)
|
|||
/* Reload the texture */
|
||||
_sprite.clear_textures();
|
||||
nlohmann::json frames = configuration("progress", "jackpot") == 777 ? configuration("character", "jackpot frames") : profile().at("animation frames");
|
||||
for (const std::string& path : frames)
|
||||
for (const std::string path : frames)
|
||||
{
|
||||
_sprite.texture(path);
|
||||
_sprite.texture(path, GL_LINEAR);
|
||||
}
|
||||
_sprite.scale(size);
|
||||
}
|
||||
|
|
|
@ -66,8 +66,8 @@ void Enemy::draw(GLuint transformation_uniform, const glm::mat4& view, const glm
|
|||
Slicer::Slicer(const Curve& curve, float relative, float speed, float stray) : curve(curve), relative(relative), speed(speed), stray(stray)
|
||||
{
|
||||
position = start();
|
||||
sprite.texture("resource/slicer/slicer-1.png");
|
||||
sprite.texture("resource/slicer/slicer-2.png");
|
||||
sprite.texture("resource/slicer/slicer-1.png", GL_LINEAR);
|
||||
sprite.texture("resource/slicer/slicer-2.png", GL_LINEAR);
|
||||
sprite.frames.frame_length(0.5f);
|
||||
sprite.frames.play();
|
||||
|
||||
|
@ -171,8 +171,8 @@ bool Slicer::collide_coin(sb::Box box, const glm::vec3& clip_lower, const glm::v
|
|||
Fish::Fish(const Curve& curve, float relative, float speed, float radius, float offset) :
|
||||
curve(curve), relative(relative), speed(speed), radius(radius), offset(offset)
|
||||
{
|
||||
sprite.texture("resource/fish/fish-1.png");
|
||||
sprite.texture("resource/fish/fish-2.png");
|
||||
sprite.texture("resource/fish/fish-1.png", GL_LINEAR);
|
||||
sprite.texture("resource/fish/fish-2.png", GL_LINEAR);
|
||||
sprite.frames.frame_length(0.3f);
|
||||
sprite.frames.play();
|
||||
|
||||
|
@ -257,10 +257,10 @@ Projectile::Projectile(const glm::vec3& position, const glm::vec3& target, float
|
|||
angle = sb::angle_between(position, target);
|
||||
|
||||
/* Initialize sprite */
|
||||
sprite.texture("resource/projectile/projectile-1.png");
|
||||
sprite.texture("resource/projectile/projectile-2.png");
|
||||
sprite.texture("resource/projectile/projectile-3.png");
|
||||
sprite.texture("resource/projectile/projectile-4.png");
|
||||
sprite.texture("resource/projectile/projectile-1.png", GL_LINEAR);
|
||||
sprite.texture("resource/projectile/projectile-2.png", GL_LINEAR);
|
||||
sprite.texture("resource/projectile/projectile-3.png", GL_LINEAR);
|
||||
sprite.texture("resource/projectile/projectile-4.png", GL_LINEAR);
|
||||
sprite.frames.frame_length(0.05f);
|
||||
sprite.frames.play();
|
||||
|
||||
|
@ -324,11 +324,11 @@ bool Projectile::coinified() const
|
|||
}
|
||||
|
||||
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)
|
||||
character(character), position(position), speed(speed), release_delay(release_delay)
|
||||
{
|
||||
animation_charge.frame_length(rate);
|
||||
sprite.texture("resource/projector/projector-1.png");
|
||||
sprite.texture("resource/projector/projector-2.png");
|
||||
sprite.texture("resource/projector/projector-1.png", GL_LINEAR);
|
||||
sprite.texture("resource/projector/projector-2.png", GL_LINEAR);
|
||||
|
||||
/* Set size and position of objects */
|
||||
glm::vec2 size {12.0f / 486.0f};
|
||||
|
@ -474,12 +474,12 @@ Flame::Flame(const sb::Box& field, const glm::vec3& position, float speed, float
|
|||
/* Set up animation */
|
||||
if (!camo)
|
||||
{
|
||||
sprite.texture("resource/flame/flame-1.png");
|
||||
sprite.texture("resource/flame/flame-2.png");
|
||||
sprite.texture("resource/flame/flame-1.png", GL_LINEAR);
|
||||
sprite.texture("resource/flame/flame-2.png", GL_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite.texture("resource/coin/coin-0.png");
|
||||
sprite.texture("resource/coin/coin-0.png", GL_LINEAR);
|
||||
}
|
||||
sprite.frames.frame_length(0.3f);
|
||||
sprite.frames.play();
|
||||
|
|
|
@ -286,7 +286,7 @@ private:
|
|||
|
||||
const Character& character;
|
||||
glm::vec3 position = glm::vec3{0.0f};
|
||||
float speed = 0.0f, rate = 0.0f;
|
||||
float speed = 0.0f;
|
||||
float release_delay;
|
||||
sb::Animation animation_charge = sb::Animation(std::bind(&Projector::charge, this)),
|
||||
animation_release = sb::Animation(std::bind(&Projector::release, this));
|
||||
|
|
|
@ -1,6 +1,17 @@
|
|||
{
|
||||
"display":
|
||||
{
|
||||
"title": "cakefoot🍰👣 – Play it now at CoolmathGames.com"
|
||||
"dimensions": [800, 450],
|
||||
"title": "cakefoot🍰👣 – Play it now at CoolmathGames.com",
|
||||
"fullscreen enabled": false
|
||||
},
|
||||
|
||||
"keys":
|
||||
{
|
||||
"reset": [],
|
||||
"skip forward": [],
|
||||
"skip backward": [],
|
||||
"memory": [],
|
||||
"coords": []
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,14 +21,40 @@
|
|||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
|
||||
p#loading
|
||||
{
|
||||
font-size: 16px;
|
||||
background: #000;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p id="loading">
|
||||
Loading...
|
||||
</p>
|
||||
|
||||
<!-- Emscripten's module object will update this canvas with WebGL content. -->
|
||||
<canvas id="canvas"></canvas>
|
||||
|
||||
<!-- This file is built by Emscripten when compiling the program -->
|
||||
<script src="cakefoot_coolmath.js"></script>
|
||||
|
||||
<!-- Coolmath API requirements -->
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="https://www.coolmathgames.com/sites/default/files/cmg-ads.js"></script>
|
||||
|
||||
<!-- Coolmath API custom events. Pause/unpause the game for ads -->
|
||||
<script>
|
||||
document.addEventListener("adBreakStart", () => {
|
||||
console.log("AdBreak Started")
|
||||
_pause_for_ads();
|
||||
});
|
||||
document.addEventListener("adBreakComplete", () => {
|
||||
console.log("adBreak Complete")
|
||||
_unpause_for_ads();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -26,6 +26,7 @@ Module.onRuntimeInitialized = function()
|
|||
}
|
||||
else
|
||||
{
|
||||
document.getElementById("loading").remove();
|
||||
_main();
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue