Na verdade, o algoritmo do site está um pouco desatualizado mesmo…
A versão final dele está nesse anexo.
Na verdade, o algoritmo do site está um pouco desatualizado mesmo…
A versão final dele está nesse anexo.
Esse trecho em específico ficaria corrigido assim:
while (isRunning) {
long beforeTime = System.currentTimeMillis();
game.paintGraphics();
game.updateLogics();
long afterTime = System.currentTimeMillis();
long sleepTime = afterTime - beforeTime ;
if (sleepTime < 40)
sleep(40 - sleepTime);
}
Obrigado por reparar e comentar!
Você tem razão. O teste tem que ser < DESIRED_UPDATE_TIME. Basicamente, se o tempo é menor, damos uma pausa, se é maior, calculamos o excesso. Dei uma revisada no algoritmo por lá, se quiser depois dá uma conferida.
O algoritmo final atualizei para o mesmo que está rodando no meu jogo.
Abraços!
dyorgio, você está trabalhando em alguma coisa relacionada a jogos e física?
Quanto a APIs, até que ponto vale a pena usá-las e a partir de quando vale a pena fazer a sua própria?
Pelo que tenho visto os subsistemas numa engine não são tão facilmente separáveis e reutilizáveis em vários softwares diferentes (por exemplo, um loader depende das estruturas de cena da engine, e isso é impossível de se fazer genérico), portanto imagino que fazer algumas coisas do zero seja vantajoso.
Olá, dyorgio!
Infelizmente, não me lembro de quase nada de física…
Antes de mais nada, não estou tomando partido de ninguém… :lol:
É que a grande maioria do pessoal aqui não curte muito quando o povo vem no GUJ com a intenção de pegar código pronto. Eu mesmo não costumo fornecer, principalmente se percebo que é pra trabalho de escola… :lol: Mas as vezes rola umas exceções :thumbup:
Como eu disse, não rola muito disso… sorry…
[quote=dyorgio]já procurei …alias em muitos outros sites de código fonte…
mas não achei[/quote]
Tem um treco no google que é massa pra achar código fonte:
http://www.google.com/codesearch
A busca avançada dele é fenomenal. Aposto que lá você vai conseguir achar alguma coisa!
[quote=dyorgio]se você não tem…
não entre no tópico
[/quote]
Opa! Pra quê brigar? Sem apelar, ok? Aqui todo mundo é colega! Se há alguma rusga, por favor, utilize MP, ok? A comunidade do GUJ agradeçe.
“Don’t feed the trolls”
Você pergunta “capisci”, aí eu respondo (ou não) “capisco”. :thumbup:
Que é isso! Pra quê revidar? Que coisa! Quer revidar, use MP!
Eu digo isso por que já dei uma dessa antes. Vi que realmente os outros GUJnautas não querem ver discussões sem ser sobre Java.
A propósito, se ficar bravo comigo, por favor: MP em mim, ok?
“Don’t feed the troll”
Paz e Amor, pessoal!
Divirtam-se!
Um código para loops que uso por aqui…
[code] /**
*
* Loop principal do jogo.
*
* Este método calcula o tempo que se passou desde a última iteração com o
* jogo, checa a entrada do usuário e atualiza os objetos do jogo.
*
if (oldTime == -1) {
oldTime = clock.getCurrentTime();
}
while (running) {
newTime = clock.getCurrentTime();
if (oldTime != newTime) {
/* calcula a diferença de tempo e atualiza o oldTime */
deltaT = newTime - oldTime;
oldTime = newTime;
/*
* adiciona e remove os objetos que se encontram nas listas de
* espera
*/
objectsList.addAll(addList);
addList.clear();
objectsList.removeAll(removeList);
removeList.clear();
/* verifica entrada do usuário */
checkInput(deltaT);
/* atualiza o estado do jogo */
updateGame(deltaT);
/* desenha o frame */
graphics = (Graphics2D) screenManager.getDrawGraphics();
draw(graphics);
graphics.dispose();
screenManager.showBuffer();
}
}
}[/code]
Bem, um resumo por cima, o objeto clock ali é atualizado constantemente a cada intervalo de tempo pré-definido, e o loop verifica se chegou a hora de atualizar o jogo se este valor for diferente de quando houve a última atualização.
Se precisar atualizar, calcula-se a variação do tempo que teve desde a última atualização e guarda em “deltaT” este valor, em ms, que é passado para cada objeto da cena no método update, implementado geralmente deste modo:
public void update(long deltaT) {
setX(getX() + deltaT * getVx());
setY(getY() + deltaT * getVy());
}
onde o vx e o vy são as velocidades em cada eixo, no meu caso em pixels / ms.
Como pode ver, meu método é um pouco diferente do que o ViniGodoy mostrou. O meu atualiza o estado do jogo antes de desenhar na tela e pode também pular alguns quadros, em momentos que o computador estiver muito ocupado com alguma coisa ou for lento demais para alcançar a taxa de quadros por segundo desejada, assim ele não rodará em câmera-lenta em micros mais modestos hehehe.
Espero que ajude
Pois é, o algoritmo que propus implementa outra técnica, que busca manter o deltaT constante no update.
Acho isso interessante pois, embora o algoritmo do loop fique mais complicado, evita calculos de delta espalhados pelo código inteiro.
Não é pior ou melhor. Ambos algoritmos tem seus pontos fortes e fracos…
Bom, mas se você ver ali em cima, o deltaT só é calculado uma vez também, assim ele se mantém inalterado durante a atualização. [edit] Demorou mas agora entendi o que você quis dizer com deltaT constante… cada update vai sempre incrementar em um passo o jogo.
E com certeza não há melhor ou pior, isso vai depender de cada caso. O melhor seria juntar os dois e dar a opção pro usuário, se deseja habilitar o frame skip ou não, e quantos frames no máximo pular… com o método que usei ali fica um pouco complicado fazer isso mesmo.
Aliás, só vi agora que no código que você anexou aqui implementa tudo isso. Muito legal. Se eu tivesse internet liberada estaria lendo os links que você colocou hehehe.
Isso. É como o JMonkey trabalha. Lá tem diversas implementações do algoritmo.
O básico é ter aquela interface que eu descrevo no blog, com os métodos setup, renderGraphics, paint, update e tearDown.
Aí você pode fazer algoritmos com a política que quiser. Ou mesmo trocar de política e ver como o jogo fica.