示例#1
0
void Character2D::Update(float timeStep)
{
    // Handle wounded/killed states
    if (killed_)
        return;

    if (wounded_)
    {
        HandleWoundedState(timeStep);
        return;
    }

    // Set temporary variables
    auto* input = GetSubsystem<Input>();
    auto* body = GetComponent<RigidBody2D>();
    auto* animatedSprite = GetComponent<AnimatedSprite2D>();
    bool onGround = false;
    bool jump = false;

    // Collision detection (AABB query)
    Vector2 characterHalfSize = Vector2(0.16f, 0.16f);
    auto* physicsWorld = GetScene()->GetComponent<PhysicsWorld2D>();
    PODVector<RigidBody2D*> collidingBodies;
    physicsWorld->GetRigidBodies(collidingBodies, Rect(node_->GetWorldPosition2D() - characterHalfSize - Vector2(0.0f, 0.1f), node_->GetWorldPosition2D() + characterHalfSize));

    if (collidingBodies.Size() > 1 && !isClimbing_)
        onGround = true;

    // Set direction
    Vector2 moveDir = Vector2::ZERO; // Reset

    if (input->GetKeyDown(KEY_A) || input->GetKeyDown(KEY_LEFT))
    {
        moveDir = moveDir + Vector2::LEFT;
        animatedSprite->SetFlipX(false); // Flip sprite (reset to default play on the X axis)
    }
    if (input->GetKeyDown(KEY_D) || input->GetKeyDown(KEY_RIGHT))
    {
        moveDir = moveDir + Vector2::RIGHT;
        animatedSprite->SetFlipX(true); // Flip sprite (flip animation on the X axis)
    }

    // Jump
    if ((onGround || aboveClimbable_) && (input->GetKeyPress(KEY_W) || input->GetKeyPress(KEY_UP)))
        jump = true;

    // Climb
    if (isClimbing_)
    {
        if (!aboveClimbable_ && (input->GetKeyDown(KEY_UP) || input->GetKeyDown(KEY_W)))
            moveDir = moveDir + Vector2(0.0f, 1.0f);

        if (input->GetKeyDown(KEY_DOWN) || input->GetKeyDown(KEY_S))
            moveDir = moveDir + Vector2(0.0f, -1.0f);
    }

    // Move
    if (!moveDir.Equals(Vector2::ZERO) || jump)
    {
        if (onSlope_)
            body->ApplyForceToCenter(moveDir * MOVE_SPEED / 2, true); // When climbing a slope, apply force (todo: replace by setting linear velocity to zero when will work)
        else
            node_->Translate(Vector3(moveDir.x_, moveDir.y_, 0) * timeStep * 1.8f);
        if (jump)
            body->ApplyLinearImpulse(Vector2(0.0f, 0.17f) * MOVE_SPEED, body->GetMassCenter(), true);
    }

    // Animate
    if (input->GetKeyDown(KEY_SPACE))
    {
        if (animatedSprite->GetAnimation() != "attack")
        {
            animatedSprite->SetAnimation("attack", LM_FORCE_LOOPED);
            animatedSprite->SetSpeed(1.5f);
        }
    }
    else if (!moveDir.Equals(Vector2::ZERO))
    {
        if (animatedSprite->GetAnimation() != "run")
            animatedSprite->SetAnimation("run");
    }
    else if (animatedSprite->GetAnimation() != "idle")
    {
        animatedSprite->SetAnimation("idle");
    }
}