Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
GameDevWeek
S
Sommersemester 2019
Cpp
PhaseShifter
Commits
49857bb7
Commit
49857bb7
authored
Sep 19, 2019
by
Tim Scheiber
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Turrets can now target the player when they are in range
parent
c66978ba
Pipeline
#3304
failed with stage
in 5 minutes and 8 seconds
Changes
12
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
167 additions
and
86 deletions
+167
-86
assets/game_assets/blueprints/basic_enemy.json
assets/game_assets/blueprints/basic_enemy.json
+6
-3
assets/game_assets/blueprints/player.json
assets/game_assets/blueprints/player.json
+4
-3
src/gameplay/continuous_path_comp.hpp
src/gameplay/continuous_path_comp.hpp
+4
-1
src/gameplay/enemy_system.cpp
src/gameplay/enemy_system.cpp
+111
-65
src/gameplay/enemy_system.hpp
src/gameplay/enemy_system.hpp
+1
-0
src/gameplay/fixed_path_comp.cpp
src/gameplay/fixed_path_comp.cpp
+2
-5
src/gameplay/fixed_path_comp.hpp
src/gameplay/fixed_path_comp.hpp
+7
-0
src/gameplay/follow_target_comp.hpp
src/gameplay/follow_target_comp.hpp
+6
-0
src/gameplay/shooting_comp.cpp
src/gameplay/shooting_comp.cpp
+2
-2
src/gameplay/shooting_comp.hpp
src/gameplay/shooting_comp.hpp
+7
-5
src/gameplay/target_comp.hpp
src/gameplay/target_comp.hpp
+15
-0
src/meta_system.cpp
src/meta_system.cpp
+2
-2
No files found.
assets/game_assets/blueprints/basic_enemy.json
View file @
49857bb7
...
...
@@ -18,12 +18,15 @@
"off_beat_threshold"
:
0.0
},
"FixedPath"
:
{
"pause_between_steps"
:
1
},
"Shooting"
:
{
"default_orientation"
:
270
,
"rotation_per_step"
:
5
,
"max_rotation"
:
10
,
"spawn_offset"
:
1
"rotation_per_step"
:
15
,
"max_rotation"
:
30
,
"spawn_offset"
:
1
,
"attack_radius"
:
5
,
"pause_between_shots"
:
1
},
"Killable"
:
{
}
...
...
assets/game_assets/blueprints/player.json
View file @
49857bb7
...
...
@@ -22,7 +22,8 @@
"Dash"
:
{
"attack_width"
:
0.8
},
"Rigid_body"
:
{
"radius"
:
0.5
}
"Rigid_body"
:
{
"radius"
:
0.5
},
"Target"
:
{}
}
src/gameplay/continuous_path_comp.hpp
View file @
49857bb7
...
...
@@ -12,8 +12,11 @@ namespace phase_shifter::gameplay {
float
direction
=
0
;
// angle of direction with 0° beeing North (-Z)
float
curvature
=
0
;
// angle of curvature in degrees
unsigned
int
pause_between_steps
=
0
;
// number of beats the entity waits between steps
unsigned
int
wait_beats
=
0
;
// number of beats the entity waits before taking the next step
};
sf2_structDef
(
Continuous_path_comp
,
direction
,
curvature
);
sf2_structDef
(
Continuous_path_comp
,
direction
,
curvature
,
pause_between_steps
);
}
// namespace phase_shifter::gameplay
\ No newline at end of file
src/gameplay/enemy_system.cpp
View file @
49857bb7
...
...
@@ -7,13 +7,16 @@
namespace
phase_shifter
::
gameplay
{
Enemy_system
::
Enemy_system
(
mirrage
::
ecs
::
Entity_manager
&
entity_manager
,
const
Beat_system
&
beat_system
)
using
namespace
mirrage
::
ecs
;
Enemy_system
::
Enemy_system
(
Entity_manager
&
entity_manager
,
const
Beat_system
&
beat_system
)
:
_entity_manager
(
entity_manager
),
_beat_system
(
beat_system
)
{
_entity_manager
.
register_component_type
<
Fixed_path_comp
>
();
_entity_manager
.
register_component_type
<
Follow_target_comp
>
();
_entity_manager
.
register_component_type
<
Continuous_path_comp
>
();
_entity_manager
.
register_component_type
<
Shooting_comp
>
();
_entity_manager
.
register_component_type
<
Target_comp
>
();
}
void
Enemy_system
::
update
(
mirrage
::
util
::
Time
dt
)
...
...
@@ -21,91 +24,134 @@ namespace phase_shifter::gameplay {
auto
beat
=
_beat_system
.
beat_state
();
for
(
auto
&&
[
movement
,
fixed_path
]
:
_entity_manager
.
list
<
Movement_comp
,
Fixed_path_comp
>
())
{
if
(
!
movement
.
move
)
{
float
rad_direction
=
fixed_path
.
next_direction
()
*
mirrage
::
util
::
PI
/
180.
f
;
if
(
rad_direction
>=
0
)
{
movement
.
aim
.
x
=
std
::
sin
(
rad_direction
);
movement
.
aim
.
y
=
-
std
::
cos
(
rad_direction
);
movement
.
move
=
true
;
if
(
beat
.
beat
)
{
if
(
fixed_path
.
wait_beats
==
0
&&
!
movement
.
move
)
{
float
direction
=
fixed_path
.
next_direction
();
if
(
direction
<
360
)
{
float
rad_direction
=
direction
*
mirrage
::
util
::
PI
/
180.
f
;
movement
.
aim
.
x
=
std
::
sin
(
rad_direction
);
movement
.
aim
.
y
=
-
std
::
cos
(
rad_direction
);
movement
.
move
=
true
;
}
fixed_path
.
wait_beats
=
fixed_path
.
pause_between_steps
;
}
else
{
fixed_path
.
wait_beats
--
;
}
}
}
for
(
auto
&&
[
movement
,
follow_target
,
transform
]
:
_entity_manager
.
list
<
Movement_comp
,
Follow_target_comp
,
mirrage
::
ecs
::
components
::
Transform_comp
>
())
{
auto
target_facet
=
_entity_manager
.
get
(
follow_target
.
target
);
for
(
auto
&&
[
movement
,
follow_target
,
transform
]
:
_entity_manager
.
list
<
Movement_comp
,
Follow_target_comp
,
components
::
Transform_comp
>
())
{
if
(
beat
.
beat
)
{
if
(
follow_target
.
wait_beats
==
0
&&
!
movement
.
move
)
{
auto
target_facet
=
_entity_manager
.
get
(
follow_target
.
target
);
if
(
target_facet
.
is_some
())
{
auto
target_transform
=
target_facet
.
get_or_throw
().
get
<
mirrage
::
ecs
::
components
::
Transform_comp
>
();
if
(
target_facet
.
is_some
())
{
auto
target_transform
=
target_facet
.
get_or_throw
().
get
<
components
::
Transform_comp
>
();
if
(
target_transform
.
is_some
())
{
auto
&
target_position
=
target_transform
.
get_or_throw
().
position
;
auto
&
my_position
=
transform
.
position
;
movement
.
aim
=
glm
::
vec2
({
target_position
.
x
-
my_position
.
x
,
target_position
.
z
-
my_position
.
z
});
movement
.
move
=
true
;
if
(
target_transform
.
is_some
())
{
auto
&
target_position
=
target_transform
.
get_or_throw
().
position
;
auto
&
my_position
=
transform
.
position
;
movement
.
aim
=
glm
::
vec2
(
{
target_position
.
x
-
my_position
.
x
,
target_position
.
z
-
my_position
.
z
});
movement
.
move
=
true
;
}
}
follow_target
.
wait_beats
=
follow_target
.
pause_between_steps
;
}
else
{
follow_target
.
wait_beats
--
;
}
}
}
for
(
auto
&&
[
movement
,
cont_path
]
:
_entity_manager
.
list
<
Movement_comp
,
Continuous_path_comp
>
())
{
if
(
!
movement
.
move
)
{
float
rad_direction
=
cont_path
.
next_direction
()
*
mirrage
::
util
::
PI
/
180.
f
;
movement
.
aim
.
x
=
std
::
sin
(
rad_direction
);
movement
.
aim
.
y
=
-
std
::
cos
(
rad_direction
);
movement
.
move
=
true
;
if
(
beat
.
beat
)
{
if
(
cont_path
.
wait_beats
==
0
&&
!
movement
.
move
)
{
float
rad_direction
=
cont_path
.
next_direction
()
*
mirrage
::
util
::
PI
/
180.
f
;
movement
.
aim
.
x
=
std
::
sin
(
rad_direction
);
movement
.
aim
.
y
=
-
std
::
cos
(
rad_direction
);
movement
.
move
=
true
;
cont_path
.
wait_beats
=
cont_path
.
pause_between_steps
;
}
else
{
cont_path
.
wait_beats
--
;
}
}
}
for
(
auto
&&
[
shooting
,
transform
]
:
_entity_manager
.
list
<
Shooting_comp
,
mirrage
::
ecs
::
components
::
Transform_comp
>
())
{
auto
target_facet
=
_entity_manager
.
get
(
shooting
.
target
);
if
(
target_facet
.
is_some
())
{
auto
target_transform
=
target_facet
.
get_or_throw
().
get
<
mirrage
::
ecs
::
components
::
Transform_comp
>
();
if
(
target_transform
.
is_some
())
{
auto
&
target_position
=
target_transform
.
get_or_throw
().
position
;
auto
&
my_position
=
transform
.
position
;
auto
dist
=
glm
::
length
(
glm
::
vec2
(
target_position
.
x
,
target_position
.
z
)
-
glm
::
vec2
(
my_position
.
x
,
my_position
.
z
));
shooting
.
target_direction
=
std
::
asin
((
target_position
.
x
-
my_position
.
x
)
/
dist
);
if
(
dist
<=
shooting
.
attack_radius
)
{
shooting
.
idle
=
false
;
}
else
{
shooting
.
idle
=
true
;
}
for
(
auto
&&
[
shooting
,
transform
]
:
_entity_manager
.
list
<
Shooting_comp
,
components
::
Transform_comp
>
())
{
auto
my_position
=
transform
.
position
;
glm
::
vec3
closest_target_pos
;
float
closest_dist
=
999999999.
f
;
for
(
auto
&&
[
target
,
target_comp
,
target_transform
]
:
_entity_manager
.
list
<
Entity_facet
,
Target_comp
,
components
::
Transform_comp
>
())
{
auto
target_position
=
target_transform
.
position
;
auto
dist
=
glm
::
length
(
glm
::
vec2
(
target_position
.
x
,
target_position
.
z
)
-
glm
::
vec2
(
my_position
.
x
,
my_position
.
z
));
if
(
dist
<
closest_dist
)
{
closest_dist
=
dist
;
closest_target_pos
=
target_position
;
}
}
glm
::
vec2
t_direction
(
closest_target_pos
.
x
-
my_position
.
x
,
closest_target_pos
.
z
-
my_position
.
z
);
shooting
.
target_direction
=
std
::
acos
(
-
t_direction
.
y
/
glm
::
length
(
t_direction
))
*
180.
f
/
mirrage
::
util
::
PI
;
if
(
t_direction
.
x
<
0
)
{
shooting
.
target_direction
*=
-
1
;
}
if
(
closest_dist
<=
shooting
.
attack_radius
)
{
shooting
.
idle
=
false
;
}
else
{
shooting
.
idle
=
true
;
}
auto
orientation
=
shooting
.
target_direction
;
if
(
shooting
.
idle
)
{
orientation
=
shooting
.
default_orientation
+
shooting
.
rotation
;
}
auto
rad_orientation
=
orientation
*
mirrage
::
util
::
PI
/
180.
f
;
if
(
beat
.
beat
)
{
auto
bullet_pattern
=
shooting
.
next_pattern
();
auto
orientation
=
shooting
.
target_direction
;
if
(
shooting
.
idle
)
{
orientation
=
shooting
.
default_orientation
+
shooting
.
rotation
;
shooting
.
rotate
();
if
(
shooting
.
idle
&&
shooting
.
rotate
)
{
shooting
.
do_rotation
();
shooting
.
rotate
=
false
;
}
auto
rad_orientation
=
orientation
*
mirrage
::
util
::
PI
/
180.
f
;
auto
spawn_position
=
transform
.
position
+
shooting
.
spawn_offset
*
glm
::
vec3
(
std
::
sin
(
rad_orientation
),
0
,
-
std
::
cos
(
rad_orientation
));
for
(
auto
bullet
:
bullet_pattern
.
bullets
)
{
auto
bullet_direction
=
orientation
+
bullet
.
direction
;
auto
rad_bullet_direction
=
bullet_direction
*
mirrage
::
util
::
PI
/
180.
f
;
_entity_manager
.
entity_builder
(
"bullet"
)
.
position
(
spawn_position
)
.
rotation
(
glm
::
rotation
(
{
0
,
0
,
1
},
glm
::
vec3
(
std
::
sin
(
rad_bullet_direction
),
0
,
-
std
::
cos
(
rad_bullet_direction
))))
.
post_create
([
=
](
auto
entity
)
{
entity
.
process
([
=
](
Continuous_path_comp
&
cont_path
)
{
cont_path
.
direction
=
bullet_direction
;
cont_path
.
curvature
=
bullet
.
curvature
;
});
})
.
create
();
if
(
shooting
.
wait_beats
==
0
)
{
auto
bullet_pattern
=
shooting
.
next_pattern
();
auto
spawn_position
=
transform
.
position
+
shooting
.
spawn_offset
*
glm
::
vec3
(
std
::
sin
(
rad_orientation
),
0
,
-
std
::
cos
(
rad_orientation
));
for
(
auto
bullet
:
bullet_pattern
.
bullets
)
{
auto
bullet_direction
=
orientation
+
bullet
.
direction
;
auto
rad_bullet_direction
=
bullet_direction
*
mirrage
::
util
::
PI
/
180.
f
;
_entity_manager
.
entity_builder
(
"bullet"
)
.
position
(
spawn_position
)
.
rotation
(
glm
::
rotation
({
0
,
0
,
1
},
glm
::
vec3
(
std
::
sin
(
rad_bullet_direction
),
0
,
-
std
::
cos
(
rad_bullet_direction
))))
.
post_create
([
=
](
auto
entity
)
{
entity
.
process
([
=
](
Continuous_path_comp
&
cont_path
)
{
cont_path
.
direction
=
bullet_direction
;
cont_path
.
curvature
=
bullet
.
curvature
;
});
})
.
create
();
}
shooting
.
wait_beats
=
shooting
.
pause_between_shots
;
shooting
.
rotate
=
true
;
}
else
{
shooting
.
wait_beats
--
;
}
}
transform
.
orientation
=
glm
::
rotation
(
{
0
,
0
,
1
},
glm
::
vec3
(
std
::
sin
(
rad_orientation
),
0
,
-
std
::
cos
(
rad_orientation
)));
}
}
}
\ No newline at end of file
src/gameplay/enemy_system.hpp
View file @
49857bb7
...
...
@@ -7,6 +7,7 @@
#include "follow_target_comp.hpp"
#include "continuous_path_comp.hpp"
#include "shooting_comp.hpp"
#include "target_comp.hpp"
namespace
phase_shifter
::
gameplay
{
...
...
src/gameplay/fixed_path_comp.cpp
View file @
49857bb7
...
...
@@ -11,16 +11,13 @@ namespace phase_shifter::gameplay {
while
(
angle
<
0
)
{
angle
+=
360
;
}
while
(
angle
>=
360
)
{
angle
-=
360
;
}
}
}
float
Fixed_path_comp
::
next_direction
()
{
if
(
directions
.
empty
())
{
return
-
1
;
return
1
000
;
}
float
dir
=
directions
[
next_step
];
...
...
@@ -32,7 +29,7 @@ namespace phase_shifter::gameplay {
reverse
=
true
;
}
}
else
{
if
(
dir
>=
180
)
{
if
(
dir
>=
180
&&
dir
<
360
)
{
dir
-=
180
;
}
else
{
dir
+=
180
;
...
...
src/gameplay/fixed_path_comp.hpp
View file @
49857bb7
...
...
@@ -13,9 +13,16 @@ namespace phase_shifter::gameplay {
void
update_path
(
std
::
vector
<
float
>
directions
);
float
next_direction
();
unsigned
int
pause_between_steps
=
0
;
// number of beats the entity waits between steps
unsigned
int
wait_beats
=
0
;
// number of beats the entity waits before taking the next step
private:
unsigned
int
next_step
=
0
;
//index of the next step
std
::
vector
<
float
>
directions
;
//vector containing the steps as angles (degrees) with 0° being North (-Z)
bool
reverse
=
false
;
//flag wether the path is now traced backwards
};
sf2_structDef
(
Fixed_path_comp
,
pause_between_steps
);
}
\ No newline at end of file
src/gameplay/follow_target_comp.hpp
View file @
49857bb7
...
...
@@ -8,6 +8,12 @@ namespace phase_shifter::gameplay {
static
constexpr
const
char
*
name
()
{
return
"FollowTarget"
;
}
using
Component
::
Component
;
unsigned
int
pause_between_steps
=
0
;
// number of beats the entity waits between steps
mirrage
::
ecs
::
Entity_handle
target
;
unsigned
int
wait_beats
=
0
;
// number of beats the entity waits before taking the next step
};
sf2_structDef
(
Follow_target_comp
,
pause_between_steps
);
}
// namespace phase_shifter::gameplay
\ No newline at end of file
src/gameplay/shooting_comp.cpp
View file @
49857bb7
...
...
@@ -11,9 +11,9 @@ namespace phase_shifter::gameplay {
return
pattern
;
}
void
Shooting_comp
::
rotat
e
()
{
void
Shooting_comp
::
do_
rotat
ion
()
{
rotation
+=
rotation_per_step
;
if
(
glm
::
abs
(
rotation
)
>
max_rotation
)
{
if
(
max_rotation
>=
0
&&
glm
::
abs
(
rotation
)
>
max_rotation
)
{
rotation_per_step
*=
-
1
;
rotation
+=
2
*
rotation_per_step
;
}
...
...
src/gameplay/shooting_comp.hpp
View file @
49857bb7
...
...
@@ -27,24 +27,26 @@ namespace phase_shifter::gameplay {
using
Component
::
Component
;
Bulletpattern
next_pattern
();
void
rotat
e
();
void
do_
rotat
ion
();
float
default_orientation
=
0
;
// default orientation of "forward" in degrees with 0° beeing North (-Z)
float
rotation_per_step
=
0
;
// rotation the turret does per beat in degrees during idle state
float
max_rotation
=
0
;
// max rotation the turret does in degrees during idle before reversing rotation direction
float
spawn_offset
=
0
;
// offset of the bullet spawn point in meters
float
attack_radius
=
0
;
// radius in which the turret targets the target
unsigned
int
pause_between_shots
=
0
;
// number of beats the turret waits between shots
mirrage
::
ecs
::
Entity_handle
target
;
// the target the turret targets while not idle
float
target_direction
=
0
;
// angular direction towards the target in degrees with 0° beeing North (-Z)
std
::
vector
<
Bulletpattern
>
patterns
;
// sequence of bullet patterns that are looped through
float
rotation
=
0
;
// current rotation from default_orientation in degrees
bool
idle
=
true
;
// if false, the turret targets the target
float
rotation
=
0
;
// current rotation from default_orientation in degrees
unsigned
int
wait_beats
=
0
;
// number of beats the turret waits before shooting again
bool
rotate
=
false
;
//flag whether the turret will rotate next beat
bool
idle
=
true
;
// if false, the turret targets the target
private:
unsigned
int
i_next_pattern
=
0
;
};
sf2_structDef
(
Shooting_comp
,
default_orientation
,
rotation_per_step
,
max_rotation
,
spawn_offset
,
attack_radius
);
sf2_structDef
(
Shooting_comp
,
default_orientation
,
rotation_per_step
,
max_rotation
,
spawn_offset
,
attack_radius
,
pause_between_shots
);
}
\ No newline at end of file
src/gameplay/target_comp.hpp
0 → 100644
View file @
49857bb7
#pragma once
#include <mirrage/ecs/ecs.hpp>
#include <mirrage/utils/sf2_glm.hpp>
#include <mirrage/utils/units.hpp>
namespace
phase_shifter
::
gameplay
{
struct
Target_comp
:
public
mirrage
::
ecs
::
Stateless_tag_component
<
Target_comp
>
{
static
constexpr
const
char
*
name
()
{
return
"Target"
;
}
using
Stateless_tag_component
::
Stateless_tag_component
;
};
}
// namespace phase_shifter::gameplay
src/meta_system.cpp
View file @
49857bb7
...
...
@@ -105,9 +105,9 @@ namespace phase_shifter {
.
entity_builder
(
"basic_enemy"
)
.
position
({
20
,
0
,
15
})
.
post_create
([
=
](
auto
entity
)
{
entity
.
process
([
&
](
gameplay
::
Fixed_path_comp
&
fixed_path
)
{
fixed_path
.
update_path
({});
});
entity
.
process
([
&
](
gameplay
::
Fixed_path_comp
&
fixed_path
)
{
fixed_path
.
update_path
({
180
});
});
entity
.
process
([
&
](
gameplay
::
Shooting_comp
&
shooting
)
{
shooting
.
patterns
.
push_back
(
gameplay
::
Bulletpattern
({{
0
,
0
}}));
shooting
.
patterns
.
push_back
(
gameplay
::
Bulletpattern
({{
0
,
5
}}));
});
})
.
create
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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