JavascriptProva

venerdì 15 marzo 2013

Creato finalmente il codice di gestione delle collisioni, ci si studia un po' sopra.

Bene! Non metto qui il codice per esteso, ma cerco di aggiustarmelo in modo tale da incapsularmelo un po'.

Sembra che finalmente ci sono riuscito!, a fare un codice per la gestione delle collisioni.
Dopo un paio di bugs, uno che mi ha fatto sputare il sangue e un altro che ho capito subito e risolto con poca fatica, sembra che adesso sia perfetto.


Gestiamo ora il modo di chiamare questo modulo, che si chiama dragdrop.js.

Quando volevo usare quel dragdrop.js che avevo costruito basandomi sul tutorial per il trascinamento trovato in rete, l'unica cosa fondamentale era l'operazione
window.onload=main;
 
function main(){
 document.onmousedown=OnMouseDown;
}
Ossia innescare la funzione main() al caricamento della finestra e quindi, nel contesto della funzione main() assimilare l'evento mousedown alla funzione OnMouseDown.

Ora, invece, sulla pagina che usa il modulo dragdrop.js il codice è un po' più complesso perchè deve definire la matrice di ostacoli:
var ostacoli;
window.onload=main;

function main(){
 ostacoli=document.getElementsByTagName("div");
 document.onmousedown=OnMouseDown;
}
In questo caso ho impostato come matrice l'insieme degli elemento div, ma posso impostare qualunque matrice mediante l'uso dell'oggetto Array.
Quindi, riepilogando, le uniche condizioni per usare il modulo dragdrop.js sono:
  • associare all'evento onmousedown la funzione OnMouseDown;
  • impostare la matrice di ostacoli.
A questo punto la prossima mossa è creare matrici diverse da questa, immettendo elementi selezionati in essa e non tutti i DIV in generale.

giovedì 7 marzo 2013

Appunto bozza ennesima strategia nel tentativo di un codice per le collisioni (dannazione!)

Una bozza dell'ennesimo tentativo di strategia per le collisioni (speriamo che sia la volta buona). Appunto per ricopiare il codice da altro computer.
var BaseX, BaseY;
var MouseX, MouseY;
var oggetto;
var ostacolo;
var ostacolo2;
var prevSx,prevDx,prevHi,prevLo;
var MotoOrizzontale=true;
var MotoVerticale=true;
var ostacoli;
var Sx,Hi;
var ConsentitoADestra;
var ConsentitoASinistra=true;
function OnMouseDown(){
 ostacoli=document.getElementsByTagName("div");
 ostacolo=$("ostacolo1");
 ostacolo2=$("ostacolo2");
 oggetto=event.srcElement;
 oggetto.onselectstart=function(){return false};
 BaseX=EN(oggetto.currentStyle.left);
 BaseY=EN(oggetto.currentStyle.top);
 MouseX=event.clientX;
 MouseY=event.clientY;
 document.onmousemove=OnMouseMove;
 document.onmouseup=OnMouseUp;
 
}

function OnMouseMove(){
 prevSx=sinistro(oggetto);
 prevDx=destro(oggetto);
 prevHi=alto(oggetto);
 prevLo=basso(oggetto);
 
 Sx=BaseX+event.clientX-MouseX;
 Hi=BaseY+event.clientY-MouseY
 
 $("test").innerHTML=DirezioneOrizzontale(Sx,prevSx);
 if (ConsentitoADestra){
  if(DirezioneOrizzontale(Sx,prevSx)=="destra") oggetto.style.left=Sx+"px";
 }
 if (ConsentitoASinistra){
  if(DirezioneOrizzontale(Sx,prevSx)=="sinistra") oggetto.style.left=Sx+"px";
 }
 oggetto.style.top=Hi+"px";
 
 
 
 
} 
 

function DirezioneOrizzontale(X, prevX){
 if(X>prevX) {
  return "destra";
 }else if(X<prevX) {
  return "sinistra";
 }else{
  return "fermo";
 }
}
 
 /*if(sinistro(oggetto)<100) {
  MotoOrizzontale=false;
  oggetto.style.left=(100)+"px";
 }else{
  MotoOrizzontale=true;
 }
 
 
 
 if(basso(oggetto)>300) {
  MotoVerticale=false;
  oggetto.style.top=(300-altezza(oggetto))+"px";
 }else{
  MotoVerticale=true;
 }*/




function OnMouseUp(){
 
 document.onmousemove=null;
}


//FUNZIONI DINAMICHE VERSO LE QUATTRO SEMIPROIEZIONI
//----------------------------------------------------------------------------------------
function OggettoVersoLaSemiproiezioneOrizzontaleDestra(ost){
 if(prevDx<=sinistro(ost) && OggettoNellaSemiproiezioneOrizzontaleDestra(ost)) return true;
}

function OggettoVersoLaSemiproiezioneOrizzontaleSinistra(ost){
 if(prevSx>=destro(ost) && OggettoNellaSemiproiezioneOrizzontaleSinistra(ost)) return true;
}

function OggettoVersoLaSemiproiezioneVerticaleInferiore(ost){
 if(prevLo<=alto(ost) && OggettoNellaSemiproiezioneVerticaleInferiore(ost)) return true;
}

function OggettoVersoLaSemiproiezioneVerticaleSuperiore(ost){
 if(prevHi>=basso(ost) && OggettoNellaSemiproiezioneVerticaleSuperiore(ost)) return true;
}
//-----------------------------------------------------------------------------------------


//FUNZIONI STATICHE SULLE QUATTRO SEMIPROIEZIONI
//----------------------------------------------------------------------------------------------
function OggettoNellaSemiproiezioneOrizzontaleDestra(ost){
 if(OggettoNellaProiezioneOrizzontale(ost) && OggettoNelSemicampoDestro(ost)) return true;
}

function OggettoNellaSemiproiezioneOrizzontaleSinistra(ost){
 if(OggettoNellaProiezioneOrizzontale(ost) && OggettoNelSemicampoSinistro(ost)) return true;
}

function OggettoNellaSemiproiezioneVerticaleInferiore(ost){
 if(OggettoNellaProiezioneVerticale(ost) && OggettoNelSemicampoInferiore(ost)) return true;
}

function OggettoNellaSemiproiezioneVerticaleSuperiore(ost){
 if(OggettoNellaProiezioneVerticale(ost) && OggettoNelSemicampoSuperiore(ost)) return true;
}
//----------------------------------------------------------------------------------------------



//FUNZIONI STATICHE SULLE DUE PROIEZIONI
//----------------------------------------------------------------------------------------------
function OggettoNellaProiezioneOrizzontale(ost){
 if(OggettoNelSemicampoSuperiore(ost) && OggettoNelSemicampoInferiore(ost)) return true;
}

function OggettoNellaProiezioneVerticale(ost){
 if(OggettoNelSemicampoDestro(ost) && OggettoNelSemicampoSinistro(ost)) return true;
}
//-----------------------------------------------------------------------------------------------


//FUNZIONI STATICHE SUI QUATTRO SEMICAMPI
//-----------------------------------------------------------------------------------------------
function OggettoNelSemicampoDestro(ost){
 if(destro(oggetto)>sinistro(ost)) return true;
}

function OggettoNelSemicampoSinistro(ost){
 if(sinistro(oggetto)<destro(ost)) return true;
}

function OggettoNelSemicampoInferiore(ost){
 if(basso(oggetto)>alto(ost)) return true;
}

function OggettoNelSemicampoSuperiore(ost){
 if(alto(oggetto)<basso(ost)) return true;
}
//----------------------------------------------------------------------------------------------

function sinistro(ogg){
 return EN(ogg.currentStyle.left);
}

function larghezza(ogg){
 return EN(ogg.currentStyle.width);
}

function destro(ogg){
 return EN(sinistro(ogg)+larghezza(ogg));
}

function alto(ogg){
 return EN(ogg.currentStyle.top);
}
 
function altezza(ogg){
 return EN(ogg.currentStyle.height);
}

function basso(ogg){
 return EN(alto(ogg)+altezza(ogg));
}

venerdì 22 febbraio 2013

Intercettazione della direzione di sovrapposizione fra oggetti.

Ed ecco che, con la mia tecnica, intercettiamo anche la direzione con la quale un oggetto va a sovrapporsi a un altro.
Anche questa è valida per tutti gli oggetti del documento.
function OnMouseMove(){
 prevSx=sinistro(oggetto);
 prevDx=destro(oggetto);
 prevHi=alto(oggetto);
 prevLo=basso(oggetto);
 
 Sx=BaseX+event.clientX-MouseX;
 Hi=BaseY+event.clientY-MouseY;
 Dx=Sx+EN(oggetto.currentStyle.width);
 Lo=Hi+EN(oggetto.currentStyle.height);
 
 
 //$("test").innerHTML="";
 for(n=0;n<oggetti.length;n++){
  if(prevDx<=sinistro(oggetti[n]) && EmiProjDestra(oggetti[n])) {
   $("test").innerHTML= "Da sinistra";
  }
  if(prevSx>=destro(oggetti[n]) && EmiProjSinistra(oggetti[n])){
   $("test").innerHTML="Da destra";
  }
  if(prevLo<=alto(oggetti[n]) && EmiProjBasso(oggetti[n])){
   $("test").innerHTML="Dall'alto";
  }
  if(prevHi>=basso(oggetti[n]) && EmiProjAlto(oggetti[n])){
   $("test").innerHTML="Dal basso";
  }
  
 }
 
 
 oggetto.style.left=Sx+"px";
 oggetto.style.top=Hi+"px";
}
Semplicemente grandioso!!!

Funzioni per le emiproiezioni dell'ostacolo

Creiamo un ulteriore "stock" di funzioni che condensano le precedenti e ci semplificano la vita.

Ecco l'ultima generazione di funzioni: ognuna identifica la posizione dell'oggetto su un'emiproiezione dell'ostacolo, sinistra, destra, in alto o in basso.
Funzionano, anch'esse per tutti gli oggetti.
function EmiProjAlto(ost){
 if(HorProjectAlto(ost) && VertProject(ost)) return true;
}
function EmiProjBasso(ost){
 if(HorProjectBasso(ost) && VertProject(ost)) return true;
}
function EmiProjDestra(ost){
 if(VertProjectDestra(ost) && HorProject(ost)) return true;
}
function EmiProjSinistra(ost){
 if(VertProjectSinistra(ost) && HorProject(ost)) return true;
}

Intercettazione sulle emiproiezioni dell'ostacolo.

Adesso è il momento di rimetterci tutta quella tecnica per intercettare la direzione della sovrapposizione, non soltanto la sovrapposizione fine a se stessa.

Devo ricreare una funzione che mi restituisca la sovrapposizione non alla proiezione intera ma alla semiproiezione di un oggetto.

Ecco: dimezzando le funzioni che intercettano la posizione dell'oggetto sulla proiezione orizzontale o verticale dell'ostacolo, ottengo delle funzioni che ne intercettano la posizione oltre il margine sinistro o destro o alto o basso.
Dalla fusione delle funzioni posso ottenere l'intercettazione dell'oggetto sulle quattro emiproiezioni alta, bassa, destra, sinistra.
Collaudate: funzionano.
//intercetta la posizione sulla proiezione orizzontale dell'ostacolo
function HorProject(ost){
 if(oggetto==ost) return false;
 if(Hi<basso(ost) && Lo>alto(ost)) return true;
}

//intercetta la posizione sulla proiezione verticale dell'ostacolo
function VertProject(ost){
 if(oggetto==ost) return false;
 if(Sx<destro(ost) && Dx>sinistro(ost)) return true;
}

//intercetta la posizione sulla destra dell'ostacolo
function VertProjectDestra(ost){
 if(oggetto==ost) return false;
 if(Dx>sinistro(ost))return true;
}

//intercetta la posizione sulla sinistra dell'ostacolo
function VertProjectSinistra(ost){
 if(oggetto==ost) return false;
 if(Sx<destro(ost)) return true;
}

//intercetta la posizione sul basso dell'ostacolo
function HorProjectBasso(ost){
 if(oggetto==ost) return false;
 if(Lo>alto(ost)) return true;
}

//intercetta la posizione sull'alto dell'ostacolo
function HorProjectAlto(ost){
 if(oggetto==ost) return false;
 if(Hi<basso(ost)) return true;
}
Questo codice, unendo VertProject, che intercetta sulla proiezione verticale, con HorProjectAlto, intercetta sull'emiproiezione alta dell'ostacolo.
        for(n=0;n<oggetti.length;n++){
  if(HorProjectAlto(oggetti[n]) && VertProject(oggetti[n])) {
   $("test").innerHTML= "centrato";
  }
 }


Che faticaccia!!!

Anche queste funzionano per qualunque oggetto.

Intercettazione della sovrapposizione di elementi DIV fra di loro.

Fatto!
Così ottengo l'intercettazione della sovrapposizione di un oggetto a un altro.
Creata in pochi secondi la funzione relativa alla proiezione verticale:
function VertProject(ost){
 if(oggetto==ost) return false;
 if(Sx<destro(ost) && Dx>sinistro(ost)) return true;
}
la aggiungo al precedente codice che analizza gli elementi passati dalla matrice:
function OnMouseMove(){
 
 Sx=BaseX+event.clientX-MouseX;
 Hi=BaseY+event.clientY-MouseY;
 Dx=Sx+EN(oggetto.currentStyle.width);
 Lo=Hi+EN(oggetto.currentStyle.height);
 
 
 $("test").innerHTML="";
 for(n=0;n<oggetti.length;n++){
  if(HorProject(oggetti[n]) && VertProject(oggetti[n])) {
   $("test").innerHTML= "centrato";
  }
 }
 
 
 oggetto.style.left=Sx+"px";
 oggetto.style.top=Hi+"px";
}
e ottengo l'intercettazione della parziale sovrapposizione di un oggetto a un altro: non appena uno dei DIV si sovrappone in parte a un altro, scatta l'avviso!
Ottimo!

Intercettare la sovrapposizione di un oggetto alla proiezione orizzontale di un altro oggetto

Adesso vorrei adattare la cosa a più oggetti insieme.
Creiamo un Array di tutti i DIV presenti nella pagina...

Devo creare un Array e aggiungervi tutti gli oggetti presenti.
Come si aggiunge un oggetto a un Array?

Fatto, fatto.
Mi ci sono ammattito un po' ma funziona muovendo ogni oggetto e intercetta la sovrapposizione di ogni oggetto con la proiezione orizzontale di qualsiasi altro oggetto.
function OnMouseMove(){
 
 Sx=BaseX+event.clientX-MouseX;
 Hi=BaseY+event.clientY-MouseY;
 Dx=Sx+EN(oggetto.currentStyle.width);
 Lo=Hi+EN(oggetto.currentStyle.height);
 
 
 $("test").innerHTML="";
 for(n=0;n<oggetti.length;n++){
  if(HorProject(oggetti[n])) {
   $("test").innerHTML= "centrato";
  }
 }
 
 
 oggetto.style.left=Sx+"px";
 oggetto.style.top=Hi+"px";
}
In rosso, la parte che "dà in pasto" alla funzione HorProject(ost) ogni elemento della matrice di tutti gli elementi DIV del documento.
L'array viene generato nell'ambito della funzione OnMouseDown:
function OnMouseDown(){
 oggetti=document.getElementsByTagName("div");
 ostacolo=$("ostacolo1");
 ostacolo2=$("ostacolo2");
 oggetto=event.srcElement;
 oggetto.onselectstart=function(){return false};
 BaseX=EN(oggetto.currentStyle.left);
 BaseY=EN(oggetto.currentStyle.top);
 MouseX=event.clientX;
 MouseY=event.clientY;
 document.onmousemove=OnMouseMove;
 document.onmouseup=OnMouseUp;
}
E funziona!

Adesso sarebbe il caso di passare anche alla sovrapposizione verticale, creando un'altra semplice funzione...