2D 45度倾斜斜面砖

时间:2012-12-08 05:38:36

标签: c++ 2d sdl

这是我的代码,用于检查磁贴的类型。如果它是倾斜的瓷砖,那么它会更新 角色的位置。如照片所示,我的角色不会沿着斜坡移动。我做错了什么?

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;
        }
    }
}

demonstration

角色的尺寸为48 X 96;分别是宽度和高度。他的起源就像瓷砖一样,位于左上角。

以下是该功能的使用方法

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;
}

调用前一个函数的函数是我的OnMove函数。

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;
}
}

然后在主循环中调用此函数     OnMove(SpeedX,快速); 速度计算为休耕

    SpeedX += AccelX * Time::TimeControl.GetDeltaTime();
    SpeedY += AccelY * Time::TimeControl.GetDeltaTime();

1 个答案:

答案 0 :(得分:1)

我正在给出一个“答案”,但它可能更适合作为评论...几点:

  • 第一个问题,调试器中发生了什么?你甚至进入if
  • 我没有在任何地方看到delta time的提及,它应该用于获得平滑的时间依赖运动(不依赖于帧)
  • PosValidTile并未详细说明该功能的作用...您似乎修改了Entity Y值而不是X如果你不在斜坡上水平移动,你也不会上升是正常的!
  • TILE_TYPE_ANGLEUP对我没有多大意义,因为如果你的角色从右向左转,它的“角度”是“向下”
  • 我猜人物运动在其他地方确定了吗?应该考虑角色的标题,以了解您要去的斜坡的哪一侧(您的“下一个”X,这里似乎没有计算)
  • 此处的功能是否不完整?并非所有路径都返回值

修改:您使用PosValidEntityNewX发布了使用NewY的新代码 - 我们看不到这些值的设置位置,但是请注意,PosValidTile似乎直接修改了Y,而不是“暂定的NewY”。

另外,我不太确定你的Intercept应该做什么。基本上你有Slope,你想知道X轴上有多少像素,将Slope乘以这个相对值,然后加上基数Y。在您的情况下,Slope 始终 TILE_SIZE / TILE_SIZE - &gt; 1因此,找到新的Y应该像以下一样简单 - 如果不是1,只需将相对X乘以该斜率

Y = X + (Width/2) - tileX + tileY;

你取得角色的X位置,添加Half Width并删除拼贴的基本X值,这样就可以了解X的距离轴在斜坡上。由于您的斜率始终为1,因此您在Y轴上与X轴一样远,所以如果您add(或subtract在你的情况下,因为我认为更高的值意味着你的坐标屏幕更低?)这个值到你的基础Y你应该得到你的Y值。