Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
GameDevWeek
Sommersemester 2019
Cpp
PhaseShifter
Commits
a662624c
Commit
a662624c
authored
Sep 19, 2019
by
Florian Oetke
Browse files
level collisions
parent
71ef5ba0
Changes
12
Hide whitespace changes
Inline
Side-by-side
assets/game_assets/blueprints/player.json
View file @
a662624c
...
...
@@ -23,6 +23,6 @@
"attack_width"
:
0.8
},
"Rigid_body"
:
{
"radius"
:
1.0
"radius"
:
0.5
}
}
src/gameplay/dash_system.cpp
View file @
a662624c
...
...
@@ -71,20 +71,10 @@ namespace phase_shifter::gameplay {
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
))
{
if
(
rect_circle_intersects
(
topleft
.
x
,
topleft
.
y
,
width
,
height
,
circle
.
x
,
circle
.
y
,
1
))
{
_ecs
.
erase
(
entity
);
}
}
...
...
@@ -105,4 +95,4 @@ namespace phase_shifter::gameplay {
}
}
}
}
// namespace phase_shifter::gameplay
\ No newline at end of file
}
// namespace phase_shifter::gameplay
src/gameplay/movement_comp.hpp
View file @
a662624c
...
...
@@ -23,8 +23,7 @@ namespace phase_shifter::gameplay {
float
step_time_left
=
0
;
float
step_time
=
0
;
glm
::
vec2
last_step
;
glm
::
vec2
pos_start
;
glm
::
vec2
pos_end
;
glm
::
vec2
last_aim
;
};
sf2_structDef
(
Movement_comp
,
...
...
src/gameplay/movement_system.cpp
View file @
a662624c
...
...
@@ -3,6 +3,10 @@
#include
"beat_system.hpp"
#include
"combat_system.hpp"
#include
"movement_comp.hpp"
#include
"rigid_body_comp.hpp"
#include
"../level/level_system.hpp"
#include
"../messages.hpp"
#include
<mirrage/ecs/components/transform_comp.hpp>
#include
<mirrage/ecs/ecs.hpp>
...
...
@@ -11,6 +15,7 @@
namespace
phase_shifter
::
gameplay
{
using
namespace
mirrage
::
ecs
;
using
mirrage
::
ecs
::
components
::
Transform_comp
;
namespace
{
...
...
@@ -28,8 +33,9 @@ namespace phase_shifter::gameplay {
Movement_system
::
Movement_system
(
mirrage
::
util
::
Message_bus
&
bus
,
mirrage
::
ecs
::
Entity_manager
&
ecs
,
const
Beat_system
&
beat_system
)
:
_bus
(
bus
),
_ecs
(
ecs
),
_beat_system
(
beat_system
)
const
Beat_system
&
beat_system
,
const
level
::
Level_system
&
level_system
)
:
_bus
(
bus
),
_ecs
(
ecs
),
_beat_system
(
beat_system
),
_level_system
(
level_system
)
{
_ecs
.
register_component_type
<
Movement_comp
>
();
}
...
...
@@ -38,13 +44,11 @@ namespace phase_shifter::gameplay {
{
auto
beat
=
_beat_system
.
beat_state
();
for
(
auto
&&
[
transform
,
move
]
:
_ecs
.
list
<
Transform_comp
,
Movement_comp
>
())
{
for
(
auto
&&
[
entity
,
transform
,
move
]
:
_ecs
.
list
<
Entity_facet
,
Transform_comp
,
Movement_comp
>
())
{
if
(
beat
.
beat
)
{
move
.
beats_since_move
++
;
}
auto
allowed
=
(
beat
.
beat
||
beat
.
time_since_beat
<=
move
.
off_beat_threshold
||
beat
.
time_to_beat
<=
move
.
off_beat_threshold
)
&&
move
.
beats_since_move
>=
move
.
beats_per_step
;
...
...
@@ -74,25 +78,42 @@ 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
);
auto
t0
=
overshoot
(
1.
f
-
move
.
step_time_left
/
move
.
step_time
,
move
.
overshoot
);
move
.
step_time_left
-=
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
offset
=
-
move
.
last_step
*
t0
+
move
.
last_step
*
t1
;
auto
pos
=
glm
::
vec2
(
transform
.
position
.
x
,
transform
.
position
.
z
);
entity
.
process
([
&
](
Rigid_body_comp
&
body
)
{
_level_system
.
check_contacts
(
pos
+
offset
,
body
.
radius
,
[
&
](
util
::
Contact
contact
)
{
if
(
contact
.
distance2
<=
0.0001
f
)
{
offset
=
glm
::
vec2
(
0
,
0
);
_bus
.
send
<
Entity_hit_wall
>
(
entity
.
handle
());
}
else
if
(
auto
normal_vel
=
glm
::
dot
(
offset
,
contact
.
normal
);
normal_vel
>
0
)
{
offset
-=
normal_vel
*
contact
.
normal
;
_bus
.
send
<
Entity_hit_wall
>
(
entity
.
handle
());
}
});
});
look_dir
=
offset
;
transform
.
position
.
x
=
pos
.
x
+
offset
.
x
;
transform
.
position
.
z
=
pos
.
y
+
offset
.
y
;
}
auto
look_dir_len
=
glm
::
length
(
look_dir
);
if
(
look_dir_len
<
0.001
f
)
{
look_dir
=
move
.
last_
step
;
look_dir
=
move
.
last_
aim
;
look_dir_len
=
glm
::
length
(
look_dir
);
}
if
(
look_dir_len
>
0.001
f
)
{
move
.
last_aim
=
look_dir
;
look_dir
/=
look_dir_len
;
transform
.
orientation
=
glm
::
normalize
(
glm
::
slerp
(
...
...
src/gameplay/movement_system.hpp
View file @
a662624c
...
...
@@ -7,13 +7,20 @@ namespace mirrage::ecs {
class
Entity_manager
;
}
namespace
phase_shifter
::
level
{
class
Level_system
;
}
namespace
phase_shifter
::
gameplay
{
class
Beat_system
;
class
Movement_system
{
public:
Movement_system
(
mirrage
::
util
::
Message_bus
&
,
mirrage
::
ecs
::
Entity_manager
&
,
const
Beat_system
&
);
Movement_system
(
mirrage
::
util
::
Message_bus
&
,
mirrage
::
ecs
::
Entity_manager
&
,
const
Beat_system
&
,
const
level
::
Level_system
&
);
void
update
(
mirrage
::
util
::
Time
);
...
...
@@ -21,6 +28,7 @@ namespace phase_shifter::gameplay {
mirrage
::
util
::
Message_bus
&
_bus
;
mirrage
::
ecs
::
Entity_manager
&
_ecs
;
const
Beat_system
&
_beat_system
;
const
level
::
Level_system
&
_level_system
;
};
}
// namespace phase_shifter::gameplay
src/level/level_system.cpp
View file @
a662624c
...
...
@@ -11,6 +11,7 @@
namespace
phase_shifter
::
level
{
using
namespace
mirrage
;
using
namespace
mirrage
::
ecs
::
components
;
using
namespace
mirrage
::
util
;
Level_system
::
Level_system
(
mirrage
::
ecs
::
Entity_manager
&
entities
,
mirrage
::
asset
::
Asset_manager
&
assets
)
:
_entities
(
entities
),
_assets
(
assets
)
...
...
@@ -111,6 +112,54 @@ namespace phase_shifter::level {
return
result
;
}
void
Level_system
::
check_contacts
(
glm
::
vec2
origin
,
float
radius
,
std
::
function
<
void
(
util
::
Contact
)
>
on_contact
)
const
{
auto
&
level
=
_current_level
.
get_blocking
();
auto
&
tile_types
=
level
.
tileset
->
tiles
;
auto
tile_size
=
level
.
tileset
->
tile_size
;
auto
level_size_x
=
level
.
tiles
[
0
].
size
();
auto
level_size_y
=
level
.
tiles
.
size
();
auto
min_x
=
std
::
clamp
(
static_cast
<
std
::
size_t
>
(
std
::
floor
(
origin
.
x
/
tile_size
-
radius
/
tile_size
-
0.5
f
)),
(
std
::
size_t
)
0
,
level_size_x
-
1
);
auto
min_y
=
std
::
clamp
(
static_cast
<
std
::
size_t
>
(
std
::
floor
(
origin
.
y
/
tile_size
-
radius
/
tile_size
-
0.5
f
)),
(
std
::
size_t
)
0
,
level_size_y
-
1
);
auto
max_x
=
std
::
clamp
(
static_cast
<
std
::
size_t
>
(
std
::
ceil
(
origin
.
x
/
tile_size
+
radius
/
tile_size
+
0.5
f
)),
(
std
::
size_t
)
0
,
level_size_x
-
1
);
auto
max_y
=
std
::
clamp
(
static_cast
<
std
::
size_t
>
(
std
::
ceil
(
origin
.
y
/
tile_size
+
radius
/
tile_size
+
0.5
f
)),
(
std
::
size_t
)
0
,
level_size_y
-
1
);
for
(
auto
y
=
min_y
;
y
<=
max_y
;
y
++
)
{
for
(
auto
x
=
min_x
;
x
<=
max_x
;
x
++
)
{
auto
tile
=
level
.
tiles
[
y
][
x
];
auto
key
=
std
::
string
(
1
,
tile
);
if
(
auto
tile_it
=
tile_types
.
find
(
key
);
tile_it
!=
tile_types
.
end
()
&&
tile_it
->
second
.
solid
)
{
auto
tile_origin
=
glm
::
vec2
{
x
*
tile_size
,
y
*
tile_size
};
auto
half_size
=
tile_size
/
2.
f
*
1.1
f
;
auto
half_vector
=
glm
::
vec2
{
half_size
,
half_size
};
auto
[
hit
,
contact
]
=
util
::
intersect
(
util
::
Aabb
{
tile_origin
,
half_vector
},
util
::
Circle
{
origin
,
radius
});
if
(
hit
)
{
on_contact
(
contact
);
}
}
}
}
}
auto
Level_system
::
_spawn_function
(
const
std
::
string
&
key
)
->
std
::
function
<
auto
(
const
Tile
&
,
const
glm
::
vec3
&
)
->
void
>
{
...
...
src/level/level_system.hpp
View file @
a662624c
...
...
@@ -3,6 +3,7 @@
#include
"../util/collision.hpp"
#include
"level.hpp"
#include
<mirrage/utils/maybe.hpp>
#include
<mirrage/utils/units.hpp>
#include
<functional>
...
...
@@ -26,6 +27,7 @@ namespace phase_shifter::level {
auto
update
(
const
mirrage
::
util
::
Time
&
time
)
->
void
;
auto
load
(
const
std
::
string
&
name
)
->
void
;
auto
ray_cast
(
const
glm
::
vec2
&
origin
,
const
glm
::
vec2
&
direction
)
->
std
::
pair
<
bool
,
util
::
Contact
>
;
void
check_contacts
(
glm
::
vec2
origin
,
float
radius
,
std
::
function
<
void
(
util
::
Contact
)
>
)
const
;
private:
auto
_spawn_function
(
const
std
::
string
&
key
)
...
...
src/messages.hpp
View file @
a662624c
#pragma once
#include
<mirrage/ecs/types.hpp>
namespace
phase_shifter
{
...
...
@@ -8,4 +9,8 @@ namespace phase_shifter {
struct
Lose_msg
{
};
struct
Entity_hit_wall
{
mirrage
::
ecs
::
Entity_handle
entity
;
};
}
// namespace phase_shifter
src/meta_system.cpp
View file @
a662624c
...
...
@@ -5,13 +5,13 @@
#include
"gameplay/beat_system.hpp"
#include
"gameplay/camera_system.hpp"
#include
"gameplay/combat_system.hpp"
#include
"gameplay/dash_system.hpp"
#include
"gameplay/enemy_system.hpp"
#include
"gameplay/killable_comp.hpp"
#include
"gameplay/movement_system.hpp"
#include
"helper/attachment_system.hpp"
#include
"input/input_system.hpp"
#include
"level/level_system.hpp"
#include
"gameplay/killable_comp.hpp"
#include
"gameplay/dash_system.hpp"
#include
"ui/hud_system.hpp"
#include
<context.hpp>
...
...
@@ -33,12 +33,13 @@ namespace phase_shifter {
,
_renderer
(
engine
.
renderer_factory
().
create_renderer
(
_entities
,
engine
.
render_pass_mask
()))
,
_model_loading
(
std
::
make_unique
<
renderer
::
Loading_system
>
(
_entities
,
engine
.
assets
()))
,
_beat_system
(
std
::
make_unique
<
gameplay
::
Beat_system
>
(
engine
.
bus
()))
,
_movement_system
(
std
::
make_unique
<
gameplay
::
Movement_system
>
(
engine
.
bus
(),
_entities
,
*
_beat_system
))
,
_level_system
(
std
::
make_unique
<
level
::
Level_system
>
(
_entities
,
engine
.
assets
()))
,
_movement_system
(
std
::
make_unique
<
gameplay
::
Movement_system
>
(
engine
.
bus
(),
_entities
,
*
_beat_system
,
*
_level_system
))
,
_input_system
(
std
::
make_unique
<
input
::
Input_system
>
(
engine
.
bus
(),
_entities
))
,
_combat_system
(
std
::
make_unique
<
gameplay
::
Combat_system
>
(
engine
.
bus
(),
_entities
,
*
_beat_system
))
,
_attachment_system
(
std
::
make_unique
<
helper
::
Attachment_system
>
(
_entities
))
,
_hud_system
(
std
::
make_unique
<
ui
::
Hud_system
>
(
engine
.
gui
(),
_entities
,
*
_beat_system
))
,
_level_system
(
std
::
make_unique
<
level
::
Level_system
>
(
_entities
,
engine
.
assets
()))
,
_camera_system
(
std
::
make_unique
<
gameplay
::
Camera_system
>
(
_entities
))
,
_enemy_system
(
std
::
make_unique
<
gameplay
::
Enemy_system
>
(
_entities
))
,
_dash_system
(
std
::
make_unique
<
gameplay
::
Dash_system
>
(
_entities
))
...
...
src/meta_system.hpp
View file @
a662624c
...
...
@@ -64,12 +64,12 @@ namespace phase_shifter {
std
::
unique_ptr
<
mirrage
::
renderer
::
Loading_system
>
_model_loading
;
std
::
unique_ptr
<
gameplay
::
Beat_system
>
_beat_system
;
std
::
unique_ptr
<
level
::
Level_system
>
_level_system
;
std
::
unique_ptr
<
gameplay
::
Movement_system
>
_movement_system
;
std
::
unique_ptr
<
input
::
Input_system
>
_input_system
;
std
::
unique_ptr
<
gameplay
::
Combat_system
>
_combat_system
;
std
::
unique_ptr
<
helper
::
Attachment_system
>
_attachment_system
;
std
::
unique_ptr
<
ui
::
Hud_system
>
_hud_system
;
std
::
unique_ptr
<
level
::
Level_system
>
_level_system
;
std
::
unique_ptr
<
gameplay
::
Camera_system
>
_camera_system
;
std
::
unique_ptr
<
gameplay
::
Enemy_system
>
_enemy_system
;
std
::
unique_ptr
<
gameplay
::
Dash_system
>
_dash_system
;
...
...
src/util/collision.cpp
View file @
a662624c
...
...
@@ -70,4 +70,36 @@ namespace phase_shifter::util {
return
{
false
,
{}};
}
auto
intersect
(
const
Aabb
&
aabb
,
const
Circle
&
circle
)
->
std
::
pair
<
bool
,
Contact
>
{
const
auto
n
=
aabb
.
origin
-
circle
.
origin
;
auto
closest
=
glm
::
clamp
(
n
,
-
aabb
.
half_vec
,
aabb
.
half_vec
);
auto
inside
=
glm
::
distance2
(
n
,
closest
)
<=
0.0
f
;
if
(
inside
)
{
if
(
std
::
abs
(
n
.
x
)
>
std
::
abs
(
n
.
y
))
closest
.
x
=
closest
.
x
>
0
?
aabb
.
half_vec
.
x
:
-
aabb
.
half_vec
.
x
;
else
closest
.
y
=
closest
.
y
>
0
?
aabb
.
half_vec
.
y
:
-
aabb
.
half_vec
.
y
;
}
auto
diff
=
n
-
closest
;
auto
dist2
=
glm
::
length2
(
diff
);
if
(
dist2
<=
circle
.
radius
*
circle
.
radius
||
inside
)
{
auto
dist
=
glm
::
sqrt
(
dist2
);
auto
normal
=
dist
>
0.
f
?
diff
/
dist
:
glm
::
vec2
(
1
,
0
);
//auto penetration = std::abs(dist - radius);
if
(
inside
)
{
normal
*=
-
1.
f
;
dist2
=
0
;
}
return
{
true
,
{
glm
::
vec2
{
0
,
0
},
normal
,
dist2
}};
}
else
{
return
{
false
,
{}};
}
}
}
// namespace phase_shifter::util
src/util/collision.hpp
View file @
a662624c
...
...
@@ -27,7 +27,8 @@ namespace phase_shifter::util {
float
radius
;
};
auto
intersect
(
const
Ray
&
ray
,
const
Aabb
&
aabb
)
->
std
::
pair
<
bool
,
Contact
>
;
auto
intersect
(
const
Ray
&
ray
,
const
Circle
&
circle
)
->
std
::
pair
<
bool
,
Contact
>
;
auto
intersect
(
const
Circle
&
circle1
,
const
Circle
&
circle2
)
->
std
::
pair
<
bool
,
Contact
>
;
extern
auto
intersect
(
const
Ray
&
ray
,
const
Aabb
&
aabb
)
->
std
::
pair
<
bool
,
Contact
>
;
extern
auto
intersect
(
const
Ray
&
ray
,
const
Circle
&
circle
)
->
std
::
pair
<
bool
,
Contact
>
;
extern
auto
intersect
(
const
Circle
&
circle1
,
const
Circle
&
circle2
)
->
std
::
pair
<
bool
,
Contact
>
;
extern
auto
intersect
(
const
Aabb
&
aabb
,
const
Circle
&
circle
)
->
std
::
pair
<
bool
,
Contact
>
;
}
// namespace phase_shifter::util
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment