Skip to content

Commit

Permalink
Refactored collision logic.
Browse files Browse the repository at this point in the history
  • Loading branch information
Danny Hendrix committed Sep 16, 2015
1 parent 6e1229b commit 761cfba
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 156 deletions.
6 changes: 3 additions & 3 deletions lib/game/level.dart
Expand Up @@ -100,9 +100,9 @@ class Level
{
}

void isCollision(GameObject object)
void repairCollision(GameObject object)
{
object.checkLevelBorderCollision();
object.repairLevelBorderCollision();

int tileCollStartX = (object.collisionx/32).floor().toInt();
int tileCollEndX = (object.collisionx2/32).ceil().toInt();
Expand All @@ -121,7 +121,7 @@ class Level
intkey = iy * tilesx + ix;
if(leveltiles.length <= intkey || intkey < 0)
continue;
leveltiles[intkey].isCollision(object);
leveltiles[intkey].repairCollision(object);
}
}

Expand Down
46 changes: 19 additions & 27 deletions lib/game/leveltile.dart
Expand Up @@ -16,21 +16,23 @@ class LevelTile
int _tileid = 0;
List<RenderObject> objects;
bool changed = true;
CollisionField collision;
bool hascollision = false;
Sprite sprite;

RenderLayer layer;

Level level;

static CollisionField TILE_COLLISIONFIELD = new CollisionField(0,0,32,32);

void set tileid(int value)
{
_tileid = value;
sprite.spritex = (_tileid - 1) * 32;
if(_tileid != 0)
setCollision(true);
hascollision = true;
else
setCollision(false);
hascollision = false;
}
int get tileid => _tileid;

Expand All @@ -41,7 +43,7 @@ class LevelTile
layer.height = h;

if(_tileid != 0)
setCollision(true);
hascollision = true;

sprite = new Sprite("resources/images/images.png",(_tileid - 1) * 32,0,32,32);
}
Expand All @@ -51,7 +53,6 @@ class LevelTile
if(objects == null)
objects = new List<RenderObject>();
objects.add(obj);
changed = true;
repaint();
}

Expand All @@ -64,47 +65,36 @@ class LevelTile
return remove(obj);
if(index == -1)
return insert(obj);
changed = true;

repaint();
}

void setCollision(bool value)
{
if(value == false)
collision = null;
else
collision = new CollisionField(0,0,w,h);
}

void isCollision(RenderObject obj)
void repairCollision(RenderObject obj)
{

if(collision != null)
if(hascollision)
{
obj.checkTileCollision(this);
return;
obj.repairCollisionTile(this);
return;
}
if(objects == null)
return;

if( (
//check if the collisionfield of the object within the bounderies of this tile
if( !(
obj.collisionx2 > x
&& obj.collisionx < x+w
&& obj.collisiony2+1 > y
&& obj.collisiony < y+h
) == false
)
)
{
return;
}
RenderObject levelobject;
//loop through objects currently on this tile and check for collisions
for(int i = 0; i < objects.length; i++)
{
if(objects[i] == obj)
continue;
levelobject = objects[i];
obj.checkObjectCollision(levelobject);
obj.repairCollisionObject(objects[i]);
}
}

Expand All @@ -115,10 +105,9 @@ class LevelTile
if(index == -1)
return;
objects.removeAt(index);
//objects.removeRange(index, 1);
if(objects.length == 0)
objects = null;
changed = true;

repaint();
}

Expand Down Expand Up @@ -164,6 +153,9 @@ class LevelTile

void repaint()
{
if(changed)
return;
changed = true;
level.updatetiles.add(this);
}
}
2 changes: 1 addition & 1 deletion lib/game/render.dart
Expand Up @@ -40,6 +40,6 @@ class Render

game.level.draw(layer, game.camera.x, game.camera.y);

layer.ctx.fillText("FPS: ${game..gameloop.fps}", 10, 20);
layer.ctx.fillText("FPS: ${game.gameloop.fps}", 10, 20);
}
}
25 changes: 16 additions & 9 deletions lib/game/renderobject.dart
Expand Up @@ -50,7 +50,6 @@ class RenderObject

void paint()
{

}

void drawCollision(RenderLayer targetlayer, int offsetx, int offsety)
Expand Down Expand Up @@ -78,19 +77,27 @@ class RenderObject
targetlayer.ctx.drawImage(layer.canvas, (x-offsetx).round().toInt(), (y-offsety).round().toInt());
}

bool checkCollisionField(double relativex, double relativey, CollisionField collisionfield)
bool isCollisionField(double relativex, double relativey, CollisionField collisionfield)
{
return false;
if(collision == null)
return false;
return
collisionx2 > relativex
&& collisionx < relativex+collisionfield.x2
&& collisiony2 > relativey
&& collisiony < relativey+collisionfield.y2;
}

bool checkTileCollision(LevelTile tile)
void repairCollisionTile(LevelTile tile)
{
return checkCollisionField(tile.x.toDouble(), tile.y.toDouble(),tile.collision);
}

bool checkObjectCollision(RenderObject o)
void repairCollisionObject(RenderObject obj)
{
}
void onTileCollision(LevelTile tile)
{
}
void onObjectCollision(RenderObject o)
{
return checkCollisionField(o.x, o.y, o.collision);
}

void updateDrawLocation([bool remove = false])
Expand Down
4 changes: 2 additions & 2 deletions lib/game/renderobject/door.dart
Expand Up @@ -32,7 +32,7 @@ class Door extends InteractiveObject
if(layerwidth > w)
{
w = layerwidth;
collision.x += ((w-25)/2).toInt();
collision.x += (w-25)~/2;
}
collision.y += layerheight;
h += layerheight;
Expand All @@ -49,7 +49,7 @@ class Door extends InteractiveObject
{
int drawx = 0;
if(w > 25)
drawx = ((w-25)/2).toInt();
drawx = (w-25)~/2;

sprite.drawOnPosition(drawx,layerheight,(over == true)?1:0,0,layer);
}
Expand Down
76 changes: 37 additions & 39 deletions lib/game/renderobject/gameobject.dart
Expand Up @@ -26,102 +26,100 @@ class GameObject extends RenderObject
{
}

bool checkLevelBorderCollision()
void repairLevelBorderCollision()
{
bool ret = false;
if(collisionx2 > game.level.x+game.level.w)
{
x = game.level.x+game.level.w-collision.x2;
ret = true;
}
if(collisionx < game.level.x)
{
x = game.level.x-collision.x;
ret = true;
}
if(collisiony2 > game.level.y+game.level.h)
{
y = game.level.y+game.level.h-collision.y2;
onPlatform = true;
ret = true;
}
if(collisiony < game.level.y)
{
y = game.level.y-collision.y;
ret = true;
}

if(collisiony2+1 > game.level.y+game.level.h)
onPlatform = true;
return ret;
}

bool checkCollisionField(double relativex, double relativey, CollisionField collisionfield)
void repairCollisionTile(LevelTile tile)
{
if(isCollisionField(tile.x.toDouble(),tile.y.toDouble(),LevelTile.TILE_COLLISIONFIELD))
onTileCollision(tile);
}
void repairCollisionObject(RenderObject obj)
{
if(isCollisionField(obj.x,obj.y,obj.collision))
onObjectCollision(obj);
}

void onTileCollision(LevelTile tile)
{
//collision
double dif_x = prev_x - x;
double dif_y = prev_y - y;

/*
//if no collision, only check for platform
if( (
collisionx2 > relativex
&& collisionx < relativex+collisionfield.x2
&& collisiony2 > relativey
&& collisiony < relativey+collisionfield.y2
collisionx2 > tile.x
&& collisionx < tile.x+tile.collision.x2
&& collisiony2 > tile.y
&& collisiony < tile.y+tile.collision.y2
) == false)
{
//no collision but it might be on top of the object
if( (
collisionx2 > relativex
&& collisionx < relativex+collisionfield.x2
&& collisiony2+1 > relativey
&& collisiony < relativey+collisionfield.y2
collisionx2 > tile.x
&& collisionx < tile.x+tile.collision.x2
&& collisiony2+1 > tile.y
&& collisiony < tile.y+tile.collision.y2
) == true)
{
onPlatform = true;
}
return false;
return;
}
//not moved:
if(dif_x == 0 && dif_y == 0)
return false;

return;
*/
double overlap_x = 0.0;
double overlap_y = 0.0;

if(dif_x > 0)//left
overlap_x = relativex + collisionfield.x2 - collisionx;
overlap_x = tile.x + LevelTile.TILE_COLLISIONFIELD.x2 - collisionx;
if(dif_x < 0)//right
overlap_x = relativex + collisionfield.x - collisionx2;
overlap_x = tile.x + LevelTile.TILE_COLLISIONFIELD.x - collisionx2;
if(dif_y > 0)//top
overlap_y = relativey + collisionfield.y2 - collisiony;
overlap_y = tile.y + LevelTile.TILE_COLLISIONFIELD.y2 - collisiony;
if(dif_y < 0)//bottom
overlap_y = relativey + collisionfield.y - collisiony2;
overlap_y = tile.y + LevelTile.TILE_COLLISIONFIELD.y - collisiony2;

double percentage = 0.0;
double percentage_y = 0.0;

if(dif_x != 0)
percentage = (dif_x - overlap_x) / dif_x;
if(dif_y != 0)
percentage_y = (dif_y - overlap_y) / dif_y;
percentage = Math.max(percentage, percentage_y);

x = prev_x - (dif_x * percentage);
y = prev_y - (dif_y * percentage);

//check if on platform after the obj moved
if( (
collisionx2 > relativex
&& collisionx < relativex+collisionfield.x2
&& collisiony2+1 > relativey
&& collisiony < relativey+collisionfield.y2
collisionx2 > tile.x
&& collisionx < tile.x+LevelTile.TILE_COLLISIONFIELD.x2
&& collisiony2+1 > tile.y
&& collisiony < tile.y+LevelTile.TILE_COLLISIONFIELD.y2
) == true)
{
onPlatform = true;
}

return true;
return;
}


Expand Down

0 comments on commit 761cfba

Please sign in to comment.