patternjavaMinor
Removing duplicate code from basic collision detection implementation
Viewed 0 times
collisionremovingduplicatedetectioncodeimplementationfrombasic
Problem
The code is part of a very basic 2D platformer based on code from the book Killer Game Programming in Java.
The methods are part of a
-
The first method returns the greatest distance that an entity can travel in the y axis (up to deltaY) without colliding with a tile:
-
The second method does the same thing in the x axis:
```
public int getMaxDeltaX(Point initialPoint, int deltaX){
//validate params
if(deltaX>=tileMap.getTileWidth()) throw new IllegalArgumentException("Cannot validate if moveStep is larger than brickWidth");
if(deltaX==0) return deltaX;
int testX = (initialPoint.x + deltaX);
int y = initialPoint.y;
//if we collide
if(isInsideTile(testX, y)){
//get which column we are colliding with
int mapCol = testX/tileMap.getTileWidth();
//the distance between our position and
//the left side of the tile we are colliding with
int leftOffset = testX - (mapCol * tileMap.getTile
The methods are part of a
TileMapManager class which is handling basic collision detection.-
The first method returns the greatest distance that an entity can travel in the y axis (up to deltaY) without colliding with a tile:
public int getMaxDeltaY(Point initialPoint, int deltaY){
//validate params
if(deltaY>=tileMap.getTileHeight()) throw new IllegalArgumentException("Cannot validate if deltaY is larger than brickHeight");
if(deltaY==0) return deltaY;
int x = initialPoint.x;
int testY = initialPoint.y + deltaY;
if(isInsideTile(x, testY)){
//get which row we are colliding with
int mapRow = testY/tileMap.getTileHeight();
//the distance between our position and
//the top of the tile we are colliding with
int topOffset = testY - (mapRow * tileMap.getTileHeight());
//get the amount we should move to place
//ourselves just next to the tile (top or bottom)
int maxDeltaY = 0;
//moving up case
if(deltaY 0){
maxDeltaY = deltaY - topOffset;
}
return maxDeltaY;
}
//we won't collide so it's okay to move deltaY
return deltaY;
}-
The second method does the same thing in the x axis:
```
public int getMaxDeltaX(Point initialPoint, int deltaX){
//validate params
if(deltaX>=tileMap.getTileWidth()) throw new IllegalArgumentException("Cannot validate if moveStep is larger than brickWidth");
if(deltaX==0) return deltaX;
int testX = (initialPoint.x + deltaX);
int y = initialPoint.y;
//if we collide
if(isInsideTile(testX, y)){
//get which column we are colliding with
int mapCol = testX/tileMap.getTileWidth();
//the distance between our position and
//the left side of the tile we are colliding with
int leftOffset = testX - (mapCol * tileMap.getTile
Solution
It seems this is a job for a Parameter class.
I leave to you the job of guessing what would be DeltaYParameters :p
Now you could call
What I have done here is to take the advantage of polymorphism over DeltaParameters class. Which could not be a so straigthforward method to refactor is now proven to be in a quite simple fashion imho.
public abstract class DeltaParameters{
protected ? tileMap;
protected int x, y;
DeltaParameters(Point point, ? tileMap){
this.x = point.x;
this.y = point.y;
this.tileMap = tileMap;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public abstract int getTileSideSize();
public abstract int getMovingCoordinate();
public abstract void offsetMovingCoordinate(int delta);
}
public class DeltaXParameters extends DeltaParameters{
DeltaXParameters(Point point, ? tileMap){
super(point, tileMap);
}
public int getTileSideSize(){
return tileMap.getTileWidth();
}
public int getMovingCoordinate(){
return x;
}
public void offsetMovingCoordinate(int delta){
x += delta;
}
}I leave to you the job of guessing what would be DeltaYParameters :p
public int getMaxDelta(DeltaParameters dparams, int delta){
if(delta>=dparams.getTileSideSize()) throw new IllegalArgumentException("This message is yet to be determined. It could be another method in DeltaParameters");
if(delta==0) return delta;
dparams.offsetMovingCoordinate(delta);
if(isInsideTile(dparams.getX(), dparams.getY())){
int map = dparams.getMovingCoordinate() /dparams.getTileSideSize() ;
int offset = dparams.getMovingCoordinate() - (map * dparams.getTileSideSize() );
int maxDelta = 0;
if(delta 0){
maxDelta = delta - offset;
}
return maxDelta;
}
return delta;
}Now you could call
getMaxDelta just like thisgetMaxDelta(new DeltaXParameters(new Point(0, 0), tileMap), 5);What I have done here is to take the advantage of polymorphism over DeltaParameters class. Which could not be a so straigthforward method to refactor is now proven to be in a quite simple fashion imho.
Code Snippets
public abstract class DeltaParameters{
protected ? tileMap;
protected int x, y;
DeltaParameters(Point point, ? tileMap){
this.x = point.x;
this.y = point.y;
this.tileMap = tileMap;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public abstract int getTileSideSize();
public abstract int getMovingCoordinate();
public abstract void offsetMovingCoordinate(int delta);
}
public class DeltaXParameters extends DeltaParameters{
DeltaXParameters(Point point, ? tileMap){
super(point, tileMap);
}
public int getTileSideSize(){
return tileMap.getTileWidth();
}
public int getMovingCoordinate(){
return x;
}
public void offsetMovingCoordinate(int delta){
x += delta;
}
}public int getMaxDelta(DeltaParameters dparams, int delta){
if(delta>=dparams.getTileSideSize()) throw new IllegalArgumentException("This message is yet to be determined. It could be another method in DeltaParameters");
if(delta==0) return delta;
dparams.offsetMovingCoordinate(delta);
if(isInsideTile(dparams.getX(), dparams.getY())){
int map = dparams.getMovingCoordinate() /dparams.getTileSideSize() ;
int offset = dparams.getMovingCoordinate() - (map * dparams.getTileSideSize() );
int maxDelta = 0;
if(delta < 0){
maxDelta = delta + (dparams.getTileSideSize() - offset);
}
else if(delta > 0){
maxDelta = delta - offset;
}
return maxDelta;
}
return delta;
}getMaxDelta(new DeltaXParameters(new Point(0, 0), tileMap), 5);Context
StackExchange Code Review Q#48693, answer score: 3
Revisions (0)
No revisions yet.