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 Microsoft.Xna.Framework;
using System; using System;
using System.Collections.Generic;
namespace SemiColinGames { namespace SemiColinGames {
public static class Line { public static class Line {
public static Point[] Rasterize(Point p1, Point p2) { public static void Rasterize(Point p1, Point p2, List<Point> result) {
return Line.Rasterize(p1.X, p1.Y, p2.X, p2.Y); Line.Rasterize(p1.X, p1.Y, p2.X, p2.Y, result);
} }
// Rasterizes a line using Bresenham's line-drawing algorithm. // Rasterizes a line using Bresenham's line-drawing algorithm.
@ -13,20 +14,17 @@ namespace SemiColinGames {
// https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm // https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
// http://members.chello.at/~easyfilter/bresenham.html // http://members.chello.at/~easyfilter/bresenham.html
// http://members.chello.at/~easyfilter/Bresenham.pdf (section 1.6) // 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 dx = Math.Abs(x2 - x1);
int stepX = x1 < x2 ? 1 : -1; int stepX = x1 < x2 ? 1 : -1;
int dy = -Math.Abs(y2 - y1); int dy = -Math.Abs(y2 - y1);
int stepY = y1 < y2 ? 1 : -1; int stepY = y1 < y2 ? 1 : -1;
int error = dx + dy; int error = dx + dy;
int errorXY; // Error value e_xy from the PDF. 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; int i = 0;
result[0] = new Point(x1, y1); result.Clear();
result.Add(new Point(x1, y1));
while (x1 != x2 || y1 != y2) { while (x1 != x2 || y1 != y2) {
i++; i++;
errorXY = 2 * error; errorXY = 2 * error;
@ -38,9 +36,8 @@ namespace SemiColinGames {
error += dx; error += dx;
y1 += stepY; 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 ySpeed = 0;
private float invincibilityTime = 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) { public Player(Vector2 position, int facing) {
this.position = position; this.position = position;
Facing = facing; Facing = facing;
@ -83,10 +86,8 @@ namespace SemiColinGames {
} }
bool harmedByCollision = false; bool harmedByCollision = false;
// TODO: pass in movePoints to Line.Rasterize instead of having that function allocate a Line.Rasterize(0, 0, (int) movement.X, (int) movement.Y, movePoints);
// new array. for (int i = 1; i < movePoints.Count; i++) {
Point[] movePoints = Line.Rasterize(0, 0, (int) movement.X, (int) movement.Y);
for (int i = 1; i < movePoints.Length; i++) {
int dx = movePoints[i].X - movePoints[i - 1].X; int dx = movePoints[i].X - movePoints[i - 1].X;
int dy = movePoints[i].Y - movePoints[i - 1].Y; int dy = movePoints[i].Y - movePoints[i - 1].Y;
if (dy != 0) { if (dy != 0) {

View File

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