• entries
    743
  • comments
    1924
  • views
    579617

It works!

Sign in to follow this  
Aardvajk

128 views

The approach before works really well.



Udo can run and jump in front of the blue blocks, but he lands on top of them. Most of the blocks in the screenshot above are from the map grid, but the two next to Udo are free object blocks from the item list.

The new and improved collision code is a lot cleaner:


#include "item.h"
#include "map.h"

CBasicItem::CBasicItem()
{
}

bool CBasicItem::Beneath()
{
std::vector V;

CRect R(int(X),int(Y)+H,W,1);

Map.Collides(R,V);
Items[1].Collides(this,R,V);

for(size_t I=0;I {
if(V.Layer!=ltBack && Y+H==V.Rect.Y) return true;
}

return false;
}

bool CBasicItem::HorzCollide(float &Nx,float &Vx)
{
std::vector V;
CRect R=CRect(int(Nx),int(Y),W,H);

Map.Collides(R,V);
Items[1].Collides(this,R,V);

for(size_t I=0;I {
if(V.Layer==ltFore)
{
if(Vx<0) Nx=float(V.Rect.X+V.Rect.W);
else Nx=float(V.Rect.X-W);

Vx=0; return true;
}
}

return false;
}

bool CBasicItem::VertCollide(float &Ny,float &Vy)
{
std::vector V;
CRect R=CRect(int(X),int(Ny),W,H);

Map.Collides(R,V);
Items[1].Collides(this,R,V);

for(size_t I=0;I {
if(V.Layer==ltFore)
{
if(Vy<0) Ny=float(V.Rect.Y+V.Rect.H);
else Ny=float(V.Rect.Y-H);

Vy=0; return true;
}

if(V.Layer==ltMid)
{
if(int(Y)+H-1.Rect.Y)
{
if(Vy<0) Ny=float(V.Rect.Y+V.Rect.H);
else Ny=float(V.Rect.Y-H);

Vy=0; return true;
}
}
}

return false;
}

void CDynamicItem::Call()
{
if(Vx>0){ Vx-=0.25f; if(Vx<0) Vx=0; }
if(Vx<0){ Vx+=0.25f; if(Vx>0) Vx=0; }

if(!Beneath() && Vy<14.0f) Vy+=0.2f;

float Nx=X+Vx; HorzCollide(Nx,Vx); X=Nx;
float Ny=Y+Vy; VertCollide(Ny,Vy); Y=Ny;

CBasicItem::Call();
}




Any map block types or objects are assigned a layer in the level file. Back layer is not collided at all, mid layer you can go in front of but you land on if falling from above and fore layer is completely solid.

The map and the item list Collides() methods fill a std::vector of PODs that contain the CRect and CLayerType of any items that are intersecting the rectangle passed to them.

As hoped below, this means that you can fill the same vector from multiple sources and perform the same collision code once on the contents of the vector, without the collision code needing to be in any way aware of the internal representation of the various objects that generated the vector.

I'm actually quite proud of this, if I may say so myself. It seems like a really clean and extensible solution.
Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now