[update] Implemented a damage calculation for SquareElement.
This commit is contained in:
parent
bd1c58f26e
commit
bba4cf5765
@ -1,10 +1,14 @@
|
|||||||
/// License: MIT
|
/// License: MIT
|
||||||
module sjplayer.SquareElement;
|
module sjplayer.SquareElement;
|
||||||
|
|
||||||
|
import std.algorithm,
|
||||||
|
std.typecons;
|
||||||
|
|
||||||
import gl4d;
|
import gl4d;
|
||||||
|
|
||||||
import sjplayer.ElementDrawer,
|
import sjplayer.ElementDrawer,
|
||||||
sjplayer.ElementInterface;
|
sjplayer.ElementInterface,
|
||||||
|
sjplayer.util.linalg;
|
||||||
|
|
||||||
///
|
///
|
||||||
class SquareElement : ElementInterface {
|
class SquareElement : ElementInterface {
|
||||||
@ -30,7 +34,33 @@ class SquareElement : ElementInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override DamageCalculationResult CalculateDamage(vec2 p1, vec2 p2) const {
|
override DamageCalculationResult CalculateDamage(vec2 p1, vec2 p2) const {
|
||||||
return DamageCalculationResult(0, 0); // TODO:
|
if (!alive) return DamageCalculationResult(0, 0);
|
||||||
|
|
||||||
|
const m = matrix.inverse;
|
||||||
|
const a = (m * vec3(p1, 1)).xy;
|
||||||
|
const b = (m * vec3(p2, 1)).xy;
|
||||||
|
|
||||||
|
if ((-1 <= a.x && a.x <= 1 && -1 <= a.y && a.y <= 1) ||
|
||||||
|
(-1 <= b.x && b.x <= 1 && -1 <= b.y && b.y <= 1)) {
|
||||||
|
return DamageCalculationResult(damage, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum edges = [
|
||||||
|
tuple(vec2(-1, 1), vec2(-1, -1)),
|
||||||
|
tuple(vec2(-1, -1), vec2( 1, -1)),
|
||||||
|
tuple(vec2( 1, -1), vec2( 1, 1)),
|
||||||
|
tuple(vec2( 1, 1), vec2(-1, 1)),
|
||||||
|
];
|
||||||
|
float[4] distances;
|
||||||
|
static foreach (i, edge; edges) {
|
||||||
|
distances[i] = CalculateDistance2LineSegment(edge[0], edge[1], a, b);
|
||||||
|
}
|
||||||
|
const min_distance = distances[].minElement;
|
||||||
|
|
||||||
|
if (min_distance == 0) {
|
||||||
|
return DamageCalculationResult(damage, 0);
|
||||||
|
}
|
||||||
|
return DamageCalculationResult(0, 1-(min_distance-1).clamp(0f, 1f));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -30,3 +30,50 @@ unittest {
|
|||||||
assert(CalculateDistanceOriginAndLineSegment(
|
assert(CalculateDistanceOriginAndLineSegment(
|
||||||
vec2(-2, 1), vec2(-1, 1)).approxEqual(sqrt(2f)));
|
vec2(-2, 1), vec2(-1, 1)).approxEqual(sqrt(2f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
float CalculateDistance2LineSegment(vec2 a1, vec2 b1, vec2 a2, vec2 b2) {
|
||||||
|
float cross2(vec2 v1, vec2 v2) {
|
||||||
|
return v1.x * v2.y - v1.y * v2.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a1 == b1) return CalculateDistanceOriginAndLineSegment(a2 - a1, b2 - a1);
|
||||||
|
if (a2 == b2) return CalculateDistanceOriginAndLineSegment(a1 - a2, b1 - a2);
|
||||||
|
|
||||||
|
const a1_to_b1 = b1 - a1;
|
||||||
|
const a2_to_b2 = b2 - a2;
|
||||||
|
|
||||||
|
if (cross2(a1_to_b1, a2_to_b2) == 0) {
|
||||||
|
return CalculateDistanceOriginAndLineSegment(a2 - a1, b2 - a1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const a1_to_a2 = a2 - a1;
|
||||||
|
const a1_to_b2 = b2 - a1;
|
||||||
|
const a2_to_a1 = a1 - a2;
|
||||||
|
const a2_to_b1 = b1 - a2;
|
||||||
|
|
||||||
|
if (cross2(a1_to_a2, a1_to_b1) * cross2(a1_to_b2, a1_to_b1) < 0 &&
|
||||||
|
cross2(a2_to_a1, a2_to_b2) * cross2(a2_to_b1, a2_to_b2) < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const b1_to_a2 = a2 - b1;
|
||||||
|
const b1_to_b2 = b2 - b1;
|
||||||
|
return min(
|
||||||
|
CalculateDistanceOriginAndLineSegment(a1_to_a2, a1_to_b2),
|
||||||
|
CalculateDistanceOriginAndLineSegment(b1_to_a2, b1_to_b2)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
///
|
||||||
|
unittest {
|
||||||
|
import std;
|
||||||
|
assert(CalculateDistance2LineSegment(
|
||||||
|
vec2(1, 0), vec2(1, 0), vec2(0, 1), vec2(0, -1)).approxEqual(1f));
|
||||||
|
|
||||||
|
assert(CalculateDistance2LineSegment(
|
||||||
|
vec2(-1, 0), vec2(1, 0), vec2(0, 1), vec2(0, -1)).approxEqual(0f));
|
||||||
|
assert(CalculateDistance2LineSegment(
|
||||||
|
vec2(-1, 0), vec2(1, 0), vec2(1, 1), vec2(1, -1)).approxEqual(0f));
|
||||||
|
assert(CalculateDistance2LineSegment(
|
||||||
|
vec2(-1, 0), vec2(1, 0), vec2(2, 1), vec2(2, -1)).approxEqual(1f));
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user