Impl. "hacking" a "Walker"
All checks were successful
Build and Publish WASM version of demo / Build-And-Deploy (push) Successful in 21s
All checks were successful
Build and Publish WASM version of demo / Build-And-Deploy (push) Successful in 21s
The "hack" is to press a button in a time limit after clicking on a Walker's head. If successful, the player can control the Walker. On failure, nothing happens.
This commit is contained in:
parent
17aa7f6860
commit
d7d1d4d7a0
10 changed files with 346 additions and 27 deletions
6
Makefile
6
Makefile
|
@ -19,7 +19,8 @@ SOURCES = \
|
||||||
src/raymath.cc \
|
src/raymath.cc \
|
||||||
src/ems.cc \
|
src/ems.cc \
|
||||||
src/walker.cc \
|
src/walker.cc \
|
||||||
src/surface_triangle.cc
|
src/surface_triangle.cc \
|
||||||
|
src/screen_walker_hack.cc
|
||||||
|
|
||||||
HEADERS = \
|
HEADERS = \
|
||||||
src/game.h \
|
src/game.h \
|
||||||
|
@ -29,7 +30,8 @@ HEADERS = \
|
||||||
src/3d_helpers.h \
|
src/3d_helpers.h \
|
||||||
src/ems.h \
|
src/ems.h \
|
||||||
src/walker.h \
|
src/walker.h \
|
||||||
src/surface_triangle.h
|
src/surface_triangle.h\
|
||||||
|
src/screen_walker_hack.h
|
||||||
|
|
||||||
OBJECTS = $(addprefix ${OBJDIR}/,$(subst .cc,.cc.o,${SOURCES}))
|
OBJECTS = $(addprefix ${OBJDIR}/,$(subst .cc,.cc.o,${SOURCES}))
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
// standard library includes
|
// standard library includes
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -45,9 +47,19 @@ ScreenStack::Ptr ScreenStack::new_instance() {
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScreenStack::~ScreenStack() {
|
||||||
|
UnloadRenderTexture(*render_texture);
|
||||||
|
render_texture.reset();
|
||||||
|
}
|
||||||
|
|
||||||
void ScreenStack::update(float dt) {
|
void ScreenStack::update(float dt) {
|
||||||
handle_pending_actions();
|
handle_pending_actions();
|
||||||
|
|
||||||
|
bool resized = IsWindowResized();
|
||||||
|
if (resized) {
|
||||||
|
reset_render_texture();
|
||||||
|
}
|
||||||
|
|
||||||
auto idx = stack.size();
|
auto idx = stack.size();
|
||||||
if (idx == 0) {
|
if (idx == 0) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -57,14 +69,21 @@ void ScreenStack::update(float dt) {
|
||||||
update(dt);
|
update(dt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (idx > 0 && stack.at(--idx)->update(dt)) {
|
while (idx > 0 && stack.at(--idx)->update(dt, resized)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenStack::draw() {
|
void ScreenStack::draw() {
|
||||||
for (decltype(stack.size()) idx = 0;
|
for (decltype(stack.size()) idx = 0;
|
||||||
idx < stack.size() && stack.at(idx)->draw(); ++idx) {
|
idx < stack.size() && stack.at(idx)->draw(render_texture.get()); ++idx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
DrawTextureRec(
|
||||||
|
render_texture->texture,
|
||||||
|
Rectangle{0, 0, (float)GetScreenWidth(), (float)-GetScreenHeight()},
|
||||||
|
{0, 0}, WHITE);
|
||||||
|
EndDrawing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenStack::push_screen(Screen::Ptr &&screen) {
|
void ScreenStack::push_screen(Screen::Ptr &&screen) {
|
||||||
|
@ -79,7 +98,16 @@ void ScreenStack::clear_screens() {
|
||||||
actions.push_back(PendingAction(Action::CLEAR_SCREENS));
|
actions.push_back(PendingAction(Action::CLEAR_SCREENS));
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenStack::ScreenStack() : self_weak(), stack(), actions() {}
|
void ScreenStack::reset_render_texture() {
|
||||||
|
UnloadRenderTexture(*render_texture);
|
||||||
|
|
||||||
|
*render_texture = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenStack::ScreenStack()
|
||||||
|
: render_texture(new RenderTexture), self_weak(), stack(), actions() {
|
||||||
|
*render_texture = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
||||||
|
}
|
||||||
|
|
||||||
void ScreenStack::handle_pending_actions() {
|
void ScreenStack::handle_pending_actions() {
|
||||||
while (!actions.empty()) {
|
while (!actions.empty()) {
|
||||||
|
|
33
src/screen.h
33
src/screen.h
|
@ -1,14 +1,17 @@
|
||||||
#ifndef JUMPARTIFACT_DOT_COM_DEMO_0_SCREEN_H_
|
#ifndef JUMPARTIFACT_DOT_COM_DEMO_0_SCREEN_H_
|
||||||
#define JUMPARTIFACT_DOT_COM_DEMO_0_SCREEN_H_
|
#define JUMPARTIFACT_DOT_COM_DEMO_0_SCREEN_H_
|
||||||
|
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// Forward declaration.
|
// Forward declarations.
|
||||||
class ScreenStack;
|
class ScreenStack;
|
||||||
|
struct RenderTexture;
|
||||||
|
|
||||||
class Screen {
|
class Screen {
|
||||||
public:
|
public:
|
||||||
|
@ -17,6 +20,9 @@ class Screen {
|
||||||
template <typename SubScreen>
|
template <typename SubScreen>
|
||||||
static Ptr new_screen(std::weak_ptr<ScreenStack> stack);
|
static Ptr new_screen(std::weak_ptr<ScreenStack> stack);
|
||||||
|
|
||||||
|
template <typename SubScreen, typename... Args>
|
||||||
|
static Ptr new_screen_args(std::weak_ptr<ScreenStack> stack, Args... args);
|
||||||
|
|
||||||
virtual ~Screen() {}
|
virtual ~Screen() {}
|
||||||
|
|
||||||
// No copy.
|
// No copy.
|
||||||
|
@ -28,9 +34,9 @@ class Screen {
|
||||||
Screen& operator=(Screen&&) = default;
|
Screen& operator=(Screen&&) = default;
|
||||||
|
|
||||||
/// Return true if next screen should be updated.
|
/// Return true if next screen should be updated.
|
||||||
virtual bool update(float dt) = 0;
|
virtual bool update(float dt, bool screen_resized) = 0;
|
||||||
/// Return true if next screen should be drawn.
|
/// Return true if next screen should be drawn.
|
||||||
virtual bool draw() = 0;
|
virtual bool draw(RenderTexture* renderTexture) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Screen(std::weak_ptr<ScreenStack> stack);
|
Screen(std::weak_ptr<ScreenStack> stack);
|
||||||
|
@ -67,6 +73,8 @@ class ScreenStack {
|
||||||
public:
|
public:
|
||||||
static Ptr new_instance();
|
static Ptr new_instance();
|
||||||
|
|
||||||
|
~ScreenStack();
|
||||||
|
|
||||||
// No copy.
|
// No copy.
|
||||||
ScreenStack(const ScreenStack&) = delete;
|
ScreenStack(const ScreenStack&) = delete;
|
||||||
ScreenStack& operator=(const ScreenStack&) = delete;
|
ScreenStack& operator=(const ScreenStack&) = delete;
|
||||||
|
@ -86,15 +94,21 @@ class ScreenStack {
|
||||||
template <typename SubScreen>
|
template <typename SubScreen>
|
||||||
void push_constructing_screen();
|
void push_constructing_screen();
|
||||||
|
|
||||||
|
template <typename SubScreen, typename... Args>
|
||||||
|
void push_constructing_screen_args(Args... args);
|
||||||
|
|
||||||
void pop_screen();
|
void pop_screen();
|
||||||
|
|
||||||
void clear_screens();
|
void clear_screens();
|
||||||
|
|
||||||
|
void reset_render_texture();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ScreenStack();
|
ScreenStack();
|
||||||
|
|
||||||
void handle_pending_actions();
|
void handle_pending_actions();
|
||||||
|
|
||||||
|
std::unique_ptr<RenderTexture> render_texture;
|
||||||
Weak self_weak;
|
Weak self_weak;
|
||||||
std::vector<Screen::Ptr> stack;
|
std::vector<Screen::Ptr> stack;
|
||||||
std::deque<PendingAction> actions;
|
std::deque<PendingAction> actions;
|
||||||
|
@ -105,6 +119,12 @@ Screen::Ptr Screen::new_screen(std::weak_ptr<ScreenStack> stack) {
|
||||||
return std::unique_ptr<SubScreen>(new SubScreen{stack});
|
return std::unique_ptr<SubScreen>(new SubScreen{stack});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename SubScreen, typename... Args>
|
||||||
|
Screen::Ptr Screen::new_screen_args(std::weak_ptr<ScreenStack> stack,
|
||||||
|
Args... args) {
|
||||||
|
return std::unique_ptr<SubScreen>(new SubScreen{stack, args...});
|
||||||
|
}
|
||||||
|
|
||||||
template <typename SubScreen>
|
template <typename SubScreen>
|
||||||
void ScreenStack::push_screen() {
|
void ScreenStack::push_screen() {
|
||||||
actions.emplace_back(Screen::new_screen<SubScreen>(self_weak));
|
actions.emplace_back(Screen::new_screen<SubScreen>(self_weak));
|
||||||
|
@ -117,4 +137,11 @@ void ScreenStack::push_constructing_screen() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename SubScreen, typename... Args>
|
||||||
|
void ScreenStack::push_constructing_screen_args(Args... args) {
|
||||||
|
actions.emplace_back([args...](ScreenStack::Weak ss) -> Screen::Ptr {
|
||||||
|
return Screen::new_screen_args<SubScreen>(ss, args...);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,19 +10,19 @@ TestScreen::TestScreen(ScreenStack::Weak weak_ptr)
|
||||||
: Screen(weak_ptr), TEMP_cached_dt(0.0F) {}
|
: Screen(weak_ptr), TEMP_cached_dt(0.0F) {}
|
||||||
TestScreen::~TestScreen() {}
|
TestScreen::~TestScreen() {}
|
||||||
|
|
||||||
bool TestScreen::update(float dt) {
|
bool TestScreen::update(float dt, bool) {
|
||||||
TEMP_cached_dt = dt;
|
TEMP_cached_dt = dt;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TestScreen::draw() {
|
bool TestScreen::draw(RenderTexture *render_texture) {
|
||||||
std::string dt_string =
|
std::string dt_string =
|
||||||
std::string("Delta-time: ") + std::to_string(TEMP_cached_dt);
|
std::string("Delta-time: ") + std::to_string(TEMP_cached_dt);
|
||||||
|
|
||||||
BeginDrawing();
|
BeginTextureMode(*render_texture);
|
||||||
ClearBackground(BLACK);
|
ClearBackground(BLACK);
|
||||||
DrawText("Testing...", 100, 100, 30, RAYWHITE);
|
DrawText("Testing...", 100, 100, 30, RAYWHITE);
|
||||||
DrawText(dt_string.c_str(), 100, 140, 30, RAYWHITE);
|
DrawText(dt_string.c_str(), 100, 140, 30, RAYWHITE);
|
||||||
EndDrawing();
|
EndTextureMode();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ class TestScreen : public Screen {
|
||||||
TestScreen(ScreenStack::Weak weak_ptr);
|
TestScreen(ScreenStack::Weak weak_ptr);
|
||||||
~TestScreen() override;
|
~TestScreen() override;
|
||||||
|
|
||||||
bool update(float dt) override;
|
bool update(float dt, bool is_resized) override;
|
||||||
bool draw() override;
|
bool draw(RenderTexture *render_texture) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float TEMP_cached_dt;
|
float TEMP_cached_dt;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
// local includes
|
// local includes
|
||||||
#include "3d_helpers.h"
|
#include "3d_helpers.h"
|
||||||
#include "ems.h"
|
#include "ems.h"
|
||||||
|
#include "screen_walker_hack.h"
|
||||||
|
|
||||||
TRunnerScreen::TRunnerScreen(std::weak_ptr<ScreenStack> stack)
|
TRunnerScreen::TRunnerScreen(std::weak_ptr<ScreenStack> stack)
|
||||||
: Screen(stack),
|
: Screen(stack),
|
||||||
|
@ -55,7 +56,8 @@ TRunnerScreen::TRunnerScreen(std::weak_ptr<ScreenStack> stack)
|
||||||
right_text_width(MeasureText("Right", BUTTON_FONT_SIZE)),
|
right_text_width(MeasureText("Right", BUTTON_FONT_SIZE)),
|
||||||
forward_text_width(MeasureText("Forward", BUTTON_FONT_SIZE)),
|
forward_text_width(MeasureText("Forward", BUTTON_FONT_SIZE)),
|
||||||
reset_surface_text_width(MeasureText("Reset Surface", BUTTON_FONT_SIZE)),
|
reset_surface_text_width(MeasureText("Reset Surface", BUTTON_FONT_SIZE)),
|
||||||
surface_reset_anim_timer(0.0F) {
|
surface_reset_anim_timer(0.0F),
|
||||||
|
walker_hack_success(false) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
std::cout << "idx_hit initialized to " << idx_hit << std::endl;
|
std::cout << "idx_hit initialized to " << idx_hit << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
@ -85,8 +87,8 @@ TRunnerScreen::~TRunnerScreen() {
|
||||||
UnloadModel(TEMP_cube_model);
|
UnloadModel(TEMP_cube_model);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TRunnerScreen::update(float dt) {
|
bool TRunnerScreen::update(float dt, bool is_resized) {
|
||||||
if (IsWindowResized()) {
|
if (is_resized) {
|
||||||
UnloadRenderTexture(fgRenderTexture);
|
UnloadRenderTexture(fgRenderTexture);
|
||||||
UnloadRenderTexture(bgRenderTexture);
|
UnloadRenderTexture(bgRenderTexture);
|
||||||
|
|
||||||
|
@ -94,6 +96,15 @@ bool TRunnerScreen::update(float dt) {
|
||||||
fgRenderTexture = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
fgRenderTexture = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags.test(1)) {
|
||||||
|
if (walker_hack_success && controlled_walker_idx.has_value()) {
|
||||||
|
walkers[controlled_walker_idx.value()].set_player_controlled(true);
|
||||||
|
} else {
|
||||||
|
controlled_walker_idx.reset();
|
||||||
|
}
|
||||||
|
flags.reset(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (controlled_walker_idx.has_value()) {
|
if (controlled_walker_idx.has_value()) {
|
||||||
auto walker_body_pos =
|
auto walker_body_pos =
|
||||||
walkers[controlled_walker_idx.value()].get_body_pos();
|
walkers[controlled_walker_idx.value()].get_body_pos();
|
||||||
|
@ -173,7 +184,13 @@ bool TRunnerScreen::update(float dt) {
|
||||||
walkers[controlled_walker_idx.value()].set_player_controlled(false);
|
walkers[controlled_walker_idx.value()].set_player_controlled(false);
|
||||||
}
|
}
|
||||||
controlled_walker_idx = idx;
|
controlled_walker_idx = idx;
|
||||||
walkers[controlled_walker_idx.value()].set_player_controlled(true);
|
auto s_stack = stack.lock();
|
||||||
|
if (s_stack) {
|
||||||
|
s_stack->push_constructing_screen_args<WalkerHackScreen>(
|
||||||
|
&walker_hack_success);
|
||||||
|
flags.set(1);
|
||||||
|
}
|
||||||
|
// walkers[controlled_walker_idx.value()].set_player_controlled(true);
|
||||||
|
|
||||||
idx_hit = SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT;
|
idx_hit = SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT;
|
||||||
|
|
||||||
|
@ -264,7 +281,7 @@ post_check_click:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TRunnerScreen::draw() {
|
bool TRunnerScreen::draw(RenderTexture *render_texture) {
|
||||||
BeginTextureMode(bgRenderTexture);
|
BeginTextureMode(bgRenderTexture);
|
||||||
ClearBackground(PixelToColor(Pixel::PIXEL_SKY));
|
ClearBackground(PixelToColor(Pixel::PIXEL_SKY));
|
||||||
BeginMode3D(camera);
|
BeginMode3D(camera);
|
||||||
|
@ -317,7 +334,7 @@ bool TRunnerScreen::draw() {
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|
||||||
if (!flags.test(0)) {
|
if (!flags.test(0)) {
|
||||||
if (controlled_walker_idx.has_value()) {
|
if (!flags.test(1) && controlled_walker_idx.has_value()) {
|
||||||
int total_width = 0;
|
int total_width = 0;
|
||||||
DrawRectangle(0, GetScreenHeight() - BUTTON_FONT_SIZE, left_text_width,
|
DrawRectangle(0, GetScreenHeight() - BUTTON_FONT_SIZE, left_text_width,
|
||||||
BUTTON_FONT_SIZE, Color{255, 255, 255, 180});
|
BUTTON_FONT_SIZE, Color{255, 255, 255, 180});
|
||||||
|
@ -387,7 +404,7 @@ bool TRunnerScreen::draw() {
|
||||||
EndTextureMode();
|
EndTextureMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
BeginDrawing();
|
BeginTextureMode(*render_texture);
|
||||||
DrawTextureRec(
|
DrawTextureRec(
|
||||||
bgRenderTexture.texture,
|
bgRenderTexture.texture,
|
||||||
Rectangle{0, 0, (float)GetScreenWidth(), (float)-GetScreenHeight()},
|
Rectangle{0, 0, (float)GetScreenWidth(), (float)-GetScreenHeight()},
|
||||||
|
@ -398,9 +415,9 @@ bool TRunnerScreen::draw() {
|
||||||
Rectangle{0, 0, (float)GetScreenWidth(), (float)-GetScreenHeight()},
|
Rectangle{0, 0, (float)GetScreenWidth(), (float)-GetScreenHeight()},
|
||||||
{0, 0}, WHITE);
|
{0, 0}, WHITE);
|
||||||
}
|
}
|
||||||
EndDrawing();
|
EndTextureMode();
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color TRunnerScreen::PixelToColor(Pixel p) {
|
Color TRunnerScreen::PixelToColor(Pixel p) {
|
||||||
|
|
|
@ -37,8 +37,8 @@ class TRunnerScreen : public Screen {
|
||||||
TRunnerScreen(std::weak_ptr<ScreenStack> stack);
|
TRunnerScreen(std::weak_ptr<ScreenStack> stack);
|
||||||
~TRunnerScreen() override;
|
~TRunnerScreen() override;
|
||||||
|
|
||||||
bool update(float dt) override;
|
bool update(float dt, bool is_resized) override;
|
||||||
bool draw() override;
|
bool draw(RenderTexture *render_texture) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Pixel : unsigned char {
|
enum Pixel : unsigned char {
|
||||||
|
@ -68,6 +68,7 @@ class TRunnerScreen : public Screen {
|
||||||
Camera3D camera;
|
Camera3D camera;
|
||||||
/*
|
/*
|
||||||
* 0 - resetting surface
|
* 0 - resetting surface
|
||||||
|
* 1 - walker hack attempted
|
||||||
*/
|
*/
|
||||||
std::bitset<64> flags;
|
std::bitset<64> flags;
|
||||||
Model TEMP_cube_model;
|
Model TEMP_cube_model;
|
||||||
|
@ -88,6 +89,7 @@ class TRunnerScreen : public Screen {
|
||||||
const int forward_text_width;
|
const int forward_text_width;
|
||||||
const int reset_surface_text_width;
|
const int reset_surface_text_width;
|
||||||
float surface_reset_anim_timer;
|
float surface_reset_anim_timer;
|
||||||
|
bool walker_hack_success;
|
||||||
|
|
||||||
void camera_to_targets(float dt);
|
void camera_to_targets(float dt);
|
||||||
void generate_surface();
|
void generate_surface();
|
||||||
|
|
191
src/screen_walker_hack.cc
Normal file
191
src/screen_walker_hack.cc
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
#include "screen_walker_hack.h"
|
||||||
|
|
||||||
|
// standard library includes
|
||||||
|
#include <cassert>
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#include <iostream>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// third party includes
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
|
// local includes
|
||||||
|
#include "ems.h"
|
||||||
|
|
||||||
|
static const char *WALKER_HACK_SCREEN_INSTRUCTIONS =
|
||||||
|
"Press The Correct Button!";
|
||||||
|
|
||||||
|
WalkerHackScreen::WalkerHackScreen(ScreenStack::Weak ss_weak,
|
||||||
|
bool *walker_hack_success)
|
||||||
|
: Screen(ss_weak),
|
||||||
|
walker_hack_success(walker_hack_success),
|
||||||
|
timer(WALKER_HACK_SCREEN_DURATION),
|
||||||
|
font_size(10),
|
||||||
|
instructions_size(1),
|
||||||
|
instructions_font_size(font_size),
|
||||||
|
type_f_size(1),
|
||||||
|
type_j_size(1),
|
||||||
|
type_a_size(1),
|
||||||
|
type_l_size(1),
|
||||||
|
button_type(BUTTON_TYPE_F) {
|
||||||
|
button_type =
|
||||||
|
(ButtonType)((int)(call_js_get_random() * (float)BUTTON_TYPE_SIZE));
|
||||||
|
*walker_hack_success = false;
|
||||||
|
set_sizes();
|
||||||
|
}
|
||||||
|
|
||||||
|
WalkerHackScreen::~WalkerHackScreen() {}
|
||||||
|
|
||||||
|
bool WalkerHackScreen::update(float dt, bool resized) {
|
||||||
|
if (resized) {
|
||||||
|
set_sizes();
|
||||||
|
}
|
||||||
|
|
||||||
|
timer -= dt;
|
||||||
|
if (timer < 0.0F) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
std::clog << "WalkerHackScreen: timer ended.\n";
|
||||||
|
#endif
|
||||||
|
timer = WALKER_HACK_SCREEN_DURATION;
|
||||||
|
auto s_stack = stack.lock();
|
||||||
|
if (s_stack) {
|
||||||
|
s_stack->pop_screen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsMouseButtonPressed(0)) {
|
||||||
|
switch (button_type) {
|
||||||
|
case BUTTON_TYPE_F:
|
||||||
|
if (GetTouchX() >=
|
||||||
|
GetScreenWidth() / 2 - type_f_size - BUTTON_DRAW_OFFSET &&
|
||||||
|
GetTouchX() <= GetScreenWidth() / 2 - BUTTON_DRAW_OFFSET &&
|
||||||
|
GetTouchY() <= font_size) {
|
||||||
|
*walker_hack_success = true;
|
||||||
|
button_type = BUTTON_TYPE_SIZE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BUTTON_TYPE_J:
|
||||||
|
if (GetTouchX() >= GetScreenWidth() / 2 + BUTTON_DRAW_OFFSET &&
|
||||||
|
GetTouchX() <=
|
||||||
|
GetScreenWidth() / 2 + BUTTON_DRAW_OFFSET + type_j_size &&
|
||||||
|
GetTouchY() <= font_size) {
|
||||||
|
*walker_hack_success = true;
|
||||||
|
button_type = BUTTON_TYPE_SIZE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BUTTON_TYPE_A:
|
||||||
|
if (GetTouchX() >=
|
||||||
|
GetScreenWidth() / 2 - type_f_size - BUTTON_DRAW_OFFSET &&
|
||||||
|
GetTouchX() <= GetScreenWidth() / 2 - BUTTON_DRAW_OFFSET &&
|
||||||
|
GetTouchY() >= font_size + BUTTON_DRAW_OFFSET &&
|
||||||
|
GetTouchY() <= font_size * 2 + BUTTON_DRAW_OFFSET) {
|
||||||
|
*walker_hack_success = true;
|
||||||
|
button_type = BUTTON_TYPE_SIZE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BUTTON_TYPE_L:
|
||||||
|
if (GetTouchX() >= GetScreenWidth() / 2 + BUTTON_DRAW_OFFSET &&
|
||||||
|
GetTouchX() <=
|
||||||
|
GetScreenWidth() / 2 + BUTTON_DRAW_OFFSET + type_l_size &&
|
||||||
|
GetTouchY() >= font_size + BUTTON_DRAW_OFFSET &&
|
||||||
|
GetTouchY() <= font_size * 2 + BUTTON_DRAW_OFFSET) {
|
||||||
|
*walker_hack_success = true;
|
||||||
|
button_type = BUTTON_TYPE_SIZE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (GetKeyPressed()) {
|
||||||
|
case KEY_F:
|
||||||
|
if (button_type == BUTTON_TYPE_F) {
|
||||||
|
*walker_hack_success = true;
|
||||||
|
button_type = BUTTON_TYPE_SIZE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_J:
|
||||||
|
if (button_type == BUTTON_TYPE_J) {
|
||||||
|
*walker_hack_success = true;
|
||||||
|
button_type = BUTTON_TYPE_SIZE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_A:
|
||||||
|
if (button_type == BUTTON_TYPE_A) {
|
||||||
|
*walker_hack_success = true;
|
||||||
|
button_type = BUTTON_TYPE_SIZE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case KEY_L:
|
||||||
|
if (button_type == BUTTON_TYPE_L) {
|
||||||
|
*walker_hack_success = true;
|
||||||
|
button_type = BUTTON_TYPE_SIZE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalkerHackScreen::draw(RenderTexture *render_texture) {
|
||||||
|
BeginTextureMode(*render_texture);
|
||||||
|
|
||||||
|
DrawRectangle(GetScreenWidth() / 2 - instructions_size / 2,
|
||||||
|
(GetScreenHeight() / 4) * 3, instructions_size,
|
||||||
|
instructions_font_size, BLACK);
|
||||||
|
DrawText(WALKER_HACK_SCREEN_INSTRUCTIONS,
|
||||||
|
GetScreenWidth() / 2 - instructions_size / 2,
|
||||||
|
(GetScreenHeight() / 4) * 3, instructions_font_size, WHITE);
|
||||||
|
|
||||||
|
float ratio =
|
||||||
|
(WALKER_HACK_SCREEN_DURATION - timer) / WALKER_HACK_SCREEN_DURATION;
|
||||||
|
DrawRectangle(GetScreenWidth() * ratio,
|
||||||
|
(float)GetScreenHeight() * BUTTON_FONT_SIZE_RATIO * 2.0F +
|
||||||
|
BUTTON_DRAW_OFFSET * 3.0F,
|
||||||
|
GetScreenWidth() * (1.0F - ratio), 30, GREEN);
|
||||||
|
|
||||||
|
DrawRectangle(GetScreenWidth() / 2 - type_f_size - BUTTON_DRAW_OFFSET, 0,
|
||||||
|
type_f_size, font_size,
|
||||||
|
button_type == BUTTON_TYPE_F ? GREEN : BLACK);
|
||||||
|
DrawText("F", GetScreenWidth() / 2 - type_f_size - BUTTON_DRAW_OFFSET, 0,
|
||||||
|
font_size, WHITE);
|
||||||
|
|
||||||
|
DrawRectangle(GetScreenWidth() / 2 + BUTTON_DRAW_OFFSET, 0, type_j_size,
|
||||||
|
font_size, button_type == BUTTON_TYPE_J ? GREEN : BLACK);
|
||||||
|
DrawText("J", GetScreenWidth() / 2 + BUTTON_DRAW_OFFSET, 0, font_size, WHITE);
|
||||||
|
|
||||||
|
DrawRectangle(GetScreenWidth() / 2 - type_a_size - BUTTON_DRAW_OFFSET,
|
||||||
|
font_size + BUTTON_DRAW_OFFSET, type_a_size, font_size,
|
||||||
|
button_type == BUTTON_TYPE_A ? GREEN : BLACK);
|
||||||
|
DrawText("A", GetScreenWidth() / 2 - type_a_size - BUTTON_DRAW_OFFSET,
|
||||||
|
font_size + BUTTON_DRAW_OFFSET, font_size, WHITE);
|
||||||
|
|
||||||
|
DrawRectangle(GetScreenWidth() / 2 + BUTTON_DRAW_OFFSET,
|
||||||
|
font_size + BUTTON_DRAW_OFFSET, type_l_size, font_size,
|
||||||
|
button_type == BUTTON_TYPE_L ? GREEN : BLACK);
|
||||||
|
DrawText("L", GetScreenWidth() / 2 + BUTTON_DRAW_OFFSET,
|
||||||
|
font_size + BUTTON_DRAW_OFFSET, font_size, WHITE);
|
||||||
|
|
||||||
|
EndTextureMode();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalkerHackScreen::set_sizes() {
|
||||||
|
font_size = GetScreenHeight() * BUTTON_FONT_SIZE_RATIO;
|
||||||
|
instructions_font_size = font_size;
|
||||||
|
instructions_size =
|
||||||
|
MeasureText(WALKER_HACK_SCREEN_INSTRUCTIONS, instructions_font_size);
|
||||||
|
while (instructions_size > GetScreenWidth() && instructions_font_size > 1) {
|
||||||
|
--instructions_font_size;
|
||||||
|
instructions_size =
|
||||||
|
MeasureText(WALKER_HACK_SCREEN_INSTRUCTIONS, instructions_font_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
type_f_size = MeasureText("F", font_size);
|
||||||
|
type_j_size = MeasureText("J", font_size);
|
||||||
|
type_a_size = MeasureText("A", font_size);
|
||||||
|
type_l_size = MeasureText("L", font_size);
|
||||||
|
}
|
50
src/screen_walker_hack.h
Normal file
50
src/screen_walker_hack.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#ifndef JUMPARTIFACT_DOT_COM_DEMO_0_WALKER_HACK_SCREEN_H_
|
||||||
|
#define JUMPARTIFACT_DOT_COM_DEMO_0_WALKER_HACK_SCREEN_H_
|
||||||
|
|
||||||
|
// local includes
|
||||||
|
#include "screen.h"
|
||||||
|
|
||||||
|
constexpr float WALKER_HACK_SCREEN_DURATION = 2.0F;
|
||||||
|
constexpr float BUTTON_FONT_SIZE_RATIO = 0.28F;
|
||||||
|
constexpr int BUTTON_DRAW_OFFSET = 5;
|
||||||
|
|
||||||
|
class WalkerHackScreen : public Screen {
|
||||||
|
public:
|
||||||
|
WalkerHackScreen(ScreenStack::Weak ss_weak, bool *walkerHackSuccess);
|
||||||
|
~WalkerHackScreen() override;
|
||||||
|
|
||||||
|
// Disallow copy.
|
||||||
|
WalkerHackScreen(const WalkerHackScreen &) = delete;
|
||||||
|
WalkerHackScreen &operator=(const WalkerHackScreen &) = delete;
|
||||||
|
|
||||||
|
// Allow move.
|
||||||
|
WalkerHackScreen(WalkerHackScreen &&) = default;
|
||||||
|
WalkerHackScreen &operator=(WalkerHackScreen &&) = default;
|
||||||
|
|
||||||
|
bool update(float dt, bool is_resized) override;
|
||||||
|
bool draw(RenderTexture *render_texture) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum ButtonType {
|
||||||
|
BUTTON_TYPE_F = 0,
|
||||||
|
BUTTON_TYPE_J,
|
||||||
|
BUTTON_TYPE_A,
|
||||||
|
BUTTON_TYPE_L,
|
||||||
|
BUTTON_TYPE_SIZE
|
||||||
|
};
|
||||||
|
|
||||||
|
bool *walker_hack_success;
|
||||||
|
float timer;
|
||||||
|
int font_size;
|
||||||
|
int instructions_size;
|
||||||
|
int instructions_font_size;
|
||||||
|
int type_f_size;
|
||||||
|
int type_j_size;
|
||||||
|
int type_a_size;
|
||||||
|
int type_l_size;
|
||||||
|
ButtonType button_type;
|
||||||
|
|
||||||
|
void set_sizes();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -16,7 +16,8 @@ SOURCES = \
|
||||||
../src/3d_helpers.cc \
|
../src/3d_helpers.cc \
|
||||||
../src/raymath.cc \
|
../src/raymath.cc \
|
||||||
../src/walker.cc \
|
../src/walker.cc \
|
||||||
../src/surface_triangle.cc
|
../src/surface_triangle.cc \
|
||||||
|
../src/screen_walker_hack.cc
|
||||||
|
|
||||||
HEADERS = \
|
HEADERS = \
|
||||||
../src/ems.h \
|
../src/ems.h \
|
||||||
|
@ -26,7 +27,8 @@ HEADERS = \
|
||||||
../src/screen_trunner.h \
|
../src/screen_trunner.h \
|
||||||
../src/3d_helpers.h \
|
../src/3d_helpers.h \
|
||||||
../src/walker.h \
|
../src/walker.h \
|
||||||
../src/surface_triangle.h
|
../src/surface_triangle.h \
|
||||||
|
../src/screen_walker_hack.h
|
||||||
|
|
||||||
OBJECTS = $(addprefix ${OBJDIR}/,$(subst ..,PREVDIR,$(subst .cc,.cc.o,${SOURCES})))
|
OBJECTS = $(addprefix ${OBJDIR}/,$(subst ..,PREVDIR,$(subst .cc,.cc.o,${SOURCES})))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue