Visualizzazione risultati 1 fino 5 di 5

Discussione: Canvas - JS

  1. #1
    Guest

    Exclamation Canvas - JS

    Ciao a tutti,
    ho una domanda da farvi. Ho creato questo piccolo giochino con HTML5 e JS.
    Funziona tutto, però ogni tanto la pallina mentre è ferma (o in movimento) su una linea cade dalla stessa finendo a terra.
    Qualcuno di voi saprebbe dirmi come mai succede questa cosa? Grazie mille.

    Questo è il sorgente:

    Codice:
    <html>
      <head>
        <script type="text/javascript" src="jquery.min.js"></script>
    	<script type="text/javascript">
    	$(document).ready(function(){
    	  //get a reference to the canvas
          ctx = $('#myCanvas')[0].getContext("2d");	  
    	  palla = {
    	    baseX   : 20,//---------coord. x di partenza della palla
    		baseY   : 390,//--------coord. y di partenza della palla
    		vectorX : 4,//----------velocità di spostamento sull'asse x
    		vectorY : 6,//----------velocità di spostamento sull'asse y
    		colore  : "#FF1C0A",//--colore della palla
    		width   : 500,//--------larghezza del canvas
    	    height  : 400,//--------altezza del canvas
    	    radius  : 10,//---------raggio della palla
    		costDecX : 0.8,//--------all'aumentare della costante, aumenta la rapidità di frenata lungo X [[>COSTANTE DI DECELERAZIONE>]]
    		costDecY : 0.5,//--------all'aumentare della costante, aumenta la rapidità di frenata lungo Y [[>COSTANTE DI DECELERAZIONE>]]
    		caricaSalto : 20,//-----più è alto il valore, più la palla può saltare in alto [[valore consigliato = 20]]
    		is_a_terra : true,//----true => la palla è su un piano; false => la palla è in aria
    		linee : Array(Array(50,400,500,250,4),Array(320,250,0,250,4)),
    		/***************VARIABILI DI SISTEMA*************/
    		vectorX_DEC : 0,
    		vectorY_DEC : 0,
    		rightClick  : false,
    	    leftClick   : false,
    	    topClick    : false,
    	    bottomClick : true,
    	    GRAVITY     : true,
    	    widthPad    : 0,
    	    heightPad   : 0,
    		caricaSalto_NOW : 0,
    		lastMove    : +new Date(),
    		bloccoX     : false,
    		/***************FUNZIONI*************************/
    		init : function(){
    		  this.widthPad = this.width - this.radius;
    	      this.heightPad = this.height - this.radius;
    		  
    		  this.vectorX_NOW = this.vectorX;
    		  this.vectorY_NOW = this.vectorY;
    		  /*****SE LA PALLA PARTE DA TERRA*****/this.aTerra();
    		  this.prevD = +new Date();
    		  this.intervallo = window.setInterval(function(){palla.draw()},10);
    		},
    		clear_all : function(){
    		  ctx.clearRect(0, 0, this.width, this.height);
    		},
    		draw_palla : function(x,y){
    		  ctx.fillStyle = this.colore;
              ctx.beginPath();
              ctx.arc(x, y, this.radius, 0, Math.PI*2, true);
    		  ctx.closePath();
              ctx.fill();
    		},
    		draw_line : function(d){
    		  //from_x,from_y,to_x,to_y,width
    		  ctx.lineWidth = d[4];
              ctx.beginPath();
              ctx.moveTo(d[0],d[1]);
    	      ctx.lineTo(d[2],d[3]);
    	      ctx.closePath();
              ctx.stroke();
    		},
    		moveTo : function(whereToGo){
    		  switch(whereToGo){
    		    case "right":
    			  palla.rightClick = true;
    			break;
    			case "left":
    			  palla.leftClick = true;
    			break;
    			case "top":
    			  if(this.is_a_terra && this.caricaSalto_NOW>0){
    			    palla.topClick = true;
    				this.is_a_terra = false;
    			  }
    			break;
    			case "bottom":
    			  palla.bottomClick = true;
    			  this.is_a_terra = false;
    			break;
    		  }
    		},
    		deceleraX : function(dir){ /***decelera il moto***/		  
    		  /***CONTROLLO DI ECCESSIVA FREQUENZA DI RICHIAMO FUNZIONE***/
    		  if(this.bloccoX){return;}
    		  var now = +new Date()
    		  if((now-this.lastMove)<=80){
    		    console.warn("BLOCCO: ON");
    			this.bloccoX = true;
    			setTimeout(function(){
    			  palla.bloccoX = false;
    			  palla.leftClick = false;
    			  palla.rightClick = false;
    			  console.warn("BLOCCO: OFF");
    			},500);
    			return;
    		  }
    		  this.lastMove = now;
    		  /***FINE CONTROLLO***/
    		  
    		  deceleraX = window.setInterval(function(){
    		    palla.vectorX_DEC += palla.costDecX ;
    		    if(palla.vectorX_NOW<=0){
    			  palla.vectorX_DEC = 0;
    			  if(dir=="right"){palla.rightClick = false;}else{palla.leftClick = false;}
    		      clearInterval(deceleraX);
    		    }
    		  },10);
    		},
    		stopDeceleraX : function(){ /***ferma la decelerazione***/
    		  try{clearInterval(deceleraX);}catch(err){}
    		  palla.vectorX_DEC = 0;
    		  palla.rightClick = false;
    		  palla.leftClick = false;
    		},
    		deceleraY : function(){
    		  topClick = true;
    		  deceleraY = window.setInterval(function(){
    		    palla.vectorY_DEC += palla.costDecY;
    		    if(palla.vectorY_NOW<=0){
    			  palla.vectorY_DEC = 0;
    			  palla.topClick = false;
    		      clearInterval(deceleraY);
    			  palla.agisciGravita();
    		    }
    		  },10);
    		},
    		aTerra : function(){ /***la palla è su un piano solido***/
    		  this.caricaSalto_NOW = this.caricaSalto;
    		  this.is_a_terra = true;
    		  //this.bottomClick = false;
    		},
    		agisciGravita : function(){
    		  this.topClick = false;
    		  if(this.GRAVITY){this.bottomClick=true;}
    		},
    		draw : function(){
    		  /*********imposto framerate*******/
    		  var now = +new Date();	
              var delta = (now - this.prevD)/10;
              this.prevD = now;		
              this.clear_all();
    		
    		  this.vectorX_NOW = this.vectorX * delta - this.vectorX_DEC;
    		  this.vectorY_NOW = this.vectorY * delta - this.vectorY_DEC;
    		
    		  /******disegno elementi scenografici****/
    		  
    		  var linee = this.linee;
    		  for(i in linee){
    			this.draw_line(linee[i]);
    			/***imposto le sensibilità ai piani***/
    			//500,350,300,300,2
    			//var y = linee[i][1];
    			
    			if((linee[i][0]>linee[i][2] && (this.baseX>linee[i][2] && this.baseX<linee[i][0])) || (linee[i][0]<linee[i][2] && (this.baseX>linee[i][0] && this.baseX<linee[i][2]))){
    			  if(linee[i][1]!=linee[i][3]){
    			    var y1 = linee[i][1];
    			    var y2 = linee[i][3];
    			    var x1 = linee[i][0];
    			    var x2 = linee[i][2];
    			    var xp = this.baseX;
    			    var y = ((y2-y1)*(xp-x1)/(x2-x1))+y1;
    				var obliqua = true;
    			  } else {
    			    var y = linee[i][1];
    				var obliqua = false;
    			  }
    			  
    			  if( this.baseY>y && this.baseY<y+this.radius ){
    			    this.agisciGravita(); this.baseY = y+this.radius;
    				this.leftClick = false;
    			  }
    			  else if( this.baseY<y && this.baseY>y-this.radius ){			    
    				this.aTerra();
    			    this.baseY = y-this.radius-linee[i][4]+1;
    				//if(obliqua){this.leftClick = true;}
    			  }
    			}
    			else if(this.baseY == linee[i][1]-this.radius-linee[i][4]+1){
    			  this.agisciGravita();
    			}
    		  }
    	      
    		  /****LIMITE DELLA PAGINA****/
    		  if(this.baseX<this.radius){this.baseX = this.radius;}
    		  if(this.baseX>this.widthPad){this.baseX = this.widthPad;}
    		  if(this.baseY<this.radius){this.baseY = this.radius;}
    		  if(this.baseY>this.heightPad){this.baseY = this.heightPad; this.aTerra();}
    		  
    		  /*****disegno la palla dove deve essere*******/
    	      this.draw_palla(this.baseX,this.baseY);
    		  /*****sposto la palla in funzione delle indicazioni*****/
    		  /*****>ASSE X<*****/
    		  if(this.rightClick){
    		    this.baseX += this.vectorX_NOW;
    		  }
    		  else if(this.leftClick){
    		    this.baseX -= this.vectorX_NOW;
    		  }
    		  /*****>ASSE Y<*****/
    		  if(this.topClick){
    		    this.baseY -= this.vectorY_NOW;
    			this.caricaSalto_NOW--;
    		    if(this.caricaSalto_NOW==0){
    			  this.deceleraY();
    			}
    		  } else if(this.bottomClick){
    		    this.baseY += this.vectorY_NOW;
    		  }
    		}
    	  };
    	  
    	  $(document).keydown(function(e){
    	    if(e.keyCode == 37){ palla.moveTo("left"); }
    	    if(e.keyCode == 38){ palla.moveTo("top"); }
    	    if(e.keyCode == 39){ palla.moveTo("right"); }
    	  });
    	  
    	  $(document).keyup(function(e){
    	    if(e.keyCode == 37){ palla.deceleraX("left");}
    	    if(e.keyCode == 38){ palla.agisciGravita(); }
    	    if(e.keyCode == 39){ palla.deceleraX("right");}
    	  });
    	  
    	  palla.init();
    	  
    	});
    	</script>
      </head>
      <body>
        <canvas id="myCanvas" width="500" height="400" style="border:1px solid black"></canvas> 
      </body>
    </html>

  2. #2
    L'avatar di dreadnaut
    dreadnaut non è connesso Super Moderatore
    Data registrazione
    22-02-2004
    Messaggi
    6,262

    Predefinito

    Lo proverei volentieri, ma visto che ci sono delle dipendenze mettilo online da qualche parte. In fondo hai un sito, no?

  3. #3
    Guest

  4. #4
    L'avatar di dreadnaut
    dreadnaut non è connesso Super Moderatore
    Data registrazione
    22-02-2004
    Messaggi
    6,262

    Predefinito

    Visto che la palla cade anche se la lasci ferma, c'è qualcosa che non va nei vari controlli che fai in draw(). D'altro canto, in quella funzione non dovrebbero esserci controlli, visto che viene eseguita in continuazione. E comunque, come funzione di ridisegno non dovrebbe venire eseguita in continuazione.

    Suggerirei di rifattorizzare il codice in modo da non eseguire nulla quando la palla è ferma. Puoi aggiungere più avanti un tick per la logica del gioco, nel caso tu voglia inserire nemici o ostacoli in momento.

    Quando ricevi un evento da tastiera, attivi il timer e muovi la palla, ridisegnando quanto necessario, fino a quando la palla non si ferma di nuovo.

  5. #5
    Guest

    Predefinito

    Capisco fermare i controlli quando la palla è ferma, sono inutili; non capisco però il fatto di togliere i controlli da draw. Nel caso in cui si preme la freccia a destra, quando se non durante la funzione draw() dovrei controllare se (per esempio) la pallina sia arrivata o meno al margine del canvas? :)

    ...

    Pensandoci, potrei per esempio far ciclare draw solo per disegnare. I controlli sarebbero eseguiti dall'evento onkeydown, e in caso di necessità scatenerei un evento personalizzato: http://www.sitepoint.com/jquery-custom-events/
    Potrebbe essere una soluzione secondo te? (Sempre ovviamente che poi non vada a rallentare troppo il keydown)
    Ultima modifica di federlest : 17-07-2013 alle ore 14.30.44

Tags for this Thread

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •