Skip to content
Snippets Groups Projects
Commit 1bcd74f3 authored by Tomas Vybiral's avatar Tomas Vybiral
Browse files

moved shooting controlls to separate lib and added tests for them

parent 6f44d642
No related branches found
No related tags found
No related merge requests found
add_subdirectory(state)
add_subdirectory(input)
add_subdirectory(shoot_controller)
add_subdirectory(renderer)
 
add_library(game
game.h game.cpp
shoot_controller.h shoot_controller.cpp
single_shot.h single_shot.cpp
multi_shot.h multi_shot.cpp)
game.h game.cpp)
 
target_include_directories(game PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
 
......@@ -17,5 +15,6 @@ target_link_libraries(game
state
input
renderer
shoot_controller
${SDL2_LIBRARY}
)
\ No newline at end of file
......@@ -2,8 +2,6 @@
 
#include "input/sdl_input.h"
#include "renderer/sdl_renderer.h"
#include "single_shot.h"
#include "multi_shot.h"
#include "state/level.h"
 
#include <variant>
......@@ -25,7 +23,7 @@ game::game(uint32_t fps):current_state(),
debug(false) {
input_processor = new sdl_input();
renderer = new sdl_renderer();
shoot_control = new single_shot();
shoot_control = shooter_factory::get_single_shooter();
 
load_levels();
 
......@@ -45,9 +43,6 @@ game::~game() {
if (!renderer) {
delete renderer;
}
if (!shoot_control) {
delete shoot_control;
}
}
 
void game::run_loop() {
......@@ -119,13 +114,12 @@ void game::process_event(const event& e) {
do_event<shoot_event>(e, [&](auto&) {shoot = true;});
do_event<change<shooting_controller>>(e, [&](const auto& sc) {
if (shoot_control->can_switch()) {
delete shoot_control;
switch(sc.data.mode) {
case shooting_mode::SINGLE:
shoot_control = new single_shot();
shoot_control = shooter_factory::get_single_shooter();
break;
case shooting_mode::MULTIPLE:
shoot_control = new multi_shot();
shoot_control = shooter_factory::get_multi_shooter();
break;
}
}
......
......@@ -7,7 +7,7 @@
#include "state/state.h"
#include "input/abstract_input.h"
#include "renderer/abstract_renderer.h"
#include "shoot_controller.h"
#include "shoot_controller/shoot_controller.h"
 
/// Basic game structure - behaves like controler in MVC schema.
class game {
......@@ -44,7 +44,7 @@ protected:
/// Current game renderer
abstract_renderer* renderer;
/// Controlls current shooting mode
shoot_controller* shoot_control;
shoot_controller shoot_control;
/// Player position is updated every second by this value
int32_t player_position_delta;
/// Player angle is updated every second by this value
......
add_library(shoot_controller
shoot_controller.h shoot_controller.cpp
multi_shot.h multi_shot.cpp
single_shot.h single_shot.cpp)
target_include_directories(shoot_controller PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/..)
target_link_libraries(shoot_controller
PRIVATE
project_options
project_warnings)
\ No newline at end of file
#include "multi_shot.h"
 
multi_shot::multi_shot():shoot_controller(DELAY), count(0) { }
multi_shot::multi_shot():shoot_controller_impl(DELAY), count(0) { }
 
bool multi_shot::shoot(bool did_shoot) {
if (count == 0 && can_shoot() && did_shoot) {
......
......@@ -6,7 +6,7 @@
#include "shoot_controller.h"
 
/// Controller that shoots multiple shot slightly delayed
class multi_shot: public shoot_controller {
class multi_shot: public shoot_controller_impl {
public:
/// Contructs controller with default values
multi_shot();
......
#include "shoot_controller.h"
#include "single_shot.h"
#include "multi_shot.h"
 
shoot_controller::shoot_controller(double delay): remaining_time(0), shoot_delay(delay) { }
shoot_controller_impl::shoot_controller_impl(double delay): remaining_time(0), shoot_delay(delay) { }
 
void shoot_controller::update_timer(double delta_time) {
void shoot_controller_impl::update_timer(double delta_time) {
remaining_time -= delta_time;
if (remaining_time < 0.0) {
remaining_time = 0.0;
}
}
 
bool shoot_controller::can_shoot() const {
bool shoot_controller_impl::can_shoot() const {
return remaining_time == 0.0;
}
 
bool shoot_controller::shoot(bool did_shoot) {
bool shoot_controller_impl::shoot(bool did_shoot) {
if (can_shoot() && did_shoot) {
remaining_time = shoot_delay;
return true;
......@@ -21,6 +23,15 @@ bool shoot_controller::shoot(bool did_shoot) {
return false;
}
 
bool shoot_controller::can_switch() {
bool shoot_controller_impl::can_switch() {
return can_shoot();
}
shoot_controller shooter_factory::get_single_shooter() {
return std::make_shared<single_shot>();
}
shoot_controller shooter_factory::get_multi_shooter() {
return std::make_shared<multi_shot>();
}
\ No newline at end of file
#ifndef SHOOT_CONTROLLER_H
#define SHOOT_CONTROLLER_H
 
#include <memory>
/// Controls shooting behavior
class shoot_controller {
class shoot_controller_impl {
public:
/// Initializes controller with max delay
explicit shoot_controller(double delay);
explicit shoot_controller_impl(double delay);
/// Virtual destructor to prevent memory leaks
virtual ~shoot_controller() = default;
virtual ~shoot_controller_impl() = default;
 
/// Try to shoot - returns true if can
virtual bool shoot(bool did_shoot);
......@@ -19,8 +22,18 @@ protected:
/// Checks if timer is expired
bool can_shoot() const;
 
/// Remaining time before you can shoot again
double remaining_time;
/// Dealy between two shots
double shoot_delay;
};
 
typedef std::shared_ptr<shoot_controller_impl> shoot_controller;
class shooter_factory {
public:
static shoot_controller get_single_shooter();
static shoot_controller get_multi_shooter();
};
#endif//SHOOT_CONTROLLER_H
\ No newline at end of file
#include "single_shot.h"
 
single_shot::single_shot():shoot_controller(DELAY) { }
\ No newline at end of file
single_shot::single_shot():shoot_controller_impl(DELAY) { }
\ No newline at end of file
......@@ -4,7 +4,7 @@
#include "shoot_controller.h"
 
/// Controller that shoots simple shot
class single_shot: public shoot_controller {
class single_shot: public shoot_controller_impl {
public:
/// Default contructor that initializes controller with default values
single_shot();
......
......@@ -3,8 +3,8 @@
 
#include "state/state.h"
#include "state/shooter.h"
#include "game/game.h"
#include "state/level.h"
#include "game/game.h"
 
TEST_CASE("Testing state history storing", "[state]")
{
......@@ -85,3 +85,45 @@ TEST_CASE("Testing level loading", "[level]") {
REQUIRE(true);
}
}
TEST_CASE("Testing shooting controllers", "[shoot_controller]") {
shoot_controller sc = shooter_factory::get_single_shooter();
REQUIRE(sc->shoot(false) == false);
REQUIRE(sc->can_switch() == true);
REQUIRE(sc->shoot(true) == true);
REQUIRE(sc->can_switch() == false);
REQUIRE(sc->shoot(true) == false);
sc->update_timer(0.25);
REQUIRE(sc->can_switch() == false);
sc->update_timer(0.3);
REQUIRE(sc->can_switch() == true);
sc = shooter_factory::get_multi_shooter();
REQUIRE(sc->shoot(false) == false);
REQUIRE(sc->can_switch() == true);
REQUIRE(sc->shoot(true) == true);
REQUIRE(sc->can_switch() == false);
REQUIRE(sc->shoot(true) == false);
sc->update_timer(0.2);
REQUIRE(sc->can_switch() == false);
REQUIRE(sc->shoot(false) == true);
REQUIRE(sc->can_switch() == false);
sc->update_timer(0.1);
REQUIRE(sc->shoot(false) == false);
REQUIRE(sc->shoot(true) == false);
REQUIRE(sc->can_switch() == false);
sc->update_timer(0.1);
REQUIRE(sc->shoot(true) == true);
REQUIRE(sc->can_switch() == false);
sc->update_timer(0.2);
REQUIRE(sc->can_switch() == true);
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment