Fix ray calculations by normalizing angles properly
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
+19
-42
@@ -24,8 +24,9 @@ const double gameWidth = 320;
|
||||
const double gameHeight = 256;
|
||||
|
||||
extension GameValues on double {
|
||||
/// Normalizes an angle back into [0, 2π].
|
||||
double get normalize => (this % (2 * math.pi) + 2 * math.pi) % (2 * math.pi);
|
||||
/// Normalizes an angle back into [0, 2π) from (-π, π].
|
||||
double get normalizeAngle =>
|
||||
(this % (2 * math.pi) + 2 * math.pi) % (2 * math.pi);
|
||||
|
||||
/// Returns the degree angle
|
||||
double get radianToDegree {
|
||||
@@ -52,14 +53,14 @@ extension GameValues on double {
|
||||
// Flutter's coordinate system flips the y-axis, which is why we have -sin() -- to flip
|
||||
// it back in the correct direction.
|
||||
Offset get direction => Offset(
|
||||
math.cos(normalize),
|
||||
-math.sin(normalize),
|
||||
math.cos(normalizeAngle),
|
||||
math.sin(normalizeAngle),
|
||||
);
|
||||
|
||||
/// Get the delta from the given angle
|
||||
Offset get playerDelta => Offset(
|
||||
math.cos(this) * Player.speed,
|
||||
math.sin(this) * Player.speed,
|
||||
direction.dx * Player.speed,
|
||||
direction.dy * Player.speed,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -191,7 +192,7 @@ class _PlayerState extends State<Player> {
|
||||
widget.onRaysUpdated(
|
||||
calculateRays(
|
||||
widget.rayData.playerPosition,
|
||||
widget.rayData.playerAngle.playerDelta,
|
||||
widget.rayData.playerAngle,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -243,28 +244,23 @@ class _PlayerState extends State<Player> {
|
||||
// Where is the player now?
|
||||
Offset playerPosition = widget.rayData.playerPosition;
|
||||
double playerAngle = widget.rayData.playerAngle;
|
||||
final Offset direction = playerAngle.direction;
|
||||
|
||||
// How many pixels away from a wall to stay
|
||||
const double buffer = 8;
|
||||
|
||||
if (keys.contains(LogicalKeyboardKey.keyA)) {
|
||||
// Move left
|
||||
// Turn left
|
||||
playerAngle -= 0.1;
|
||||
if (playerAngle < 0) {
|
||||
playerAngle += 2 * math.pi;
|
||||
}
|
||||
handled = true;
|
||||
} else if (keys.contains(LogicalKeyboardKey.keyD)) {
|
||||
// Move right
|
||||
// Turn right
|
||||
playerAngle += 0.1;
|
||||
|
||||
if (playerAngle > 2 * math.pi) {
|
||||
playerAngle -= 2 * math.pi;
|
||||
}
|
||||
handled = true;
|
||||
}
|
||||
|
||||
// Capture the direction *after* it's potentially mutated
|
||||
final Offset direction = playerAngle.direction;
|
||||
|
||||
if (keys.contains(LogicalKeyboardKey.keyW)) {
|
||||
if (safeDistanceToWall(playerPosition, direction) >
|
||||
Player.speed + buffer) {
|
||||
@@ -283,7 +279,7 @@ class _PlayerState extends State<Player> {
|
||||
|
||||
if (handled) {
|
||||
widget.onRaysUpdated(
|
||||
calculateRays(playerPosition, playerAngle.playerDelta),
|
||||
calculateRays(playerPosition, playerAngle),
|
||||
);
|
||||
widget.onAngleUpdated(playerAngle);
|
||||
widget.onPositionUpdated(playerPosition);
|
||||
@@ -293,7 +289,7 @@ class _PlayerState extends State<Player> {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Ray> calculateRays(Offset offset, Offset delta) {
|
||||
List<Ray> calculateRays(Offset offset, double playerAngle) {
|
||||
const double dr = math.pi / 180;
|
||||
|
||||
final List<Ray> rays = [];
|
||||
@@ -312,14 +308,7 @@ class _PlayerState extends State<Player> {
|
||||
double rayY = 0;
|
||||
double disT = 0;
|
||||
|
||||
double rayAngle = delta.direction - (dr * 30);
|
||||
|
||||
if (rayAngle < 0) {
|
||||
rayAngle += 2 * math.pi;
|
||||
}
|
||||
if (rayAngle > 2 * math.pi) {
|
||||
rayAngle -= 2 * math.pi;
|
||||
}
|
||||
double rayAngle = (playerAngle - (dr * 30)).normalizeAngle;
|
||||
|
||||
int r;
|
||||
for (r = 0; r < 60; r++) {
|
||||
@@ -492,14 +481,8 @@ class _PlayerState extends State<Player> {
|
||||
}
|
||||
|
||||
// * Increase the ray angle to draw the next ray
|
||||
rayAngle += dr;
|
||||
|
||||
if (rayAngle < 0) {
|
||||
rayAngle += 2 * math.pi;
|
||||
}
|
||||
if (rayAngle > 2 * math.pi) {
|
||||
rayAngle -= 2 * math.pi;
|
||||
}
|
||||
rayAngle =
|
||||
(playerAngle.normalizeAngle - (dr * 30) + r * dr).normalizeAngle;
|
||||
}
|
||||
|
||||
return rays;
|
||||
@@ -608,13 +591,7 @@ class WallPainter extends CustomPainter {
|
||||
const double dr = math.pi / 180;
|
||||
final double rayAngle = playerAngle - (dr * 30) + (i * dr);
|
||||
|
||||
double correctedAngle = playerAngle - rayAngle;
|
||||
if (correctedAngle < 0) {
|
||||
correctedAngle += 2 * math.pi;
|
||||
}
|
||||
if (correctedAngle > 2 * math.pi) {
|
||||
correctedAngle -= 2 * math.pi;
|
||||
}
|
||||
final double correctedAngle = (playerAngle - rayAngle).normalizeAngle;
|
||||
|
||||
final double disT = ray.distance * math.cos(correctedAngle);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user