Реализация «резиновой ленты» камеры с использованием преобразований Canvas в Android - PullRequest
2 голосов
/ 30 мая 2011

Я пишу 2D-игру с боковой прокруткой для Android и пытаюсь реализовать своего рода движение резиновых полос / упругих камер, которое следует за персонажем игрока вверх и вниз.

Например, допустим, что нормальное состояние экрана таково, что символ всегда центрирован вертикально. Если персонаж прыгает, «камера» следует за персонажем, сначала вверх, когда он поднимается, затем вниз, когда он падает.

Я выполнил это, используя canvas.translate(x,y) с кодом, подобным следующему:

drawBackground();
canvas.save();
canvas.translate(0, canvasHeight/2 - player.y);
drawPlayer();
canvas.restore();

Однако это выглядит неестественно, поскольку не учитывает скорость, поэтому независимо от того, насколько быстро персонаж поднимается или опускается, экран всегда ориентирован на него. Я пытался использовать какие-то переменные скорости холста, но я не могу понять это правильно. Я хочу, чтобы камера оставалась центрированной на игроке, если он неподвижен, но когда он прыгает, камера должна немного «отставать» от него и пытаться наверстать упущенное.

Может кто-нибудь дать мне несколько советов, как мне это сделать? Пожалуйста, будьте как можно точнее!

Спасибо

1 Ответ

6 голосов
/ 30 мая 2011

Просто напишите фильтр низких частот для положения камеры:

var player = {x: 0, y: 0};
var camera = {x: 0, y: 0};
var t = 0.1;

while(true) {
    camera.x = camera.x*(1 - t) + player.x*t
    camera.y = camera.y*(1 - t) + player.y*t
    drawStuff(camera, player)
}

Чем больше значение t, тем быстрее реагирует камера. drawStuff - это функция, которую я не могу написать, не зная, как работает ваша игра. Надеюсь, вы делаете!

Контрольный вопрос

var playerPosition = {x: 0, y: 0};
var playerVelocity = {x: 0, y: 0};
var camera = {x: 0, y: 0};
var t = 0.1;

while(true) {
    var targetPosition = f(playerPosition, playerVelocity);
    camera.x = camera.x*(1 - t) + targetPosition.x*t
    camera.y = camera.y*(1 - t) + targetPosition.y*t
    drawStuff(camera, player)
}

Где f - некоторая функция, которая описывает, куда камера должна указывать для данной скорости и положения. Что-то вроде этого может быть достаточно:

function f(pos, vel) {
    var k = 0.5;
    return {x: pos.x + vel.x * k, y: pos.x + vel.y*k}
}

Очевидно, что это приведет к тому, что плеер окажется за кадром, если камера будет двигаться слишком быстро!

...