0

タイルのタイプをチェックする私のコードは次のとおりです。傾斜したタイルの場合、キャラクターの位置を更新します。写真に示されているように、私のキャラクターは斜面に沿って移動しません。私は何を間違っていますか?

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

デモンストレーション

キャラクターの寸法は 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,SpeedY); 速度は休閑地として計算されます

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

1 に答える 1

1

私は「答え」を出していますが、おそらくコメントの方が適しています...いくつかのポイント:

  • 最初の質問は、デバッガーで何が起こっているのですか? あなたも入りますifか?
  • delta timeどこにも言及されていません。時間に依存した動きをスムーズにするために使用する必要があります(フレームに依存しません)。
  • PosValidTile関数が何をするかについてはあまり言いません...Entity Y値を変更しているように見えますが、X斜面に対して水平に動かないと上がらないのが当たり前!
  • TILE_TYPE_ANGLEUPキャラクターが向きを変えて右から左に移動する場合、その「角度」は「下」であるため、私にはあまり意味がありません
  • キャラクターの動きは別のところに決まっているのかな?坂のどちら側に行くのかを知るために、キャラクターの方向を考慮する必要があります (「次の」X、ここでは計算されていないようです)。
  • ここの機能は不完全ですか?すべてのパスが値を返すわけではない

編集:PosValidEntity使用する場所に新しいコードを投稿NewXしましたNewY- これらの値がどこに設定されているかはわかりませんが、「暫定的な NewY」ではなく、PosValidTile直接変更しているように見えることに注意してください。Y

また、私はあなたInterceptが何をすべきかよくわかりません。基本的に、あなたはあなたを持っていて、あなたが軸Slopeに沿って何ピクセルあるかを知りたいのですが、にこの相対値を掛けてから base を追加します。あなたの場合は常に->ですので、新しいものを見つけるのは次のように簡単なはずです。XSlopeYSlope TILE_SIZE / TILE_SIZE1Y1X

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

キャラクターの位置を取得し、タイルの基本値をX追加しHalf Widthて削除します。これにより、斜面の軸に沿った距離がわかります。あなたの傾きは常にであるため、あなたは軸上にいるのと同じくらい軸に沿っています。あなたの価値を得る。XX1YXaddsubtractYY

于 2012-12-08T20:54:56.930 に答える