Player: stop creating a new Point[] via Line.Rasterize every frame.

This commit is contained in:
Colin McMillen 2020-03-18 14:34:47 -04:00
parent 67550a789b
commit de01b04873
3 changed files with 42 additions and 29 deletions

View File

@ -1,10 +1,11 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
namespace SemiColinGames {
public static class Line {
public static Point[] Rasterize(Point p1, Point p2) {
return Line.Rasterize(p1.X, p1.Y, p2.X, p2.Y);
public static void Rasterize(Point p1, Point p2, List<Point> result) {
Line.Rasterize(p1.X, p1.Y, p2.X, p2.Y, result);
}
// Rasterizes a line using Bresenham's line-drawing algorithm.
@ -13,20 +14,17 @@ namespace SemiColinGames {
// https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
// http://members.chello.at/~easyfilter/bresenham.html
// http://members.chello.at/~easyfilter/Bresenham.pdf (section 1.6)
public static Point[] Rasterize(int x1, int y1, int x2, int y2) {
public static void Rasterize(int x1, int y1, int x2, int y2, List<Point> result) {
int dx = Math.Abs(x2 - x1);
int stepX = x1 < x2 ? 1 : -1;
int dy = -Math.Abs(y2 - y1);
int stepY = y1 < y2 ? 1 : -1;
int error = dx + dy;
int errorXY; // Error value e_xy from the PDF.
// The size of the output is the size of the longer dimension, plus one.
int resultSize = Math.Max(dx, -dy) + 1;
// TODO: an array or list should be passed in by the caller.
var result = new Point[resultSize];
int i = 0;
result[0] = new Point(x1, y1);
result.Clear();
result.Add(new Point(x1, y1));
while (x1 != x2 || y1 != y2) {
i++;
errorXY = 2 * error;
@ -38,9 +36,8 @@ namespace SemiColinGames {
error += dx;
y1 += stepY;
}
result[i] = new Point(x1, y1);
result.Add(new Point(x1, y1));
}
return result;
}
}
}

View File

@ -35,6 +35,9 @@ namespace SemiColinGames {
private float ySpeed = 0;
private float invincibilityTime = 0;
// For passing into Line.Rasterize() during movement updates.
private List<Point> movePoints = new List<Point>(100);
public Player(Vector2 position, int facing) {
this.position = position;
Facing = facing;
@ -83,10 +86,8 @@ namespace SemiColinGames {
}
bool harmedByCollision = false;
// TODO: pass in movePoints to Line.Rasterize instead of having that function allocate a
// new array.
Point[] movePoints = Line.Rasterize(0, 0, (int) movement.X, (int) movement.Y);
for (int i = 1; i < movePoints.Length; i++) {
Line.Rasterize(0, 0, (int) movement.X, (int) movement.Y, movePoints);
for (int i = 1; i < movePoints.Count; i++) {
int dx = movePoints[i].X - movePoints[i - 1].X;
int dy = movePoints[i].Y - movePoints[i - 1].Y;
if (dy != 0) {

View File

@ -10,7 +10,8 @@ namespace SemiColinGames.Tests {
public void TestRasterizeSinglePoint() {
var p1 = new Point(10, 10);
var expected = new Point[] { p1 };
var result = Line.Rasterize(p1, p1);
var result = new List<Point>();
Line.Rasterize(p1, p1, result);
CollectionAssert.AreEqual(expected, result);
}
@ -26,7 +27,8 @@ namespace SemiColinGames.Tests {
new Point(14, 10),
new Point(15, 10)
};
var result = Line.Rasterize(p1, p2);
var result = new List<Point>();
Line.Rasterize(p1, p2, result);
CollectionAssert.AreEqual(expected, result);
}
@ -42,7 +44,8 @@ namespace SemiColinGames.Tests {
new Point(11, 10),
new Point(10, 10)
};
var result = Line.Rasterize(p1, p2);
var result = new List<Point>();
Line.Rasterize(p1, p2, result);
CollectionAssert.AreEqual(expected, result);
}
@ -58,7 +61,8 @@ namespace SemiColinGames.Tests {
new Point(10, 14),
new Point(10, 15)
};
var result = Line.Rasterize(p1, p2);
var result = new List<Point>();
Line.Rasterize(p1, p2, result);
CollectionAssert.AreEqual(expected, result);
}
@ -74,7 +78,8 @@ namespace SemiColinGames.Tests {
new Point(10, 11),
new Point(10, 10)
};
var result = Line.Rasterize(p1, p2);
var result = new List<Point>();
Line.Rasterize(p1, p2, result);
CollectionAssert.AreEqual(expected, result);
}
@ -90,7 +95,8 @@ namespace SemiColinGames.Tests {
new Point(4, 4),
new Point(5, 5)
};
var result = Line.Rasterize(p1, p2);
var result = new List<Point>();
Line.Rasterize(p1, p2, result);
CollectionAssert.AreEqual(expected, result);
}
@ -106,7 +112,8 @@ namespace SemiColinGames.Tests {
new Point(4, 1),
new Point(5, 0)
};
var result = Line.Rasterize(p1, p2);
var result = new List<Point>();
Line.Rasterize(p1, p2, result);
CollectionAssert.AreEqual(expected, result);
}
@ -122,7 +129,8 @@ namespace SemiColinGames.Tests {
new Point(1, 4),
new Point(0, 5)
};
var result = Line.Rasterize(p1, p2);
var result = new List<Point>();
Line.Rasterize(p1, p2, result);
CollectionAssert.AreEqual(expected, result);
}
@ -138,7 +146,8 @@ namespace SemiColinGames.Tests {
new Point(1, 1),
new Point(0, 0)
};
var result = Line.Rasterize(p1, p2);
var result = new List<Point>();
Line.Rasterize(p1, p2, result);
CollectionAssert.AreEqual(expected, result);
}
@ -158,7 +167,8 @@ namespace SemiColinGames.Tests {
new Point(4, 8),
new Point(4, 9)
};
var result = Line.Rasterize(p1, p2);
var result = new List<Point>();
Line.Rasterize(p1, p2, result);
CollectionAssert.AreEqual(expected, result);
}
@ -179,7 +189,8 @@ namespace SemiColinGames.Tests {
new Point(5, 9),
new Point(5, 10)
};
var result = Line.Rasterize(p1, p2);
var result = new List<Point>();
Line.Rasterize(p1, p2, result);
CollectionAssert.AreEqual(expected, result);
}
@ -200,7 +211,8 @@ namespace SemiColinGames.Tests {
new Point(0, 1),
new Point(0, 0)
};
var result = Line.Rasterize(p1, p2);
var result = new List<Point>();
Line.Rasterize(p1, p2, result);
CollectionAssert.AreEqual(expected, result);
}
@ -220,7 +232,8 @@ namespace SemiColinGames.Tests {
new Point(8, 4),
new Point(9, 4)
};
var result = Line.Rasterize(p1, p2);
var result = new List<Point>();
Line.Rasterize(p1, p2, result);
CollectionAssert.AreEqual(expected, result);
}
@ -241,7 +254,8 @@ namespace SemiColinGames.Tests {
new Point(9, 5),
new Point(10, 5)
};
var result = Line.Rasterize(p1, p2);
var result = new List<Point>();
Line.Rasterize(p1, p2, result);
CollectionAssert.AreEqual(expected, result);
}
@ -262,7 +276,8 @@ namespace SemiColinGames.Tests {
new Point(1, 0),
new Point(0, 0)
};
var result = Line.Rasterize(p1, p2);
var result = new List<Point>();
Line.Rasterize(p1, p2, result);
CollectionAssert.AreEqual(expected, result);
}
}