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 :/
możesz wrzucić cały kod odpowiedzialny za obsluge eventów, zmazywanie i rysowanie tarczy i kulek?
function inputdown(e, x, y){if(renderer.ballClicked(x, y)){mousedown=true; inputx=x; inputy=y; deltax=0; deltay=0;} e.preventDefault();} function inputmove(e, x, y){ if(mousedown==true){ deltax=Math.abs(x-inputx); deltay=Math.abs(x-inputy); if(move==false) move=true; } if(move==true){ var n_angle=now_angle[3]; var move_angle=Math.PI*Math.round(renderer.getCoordsAngle(x, y)*180/Math.PI)/180; if(move_angle!=n_angle){ console.log(move_angle*180/Math.PI); now_angle[3]=move_angle; renderer.drawCircle(3); renderer.drawBallsInCircle(3, move_angle, w/2); } } e.preventDefault(); } function inputup(e){mousedown=false; move=false; e.preventDefault();} _p.drawCircle=function(n) { var data=this._model.getData(); var ctx=this._ctx; ctx.beginPath(); ctx.arc(this.x, this.y, Math.round(this.size*n), 0, 2*Math.PI, false); ctx.lineWidth=this.size; ctx.strokeStyle=this._getColor(data[0][data[0].length-n-1]); console.log(ctx.strokeStyle); ctx.stroke(); } _p.drawBallsInCircle=function(n, start_angle, x2) { var data=this._model.getData(); var angle=2*Math.PI/data[2].length; var ctx=this._ctx; if(n==0) { 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); //this._bcoords.push([this.x, this.y]); } else { var r=Math.round(this.size*n); var y2=this.y-r; //alert(data[i].length+', '+x+', '+y+', '+x2+', '+y2+', '+r+', '+ball_size+', '+ball_anchor); //this._drawBalls2(data[j], angle, x, y, x2, y2, ball_size, ball_anchor, ctx); for(var i=0; i<data[n+1].length; i++) { var coords=this._getRotatedCoords(start_angle+angle*i, x2, y2); //x2=coords[0]; //y2=coords[1]; 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); //this._bcoords.push([coords[0], coords[1]]); } } } _p._getRotatedCoords=function(angle, x2, y2) { var dx2=x2-this.x; var dy2=y2-this.y; var dx3=Math.round(dx2*Math.cos(angle)-dy2*Math.sin(angle)); var dy3=Math.round(dx2*Math.sin(angle)+dy2*Math.cos(angle)); return [dx3+this.x, dy3+this.y]; } _p.getCoordsAngle=function(x, y) { var x_dist=x-this.x; var y_dist=y-this.y; var tan=Math.abs(x_dist/y_dist); if(x_dist>=0 && y_dist>=0) return Math.PI-Math.atan(tan); else if(x_dist<0 && y_dist>=0) return Math.PI+Math.atan(tan); else if(x_dist<0 && y_dist<0) return 2*Math.PI-Math.atan(tan); else return Math.atan(tan); }
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ć:
var dx3=Math.round(dx2*Math.cos(angle)-dy2*Math.sin(angle)); var dy3=Math.round(dx2*Math.sin(angle)+dy2*Math.cos(angle));
var sinAgnle = Math.sin(angle); var cosAngle = Math.cos(angle); var dx3=Math.round(dx2*cosAngle-dy2*sinAgnle); var dy3=Math.round(dx2*sinAgnle+dy2*cosAngle);
if(x_dist>=0 && y_dist>=0) return Math.PI-Math.atan(tan); else if(x_dist<0 && y_dist>=0) return Math.PI+Math.atan(tan); else if(x_dist<0 && y_dist<0) return 2*Math.PI-Math.atan(tan); else return Math.atan(tan);
if( (x_dist>=0 && y_dist>=0 ) || (x_dist<0 && y_dist>=0)) return Math.PI-Math.atan(tan); else if(x_dist<0 && y_dist<0) return 2*Math.PI-Math.atan(tan); else return Math.atan(tan);
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?
Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)