fix: improve the terrible rasterization code

This commit is contained in:
punchready 2021-05-31 22:50:44 +02:00
parent 4b794e99e9
commit 1ba5410fd6

View File

@ -12,6 +12,7 @@ import uulm.teamname.marvelous.gamelibrary.requests.RequestType;
import java.awt.*; import java.awt.*;
import java.awt.geom.Line2D; import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.*; import java.util.*;
/** Contains game logic handling. */ /** Contains game logic handling. */
@ -97,24 +98,18 @@ class GameLogic {
} }
case MindStone -> { case MindStone -> {
EntityType target = data.originEntity.type == EntityType.P1 ? EntityType.P2 : EntityType.P1; EntityType target = data.originEntity.type == EntityType.P1 ? EntityType.P2 : EntityType.P1;
Line2D line = new Line2D.Float(data.originField.getX(), data.originField.getY(), data.targetField.getX(), data.targetField.getY()); for(IntVector2 pos: rasterize(data.originField, data.targetField)) {
for(int i = data.originField.getX(); i <= data.targetField.getX(); i++) { for(Entity entity: state.entities.findByPosition(pos)) {
for(int j = data.originField.getY(); j <= data.targetField.getY(); j++) {
var cell = new Rectangle.Float(i - 0.5f, j - 0.5f, 1, 1);
if(line.intersects(cell)) {
for(Entity entity: state.entities.findByPosition(data.targetField)) {
if(entity.id.isSameType(target)) { if(entity.id.isSameType(target)) {
result.add(new EventBuilder(EventType.TakenDamageEvent) result.add(new EventBuilder(EventType.TakenDamageEvent)
.withTargetEntity(entity.id) .withTargetEntity(entity.id)
.withTargetField(new IntVector2(i, j)) .withTargetField(pos)
.withAmount(data.value) .withAmount(data.value)
.buildEntityEvent()); .buildEntityEvent());
} }
} }
} }
} }
}
}
case RealityStone -> { case RealityStone -> {
if(data.originEntity == data.targetEntity) { // => place stone if(data.originEntity == data.targetEntity) { // => place stone
result.add(new EventBuilder(EventType.SpawnEntityEvent) result.add(new EventBuilder(EventType.SpawnEntityEvent)
@ -441,20 +436,11 @@ class GameLogic {
* @return Whether or not the light of sight exists * @return Whether or not the light of sight exists
*/ */
private static boolean checkLineOfSight(GameState state, IntVector2 start, IntVector2 end) { private static boolean checkLineOfSight(GameState state, IntVector2 start, IntVector2 end) {
//naive code for the win!!! \o/ for(IntVector2 pos: rasterize(start, end)) {
//at least its early exit and probably only O(ln(n*m)) if(state.entities.blocksVision(pos)) {
//TODO: implement proper line rasterization algorithm in GameLogic.checkLineOfSight
Line2D line = new Line2D.Float(start.getX(), start.getY(), end.getX(), end.getY());
for(int i = start.getX(); i <= end.getX(); i++) {
for(int j = start.getY(); j <= end.getY(); j++) {
var cell = new Rectangle.Float(i - 0.5f, j - 0.5f, 1, 1);
if(line.intersects(cell)) {
if(state.entities.blocksVision(new IntVector2(i, j))) {
return false; return false;
} }
} }
}
}
return true; return true;
} }
@ -866,4 +852,30 @@ class GameLogic {
return result; return result;
} }
/**
* Computes all fields which intersect the line between the center points of the given two fields.
* @return The list of intersecting positions
*/
public static ArrayList<IntVector2> rasterize(IntVector2 a, IntVector2 b) {
ArrayList<IntVector2> result = new ArrayList<>();
//TODO: implement proper line rasterization algorithm in GameLogic.rasterize
int x1 = Math.min(a.getX(), b.getX());
int x2 = Math.max(a.getX(), b.getX());
int y1 = Math.min(a.getY(), b.getY());
int y2 = Math.max(a.getY(), b.getY());
Line2D line = new Line2D.Float(x1 + 0.5f, y1 + 0.5f, x2 + 0.5f, y2 + 0.5f);
for(int i = x1; i <= x2; i++) {
for(int j = y1; j <= y2; j++) {
Rectangle2D cell = new Rectangle.Float(i, j, 1, 1);
if(line.intersects(cell)) {
result.add(new IntVector2(i, j));
}
}
}
return result;
}
} }