Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [Canvas] Optymalizacja kodu obracającego koło z kulkami
bpawel10
post 27.03.2014, 22:33:35
Post #1





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 9.10.2010

Ostrzeżenie: (0%)
-----


Witajcie,

piszę w canvas grę na systemy mobilne korzystając z Apache Cordova.
Mam na planszy koło puste w środku, taki jakby pierścień, w którym są kulki. Gdy gracz kliknie na dowolną kulkę i zacznie przesuwać myszkę (lub palcem po ekranie), to koło razem z kulkami ma się obracać, podążać za palcem/myszą. Już napisałem kod za to odpowiedzialny, wszystko działa idealnie, ale niestety tylko na kompie. Komórka nie nadąża i przy szybkim obracaniu jest bardzo duży brak płynności.
Mój kod działa tak: gdy wykryjemy ruch myszy/palca przy wciśniętej myszy, pobieramy współrzędne dotknięcia/myszy i obliczamy kąt. następnie rysujemy w canvasie tło, aby zmazać poprzednie kule, po czym rysujemy kule od nowa, ale zaczynając od wyliczonego kąta. Nawet zmodyfikowałem kod w ten sposób, żeby kąty zokrąglać do pełnych stopni, i kulki są renderowane co 1 stopień. Ale dalej nie jest płynnie, da się to jeszcze jakoś zoptymalizować, bo już nie mam pomysłu? Mam nadzieję, że jednak uda się to z Cordovą, bo nauka natywnego programowania to kolejna książka do przeczytania :/
Go to the top of the page
+Quote Post
PrinceOfPersia
post 27.03.2014, 23:56:43
Post #2





Grupa: Zarejestrowani
Postów: 717
Pomógł: 120
Dołączył: 18.04.2009

Ostrzeżenie: (0%)
-----


możesz wrzucić cały kod odpowiedzialny za obsluge eventów, zmazywanie i rysowanie tarczy i kulek?

Ten post edytował PrinceOfPersia 27.03.2014, 23:57:08


--------------------
Go to the top of the page
+Quote Post
bpawel10
post 28.03.2014, 00:03:58
Post #3





Grupa: Zarejestrowani
Postów: 10
Pomógł: 0
Dołączył: 9.10.2010

Ostrzeżenie: (0%)
-----


  1. function inputdown(e, x, y){if(renderer.ballClicked(x, y)){mousedown=true; inputx=x; inputy=y; deltax=0; deltay=0;} e.preventDefault();}
  2. function inputmove(e, x, y){
  3. if(mousedown==true){
  4. deltax=Math.abs(x-inputx);
  5. deltay=Math.abs(x-inputy);
  6. if(move==false)
  7. move=true;
  8. }
  9. if(move==true){
  10. var n_angle=now_angle[3];
  11. var move_angle=Math.PI*Math.round(renderer.getCoordsAngle(x, y)*180/Math.PI)/180;
  12. if(move_angle!=n_angle){
  13. console.log(move_angle*180/Math.PI);
  14. now_angle[3]=move_angle;
  15. renderer.drawCircle(3);
  16. renderer.drawBallsInCircle(3, move_angle, w/2);
  17. }
  18. }
  19. e.preventDefault();
  20. }
  21. function inputup(e){mousedown=false; move=false; e.preventDefault();}
  22.  
  23. _p.drawCircle=function(n)
  24. {
  25. var data=this._model.getData();
  26. var ctx=this._ctx;
  27. ctx.beginPath();
  28. ctx.arc(this.x, this.y, Math.round(this.size*n), 0, 2*Math.PI, false);
  29. ctx.lineWidth=this.size;
  30. ctx.strokeStyle=this._getColor(data[0][data[0].length-n-1]);
  31. console.log(ctx.strokeStyle);
  32. ctx.stroke();
  33. }
  34. _p.drawBallsInCircle=function(n, start_angle, x2)
  35. {
  36. var data=this._model.getData();
  37. var angle=2*Math.PI/data[2].length;
  38. var ctx=this._ctx;
  39. if(n==0)
  40. {
  41. ctx.drawImage(this._getImage(data[1][0]), 0, 0, 256, 256, this.x-this.ball_anchor, this.y-this.ball_anchor, this.ball_size, this.ball_size);
  42. //this._bcoords.push([this.x, this.y]);
  43. }
  44. else
  45. {
  46. var r=Math.round(this.size*n);
  47. var y2=this.y-r;
  48. //alert(data[i].length+', '+x+', '+y+', '+x2+', '+y2+', '+r+', '+ball_size+', '+ball_anchor);
  49. //this._drawBalls2(data[j], angle, x, y, x2, y2, ball_size, ball_anchor, ctx);
  50. for(var i=0; i<data[n+1].length; i++)
  51. {
  52. var coords=this._getRotatedCoords(start_angle+angle*i, x2, y2);
  53. //x2=coords[0];
  54. //y2=coords[1];
  55. ctx.drawImage(this._getImage(data[n+1][i]), 0, 0, 256, 256, coords[0]-this.ball_anchor, coords[1]-this.ball_anchor, this.ball_size, this.ball_size);
  56. //this._bcoords.push([coords[0], coords[1]]);
  57. }
  58. }
  59.  
  60. }
  61. _p._getRotatedCoords=function(angle, x2, y2)
  62. {
  63. var dx2=x2-this.x;
  64. var dy2=y2-this.y;
  65. var dx3=Math.round(dx2*Math.cos(angle)-dy2*Math.sin(angle));
  66. var dy3=Math.round(dx2*Math.sin(angle)+dy2*Math.cos(angle));
  67. return [dx3+this.x, dy3+this.y];
  68. }
  69. _p.getCoordsAngle=function(x, y)
  70. {
  71. var x_dist=x-this.x;
  72. var y_dist=y-this.y;
  73. var tan=Math.abs(x_dist/y_dist);
  74. if(x_dist>=0 && y_dist>=0)
  75. return Math.PI-Math.atan(tan);
  76. else if(x_dist<0 && y_dist>=0)
  77. return Math.PI+Math.atan(tan);
  78. else if(x_dist<0 && y_dist<0)
  79. return 2*Math.PI-Math.atan(tan);
  80. else
  81. return Math.atan(tan);
  82. }

Go to the top of the page
+Quote Post
lukasz1985
post 3.04.2014, 18:38:18
Post #4





Grupa: Zarejestrowani
Postów: 205
Pomógł: 43
Dołączył: 5.03.2012

Ostrzeżenie: (0%)
-----


Moje sugestie są takie:
- "zcacheować" pewne zmienne, które są obliczane przy każdym wykonaniu funkcji lub wielokrotnie podczas jednego wykonania, czyli np, zamiast pisać:

[JAVASCRIPT] pobierz, plaintext
  1.  
  2. var dx3=Math.round(dx2*Math.cos(angle)-dy2*Math.sin(angle));
  3. var dy3=Math.round(dx2*Math.sin(angle)+dy2*Math.cos(angle));
[JAVASCRIPT] pobierz, plaintext


To napisać zmienne:

[JAVASCRIPT] pobierz, plaintext
  1. var sinAgnle = Math.sin(angle);
  2. var cosAngle = Math.cos(angle);
  3.  
  4.  
  5. var dx3=Math.round(dx2*cosAngle-dy2*sinAgnle);
  6. var dy3=Math.round(dx2*sinAgnle+dy2*cosAngle);
[JAVASCRIPT] pobierz, plaintext


I używać tych zmiennych bezpośrednio w kodzie, później.

Druga sprawa, unikać "if" -ów. Czyli zamiast pisać:


[JAVASCRIPT] pobierz, plaintext
  1. if(x_dist>=0 && y_dist>=0)
  2.  
  3. return Math.PI-Math.atan(tan);
  4.  
  5. else if(x_dist<0 && y_dist>=0)
  6.  
  7. return Math.PI+Math.atan(tan);
  8.  
  9. else if(x_dist<0 && y_dist<0)
  10.  
  11. return 2*Math.PI-Math.atan(tan);
  12.  
  13. else
  14.  
  15. return Math.atan(tan);
[JAVASCRIPT] pobierz, plaintext




To napisać instrukcje łączne:

[JAVASCRIPT] pobierz, plaintext
  1.  
  2.  
  3. if( (x_dist>=0 && y_dist>=0 ) || (x_dist<0 && y_dist>=0))
  4.  
  5. return Math.PI-Math.atan(tan);
  6.  
  7.  
  8. else if(x_dist<0 && y_dist<0)
  9.  
  10. return 2*Math.PI-Math.atan(tan);
  11.  
  12. else
  13.  
  14. return Math.atan(tan);
  15.  
[JAVASCRIPT] pobierz, plaintext




Co do funkcji trygonometrycznych: można spróbować używać tablic trygonometrycznych, możliwe, że taka optymalizacja coś da. W ostateczności warto spróbować, więcej do poczytania w temacie
http://jfdube.wordpress.com/2011/12/06/tri...bles-revisited/

To prawdopodobnie i tak nie wiele da.

W ostateczności można by spróbować stworzyć jakiś mechanizm, który reaguje na zdarzenia w regularnych odstępach czasu. Wtedy myślę, że aplikacja troche by skakała ale nie chodziła powoli.
Go to the top of the page
+Quote Post
#luq
post 3.04.2014, 19:08:52
Post #5





Grupa: Zarejestrowani
Postów: 589
Pomógł: 91
Dołączył: 22.05.2008
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


Optymalizacja dla rysowanie na canvasie która może dać dużo ale nie prosto coś takiego zrobić.
Podziel cały ekran na jakieś fragmenty i przerysowuj jedynie te fragmenty ekranu na których wystąpiła zmiana. Generalnie samo rysowanie jest najbardziej obciążające.

Możesz wrzucić gdzieś kod live?


--------------------
Moja gra - scraby.io
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 28.03.2024 - 17:45