Skip to content

Instantly share code, notes, and snippets.

@kyubuns
Last active February 3, 2020 16:48
Show Gist options
  • Save kyubuns/940a739151a58ffd0c9cd5ff570736e5 to your computer and use it in GitHub Desktop.
Save kyubuns/940a739151a58ffd0c9cd5ff570736e5 to your computer and use it in GitHub Desktop.
Breakout
using System.Collections.Generic;
using Breakout.Component;
using Component;
using MessagePack;
namespace Component
{
[Union(0, typeof(KTransform))]
[Union(3, typeof(KCubeRenderer))]
[Union(4, typeof(KScale))]
[Union(5, typeof(Paddle))]
[Union(6, typeof(Block))]
[Union(7, typeof(Ball))]
[Union(8, typeof(Collider))]
public interface IComponent
{
}
}
namespace Breakout.Component
{
[MessagePackObject(true)]
public class Paddle : IComponent
{
}
[MessagePackObject(true)]
public class Ball : IComponent
{
public Vector2 Velocity { get; set; }
}
[MessagePackObject(true)]
public class Block : IComponent
{
}
[MessagePackObject(true)]
public class Collider : IComponent
{
public ColliderType Type { get; set; }
public List<ColliderType> Hit { get; set; }
}
public enum ColliderType
{
Ball,
Paddle,
XWall,
YWall,
Block,
}
}
using System;
using System.Collections.Generic;
using Breakout.Component;
using Breakout.System;
using Component;
using Context;
using GameSystem;
namespace Breakout
{
public static class Setup
{
public static IComponent[][] Initialize()
{
var entities = new List<IComponent[]>();
entities.Add(new IComponent[]
{
new Paddle(),
new KCubeRenderer { R = 0, G = 255, B = 255 },
new KTransform { X = 0f, Y = -8f },
new KScale { X = 3f, Y = 1f },
new Collider { Type = ColliderType.Paddle },
});
entities.Add(new IComponent[]
{
new Ball { Velocity = new Vector2 { X = 4f, Y = -4f } },
new KCubeRenderer { R = 200, G = 215, B = 225 },
new KTransform { X = 0f, Y = 0f },
new KScale { X = 1f, Y = 1f },
new Collider { Type = ColliderType.Ball },
});
entities.Add(new IComponent[]
{
new KCubeRenderer { R = 189, G = 198, B = 161 },
new KTransform { X = 5f, Y = 0f },
new KScale { X = 1f, Y = 20f },
new Collider { Type = ColliderType.YWall },
});
entities.Add(new IComponent[]
{
new KCubeRenderer { R = 189, G = 198, B = 161 },
new KTransform { X = -5f, Y = 0f },
new KScale { X = 1f, Y = 20f },
new Collider { Type = ColliderType.YWall },
});
entities.Add(new IComponent[]
{
new KCubeRenderer { R = 189, G = 198, B = 161 },
new KTransform { X = 0f, Y = 10f },
new KScale { X = 10f, Y = 1f },
new Collider { Type = ColliderType.XWall },
});
for (var x = -3; x <= 3; x += 2)
{
for (var y = 5; y <= 8; y += 1)
{
entities.Add(new IComponent[]
{
new Block(),
new KCubeRenderer { R = 200, G = 206, B = 208 },
new KTransform { X = x, Y = y },
new KScale { X = 1.5f, Y = 0.8f },
new Collider { Type = ColliderType.Block },
});
}
}
return entities.ToArray();
}
public static ISystem[] Systems()
{
return new ISystem[]
{
new PaddleMoveSystem(),
new BallMoveSystem(),
new CollisionSystem(),
new BallReflectSystem(),
new BlockBreakSystem(),
};
}
}
}
namespace Breakout.System
{
public class CollisionSystem : System<(KTransform, KScale, Collider)>
{
public override void OnUpdate(IWorld world, (KTransform, KScale, Collider)[] colliders)
{
for (var i = 0; i < colliders.Length; ++i)
{
colliders[i].Item3.Hit = new List<ColliderType>();
}
for (var i = 0; i < colliders.Length; ++i)
{
for (var j = i + 1; j < colliders.Length; ++j)
{
var a = colliders[i];
var b = colliders[j];
if ((Math.Abs(a.Item1.X - b.Item1.X) < (a.Item2.X + b.Item2.X) / 2)
&& (Math.Abs(a.Item1.Y - b.Item1.Y) < (a.Item2.Y + b.Item2.Y) / 2))
{
a.Item3.Hit.Add(b.Item3.Type);
b.Item3.Hit.Add(a.Item3.Type);
}
}
}
}
}
public class BallMoveSystem : SystemForeach<(Ball, KTransform)>
{
public override void OnUpdate(IWorld world, (Ball, KTransform) ball)
{
var time = world.GetContext<KTime>();
ball.Item2.X += ball.Item1.Velocity.X * time.DeltaTime;
ball.Item2.Y += ball.Item1.Velocity.Y * time.DeltaTime;
}
}
public class PaddleMoveSystem : SystemForeach<(Paddle, KTransform)>
{
public override void OnUpdate(IWorld world, (Paddle, KTransform) paddle)
{
var keyInput = world.GetContext<KKeyInput>();
var time = world.GetContext<KTime>();
paddle.Item2.X += keyInput.X * time.DeltaTime * 5f;
}
}
public class BallReflectSystem : SystemForeach<(Ball, Collider)>
{
public override void OnUpdate(IWorld world, (Ball, Collider) ball)
{
if (ball.Item2.Hit.Contains(ColliderType.Paddle)
|| ball.Item2.Hit.Contains(ColliderType.XWall)
|| ball.Item2.Hit.Contains(ColliderType.Block))
{
ball.Item1.Velocity.Y *= -1;
}
if (ball.Item2.Hit.Contains(ColliderType.YWall))
{
ball.Item1.Velocity.X *= -1;
}
}
}
public class BlockBreakSystem : SystemForeach<(EntityID, Collider, Block)>
{
public override void OnUpdate(IWorld world, (EntityID, Collider, Block) block)
{
if (!block.Item2.Hit.Contains(ColliderType.Ball)) return;
world.RemoveEntity(block.Item1);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment