From 83ed3de28841d1eecfca39ff540e804cf6809b32 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Tue, 2 Jun 2015 14:30:34 +0200 Subject: [PATCH] block place/remove timers --- TODO | 5 +-- src/app.cpp | 9 +++- src/interface.cpp | 107 ++++++++++++++++++++++++++++++++-------------- src/interface.hpp | 15 ++++++- src/timer.hpp | 49 +++++++++++++++++++++ 5 files changed, 145 insertions(+), 40 deletions(-) create mode 100644 src/timer.hpp diff --git a/TODO b/TODO index 411172d..926a355 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,7 @@ block placement/removal timers - currently block placement and removal is instantaneous. it should - actually take some time to place and remove a block. with - removal timing depending on the tool used to remove the block + removal timing depending on the tool/block combination + animation for remove composite entity animations diff --git a/src/app.cpp b/src/app.cpp index 21f5bcf..57651e3 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -88,11 +88,16 @@ void Application::HandleEvents() { while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_KEYDOWN: + interface.HandlePress(event.key); + break; case SDL_KEYUP: - interface.Handle(event.key); + interface.HandleRelease(event.key); break; case SDL_MOUSEBUTTONDOWN: - interface.Handle(event.button); + interface.HandlePress(event.button); + break; + case SDL_MOUSEBUTTONUP: + interface.HandleRelease(event.button); break; case SDL_MOUSEMOTION: interface.Handle(event.motion); diff --git a/src/interface.cpp b/src/interface.cpp index 12117f7..f846cc8 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -1,6 +1,5 @@ #include "interface.hpp" -#include "geometry.hpp" #include "world.hpp" #include @@ -14,12 +13,15 @@ Interface::Interface(const Config &config, World &world) : world(world) , ctrl(world.Player()) , hud(world.BlockTypes()) +, aim{{ 0, 0, 0 }, { 0, 0, -1 }} , aim_chunk(nullptr) , aim_block(0) , aim_normal() , outline() , outline_transform(1.0f) , config(config) +, place_timer(256) +, remove_timer(256) , remove(0) , selection(1) , fwd(0) @@ -29,59 +31,72 @@ Interface::Interface(const Config &config, World &world) } -void Interface::Handle(const SDL_KeyboardEvent &event) { +void Interface::HandlePress(const SDL_KeyboardEvent &event) { if (config.keyboard_disabled) return; switch (event.keysym.sym) { case SDLK_w: - rev.z = event.state == SDL_PRESSED; + rev.z = 1; break; case SDLK_s: - fwd.z = event.state == SDL_PRESSED; + fwd.z = 1; break; case SDLK_a: - rev.x = event.state == SDL_PRESSED; + rev.x = 1; break; case SDLK_d: - fwd.x = event.state == SDL_PRESSED; + fwd.x = 1; break; case SDLK_SPACE: - fwd.y = event.state == SDL_PRESSED; + fwd.y = 1; break; case SDLK_LSHIFT: - rev.y = event.state == SDL_PRESSED; + rev.y = 1; break; case SDLK_q: - if (event.state == SDL_PRESSED) { - FaceBlock(); - } + FaceBlock(); break; case SDLK_e: - if (event.state == SDL_PRESSED) { - TurnBlock(); - } + TurnBlock(); break; case SDLK_b: - if (event.state == SDL_PRESSED) { - PrintBlockInfo(); - } + PrintBlockInfo(); break; case SDLK_c: - if (event.state == SDL_PRESSED) { - PrintChunkInfo(); - } + PrintChunkInfo(); break; case SDLK_l: - if (event.state == SDL_PRESSED) { - PrintLightInfo(); - } + PrintLightInfo(); break; case SDLK_p: - if (event.state == SDL_PRESSED) { - PrintSelectionInfo(); - } + PrintSelectionInfo(); + break; + } +} + +void Interface::HandleRelease(const SDL_KeyboardEvent &event) { + if (config.keyboard_disabled) return; + + switch (event.keysym.sym) { + case SDLK_w: + rev.z = 0; + break; + case SDLK_s: + fwd.z = 0; + break; + case SDLK_a: + rev.x = 0; + break; + case SDLK_d: + fwd.x = 0; + break; + case SDLK_SPACE: + fwd.y = 0; + break; + case SDLK_LSHIFT: + rev.y = 0; break; } } @@ -169,17 +184,27 @@ void Interface::Handle(const SDL_MouseMotionEvent &event) { ctrl.RotatePitch(event.yrel * config.pitch_sensitivity); } -void Interface::Handle(const SDL_MouseButtonEvent &event) { +void Interface::HandlePress(const SDL_MouseButtonEvent &event) { if (config.mouse_disabled) return; - if (event.state != SDL_PRESSED) return; - if (event.button == 1) { RemoveBlock(); + remove_timer.Start(); } else if (event.button == 2) { PickBlock(); } else if (event.button == 3) { PlaceBlock(); + place_timer.Start(); + } +} + +void Interface::HandleRelease(const SDL_MouseButtonEvent &event) { + if (config.mouse_disabled) return; + + if (event.button == 1) { + remove_timer.Stop(); + } else if (event.button == 3) { + place_timer.Stop(); } } @@ -245,18 +270,34 @@ void Interface::Update(int dt) { ctrl.Velocity(glm::vec3(fwd - rev) * config.move_velocity); ctrl.Update(dt); - Ray aim = ctrl.Aim(); + place_timer.Update(dt); + remove_timer.Update(dt); + + aim = ctrl.Aim(); + CheckAim(); + + if (remove_timer.Hit()) { + RemoveBlock(); + CheckAim(); + } + + if (place_timer.Hit()) { + PlaceBlock(); + CheckAim(); + } +} + +void Interface::CheckAim() { float dist; if (world.Intersection(aim, glm::mat4(1.0f), &aim_chunk, &aim_block, &dist, &aim_normal)) { outline.Clear(); aim_chunk->Type(aim_chunk->BlockAt(aim_block)).FillOutlineModel(outline); - outline_transform = glm::scale(glm::mat4(1.0f), glm::vec3(1.0002f)); - outline_transform = aim_chunk->Transform(world.Player().ChunkCoords()); + outline_transform = glm::scale(glm::vec3(1.0002f)); + outline_transform *= aim_chunk->Transform(world.Player().ChunkCoords()); outline_transform *= aim_chunk->ToTransform(aim_block); } else { aim_chunk = nullptr; } - } diff --git a/src/interface.hpp b/src/interface.hpp index 16ee89f..9f43f4f 100644 --- a/src/interface.hpp +++ b/src/interface.hpp @@ -3,9 +3,11 @@ #include "block.hpp" #include "controller.hpp" +#include "geometry.hpp" #include "hud.hpp" #include "model.hpp" #include "shader.hpp" +#include "timer.hpp" #include #include @@ -31,9 +33,11 @@ public: Interface(const Config &, World &); - void Handle(const SDL_KeyboardEvent &); + void HandlePress(const SDL_KeyboardEvent &); + void HandleRelease(const SDL_KeyboardEvent &); void Handle(const SDL_MouseMotionEvent &); - void Handle(const SDL_MouseButtonEvent &); + void HandlePress(const SDL_MouseButtonEvent &); + void HandleRelease(const SDL_MouseButtonEvent &); void Handle(const SDL_MouseWheelEvent &); void Handle(const SDL_WindowEvent &) noexcept; @@ -57,11 +61,15 @@ public: void Render(DirectionalLighting &) noexcept; +private: + void CheckAim(); + private: World &world; FPSController ctrl; HUD hud; + Ray aim; Chunk *aim_chunk; int aim_block; glm::vec3 aim_normal; @@ -71,6 +79,9 @@ private: Config config; + IntervalTimer place_timer; + IntervalTimer remove_timer; + Block remove; Block selection; diff --git a/src/timer.hpp b/src/timer.hpp new file mode 100644 index 0000000..c5445b2 --- /dev/null +++ b/src/timer.hpp @@ -0,0 +1,49 @@ +#ifndef BLANK_TIMER_HPP +#define BLANK_TIMER_HPP + + +namespace blank { + +class IntervalTimer { + +public: + explicit IntervalTimer(int interval_ms) noexcept + : intv(interval_ms) { } + + void Start() noexcept { + speed = 1; + } + void Stop() noexcept { + value = 0; + speed = 0; + } + + bool Running() const noexcept { + return speed != 0; + } + bool Hit() const noexcept { + return Running() && value % intv < last_dt; + } + int Elapsed() const noexcept { + return value; + } + int Iteration() const noexcept { + return value / intv; + } + + void Update(int dt) noexcept { + value += dt * speed; + last_dt = dt; + } + +private: + int intv; + int value = 0; + int speed = 0; + int last_dt = 0; + +}; + +} + +#endif -- 2.39.2