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; struct CLocation { mixin ECS.Component; alias value this; vec2 value = vec2(0); } struct CScale { mixin ECS.Component; alias value this;///use component as it value vec2 value = vec2(16,16); } struct CRotation { mixin ECS.Component; alias value this;///use component as it value float value = 0; } struct CDepth { mixin ECS.Component; alias value this; short value; } struct CColor { mixin ECS.Component; alias value this; @GUIColor uint value; } struct CSelected { mixin ECS.Component; bool value = false; } struct CInput { mixin ECS.Component; } struct CDamping { mixin ECS.Component; alias value this; @GUIRange(0,9) byte value = 1; } struct CVelocity { mixin ECS.Component; alias value this; vec2 value = vec2(0,0); } struct CVelocityFactor { mixin ECS.Component; alias value this; vec2 value = vec2(1); } struct CStatic { mixin ECS.Component; } struct DampingSystem { mixin ECS.System!32; struct EntitiesData { uint length; const (Entity)[] entity; @readonly CDamping[] damping; CVelocity[] velocity; } float[20] damp = 0; bool onBegin() { foreach(i;0..20) { damp[i] = powf((0.99 - cast(float)i * 0.01),launcher.delta_time*0.1); } return true; } void onUpdate(EntitiesData data) { foreach(i; 0..data.length) { data.velocity[i] = data.velocity[i] * damp[data.damping[i]]; } } } struct MoveSystem { mixin ECS.System!64; struct EntitiesData { uint length; CLocation[] location; @readonly CVelocity[] velocity; @optional @readonly CVelocityFactor[] vel_factor; } void onUpdate(EntitiesData data) { if(data.vel_factor) { foreach(i; 0..data.length) { data.location[i] += data.velocity[i] * data.vel_factor[i] * launcher.delta_time; } } else { foreach(i; 0..data.length) { data.location[i] += data.velocity[i] * launcher.delta_time; } } } } /** *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) { /*if(move_vector.x == 0) { foreach(i; 0..data.length) { data.textures[i].coords = vec4(0*px,80*px,48*px,32*px); } //return; }*/ //move every entity using movement vector //if(move_vector.x != 0 || move_vector.y != 0) foreach(i; 0..data.length) { data.velocity[i] += move_vector * launcher.delta_time * 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; //data.locations[i].x += move_vector.x * launcher.delta_time * 0.25; //data.locations[i].y += move_vector.y * launcher.delta_time * 0.25; //if(move_vector.x > 0)data.textures[i].coords = vec4(48*px,80*px,48*px,32*px); //else data.textures[i].coords = vec4(0*px,80*px,48*px,32*px); } /*else foreach(i; 0..data.length) { data.velocity[i] = vec2(0,0); }*/ } }