A stealth-based 2D platformer where you don't have to kill anyone unless you want to. https://www.semicolin.games
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

130 lines
4.8 KiB

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
namespace SemiColinGames {
public sealed class TreeScene : IScene {
const int MAX_SEGMENTS = 1000;
const int MAX_VERTICES = MAX_SEGMENTS * 6; // 2 triangles per segment
private readonly Color backgroundColor = Color.SkyBlue;
private readonly GraphicsDevice graphics;
private readonly BasicEffect basicEffect;
private VertexPositionColor[] vertices;
private VertexBuffer vertexBuffer;
public TreeScene(GraphicsDevice graphics) {
this.graphics = graphics;
basicEffect = new BasicEffect(graphics) {
World = Matrix.CreateTranslation(0, 0, 0),
View = Matrix.CreateLookAt(Vector3.Backward, Vector3.Zero, Vector3.Up),
VertexColorEnabled = true,
Projection = Matrix.CreateOrthographicOffCenter(-1920 / 2, 1920 / 2, -1080 / 4, 1080 * 3 / 4, -1, 1)
};
vertices = new VertexPositionColor[MAX_VERTICES];
vertexBuffer = new VertexBuffer(
graphics, typeof(VertexPositionColor), MAX_VERTICES, BufferUsage.WriteOnly);
}
~TreeScene() {
Dispose();
}
public void Dispose() {
vertexBuffer.Dispose();
GC.SuppressFinalize(this);
}
public struct Trapezoid {
public Vector2 p1, p2, p3, p4;
}
public class TreeNode {
public float Orientation; // relative to parent
public float Length;
public float InWidth;
public float OutWidth;
public readonly List<TreeNode> Children;
public Vector2 Position;
public TreeNode(float orientation, float length, float inWidth, float outWidth) :
this(orientation, length, inWidth, outWidth, new List<TreeNode>()) {}
public TreeNode(float orientation, float length, float inWidth, float outWidth, List<TreeNode> children) {
Orientation = orientation;
Length = length;
InWidth = inWidth;
OutWidth = outWidth;
Children = children;
Position = Vector2.Zero;
}
}
public void Draw(bool isRunningSlowly, IWorld iworld, bool paused) {
var tree =
new TreeNode(0.0f, 100, 10, 6, new List<TreeNode>() {
new TreeNode(-0.1f, 100, 10, 6, new List<TreeNode>() {
new TreeNode(-0.1f, 100, 10, 6, new List<TreeNode>() {
new TreeNode(-0.3f, 100, 6, 4, new List<TreeNode>() {
new TreeNode(-0.1f, 100, 6, 4, new List<TreeNode>() {
new TreeNode(-0.3f, 150, 4, 2),
new TreeNode(0.2f, 200, 4, 2),
new TreeNode(0.5f, 100, 4, 2)
})}),
new TreeNode(0.5f, 100, 6, 4, new List<TreeNode>() {
new TreeNode(-0.1f, 100, 6, 4, new List<TreeNode>() {
new TreeNode(-0.1f, 150, 4, 2),
new TreeNode(0.2f, 200, 4, 2)
})}),
})})});
graphics.Clear(backgroundColor);
var segments = new List<Trapezoid>();
LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
queue.AddLast(tree);
while (queue.Count > 0) {
TreeNode parent = queue.First.Value;
queue.RemoveFirst();
Vector2 outVector = new Vector2(0, parent.Length).Rotate(parent.Orientation);
Vector2 outPosition = Vector2.Add(parent.Position, outVector);
Trapezoid t = new Trapezoid();
t.p1 = new Vector2(parent.Position.X - parent.InWidth, parent.Position.Y);
t.p2 = new Vector2(parent.Position.X + parent.InWidth, parent.Position.Y);
t.p3 = new Vector2(outPosition.X - parent.OutWidth, outPosition.Y);
t.p4 = new Vector2(outPosition.X + parent.OutWidth, outPosition.Y);
segments.Add(t);
foreach (TreeNode child in parent.Children) {
child.Position = outPosition;
child.Orientation += parent.Orientation;
queue.AddLast(child);
}
}
Color color = Color.SaddleBrown;
for (int i = 0; i < segments.Count; i++) {
Trapezoid t = segments[i];
vertices[i * 6] = new VertexPositionColor(new Vector3(t.p1.X, t.p1.Y, 0), color);
vertices[i * 6 + 1] = new VertexPositionColor(new Vector3(t.p2.X, t.p2.Y, 0), color);
vertices[i * 6 + 2] = new VertexPositionColor(new Vector3(t.p3.X, t.p3.Y, 0), color);
vertices[i * 6 + 3] = new VertexPositionColor(new Vector3(t.p2.X, t.p2.Y, 0), color);
vertices[i * 6 + 4] = new VertexPositionColor(new Vector3(t.p3.X, t.p3.Y, 0), color);
vertices[i * 6 + 5] = new VertexPositionColor(new Vector3(t.p4.X, t.p4.Y, 0), color);
}
graphics.SetVertexBuffer(vertexBuffer);
vertexBuffer.SetData(vertices);
foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes) {
pass.Apply();
graphics.DrawPrimitives(PrimitiveType.TriangleList, 0, segments.Count * 2);
}
}
}
}