Então, depois de algumas horas de pesquisa na internet, ainda não encontrei uma resposta agradável sobre como lidar com plataformas móveis em um jogo de plataforma 2D. Decidi fazer um protótipo simples, onde você interage com 2 plataformas diferentes, uma que se move verticalmente e outra horizontalmente. Eu adoraria alguma ajuda para dissecar e ver o que não está funcionando e como corrigi-los. Enviei o arquivo .fla + .as abaixo, acompanhado de um link para o .swf reproduzível.
O objetivo é fazer com que o Herói interaja com as plataformas como se fossem objetos sólidos nos quais ele possa se apoiar, empurrado ao lado, pular / embaixo etc.
Os problemas com o meu protótipo são estes:
Quando você fica na plataforma em movimento horizontal, sem se mover (sem tocar em nenhuma tecla), o Herói se move junto com a plataforma, mas com um pequeno atraso, fazendo com que o herói recue um pouco.
Quando você fica na plataforma que se move horizontalmente e pula, você se move junto com a plataforma no ar (alguns jogos preferem tê-lo assim, mas não parece natural e não é desejado aqui). O que pode ser causado pelo herói reter a velocidade no eixo X da plataforma.
Quando você pula para o lado inferior na plataforma em movimento vertical, enquanto a plataforma está se movendo para baixo, você afunda por um breve segundo. O herói penetra como se a colisão não existisse por um momento.
Quando você pula na plataforma em movimento vertical, a velocidade no eixo Y é mantida; portanto, quando você sai da plataforma, cai em uma velocidade mais alta. Com a velocidade da velocidade retida, + a gravidade adicionada (isso ocorre principalmente porque não consigo descobrir uma maneira de redefinir a velocidade no eixo Y para 0 quando você pousa na plataforma, sem o jogador congelar no ar).
Sou um programador iniciante, por isso tenho certeza de que existem maneiras MELHORES de fazer isso e gostaria de ouvi-las todas. Quaisquer idéias sobre como melhorar o código ou outros métodos nos quais você pode implementar plataformas móveis em um jogo baseado em til são bem-vindas. No final, estou tentando encontrar uma maneira sólida de lidar com plataformas móveis em plataformas 2D.
SWF reproduzível: http://dl.dropbox.com/u/28271061/PlatformerhowtoFLA.html (Mover com as setas, Ir com a tecla X, Executar com a tecla Z)
Arquivo AS do código-fonte: http://dl.dropbox.com/u/28271061/Platformerhowto.as
SourcefileFLA: http://dl.dropbox.com/u/28271061/PlatformerhowtoFLA.fla
Se você preferir apenas ler o código através do Pastie online: http://pastie.org/2266764
Respostas:
Vamos separar seu problema em problemas distintos ...
Uma palavra sobre a qualidade do código
Atualmente, seu código tem suas plataformas controlando diretamente a velocidade do seu jogador e até a constante de gravidade do mundo . É hacky e processual quando deveria ser orientado a objetos. Quando você começar a expandir esse jogo, as coisas ficarão feias rapidamente .
Você precisa refatorar seu código. Implemente uma classe de jogador, uma classe de plataforma e uma classe de andar. Separe suas preocupações: peça ao jogador que interprete os controles do teclado e controle como ele corre e salta, e faça com que as plataformas alterem seu momento conforme necessário (adicionando sua própria velocidade à velocidade já determinada do jogador, quando necessário).
Peça ao seu jogador que determine onde está em relação a um objeto do tipo piso (plataformas e pisos teriam um
BodyType = BodyTypes.Floor
, ou algo assim) e determine por si próprio onde está em relação ao objeto, como deve reagir e se está caindo ou não. no chão.Isso pode merecer um tópico separado, pois é uma questão bastante separada de tudo que você mencionou. No entanto, você precisará fazer isso em algum momento.
Inércia horizontal / vertical ao sair de uma plataforma
Para resolver seus problemas de velocidade vertical e horizontal, observe duas coisas:
Seu jogador está simplesmente sofrendo de inércia : o momento dele é mantido até que algo o interrompa.
Solução: Ambos os problemas seriam resolvidos pela solução da jSepia para Como lidar com plataformas móveis em um jogo de plataforma? pois separaria completamente o processo de movimentação do jogador de como as plataformas o movem. Você simplesmente não cairia mais rápido ao sair de uma plataforma vertical e não preservaria seu momento horizontal saltando de uma plataforma horizontal, porque as plataformas não afetarão mais o vx e vy do seu jogador .
Nota: Você pode ter alguma dificuldade em implementar a solução do jSepia antes que seu código seja refatorado.
Deslizando de um lado para o outro pela plataforma horizontal
Seu jogador não é movido horizontalmente tão rápido quanto a plataforma se move. Não é óbvio para mim o porquê. Esse problema provavelmente também seria resolvido com a implementação da solução da jSepia e a refatoração correta do seu código (o último simplesmente tornaria a causa óbvia).
Detecção de colisão: sobreposição com a plataforma vertical
Veja a linha 381 do Pastie: a cada passo, é redefinido o vy do jogador para 0, desde que o jogador colidir com a parte inferior da plataforma vertical. Na etapa seguinte, vy é aumentado pela aceleração da gravidade e, em seguida, o jogador é movido (e depois redefinido para 0 novamente).
Isso significa que, enquanto o seu jogador estiver colidindo com o fundo da plataforma, ele estará se movendo para baixo a uma velocidade constante (a constante da gravidade). A plataforma vertical é mais rápida que isso, por isso se sobrepõe. Se a plataforma vertical se movesse por uma distância maior, ela deslizaria através dele até o jogador ser registrado como estando na plataforma.
Solução: não redefina o vy do jogador para 0. Basta definir o vy do jogador para a velocidade vertical da plataforma ( se a plataforma estiver viajando para baixo ). Seu player estará se afastando da plataforma vertical pelo menos tão rápido quanto a plataforma e acelerando para longe dela.
fonte
Player
possui um métodoGetPosition
e variáveis internasparent
(para o nó pai) eposition
(para sua posição em relação ao pai).Player.GetPosition()
retornaposition + parent.GetPosition()
. Seu pai faz a mesma coisa até chegar à raiz da árvore - o nó do mundo. Quando o seu jogador se move, você lida apenas com aposition
variável privada . Seu jogador é sorteado na tela do jogo de acordo comGetPosition()
o valor. Vou deixar você descobrir como fazer a transição entre nós. ;)