Huge demos update

-moved C stdlib function definitions to ecs_utils.utils
-added function to calculate mix(linear interpolation) and rsqrt(fast inverse sqrt)
-added some math to vec2 (length, normalize...)
-improved renderer with possibility to use multiple materials (one per block, not perfect solution for parallel compute, but works with some requirements)
-added blending support for material (opaque, additive, mixed)
-added Android support
-added gprahical representation for mouse tools (tool_circle.d)
-added initial support for editing template components variables
-better Component and Templates listing
-added possibility to add/removes components using mouse
-move CLocation to game_core.basic and reuse in every test
-moved tools code from demos to App (now code is fully separated from demos!)
-some improvement and fixes in Snake demo, with additional systems to handle adding and removing entities
-added new demo: Particles. By now demo has several particles to spawn and support for attractors and vortexes (calculation is made as every attractor with every entity)
-fixed bug with window hover and tools
-improved tool behaviour
-added new material
-now window is always opened as maximized windowed mode
-some minor fixes and improvements
This commit is contained in:
Mergul 2020-06-06 22:46:29 +02:00
parent 13e6ed8fd5
commit e76c5ccdb2
20 changed files with 1804 additions and 288 deletions

View file

@ -4,8 +4,6 @@ import app;
import bindbc.sdl;
import cimgui.cimgui;
import bubel.ecs.attributes;
import bubel.ecs.core;
import bubel.ecs.entity;
@ -13,10 +11,14 @@ import bubel.ecs.manager;
import bubel.ecs.std;
import bubel.ecs.vector;
import cimgui.cimgui;
import ecs_utils.gfx.texture;
import ecs_utils.math.vector;
import ecs_utils.utils;
import game_core.basic;
//import std.array : staticArray;
enum float px = 1.0/512.0;
@ -31,22 +33,6 @@ struct MapElement
apple = 1,
wall = 2,
snake = 3,
/* snake_head_up = 5,
snake_head_down = 6,
snake_head_left = 7,
snake_head_right = 8,
snake_tail_up = 9,
snake_tail_down = 10,
snake_tail_left = 11,
snake_tail_right = 12,
snake_turn_ld = 13,
snake_turn_lu = 14,
snake_turn_rd = 15,
snake_turn_ru = 16,
snake_vertical = 17,
snake_horizontal = 18*/
}
Type type;
EntityID id;
@ -129,10 +115,7 @@ struct Snake
}
if(base_pos.x == random_pos.x && base_pos.y == random_pos.y)return;
}
//CILocation* location = apple_tmpl.getComponent!CILocation;
//*location = random_pos;
//Entity* apple =
launcher.manager.addEntity(apple_tmpl,[CILocation(random_pos).ref_].staticArray);
launcher.manager.addEntity(apple_tmpl,[CLocation(cast(vec2)(random_pos)*16).ref_].staticArray);
}
}
@ -158,14 +141,14 @@ struct CILocation
ivec2 location;
}
struct CLocation
{
mixin ECS.Component;
// struct CLocation
// {
// mixin ECS.Component;
alias location this;
// alias location this;
vec2 location = vec2(0,0);
}
// vec2 location = vec2(0,0);
// }
struct CSnake
{
@ -264,8 +247,8 @@ struct AppleSystem
struct EntitiesData
{
uint length;
@readonly Entity[] entities;
@readonly CApple[] movement;
@readonly Entity[] entity;
@readonly CApple[] apple;
@readonly CILocation[] location;
}
@ -273,7 +256,17 @@ struct AppleSystem
{
foreach(i;0..data.length)
{
snake.element(MapElement(MapElement.Type.apple,data.entities[i].id),data.location[i]);
if(snake.element(data.location[i]).id == EntityID())snake.element(MapElement(MapElement.Type.apple,data.entity[i].id),data.location[i]);
else launcher.manager.removeEntity(data.entity[i].id);
}
}
void onRemoveEntity(EntitiesData data)
{
foreach(i;0..data.length)
{
if(snake.element(data.location[i].location).id == data.entity[i].id)
snake.element(MapElement(MapElement.Type.empty, EntityID()),data.location[i].location);
}
}
}
@ -315,7 +308,7 @@ struct ParticleMovementSystem
{
foreach(i;0..data.length)
{
data.location[i].location -= data.movement[i].velocity;
data.location[i] -= data.movement[i].velocity;
}
}
}
@ -357,7 +350,7 @@ struct AnimationRenderSystem
{
foreach(i;0..data.length)
{
launcher.renderer.draw(snake.texture, cast(vec2)cast(ivec2)data.location[i].location, vec2(16,16), data.animation[i].frames[cast(int)(data.animation[i].time)], -1, 0x80808080);
launcher.renderer.draw(snake.texture, cast(vec2)cast(ivec2)data.location[i], vec2(16,16), data.animation[i].frames[cast(int)(data.animation[i].time)], -1, 0x80808080);
}
}
}
@ -477,7 +470,12 @@ struct MoveSystem
break;
case MapElement.Type.apple:
launcher.manager.removeEntity(snake.element(data.location[i].location).id);
if(data.snakes[i].parts.length < 100)data.snakes[i].parts.add(new_location);
if(data.snakes[i].parts.length >= 99)
{
snake.addApple();
goto case(MapElement.Type.empty);
}
data.snakes[i].parts.add(new_location);
if(data.snakes[i].parts.length > 1)
{
@ -506,7 +504,40 @@ struct MoveSystem
}
}
}
}
}
struct SnakeSystem
{
mixin ECS.System!1;
struct EntitiesData
{
uint length;
Entity[] entity;
@readonly CSnake[] snake;
@readonly CILocation[] location;
}
void onAddSystem(EntitiesData data)
{
foreach(i;0..data.length)
{
if(snake.element(data.location[i]).id == EntityID())snake.element(MapElement(MapElement.Type.snake,data.entity[i].id),data.location[i]);
else launcher.manager.removeEntity(data.entity[i].id);
}
}
void onRemoveEntity(EntitiesData data)
{
foreach(i;0..data.length)
{
if(snake.element(data.location[i].location).id == data.entity[i].id)
snake.element(MapElement(MapElement.Type.empty, EntityID()),data.location[i].location);
foreach(part; data.snake[i].parts.array)
if(snake.element(part).id == data.entity[i].id)
snake.element(MapElement(MapElement.Type.empty, EntityID()),part);
}
}
}
@ -750,6 +781,35 @@ struct CleanSystem
}
}
struct CopyLocationSystem
{
mixin ECS.System!32;
struct EntitiesData
{
uint length;
const (Entity)[] entity;
CLocation[] location;
@readonly CILocation[] ilocation;
}
void onAddEntity(EntitiesData data)
{
foreach(i;0..data.length)
{
data.ilocation[i] = cast(ivec2)(data.location[i] / 16);
}
}
void onUpdate(EntitiesData data)
{
foreach(i;0..data.length)
{
data.location[i] = cast(vec2)(data.ilocation[i] * 16);
}
}
}
__gshared Snake* snake;
void snakeStart()
@ -776,7 +836,6 @@ void snakeStart()
launcher.manager.registerSystem!MoveSystem(0,"fixed");
launcher.manager.registerSystem!InputSystem(-100);
launcher.manager.registerSystem!FixSnakeDirectionSystem(-1,"fixed");
launcher.manager.registerSystem!AppleSystem(-1,"fixed");
launcher.manager.registerSystem!AnimationRenderSystem(100);
launcher.manager.registerSystem!AnimationSystem(-1);
launcher.manager.registerSystem!ParticleSystem(-1);
@ -784,8 +843,20 @@ void snakeStart()
launcher.manager.registerSystem!DrawAppleSystem(99);
launcher.manager.registerSystem!DrawSnakeSystem(101);
launcher.manager.registerSystem!CopyLocationSystem(100);
//launcher.manager.registerSystem!AppleRemoveSystem(100);
launcher.manager.registerSystem!AppleSystem(101);
launcher.manager.registerSystem!SnakeSystem(101);
launcher.manager.endRegister();
launcher.gui_manager.addComponent(CApple(),"Apple");
launcher.gui_manager.addComponent(CSnake(),"Snake");
launcher.gui_manager.addComponent(CParticle(1000),"Particle (1s)");
launcher.gui_manager.addComponent(CParticleVector(vec2(0,1)),"Particle Vector (UP)");
launcher.gui_manager.addComponent(CInput(),"Input");
launcher.gui_manager.addComponent(CMovement(CMovement.Direction.up),"Movement (UP)");
launcher.gui_manager.addSystem(MoveSystem.system_id,"Move System");
launcher.gui_manager.addSystem(InputSystem.system_id,"Input System");
launcher.gui_manager.addSystem(FixSnakeDirectionSystem.system_id,"Fix Direction System");
@ -797,15 +868,13 @@ void snakeStart()
snake.snake_destroy_particle_frames = Mallocator.makeArray([vec4(64,144,16,16)*px,vec4(80,144,16,16)*px,vec4(96,144,16,16)*px,vec4(112,144,16,16)*px].staticArray);
{
ushort[4] components = [CILocation.component_id, CSnake.component_id, CMovement.component_id, CInput.component_id];
ushort[5] components = [CILocation.component_id, CSnake.component_id, CMovement.component_id, CInput.component_id, CLocation.component_id];
snake.snake_tmpl = launcher.manager.allocateTemplate(components);
//CILocation* loc_comp = snake.snake_tmpl.getComponent!CILocation;
//*loc_comp = ivec2(2,2);
launcher.manager.addEntity(snake.snake_tmpl,[CILocation(ivec2(2,2)).ref_].staticArray);
}
{
snake.snake_destroy_particle = launcher.manager.allocateTemplate([CLocation.component_id, CParticle.component_id, CParticleVector.component_id, CAnimation.component_id].staticArray);
snake.snake_destroy_particle = launcher.manager.allocateTemplate([CLocation.component_id, CParticle.component_id, CParticleVector.component_id, CAnimation.component_id, CLocation.component_id].staticArray);
CAnimation* canim = snake.snake_destroy_particle.getComponent!CAnimation;
canim.frames = snake.snake_destroy_particle_frames;
CParticle* particle = snake.snake_destroy_particle.getComponent!CParticle;
@ -813,7 +882,7 @@ void snakeStart()
}
{
ushort[2] components = [CILocation.component_id, CApple.component_id];
ushort[3] components = [CILocation.component_id, CApple.component_id, CLocation.component_id];
snake.apple_tmpl = launcher.manager.allocateTemplate(components);
snake.addApple();
}
@ -824,13 +893,6 @@ void snakeStart()
MoveSystem* move_system = launcher.manager.getSystem!MoveSystem();
move_system.setTemplates();
/*foreach(i; 0..10)
foreach(j; 0..10)
{
loc_compation = vec2(i*32+64,j*32+64);
launcher.manager.addEntity(simple.tmpl);
}*/
}
void snakeEnd()
@ -839,39 +901,6 @@ void snakeEnd()
Mallocator.dispose(snake);
}
void snakeTool(vec2 position, Tool tool, int size)
{
switch(tool)
{
case Tool.entity_spawner:
{
EntityTemplate* tmpl = launcher.gui_manager.getSelectedTemplate();
CLocation* location = tmpl.getComponent!CLocation;
if(location)
{
position.x += (randomf() - 0.5) * size;
position.y += (randomf() - 0.5) * size;
*location = position;
}
CILocation* ilocation = tmpl.getComponent!CILocation;
if(ilocation)
{
position.x += (randomf() - 0.5) * size;
position.y += (randomf() - 0.5) * size;
ivec2 ipos;
ipos.x = cast(int)(position.x / 16);
ipos.y = cast(int)(position.y / 16);
*ilocation = ipos;
if(snake.element(ipos).type != MapElement.Type.empty)return;
}
launcher.manager.addEntity(tmpl);
}
break;
default:
break;
}
}
void snakeEvent(SDL_Event* event)
{
@ -881,16 +910,16 @@ bool snakeLoop()
{
launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(288,288)) * 0.5;
/*if(launcher.show_demo_wnd)
{
igSetNextWindowPos(ImVec2(800 - 260, 30), ImGuiCond_Once, ImVec2(0,0));
igSetNextWindowSize(ImVec2(250, 0), ImGuiCond_Once);
if(igBegin("Snake",&launcher.show_demo_wnd,0))
{
// if(launcher.show_demo_wnd)
// {
// igSetNextWindowPos(ImVec2(800 - 260, 30), ImGuiCond_Once, ImVec2(0,0));
// igSetNextWindowSize(ImVec2(250, 0), ImGuiCond_Once);
// if(igBegin("Snake",&launcher.show_demo_wnd,0))
// {
}
igEnd();
}*/
// }
// igEnd();
// }
launcher.manager.begin();
@ -912,7 +941,5 @@ bool snakeLoop()
launcher.manager.end();
//snake.drawMap();
return true;
}