Here is my code that checks the type of tile. If its an inclined tile it then updates the
position of the character. As demonstrated in the photo my character does not move along the slope. What am I doing wrong?
bool Entity::PosValidTile(Tile* Tile, int tileX, int tileY)
{
if(Tile->TypeID == TILE_TYPE_ANGLEUP)
{
int Slope, Intercept;
int newY;
Vector P1,P2;
P1.X = tileX; P1.Y = tileY + TILE_SIZE;
P2.X = tileX + TILE_SIZE; P2.Y = tileY;
if(X + (Width/2) > tileX)
{
Slope = -(P2.Y- P1.Y) / (P2.X - P1.X);
Intercept = Slope * (-P1.X + P1.Y);
newY = Slope * ((X + Width/2) + Intercept);
Y = (newY - Height);
return true;
}
}
}

The dimensions of the character are 48 X 96; which are Width and Height respectively. His origin like the tile, is at the upper left corner.
Here is how that function is used
bool Entity::PosValid(int NewX, int NewY)
{
bool Return = true;
int StartX = (NewX + Col_X) / TILE_SIZE;
int StartY = (NewY + Col_Y) / TILE_SIZE;
int EndX = ((NewX + Col_X) + Width - Col_Width - 1) / TILE_SIZE;
int EndY = ((NewY + Col_Y) + Height - Col_Height - 1) / TILE_SIZE;
if(Flags & ENTITY_FLAG_IGNOREMAP)
{
}else
{
for(int iY = StartY; iY <= EndY;iY++)
{
for(int iX = StartX;iX <= EndX;iX++)
{
Tile* Tile = Area::AreaControl.GetTile(iX * TILE_SIZE, iY * TILE_SIZE);
int atileY = iY * TILE_SIZE;
int atileX = iX * TILE_SIZE;
if(PosValidTile(Tile,atileX,atileY) == false)
{
Return = false;
}
}
}
}
if(Flags & ENTITY_FLAG_MAPONLY)
{
}else
{
for(int i = 0;i < (int)EntityList.size();i++)
{
if(PosValidEntity(EntityList[i], NewX, NewY) == false)
{
Return = false;
}
}
}
return Return;
}
The function that calls the previous one is my OnMove function.
void Entity::OnMove(float MoveX, float MoveY)
{
if(MoveX == 0 && MoveY == 0) return;
double NewX = 0;
double NewY = 0;
CanJump = false;
MoveX *= Time::TimeControl.GetDeltaTime();
MoveY *= Time::TimeControl.GetDeltaTime();
if(MoveX != 0)
{
if(MoveX >= 0) NewX = Time::TimeControl.GetDeltaTime();
else NewX = -Time::TimeControl.GetDeltaTime();
}
if(MoveY != 0)
{
if(MoveY >= 0) NewY = Time::TimeControl.GetDeltaTime();
else NewY = -Time::TimeControl.GetDeltaTime();
}
while(true)
{
if(Flags & ENTITY_FLAG_GHOST)
{
PosValid((float)(X + NewX), (float)(Y + NewY));
X += (float)NewX;
Y += (float)NewY;
}else
{
if(PosValid((float)(X + NewX), (int)(Y)))
{
X += (float)NewX;
}else
{
SpeedX = 0;
}
if(PosValid((float)(X), (float)(Y + NewY)))
{
Y += (float)NewY;
}else
{
if(MoveY > 0)
{
CanJump = true;
}
SpeedY = 0;
}
}
MoveX += (float)-NewX;
MoveY += (float)-NewY;
if(NewX > 0 && MoveX <= 0) NewX = 0;
if(NewX < 0 && MoveX >= 0) NewX = 0;
if(NewY > 0 && MoveY <= 0) NewY = 0;
if(NewY < 0 && MoveY >= 0) NewY = 0;
if(MoveX == 0) NewX = 0;
if(MoveY == 0) NewY = 0;
if(MoveX == 0 && MoveY == 0) break;
if(NewX == 0 && NewY == 0) break;
}
}
This function is then called in the main Loop Like so
OnMove(SpeedX,SpeedY);
The speeds are calculated as fallows
SpeedX += AccelX * Time::TimeControl.GetDeltaTime();
SpeedY += AccelY * Time::TimeControl.GetDeltaTime();
I’m giving an “answer” but it probably better fit as a comment… a few points:
if?delta timeanywhere, it should be used to get smooth time dependent movement (not frame dependent)PosValidTiledoesn’t say much about what the function does… you seem to modify yourEntityYvalue but not theX? if you don’t move horizontally against the slope, it’s normal that you don’t go up either!TILE_TYPE_ANGLEUPdoesn’t make much sense to me, as its “angle” is “down” if your character turns and goes from right to leftX, which doesn’t seem to be computed here)Edit: You posted new code where you use
PosValidEntityusingNewXandNewY– we don’t see where these values are set to, but keep in mind that yourPosValidTileseems to modify directlyY, not a “tentative NewY”.Also, I’m not too sure what your
Interceptis supposed to do. Basically you have yourSlopeand you want to know how many pixels along theXaxis you are, multiply theSlopeby this relative value and then add the baseY. In your caseSlopeis alwaysTILE_SIZE / TILE_SIZE->1so finding your newYshould be as easy as something like – if it’s not always1, simply multiply the relativeXby that slopeYou take the
Xposition of your character, add theHalf Widthand the remove the baseXvalue of the tile, this gives you how far along theXaxis you are on the slope. Since your slope is always1, you are as far along theYaxis as you are on theXaxis, so if youadd(orsubtractin your case because I think higher values mean lower on the screen in your coordinates?) this value to your baseYyou should get yourYvalue.