260 lines
No EOL
6 KiB
D
260 lines
No EOL
6 KiB
D
module game_core.basic;
|
|
|
|
import bubel.ecs.core;
|
|
import bubel.ecs.attributes;
|
|
|
|
import ecs_utils.math.vector;
|
|
|
|
import gui.attributes;
|
|
|
|
import ecs_utils.utils;
|
|
|
|
import app : launcher;
|
|
|
|
import bindbc.sdl;
|
|
|
|
//position component
|
|
struct CLocation
|
|
{
|
|
//adds some extra functionality. Not required. Will be probably removed from library in the future.
|
|
mixin ECS.Component;
|
|
|
|
alias value this;//use component as it value
|
|
|
|
//default values work properly
|
|
vec2 value = vec2(0);
|
|
}
|
|
|
|
//scale component
|
|
struct CScale
|
|
{
|
|
mixin ECS.Component;
|
|
|
|
alias value this;//use component as it value
|
|
|
|
vec2 value = vec2(16,16);
|
|
}
|
|
|
|
//rotation component
|
|
struct CRotation
|
|
{
|
|
mixin ECS.Component;
|
|
|
|
alias value this;//use component as it value
|
|
|
|
float value = 0;
|
|
}
|
|
|
|
//depth component. Entity with higher depth will be rendered on top
|
|
struct CDepth
|
|
{
|
|
mixin ECS.Component;
|
|
|
|
alias value this;
|
|
|
|
short value;
|
|
}
|
|
|
|
//color component
|
|
struct CColor
|
|
{
|
|
mixin ECS.Component;
|
|
|
|
alias value this;
|
|
|
|
@GUIColor uint value;
|
|
}
|
|
|
|
//component used for selection
|
|
struct CSelected
|
|
{
|
|
mixin ECS.Component;
|
|
|
|
bool value = false;
|
|
}
|
|
|
|
//component indicating that entity should receive input from mouse, keyboard, etc.
|
|
struct CInput
|
|
{
|
|
mixin ECS.Component;
|
|
}
|
|
|
|
//component with damping value
|
|
struct CDamping
|
|
{
|
|
mixin ECS.Component;
|
|
|
|
alias value this;
|
|
|
|
@GUIRange(0,9) byte value = 1;
|
|
}
|
|
|
|
//velocity component
|
|
struct CVelocity
|
|
{
|
|
mixin ECS.Component;
|
|
|
|
alias value this;
|
|
|
|
vec2 value = vec2(0,0);
|
|
}
|
|
|
|
//factor which is used for velocity masking
|
|
struct CVelocityFactor
|
|
{
|
|
mixin ECS.Component;
|
|
|
|
alias value this;
|
|
|
|
vec2 value = vec2(1);
|
|
}
|
|
|
|
//flag indicating that entity is static and shouldn't be updated by most systems in every frame
|
|
struct CStatic
|
|
{
|
|
mixin ECS.Component;
|
|
}
|
|
|
|
//system which slowing down entities
|
|
struct DampingSystem
|
|
{
|
|
//system will generate up to 32 jobs
|
|
mixin ECS.System!32;
|
|
|
|
struct EntitiesData
|
|
{
|
|
uint length;
|
|
const (Entity)[] entity; //entity is readonly
|
|
@readonly CDamping[] damping;//damping is readonly. Marking with @readonly will help multithreading algorithm
|
|
CVelocity[] velocity;//velocity is wirtable as it will be modified for entities in this system
|
|
}
|
|
|
|
//20 predefined damping speeds. Gives possibility to store damping as single byte.
|
|
float[20] damp = 0;
|
|
|
|
bool onBegin()
|
|
{
|
|
//calculate damping values
|
|
foreach(i;0..20)
|
|
{
|
|
damp[i] = powf((0.99 - cast(float)i * 0.01),launcher.deltaTime*0.1);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void onUpdate(EntitiesData data)
|
|
{
|
|
foreach(i; 0..data.length)
|
|
{
|
|
//constantly slow down entity
|
|
data.velocity[i] = data.velocity[i] * damp[data.damping[i]];
|
|
}
|
|
}
|
|
}
|
|
|
|
//system used for entity movement
|
|
struct MoveSystem
|
|
{
|
|
mixin ECS.System!64;
|
|
|
|
struct EntitiesData
|
|
{
|
|
uint length;
|
|
CLocation[] location;
|
|
@readonly CVelocity[] velocity;
|
|
@optional @readonly CVelocityFactor[] vel_factor;//CVeclocityFactor is not required so entites without this component will be also updated
|
|
}
|
|
|
|
void onUpdate(EntitiesData data)
|
|
{
|
|
//split into two loops for two types of entities. Doing it in "normal" way by testing data.vel_factor inside loop in every iteration will be probably compiled as same machine code in release build (it works in LDC)
|
|
if(data.vel_factor)
|
|
{
|
|
foreach(i; 0..data.length)
|
|
{
|
|
data.location[i] += data.velocity[i] * data.vel_factor[i] * launcher.deltaTime;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach(i; 0..data.length)
|
|
{
|
|
data.location[i] += data.velocity[i] * launcher.deltaTime;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
*System is responsible for movement of objects with CInput component.
|
|
*In this example every entity has same speed when using movement system.
|
|
*/
|
|
struct InputMovementSystem
|
|
{
|
|
mixin ECS.System!32;
|
|
|
|
vec2 move_vector;
|
|
|
|
struct EntitiesData
|
|
{
|
|
uint length;
|
|
//read only components can be marked with @readonly attribute or with const expression instead
|
|
const (CInput)[] input;
|
|
//components are treated as required by default
|
|
//CLocation[] locations;
|
|
CVelocity[] velocity;
|
|
//CTexture[] textures;
|
|
}
|
|
|
|
/**
|
|
*onBegin gives opportunity to check keys once and call update on entities only when
|
|
*one key is pressed.
|
|
*/
|
|
bool onBegin()
|
|
{
|
|
move_vector = vec2(0,0);
|
|
if(launcher.getKeyState(SDL_SCANCODE_W))
|
|
{
|
|
move_vector += vec2(0,1);
|
|
}
|
|
else if(launcher.getKeyState(SDL_SCANCODE_S))
|
|
{
|
|
move_vector += vec2(0,-1);
|
|
}
|
|
if(launcher.getKeyState(SDL_SCANCODE_A))
|
|
{
|
|
move_vector += vec2(-1,0);
|
|
}
|
|
else if(launcher.getKeyState(SDL_SCANCODE_D))
|
|
{
|
|
move_vector += vec2(1,0);
|
|
}
|
|
|
|
if(move_vector.x != 0 ||move_vector.y != 0)
|
|
{
|
|
move_vector = move_vector / sqrtf(move_vector.x * move_vector.x + move_vector.y * move_vector.y);
|
|
return true;
|
|
}
|
|
//don't call system update because no key pressed
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
*Update is called multiple times in one "manager.update()" call.
|
|
*Number of "onUpdate" calls is count of buffers which must be updated during pass.
|
|
*When multithreading is used, number of "onUpdate" calls can be greater due to fact that
|
|
*JobSystem can split buffers for better data packing.
|
|
*/
|
|
void onUpdate(EntitiesData data)
|
|
{
|
|
foreach(i; 0..data.length)
|
|
{
|
|
data.velocity[i] += move_vector * launcher.deltaTime * 0.005;
|
|
if(data.velocity[i].x > 0.5)data.velocity[i].x = 0.5;
|
|
else if(data.velocity[i].x < -0.5)data.velocity[i].x = -0.5;
|
|
if(data.velocity[i].y > 0.5)data.velocity[i].y = 0.5;
|
|
else if(data.velocity[i].y < -0.5)data.velocity[i].y = -0.5;
|
|
}
|
|
}
|
|
} |