Clone Bomberman, como fazer bombas?

8

Estou brincando com um clone bomberman para aprender o desenvolvimento de jogos.

Até agora eu fiz peças, movimento, detecção de colisão e coleta de itens. Eu também tenho pseudo-bombplacing (apenas gráficos e colisão, nenhuma funcionalidade real).

Eu fiz um jsFiddle do jogo com a funcionalidade que tenho atualmente. O código no violino é muito feio. Percorra o mapa e você descobrirá como eu coloco bombas.

Enfim, o que eu gostaria de fazer é um objeto que tenha informações gerais sobre bombas como:

function Bomb(){
  this.radius = player.bombRadius;
  this.placeBomb = function (){
    if(player.bombs != 0){
      // place bomb
    }
  }
  this.explosion = function (){
  // Explosion
  }
}

Eu realmente não sei como encaixá-lo no código. Toda vez que coloco uma bomba, faço var bomb = new Bomb();ou preciso constantemente tê-la no script para poder acessá-la.

Como a bomba causa dano? É tão simples quanto fazer X, Y em todas as direções até o raio acabar ou o objeto parar? Posso usar algo como setTimeout (bomb.explosion, 3000) como timer?

Qualquer ajuda é apreciada, seja uma explicação simples da teoria ou exemplos de código baseados no violino. Quando tentei a maneira como o objeto quebra o código.

Atualização: Agora coloco bombas e, após um certo período de tempo, apago-as, dependendo da posição em que as coloquei. Mas se eu colocar uma bomba antes que a primeira bomba exploda, ela excluirá apenas uma delas (obviamente, desde que a bombaX e a bombaY mudaram desde que a primeira foi colocada).

Agora eu preciso saber como corrigir esse problema, talvez criar uma nova matriz com todas as posições da bomba? Qual é a melhor maneira de fazer isso?

Código atual:

function placeBomb(){
    if(placebomb && player.bombs != 0){
        map[player.Y][player.X].object = 2;
        bombX = player.X; bombY = player.Y;
        placebomb = false;
        player.bombs--;
        setTimeout(explode, 3000);
    }
}
function explode(){
    alert('BOOM!');
    delete map[bombY][bombX].object;
    player.bombs++;
}
justanotherhobbyist
fonte
11
jsFiddle + Firebug -> ferramenta de prototipagem de jogos? Nunca tinha pensado nisso. +1 por explodir minha mente muito agradavelmente! :)
Anko

Respostas:

6

Não parece tão ruim, mas você precisa de um melhor controle de tempo e de entrada. Como a velocidade de movimento depende da configuração da repetição de teclas na máquina do usuário, isso não é exatamente o ideal.

Em vez disso, você deve rastrear quais chaves estão sendo mantidas pressionadas no momento, pode fazer o seguinte (no pseudocódigo):

keyisdown=false
keydown event{
    if(!keyisdown){
        //This is the 'real' keydown event, the one that only happens the moment the
        //key is pressed down. You may not need it, but this is how you construct it.
    }
    keyisdown=true
}

keyup event{
    keyisdown=false
}

E então, na sua função de atualização, você move o player se keyisdown, e possivelmente aplica outras condições, como o player não pode se mover se ele moveu menos do que algumas atualizações atrás.

Mantenha um contador atualizado ou alguma outra maneira de acompanhar o tempo, para que seu código sempre saiba exatamente quanto deve progredir.

Da bomba
Pessoalmente eu mantê-lo simples, você realmente não precisa usar this, newe todas as outras coisas extravagantes em JavaScript para fazer objetos úteis.

Você poderia fazer algo como:

bombobject = {} //That is all it takes to make an object.
bombobject.blowtime = currenttime + delay
bombobject.position = mapobject
mapobject.bomb = bombobject

Em seguida, você pode percorrer o mapa a cada atualização, verificar se há uma bomba e se é hora de explodir; se houver, explodir e remover o objeto da bomba.

Rastreamento de bugs
Seu código está com erros de vazamento, eles são bem simples, mas se você não aprender sobre eles e lidar com eles, terá problemas mais tarde. Todo navegador moderno possui um console de desenvolvedores de clones do Firebug. Abra-o, veja a guia do console de scripts, veja todo o texto vermelho desagradável e corrija-o.

Edit: preocupações
com a setIntervalcontagem do tempo Apenas para o registro, você provavelmente desejaria algo um pouco mais avançado do que para o timing, se você for sério, realmente precisará fazer o seu código se ajustar ao horário. Veja minha primeira resposta do Stack Overflow para obter uma descrição aproximada do problema: https://stackoverflow.com/a/2549426/305545

Edit: setTimeOut versão corrigida
Como você está usando as mesmas variáveis ​​para bombas diferentes, você as substituirá sempre que uma nova bomba for colocada. Você pode usar um fechamento para criar variáveis ​​individuais para cada bomba, assim:

function placeBomb(){
    if(placebomb && player.bombs != 0){
        map[player.Y][player.X].object = 2;
        var bombX = player.X;
        var bombY = player.Y;
        placebomb = false;
        player.bombs--;
        setTimeout(explode, 3000);
    }
    function explode(){
        alert('BOOM!');
        delete map[bombY][bombX].object;
        player.bombs++;
    }
}

Agora os bombXe bombYvariáveis e a explodefunção são os moradores ao encerramento criado por placeBombs, portanto, é a instância local do explodeque está ligado ao tempo limite, e ele lê as variáveis locais. Cada vez que você chama placeBombum novo fechamento é criado.

Eu não teria usado o setTimeout para isso, teria contado as atualizações, garantindo assim um número fixo de atualizações antes da bomba explodir, mas acho que isso funcionará bem.

aaaaaaaaaaaa
fonte
Sim, o violino não é o mesmo código que o meu game.js, alguns copiam e colam e apenas recolhem aleatoriamente. O código real não fornece erros nas ferramentas de desenvolvedor do firebug ou cromos. Vou tentar fazer sua bomba funcionar. Obrigado. :)
justanotherhobbyist 22/03
Realmente, sem erros? Nem se você tentar sair do mapa?
Aaaaaaaaaaaa
Agora que você mencionou, recebi esse, mas isso não é um problema, já que os primeiros ladrilhos são uma estrutura de concreto. :) Apenas o mapa do violino que foi simplificado.
justanotherhobbyist
Sim, eu notei o problema com setTimeout, agora tenho uma variedade de bombas, que funciona bem com 2 bombas, com mais ele não apaga a do meio, acho que tenho que fazer algum tipo de tempo se (timer> = timeplaced) ou algo semelhante. Eu aprendo muito cometendo erros e tendo que resolvê-los da seguinte maneira: D, alguns dias atrás eu não conseguia nem fazer pong.
justanotherhobbyist
Você é bem vindo. E é ótimo saber que você está aprendendo, às vezes é difícil acreditar que resolver os problemas imediatos das pessoas realmente vai levar a qualquer lugar.
aaaaaaaaaaaa 22/03
0

Parece que você conseguiu um ótimo awnser, só queria adicionar um código útil para as explosões.

            for (int i = 0; i < actor.blasradius; ++i)
        {
            tiles[actor.tileX - i][actor.tileY].explode(); //left
            tiles[actor.tileX + i][actor.tileY].explode(); //right
            tiles[actor.tileX][actor.tileY -i].explode(); //up
            tiles[actor.tileX][actor.tileY + i].explode(); //down
        }
omgnoseat
fonte
Sim, eu tenho algo parecido, mas com condições como caixotes, concreto etc. e destruindo ou parando dependendo disso. O código pode ser lido aqui: gamedev.stackexchange.com/questions/26065/…
justanotherhobbyist