Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [HTML5][JS] Rożna prędkość gry
Forum PHP.pl > Forum > Po stronie przeglądarki > JavaScript
trollman
Witam,
Mam problem, gdyż robie grę w html5 oraz javascript i płynność gry zalezy jakby od mocy komputera (z tego co zaobserwowałem)

Pętla gry wygląda tak:
  1. if (state)
  2. gLoop = setTimeout(GameLoop, 1000 / 60);
  3. };


i w GameLoop dziają różne akcje, jak nasłuchwianie klwiszy, rysowanie i renderowania grafiki itd...
Gdy grę uruchamiam na komputerze, chodzi płynniutko, ale gdy włącze ja (oczywiscie w tej samej przeglądarce) na starym laptopie gra chodzi jakby była na 10 fps'ach.

Da się temu jakoś zapobiec?
markuz
Trzeba ją zoptymalizować. Odświeżasz pętle co 16 ms - zdecydowanie możesz dać np. 30, 60 itd.
Nasłuchiwanie klawiszy masz w GameLoop? To nie jest do końca poprawnie.
Pokaż kod to może wyłapie się jakieś większe błędy..
trollman
OK, To całe GameLoop wygląda tak

  1. var GameLoop = function(){
  2. clear();
  3. DrawBackground();
  4. player.draw();
  5. startBackground();
  6.  
  7. if(player.isJumping) player.checkJump();
  8. if(player.isFalling) player.checkFall();
  9.  
  10. if (Key.isDown(Key.LEFT)) player.moveLeft();
  11. if (Key.isDown(Key.SPACE)) player.jump();
  12. if (Key.isDown(Key.RIGHT)) player.moveRight();
  13.  
  14. platforms.forEach(function(platform, index){
  15. if (platform.isMoving) {
  16. if (platform.x < 60) {
  17. platform.direction = 1;
  18. } else if (platform.x > width-80- platformWidth) {
  19. platform.direction = -1;
  20. }
  21. platform.x += platform.direction * (index / 2) * ~~(points / 100);
  22. }
  23. if (points > 2){
  24. platform.y += 1;
  25. if(platform.y > height){
  26. var type = ~~(Math.random() *5);
  27. if(type == 0)
  28. type = 1;
  29. else
  30. type = 0;
  31.  
  32. platforms[index] = new Platform((Math.random() * (width -140- platformWidth))+60, platform.y - height, type);
  33.  
  34. }
  35. }
  36. platform.draw();
  37. });
  38. checkCollision();
  39.  
  40. ctx.fillStyle = "Black";
  41. ctx.fillText("POINTS:" + points, 10, height-10);
  42.  
  43. if (state)
  44. {
  45. gLoop = setTimeout(GameLoop, 1000 / 60);
  46. }
  47.  
  48. };


Nasłuchiwanie jest powyżej, tutaj tylko wyłapuję co jest nacisniete.
Ogólnie gra może byc bardzo nawet niezoptymalizowana bo jest to moja pierwsza taka gra w js i w sumie bardziej sie ucze smile.gif
PrinceOfPersia
Cytat
Gdy grę uruchamiam na komputerze, chodzi płynniutko, ale gdy włącze ja (oczywiscie w tej samej przeglądarce) na starym laptopie gra chodzi jakby była na 10 fps'ach.

1. może jest na 10 FPSach? Weź sprawdź ile faktycznie masz klatek na sekundę. To że nastawiłeś na tyle to nic nie znaczy.

2. możesz uniezależnić ruch od FPSów. Mierzysz ile faktycznie upłynęło czasu między obecną klatką a klatką poprzednią a potem wszelki ruch mnożysz przez wartość czasu.

czyli coś jak (pseudokod):

Kod
UPDATE:
    timeDelta =  now - lastTime
    ...
    platform.x += someCalculations * timeDelta    
    platform.y += 1 * timeDelta    
    ...
    lastTime = now

tym sposobem jeśli obiekt ma przemierzyć 600 pikseli (przykładowo) w czasie jednej sekundy, to i tak to zrobi, niezależnie czy będzie 10 czy 60 klatek na sekundę (bez tego przy mniejszych FPSach by wolniej chodził).

Jednak to ci nie powiększy FPSów, a jedynie dokona korekty ruchu. Być może będzie trzeba zrobić jakąś optymalizację, bo może gdzieś masz coś, co ci zamula.
(testuj też w różnych przeglądarkach - ta sama gra na Chrome może szybciej działać niż na Firefoxie).
trueblue
Cytat(trollman @ 9.12.2014, 13:28:53 ) *
Da się temu jakoś zapobiec?

Słyszałeś o request animation frame?
trollman
trueblue
Tak słyszałem i zastosowałem taki kod

  1. window.requestAnimFrame = (function(){
  2. return window.requestAnimationFrame ||
  3. window.webkitRequestAnimationFrame ||
  4. window.mozRequestAnimationFrame ||
  5. function( callback ){
  6. window.setTimeout(callback, 1000 / 60);
  7. };
  8. })();
  9.  
  10. (function animloop(){
  11. requestAnimFrame(animloop);
  12. GameLoop();
  13. })();


Otrzymałem efekt wręcz przeciwny, gra tak przyspieszyła aż wydawało sie, że chodzi nienaturalnie jak przyspieszony film w stosunku do starego kodu, więc nie wiem czy to jest dobre?

PrinceOfPersia
, dzięki za radę, sprawdzę jak tylko wróce do domu.

I swoją drogą mam kolejne pytanie odnosnie gry, żeby nie towrzyc już nowego wątku.
Czy porpawne jest tworzenie gry na jednym canvasie? ... Obecnie tak mam bo też się spotkałem z takimi grami, ale niektórzy to rozdzielają. Tło na innym, bohater na innym a aktywne elementy otoczenia na innym.
(Pytam bo, chciałem też obrócić obrazek bohatera o 180 stopni i mozliwe jest tylko odwócenie całego canvasa a nie pojedyńczego img = new Image() )
markuz
Cytat
Czy poprawne jest tworzenie gry na jednym canvasie?

Tak.

Cytat
chciałem też obrócić obrazek bohatera o 180 stopni i mozliwe jest tylko odwócenie całego canvasa a nie pojedyńczego img = new Image()

Skąd bierzesz takie informacje? W Canvas możesz obracać co tylko chcesz i jak chcesz - obrazki, teksty, figury, linie itd.
trollman
markuz, jedyne informacje jakie znalazlem na obrót czegokolwiek w canvasie kończyło sie bledami.
Przewaznie było to:
  1. ctx.save();
  2. ctx.scale(-1, 1);
  3. ctx.drawImage(....
  4. ctx.restore();

(ctx = canvas jakby co)

Po tym wszystko mrugało (cała gra, czyli canvas) .. rozjechało sie i dupa blada.
markuz
Cytat
jedyne informacje jakie znalazlem na obrót czegokolwiek w canvasie kończyło sie bledami.

Błąd != Brak rozwiązania

Przykład specjalnie dla Ciebie:
http://jsfiddle.net/ozrjpc5x/
2 obrazki (1 animowany, 2 nie)
http://jsfiddle.net/ozrjpc5x/1/
trollman
OK, spróbuje jeszcze raz to zaimplementowac.
Wracając do płynności gry ... to rozwiązanie które podał PrinceOfPersia będzie dobrym rozwiązaniem?
PrinceOfPersia
no tak, ale moje rozwiązanie z liczeniem "ile czasu upłynęło" nie rozwiąze ci problemów płynności a jedynie problemy z synchronizacją czasową. Bo bez tego jak będziesz miał 10 klatek na sekundę, postać będzie poruszać się 6 razy wolniej.

Cytat(trollman @ 10.12.2014, 08:22:18 ) *
Czy porpawne jest tworzenie gry na jednym canvasie? ... Obecnie tak mam bo też się spotkałem z takimi grami, ale niektórzy to rozdzielają. Tło na innym, bohater na innym a aktywne elementy otoczenia na innym.

Z innych powodów się to czasem rozdziela. coś na zasadzie warstw w Photoshopie się czasem robi. Jeśli tło jest statyczne, to wystarczy raz narysować na warstwie, i nie tracić mocy komputera na rysowanie tła od początku, tylko umieszcza się kilka canvasów żeby rysować tylko te elementy, które się ruszają, a statyczne tło na innym itp.

ale to jest optymalizacja, którą można dokonać, ale technicznie tak samo możesz korzystać z jednego canvasa i na nim wszystko rysować. Przykłady podał markuz.

EDIT:
aha, i możesz zmierzyć co ci zżera kompa. W Dev Toolsach Chrome masz audyty np. "ta i ta funkcja zajmuje ci tyle i tyle czasu".
możesz samemu liczyć też, np. spróbuj wykomentarzować jakiś kod i zobacz czy szybciej działa.itp.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.