Commit dbd9f338 authored by Tim Scheiber's avatar Tim Scheiber
Browse files

Merge branch 'develop' into feature/7-enemy-attack

parents d629454d c2a0f704
Pipeline #3278 passed with stage
in 2 minutes and 41 seconds
particle: = particles/*.json
particle_def:test_particles = particles/test_particles.json
particle_sys:test_particles = particles/test_particle_system.json
......@@ -21,5 +21,7 @@
},
"Shooting": {
"orientation": 270
},
"Killable": {
}
}
......@@ -18,5 +18,7 @@
"off_beat_threshold": 0.2
},
"FollowTarget": {
},
"Killable": {
}
}
{
"Transform":{
"scale": {"x": 0.5, "y": 0.5, "z": 0.5}
"Transform": {
"scale": {
"x": 0.5,
"y": 0.5,
"z": 0.5
}
},
"Model": {
"aid": "model:cube"
},
"Shadowcaster": {
},
"Shadowcaster": {},
"Movement": {
"beats_per_step": 1,
"distance_per_step": 1,
"step_time_percentage": 0.2,
"off_beat_threshold": 0.2
"distance_per_step": 5,
"step_time_percentage": 0.3,
"off_beat_threshold": 0.2,
"overshoot": 4
},
"Input_controller": {},
"Player": {}
"Player": {},
"Dash": {
"attack_width": 0.8
},
"Rigid_body": {
"radius": 1.0
}
}
{
"Transform":{
"scale": {"x": 1.0, "y": 1.0, "z": 1.0}
},
"Particle_system": {
"cfg": "particle_sys:test_particles"
}
}
......@@ -2,9 +2,9 @@ dummy
##################
##----############
#| |---------##
#| p |#
#| |---- |#
#| p h |#
#| |---- b |#
##----####| |#
##########| |#
##########| b |#
###########-----##
##################
{
"emitters": [{
"spawn": [
{"particles_per_second": 2000, "stddev":0, "time": 1},
{"particles_per_second": 0, "stddev":0, "time": 5}
],
"spawn_loop": true,
"size": {"x":0, "y":0},
"direction": {"mean":{"elevation":0.85, "azimuth":-0.25}, "stddev":{"elevation":0.1, "azimuth":0.1}},
"ttl": {"mean": 4, "stddev": 0.5},
"velocity": {"mean": 32, "stddev": 8.0},
"emit_script_id": "comp_shader:particle_spawn_sphere",
"type_id": "particle_def:test_particles"
}],
"effectors": [
{
"force": 10,
"force_dir": {"y":-1},
"distance_decay": 0,
"scale_with_mass": false
}
]
}
{
"keyframes": [
{
"time": 0,
"color": {"mean":{"hue":0, "saturation":1}, "stddev":{"hue":0.5}},
"size": {"mean": {"x": 0.05, "y":0.15, "z":0.04}, "stddev":{"x": 0.04, "y":0.02, "z":0.02}},
"rotation": {"mean":{"angle":0}, "stddev":{"elevation":1, "azimuth":1, "angle": 1}},
"drag": 0.1
},
{
"time": 4,
"color": {"mean":{"hue":0, "saturation":1}, "stddev":{"hue":1}},
"size": {"mean": {"x": 0.01, "y":0.1, "z":0.01}},
"rotation": {"mean":{"angle":1}, "stddev":{"elevation":1, "azimuth":1, "angle": 1}},
"drag": 1.0
}
],
"symmetric_scaling": true,
"rotate_with_velocity": false,
"blend": "solid",
/*
"geometry": "billboard",
"material_id": "mat:billboard_material.msf",
*/
"geometry": "mesh",
"model_id": "model:cube",
"update_script_id": "comp_shader:particle_update_simple"
}
......@@ -22,6 +22,18 @@
"solid": false,
"spawn": true,
"spawns": "player"
},
"h": {
"blueprint": "dummy_floor",
"solid": false,
"spawn": true,
"spawns": "hunting_enemy"
},
"b": {
"blueprint": "dummy_floor",
"solid": false,
"spawn": true,
"spawns": "basic_enemy"
}
}
}
......@@ -3,12 +3,19 @@
#include "../messages.hpp"
#include <mirrage/utils/log.hpp>
#include <mirrage/utils/min_max.hpp>
namespace phase_shifter::gameplay {
namespace {
constexpr auto beat_time = 1.f;
}
auto smootherstep(float edge0, float edge1, float x)
{
x = std::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
return x * x * x * (x * (x * 6.f - 15.f) + 10.f);
}
} // namespace
Beat_system::Beat_system(mirrage::util::Message_bus& bus) : _bus(bus) {}
......@@ -29,6 +36,20 @@ namespace phase_shifter::gameplay {
_state = {beat, _acc, beat_time - _acc, beat_time, _state.beats_left};
}
auto Beat_system::graphic_time_scale() const -> float
{
constexpr auto t1_len = 0.05f;
constexpr auto t2_len = 0.6f;
constexpr auto factor = (1.f - (1.f - t1_len - t2_len) * 0.01f) / (t1_len + t2_len) * 2.f;
auto to = _state.time_to_beat / _state.avg_beat_time;
auto from = _state.time_to_beat / _state.avg_beat_time;
return mirrage::util::max(0.01f,
factor * (1.f - smootherstep(0.f, t1_len, to)),
factor * (1.f - smootherstep(0.f, t2_len, from)));
}
void Beat_system::decrease_beats_left(int count) { _state.beats_left -= count; }
} // namespace phase_shifter::gameplay
......@@ -25,6 +25,8 @@ namespace phase_shifter::gameplay {
void decrease_beats_left(int count);
auto graphic_time_scale() const -> float;
private:
mirrage::util::Message_bus& _bus;
Beat_state _state;
......
#include "dash_comp.hpp"
\ No newline at end of file
#pragma once
#include <mirrage/ecs/ecs.hpp>
#include <mirrage/utils/sf2_glm.hpp>
#include <mirrage/utils/units.hpp>
namespace phase_shifter::gameplay {
struct Dash_comp : public mirrage::ecs::Component<Dash_comp> {
static constexpr const char* name() { return "Dash"; }
using Component::Component;
float attack_width = 1;
bool was_move = false;
bool dash = false;
glm::vec2 last_position;
};
sf2_structDef(Dash_comp, attack_width, was_move, dash, last_position);
}
\ No newline at end of file
#include "dash_system.hpp"
#include "dash_comp.hpp"
#include "killable_comp.hpp"
#include "movement_comp.hpp"
#include <mirrage/ecs/components/transform_comp.hpp>
#include <mirrage/ecs/ecs.hpp>
#include <mirrage/ecs/entity_set_view.hpp>
namespace phase_shifter::gameplay {
bool rect_circle_intersects(float rect_x,
float rect_y,
float rect_w,
float rect_h,
float circle_x,
float circle_y,
float radius)
{
float dist_x = std::abs(circle_x - rect_x - rect_w / 2);
float dist_y = std::abs(circle_y - rect_y - rect_h / 2);
if(dist_x > rect_w / 2 + radius) {
return false;
}
if(dist_y > rect_h / 2 + radius) {
return false;
}
if(dist_x <= rect_w / 2) {
return true;
}
if(dist_y <= rect_h / 2) {
return true;
}
float dx = dist_x - rect_w / 2;
float dy = dist_y - rect_h / 2;
return dx * dx + dy * dy <= radius * radius;
}
glm::vec2 rotate_point(glm::vec2 p, float angle)
{
return {p.x * std::cos(angle) - p.y * std::sin(angle), p.y * std::cos(angle) + p.x * std::sin(angle)};
}
using mirrage::ecs::Entity_handle;
using mirrage::ecs::components::Transform_comp;
Dash_system::Dash_system(mirrage::ecs::Entity_manager& ecs) : _ecs(ecs)
{
_ecs.register_component_type<Dash_comp>();
_ecs.register_component_type<Killable_comp>();
}
void Dash_system::update(mirrage::util::Time dt)
{
for(auto&& [transform, move, dash] : _ecs.list<Transform_comp, Movement_comp, Dash_comp>()) {
if((dash.dash || dash.was_move) && move.step_time_left > 0) {
//dash
glm::vec2 position(transform.position.x, transform.position.z);
auto movement = position - dash.last_position;
auto angle = std::atan2(movement.y, movement.x);
auto width = glm::length(movement);
auto height = dash.attack_width;
auto center = rotate_point(
{dash.last_position.x + movement.x / 2, dash.last_position.y + movement.y / 2},
angle);
glm::vec2 topleft(center.x - width / 2, center.y + height / 2);
std::cout << angle * 180 / 3.14 << std::endl;
for(auto&& [entity, k_transform, kill] :
_ecs.list<Entity_handle, Transform_comp, Killable_comp>()) {
auto circle = rotate_point({k_transform.position.x, k_transform.position.z}, angle);
if(rect_circle_intersects(
topleft.x,
topleft.y,
width,
height,
circle.x,
circle.y,
1))
{
_ecs.erase(entity);
}
}
dash.last_position = position;
dash.dash = true;
} else {
dash.dash = false;
}
if(move.move) {
if(!dash.was_move || move.step_time_left <= 0) {
dash.was_move = true;
dash.last_position = {transform.position.x, transform.position.z};
}
} else {
dash.was_move = false;
}
}
}
} // namespace phase_shifter::gameplay
\ No newline at end of file
#pragma once
#include <mirrage/utils/units.hpp>
namespace mirrage::ecs {
class Entity_manager;
}
namespace phase_shifter::gameplay {
class Dash_system {
public:
Dash_system(mirrage::ecs::Entity_manager&);
void update(mirrage::util::Time);
private:
mirrage::ecs::Entity_manager& _ecs;
bool _was_move = false;
glm::vec2 _start_position;
};
}
\ No newline at end of file
#pragma once
#include <mirrage/ecs/ecs.hpp>
#include <mirrage/utils/sf2_glm.hpp>
#include <mirrage/utils/units.hpp>
namespace phase_shifter::gameplay {
struct Killable_comp : public mirrage::ecs::Stateless_tag_component<Killable_comp> {
static constexpr const char* name() { return "Killable"; }
using Stateless_tag_component::Stateless_tag_component;
};
} // namespace phase_shifter::gameplay
......@@ -15,14 +15,23 @@ namespace phase_shifter::gameplay {
float distance_per_step = 1.f;
float step_time_percentage = 0.2f;
float off_beat_threshold = 0.f;
float overshoot = 0.1f;
glm::vec2 aim{0.f, 0.f};
bool move = false;
int beats_since_move = 0;
float step_time_left = 0;
float step_time = 0;
glm::vec2 last_step;
glm::vec2 pos_start;
glm::vec2 pos_end;
};
sf2_structDef(Movement_comp, beats_per_step, distance_per_step, step_time_percentage, off_beat_threshold);
sf2_structDef(Movement_comp,
beats_per_step,
distance_per_step,
step_time_percentage,
off_beat_threshold,
overshoot);
} // namespace phase_shifter::gameplay
......@@ -13,6 +13,19 @@ namespace phase_shifter::gameplay {
using mirrage::ecs::components::Transform_comp;
namespace {
float overshoot(float t, float tension)
{
auto a = [](auto t, auto s) { return t * t * ((s + 1) * t - s); };
auto o = [](auto t, auto s) { return t * t * ((s + 1) * t + s); };
if(t < 0.5)
return 0.5f * a(t * 2.0f, tension);
else
return 0.5f * (o(t * 2.0f - 2.0f, tension) + 2.0f);
}
} // namespace
Movement_system::Movement_system(mirrage::util::Message_bus& bus,
mirrage::ecs::Entity_manager& ecs,
const Beat_system& beat_system)
......@@ -47,7 +60,9 @@ namespace phase_shifter::gameplay {
// start movement
move.beats_since_move = 0;
move.step_time_left = beat.avg_beat_time * move.step_time_percentage;
move.last_step = (move.aim / aim_len * move.distance_per_step) / move.step_time_left;
move.step_time = move.step_time_left;
move.last_step =
(aim_len > 1.f ? move.aim / aim_len : move.aim) * move.distance_per_step;
}
} else {
......@@ -56,11 +71,34 @@ namespace phase_shifter::gameplay {
}
}
auto look_dir = move.aim;
if(move.step_time_left > 0.f) {
look_dir = move.last_step;
auto t0 = overshoot(1.f - move.step_time_left / move.step_time, move.overshoot);
move.step_time_left -= dt.value();
transform.position.x += move.last_step.x * dt.value();
transform.position.z += move.last_step.y * dt.value();
auto t1 = overshoot(1.f - move.step_time_left / move.step_time, move.overshoot);
transform.position.x = transform.position.x - move.last_step.x * t0 + move.last_step.x * t1;
transform.position.z = transform.position.z - move.last_step.y * t0 + move.last_step.y * t1;
}
auto look_dir_len = glm::length(look_dir);
if(look_dir_len < 0.001f) {
look_dir = move.last_step;
look_dir_len = glm::length(look_dir);
}
if(look_dir_len > 0.001f) {
look_dir /= look_dir_len;
transform.orientation = glm::normalize(glm::slerp(
transform.orientation,
glm::rotation(glm::vec3{0.f, 0.f, 1.f}, glm::vec3(look_dir.x, 0, look_dir.y)),
std::min(1.f, dt.value() * 4.f * _beat_system.graphic_time_scale())));
}
}
}
......
#include "rigid_body_comp.hpp"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment