• entries
    743
  • comments
    1924
  • views
    580353

Started again

Sign in to follow this  

119 views

It's starting to come together. The main character can now jump in front of certain block types but land on them, as well as interact correctly with entirely solid blocks, both in terms of map blocks from the grid and free object blocks. All seems to be okay.

Here's the final collision code.


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

CBasicItem::CBasicItem()
{
}

bool CBasicItem::Beneath()
{
if(IsPC())
{
CItem *IA=Items[1].At(int(X),int(Y)+H);
CItem *IB=Items[1].At(int(X)+W-1,int(Y)+H);

if(IA==this) IA=0;
if(IB==this) IB=0;

if(IA && IA->GetLayer()!=ltBack) return true;
if(IB && IB->GetLayer()!=ltBack) return true;
}

if(int(Y+H-1)%BD!=BD-1) return false;

CMapCell A=MapCells[Map.At(int(X),int(Y)+H)];
CMapCell B=MapCells[Map.At(int(X)+W-1,int(Y)+H)];

return(A.Layer!=ltBack || B.Layer!=ltBack);
}

bool CBasicItem::HorzCollide(float &Nx,float &Vx)
{
if(Vx<0)
{
if(IsPC())
{
CItem *IA=Items[1].At(int(Nx),int(Y));
CItem *IB=Items[1].At(int(Nx),int(Y)+H-1);

if(IA==this) IA=0;
if(IB==this) IB=0;

if((IA && IA->GetLayer()==ltFore) || (IB && IB->GetLayer()==ltFore))
{
CItem *I=(IA ? IA : IB);

Nx=float(I->GetX()+I->GetRect().W); Vx=0;
return true;
}
}

CMapCell MA=MapCells[Map.At(int(Nx),int(Y))];
CMapCell MB=MapCells[Map.At(int(Nx),int(Y)+H-1)];

if(MA.Layer==ltFore || MB.Layer==ltFore)
{
Nx=float((((int(Nx)+BD)/BD)*BD)); Vx=0;
return true;
}
}

else if(Vx>0)
{
if(IsPC())
{
CItem *IA=Items[1].At(int(Nx)+W,int(Y));
CItem *IB=Items[1].At(int(Nx)+W,int(Y)+H-1);

if(IA==this) IA=0;
if(IB==this) IB=0;

if((IA && IA->GetLayer()==ltFore) || (IB && IB->GetLayer()==ltFore))
{
CItem *I=(IA ? IA : IB);

Nx=float(I->GetX()-W); Vx=0;
return true;
}
}

CMapCell MA=MapCells[Map.At(int(Nx)+W,int(Y))];
CMapCell MB=MapCells[Map.At(int(Nx)+W,int(Y)+H-1)];

if(MA.Layer==ltFore || MB.Layer==ltFore)
{
Nx=float((((int(Nx)+W)/BD)*BD)-W); Vx=0;
return true;
}
}

return false;
}

bool CBasicItem::VertCollide(float &Ny,float &Vy)
{
if(Vy>0)
{
if(IsPC())
{
CItem *IA=Items[1].At(int(X),int(Ny)+H-1);
CItem *IB=Items[1].At(int(X)+W-1,int(Ny)+H-1);

if(IA==this) IA=0;
if(IB==this) IB=0;

if((IA && IA->GetLayer()==ltFore) || (IB && IB->GetLayer()==ltFore))
{
CItem *I=(IA ? IA : IB);

Ny=float(I->GetY()-H); Vy=0;
return true;
}

if((IA && IA->GetLayer()==ltMid) || (IB && IB->GetLayer()==ltMid))
{
CItem *I=(IA ? IA : IB);
if(Y+H-1<=I->GetY()){ Ny=float(I->GetY()-H); Vy=0; return true; }
}
}

CMapCell MA=MapCells[Map.At(int(X),int(Ny)+H-1)];
CMapCell MB=MapCells[Map.At(int(X)+W-1,int(Ny)+H-1)];

if(MA.Layer==ltFore || MB.Layer==ltFore)
{
Ny=float((((int(Ny)+H)/BD)*BD)-H); Vy=0;
return true;
}

if(MA.Layer==ltMid || MB.Layer==ltMid)
{
float Ty=float(((int(Ny)+H)/BD)*BD);

CMapCell MC=MapCells[Map.At(int(X),int(Ty))];
CMapCell MD=MapCells[Map.At(int(X)+W-1,int(Ty))];

if(MC.Layer==ltBack && MD.Layer==ltBack) return false;

if(Y+H-1<=Ty){ Ny=Ty-H; Vy=0; return true; }
}
}

else if(Vy<0)
{
if(IsPC())
{
CItem *IA=Items[1].At(int(X),int(Ny));
CItem *IB=Items[1].At(int(X)+W-1,int(Ny));

if(IA==this) IA=0;
if(IB==this) IB=0;

if((IA && IA->GetLayer()==ltFore) || (IB && IB->GetLayer()==ltFore))
{
CItem *I=(IA ? IA : IB);

Ny=float(I->GetY()+I->GetRect().H); Vy=0;
return true;
}
}

CMapCell MA=MapCells[Map.At(int(X),int(Ny))];
CMapCell MB=MapCells[Map.At(int(X)+W-1,int(Ny))];

if(MA.Layer==ltFore || MB.Layer==ltFore)
{
Ny=float((((int(Ny)+BD)/BD)*BD)); 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((Vy<0 || !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();
}



Each map cell type or free object can be either in a back layer (non-solid), a mid layer (can run in front of, but land on and run on top of) or a fore layer (completely solid).

This has nothing to do with the order in which layers are actually drawn, purely in terms of collision detection.

Feeling a bit more enthused again now.
Sign in to follow this  


2 Comments


Recommended Comments

Very cool. I wish I was mathematically capable of rewriting the collisions that govern objects in TGB (I have the source license). The implementation of collision layers in that engine continues to boggle me. Looks like you're doing good tho, haha

Share this comment


Link to comment
Well, I don't know really. I seem to be having to replicate a lot of code to handle free objects as to handle map blocks, and the whole thing has the rather annoying problem that larger objects can fall through smaller ones, which is a bit rubbish.

I didn't actually think of that until this morning, so the whole thing is going to have to be seriously rewritten I think. It's a bit of a pain really.

I don't know if it is just me, but these Mario blocks that you can run in front of but jump up and land on are proving really complicated to implement. Perhaps I'm missing something stupid.

[EDIT] Moved a lot of waffle into a new entry since I'd like others feedback.

Share this comment


Link to comment

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