JavascriptProva

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...

Rilevamento della sovrapposizione dell'oggetto alla proiezione orizzontale dell'ostacolo

Rilevamento della sovrapposizione dell'oggetto alla proiezione orizzontale dell'ostacolo:
function OnMouseMove(){
 
 Sx=BaseX+event.clientX-MouseX;
 Hi=BaseY+event.clientY-MouseY;
 Dx=Sx+EN(oggetto.currentStyle.width);
 Lo=Hi+EN(oggetto.currentStyle.height);
 if(HorProject(ostacolo)) {
  $("test").innerHTML= "centrato";
 }else{
  $("test").innerHTML="";
 }
 oggetto.style.left=Sx+"px";
 oggetto.style.top=Hi+"px";
}
usando la funzione che rileva la sovrapposizione dell'oggetto alla proiezione orizzontale dell'ostacolo:
function HorProject(ost){
 if(Hi<(EN(ost.currentStyle.top)+EN(ost.currentStyle.height)) && (Lo>EN(ost.currentStyle.top))) return true;
}
..la qual cosa andrebbe abbreviata...

Correzione coordinate dell'oggetto.

Correzione per le funzioni che ottengono le coordinate dell'oggetto.
Esse vengono calcolate direttamente nell'ambito della funzione OnMouseMove.
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= Hi+" "+Lo;
 oggetto.style.left=Sx+"px";
 oggetto.style.top=Hi+"px";
}
La verifica con la casella test (in blu) è positiva.

Una nuova idea per le collisioni: pensare la posizione dell'oggetto prima di attuarla...

Dunque... proviamo con un altro approccio.
Il codice può prima pensare alla posizione dell'oggetto e poi attuarla, in modo da eliminare posizioni reali e posizioni virtuali dovute a repentini rapidissimi spostamenti dell'oggetto.

Ecco: la funzione OnMouseMove che gestisce l'evento document.onmousemove mi dà valore alle variabili Sx e Hi, che sono le coordinate dell'angolo superiore sinistro dell'oggetto, ossia i lati sinistro e superiore del quadrato che costituisce l'oggetto.
Il codice, ovviamente, non muove minimamente l'oggetto.

Ora definiamo anche le coordinate degli altri lati, chiamiamole Dx e Lo.
var Sx,Hi,Dx,Lo;
E creiamo delle funzioni che le calcolino in relazione alla larghezza e all'altezza dell'oggetto.
function Dx(){
 return (Sx+oggetto.width);
}
function Lo(){
 return (Hi+oggetto.height);
}
Ecco.

La funzione OnMouseMove adesso ha questo aspetto:
function OnMouseMove(){
 
 Sx=BaseX+event.clientX-MouseX;
 Hi=BaseY+event.clientY-MouseY;
}
Proviamo a muovere l'oggetto...

che ovviamente non si muove.
Adesso concretizziamo le misure prese:
function OnMouseMove(){
 
 Sx=BaseX+event.clientX-MouseX;
 Hi=BaseY+event.clientY-MouseY;
 oggetto.style.left=Sx+"px";
 oggetto.style.top=Hi+"px";
}

e l'oggetto, come per incanto, si muove.

Ecco, adesso forse sarà più facile...

mercoledì 20 febbraio 2013

Analizziamo pazientemente (questo è il più grosso problema di programmazione con cui mi sia mai scontrato)

E' estremamente arduo.

Riproviamo dall'inizio.
Io faccio così: più mi incorno su un problema più mi ci impiccio, e più non ci cavo un ragno dal buco.
Ricominciamo.
Dato che il difetto fondamentale del resettare la posizione dell'oggetto nel momento in cui viene mosso è che la posizione dell'oggetto non corrisponde a quella che si vede, devo fermare l'oggetto nella posizione reale e non in una posizione virtuale.

Per fare questo, devo arrestare il movimento bloccando l'oggetto contro una linea, ma bloccandolo davvero.
La dinamica dei fatti è che quando viene mosso l'oggetto, esso viene mosso oltre l'ostacolo, e resettato poi a monte dell'ostacolo in un secondo tempo. La cosa potrebbe anche andare bene...

Ma proviamo ad arrestare il movimento realmente, in modo che l'oggetto non si possa più muovere orizzontalmente contro un ostacolo, ma solo nelle altre direzioni.
La funzione da modificare è questa:
function OnMouseMove(){
 oggetto.style.left=BaseX+event.clientX-MouseX;
 oggetto.style.top=BaseY+event.clientY-MouseY;
}
Modifichiamola un po'...
function OnMouseMove(){
 if(destro(oggetto)<500) oggetto.style.left=BaseX+event.clientX-MouseX;
 oggetto.style.top=BaseY+event.clientY-MouseY;
}
Bene. Mi sono creato una linea verticale che abbia per ascissa 500 per verificare dove si arresta il movimento.
Così facendo, se sposto l'oggetto lentamente, esso si arresta esattamente con il suo lato destro contro la linea verticale, ossia a 500 di ascissa, ma se vado velocemente, si arresta più a destra, perchè la posizione non viene espressa punto per punto.
Devo quindi correggere la posizione dell'oggetto.
function OnMouseMove(){

 if(destro(oggetto)<500) {
  oggetto.style.left=BaseX+event.clientX-MouseX;
 }else{
  oggetto.style.left=(500-larghezza(oggetto))+"px";
 }
 
 oggetto.style.top=BaseY+event.clientY-MouseY;
}
Sì, così funziona: anche andando a velocità supersonica, l'oggetto si arresta sempre a 500.
La differenza con il codice che usavo precedentemente è che prima l'oggetto veniva spostato oltre l'ostacolo e poi tornava dietro.
Lo riprovo:
function OnMouseMove(){

 oggetto.style.left=BaseX+event.clientX-MouseX;
 
 if(destro(oggetto)>500) oggetto.style.left=(500-larghezza(oggetto))+"px";

 oggetto.style.top=BaseY+event.clientY-MouseY;
}
Ecco: così facendo, prima l'oggetto viene spostato oltre l'ostacolo, quindi viene riportato indietro se il suo margine destro supera 500.
Questo accade a ogni movimento dell'oggetto. Non si vede, ma in realtà quando l'oggetto viene spinto contro l'ostacolo, per un infinitesimo va effettivamente oltre l'ostacolo e quindi, verificandosi la condizione "oltre l'ostacolo", viene rispinto indietro.

Nel primo caso, invece:
function OnMouseMove(){

 if(destro(oggetto)<500) {
  oggetto.style.left=BaseX+event.clientX-MouseX;
 }else{
  oggetto.style.left=(500-larghezza(oggetto))+"px";
 }
 
 oggetto.style.top=BaseY+event.clientY-MouseY;
}
l'oggetto viene mosso se il margine destro è minore del limite, altrimenti viene fissato contro il limite stesso
In questo secondo caso, non vi è una posizione "inapparente" dell'oggetto durante le primissime fasi del movimento, perchè esso viene arrestato subito nella sua posizione contro l'ostacolo.

venerdì 15 febbraio 2013

Pensieri sulle collisioni

Non funziona... Perchè?
Dunque, partiamo da zero...
L'oggetto scivola contro l'ostacolo in virtù del fatto che viene continuamente riportato, dalla sua posizione reale, ossia quella "attaccata" al cursore del mouse, nella posizione virtuale, ossia quella "aderente alla superficie dell'ostacolo". Il processo si svolge ogni volta che il cursore viene mosso, perchè questa funzione
function OnMouseMove(){
 prevSx=sinistro(oggetto);
 prevDx=destro(oggetto);
 prevHi=alto(oggetto);
 prevLo=basso(oggetto);
 oggetto.style.left=BaseX+event.clientX-MouseX;
 oggetto.style.top=BaseY+event.clientY-MouseY;

 verificaDirezione(sinistro(oggetto),destro(oggetto),alto(oggetto),basso(oggetto),ostacolo);
}
che intercetta l'evento "movimento del mouse", chiamando la funzione "verificaDirezione", dà all'oggetto delle coordinate corrispondenti alla posizione "strisciante sulla superficie dell'oggetto". A ogni movimento del mouse, in realtà, l'oggetto torna "attaccato al puntatore", per poi essere riportato "strisciante sull'oggetto".
La cosa non si nota perchè è molto rapida.
Così, se incontro un altro ostacolo attaccato al primo, e ripeto la funzione con il secondo ostacolo, ponendo come parametri della funzione le coordinate dell'oggetto, in realtà fornisco le coordinate "reali", ossia dell'oggetto che, per una frazione invisibile di secondo, si trova attaccato al cursore del mouse, non le coordinate "virtuali", ossia dell'oggetto che strofina contro il bordo dell'ostacolo.

giovedì 14 febbraio 2013

Blocco dell'oggetto contro l'ostacolo

Blocchiamo l'oggetto, adesso...
function verificaDirezione(oggSx,oggDx,oggHi,oggLo,ost){
  if(horOverDx(oggHi,oggLo,oggDx,ost)&& prevDx<=sinistro(ost)) {
   $("test").innerHTML="Da sinistra";
   oggSx=sinistro(ost)-larghezza(oggetto);
   oggDx=sinistro(ost);
   oggetto.style.left=oggSx+"px";
  }
  if(horOverSx(oggHi,oggLo,oggSx,ost)&& prevSx>=destro(ost)) {
   $("test").innerHTML="Da destra";
   oggSx=destro(ost)
   oggDx=destro(ost)+larghezza(oggetto);
   oggetto.style.left=oggSx+"px";
  }
   
  if(vertOverHi(oggSx,oggDx,oggLo,ost) && prevLo<=alto(ost)) {
   $("test").innerHTML="Da alto";
   oggHi=alto(ost)-altezza(oggetto);
   oggLo=alto(ost)
   oggetto.style.top=oggHi;
  }
  if(vertOverLo(oggSx,oggDx,oggHi,ost) && prevHi>=basso(ost)) {
   $("test").innerHTML="Da basso";
   oggHi=basso(ost);
   oggLo=basso(ost)+altezza(oggetto);
   oggetto.style.top=basso(ost);
  }
}
Ecco, così l'oggetto si blocca quando viene a cozzare con l'ostacolo.
La differenza rispetto al codice precedente è che il valore delle coordinate dell'oggetto bloccatosi viene immagazzinato in variabili a parte.
Le variabili vengono rigenerate all'inizio della funzione OnMouseMove.

domenica 10 febbraio 2013

Sintesi delle funzioni che rilevano la direzione di sovrapposizione di un oggetto a un ostacolo

Ora blocchiamo l'oggetto.

Prima fondiamo le funzioni, in modo da isolare il lavoro sporco...

Ecco il codice che verifica la direzione usando le funzioni predette:
if(horOverDx(alto(oggetto),basso(oggetto),destro(oggetto),ostacolo)&& prevDx<=sinistro(ostacolo)) $("test").innerHTML="Da sinistra";
 if(horOverSx(alto(oggetto),basso(oggetto),sinistro(oggetto),ostacolo)&& prevSx>=destro(ostacolo)) $("test").innerHTML="Da destra";
 if(vertOverHi(sinistro(oggetto),destro(oggetto),basso(oggetto),ostacolo) && prevLo<=alto(ostacolo)) $("test").innerHTML="Da alto";
 if(vertOverLo(sinistro(oggetto),destro(oggetto),alto(oggetto),ostacolo) && prevHi>=basso(ostacolo)) $("test").innerHTML="Da basso";
Come unificarlo?

Creo un'unica funzione verifica:
function verificaDirezione(oggSx,oggDx,oggHi,oggLo,ost){
 if(horOverDx(oggHi,oggLo,oggDx,ost)&& prevDx<=sinistro(ost)) $("test").innerHTML="Da sinistra";
 if(horOverSx(oggHi,oggLo,oggSx,ost)&& prevSx>=destro(ost)) $("test").innerHTML="Da destra";
 if(vertOverHi(oggSx,oggDx,oggLo,ost) && prevLo<=alto(ost)) $("test").innerHTML="Da alto";
 if(vertOverLo(oggSx,oggDx,oggHi,ost) && prevHi>=basso(ost)) $("test").innerHTML="Da basso";
}
Eccola, e viene richiamata così:
function OnMouseMove(){
 prevSx=sinistro(oggetto);
 prevDx=destro(oggetto);
 prevHi=alto(oggetto);
 prevLo=basso(oggetto);
 oggetto.style.left=BaseX+event.clientX-MouseX;
 oggetto.style.top=BaseY+event.clientY-MouseY;

 verificaDirezione(sinistro(oggetto),destro(oggetto),alto(oggetto),basso(oggetto),ostacolo);
}
Funziona!

Tutte le funzioni che intercettano la posizione dell'oggetto.

Ecco... magna cum fatica, ho creato anche le funzioni che intercettano la posizione dell'oggetto sulle emiproiezioni verticali dell'ostacolo. Le ho testate, e funzionano.
function horOver(oggHi,oggLo,ost){
 if(oggLo>=alto(ost) && oggHi<=basso(ost)) return true;
}

function vertOver(oggSx, oggDx, ost){
 if(oggDx>=sinistro(ost) && oggSx <destro(ost)) return true;
}

function horOverDx(oggHi,oggLo,oggDx,ost){
 if(horOver(oggHi,oggLo,ost) && oggDx>=sinistro(ost)) return true;
}

function horOverSx(oggHi,oggLo,oggSx,ost){
 if(horOver(oggHi,oggLo,ost) && oggSx<=destro(ost)) return true;
}
function vertOverHi(oggSx,oggDx,oggLo,ost){
 if(vertOver(oggSx,oggDx,ost) && oggLo>=alto(ost)) return true;
}
function vertOverLo(oggSx,oggDx,oggHi,ost){
 if(vertOver(oggSx,oggDx,ost) && oggHi<=basso(ost)) return true;
}
Questo è un piccolo tesoro di funzioni da tener gelosamente custodite anche perchè per rifarle potrebbe scappare una caterva di imprecazioni notevole!

Ancora sulla direzione della sovrapposizione dell'oggetto all'ostacolo, usando le metà delle proiezioni dell'ostacolo

Costruiamo progressivamente queste funzioni altrimenti combiniamo un casino che non finisce più.

Le funzioni horOver e vertOver accertano che l'oggetto sia sulla proiezione orizzontale e, rispettivamente, verticale dell'ostacolo.

Poi abbiamo funzioni che accertano se l'oggetto sia sulla parte destra o sinistra della proiezione orizzontale, e, rispettivamente, verticale dell'oggetto.
Proseguo solo con l'orizzontale.
Come posso chiamare la funzione che mi accerta la presenza dell'oggetto sull'emiproiezione destra o sinistra?
Forse horOverDx e horOverSx. Mi sembra una denominazione mnemonicamente abbastanza facile.
Eccole:
function horOver(oggHi,oggLo,ost){
 if(oggLo>=alto(ost) && oggHi<=basso(ost)) return true;
}

function vertOver(oggSx, oggDx, ost){
 if(oggDx>=sinistro(ost) && oggSx <destro(ost)) return true;
}

function horOverDx(oggHi,oggLo,oggDx,ost){
 if(horOver(oggHi,oggLo,ost) && oggDx>=sinistro(ost)) return true;
}

function horOverSx(oggHi,oggLo,oggSx,ost){
 if(horOver(oggHi,oggLo,ost) && oggSx<=destro(ost)) return true;
}
Ecco. Ora vediamo se possiamo far capire al programma se l'oggetto arriva da destra o da sinistra.
function OnMouseMove(){
 prevSx=sinistro(oggetto);
 prevDx=destro(oggetto);
 
 oggetto.style.left=BaseX+event.clientX-MouseX;
  if(horOverDx(alto(oggetto),basso(oggetto),destro(oggetto),ostacolo)&& prevDx<=sinistro(ostacolo)) $("test").innerHTML="Da sinistra";
  if(horOverSx(alto(oggetto),basso(oggetto),sinistro(oggetto),ostacolo)&& prevSx>=destro(ostacolo)) $("test").innerHTML="Da destra";
Bene! Se l'oggetto va a sovrapporsi all'ostacolo da sinistra, nella casella test appare "Da sinistra", mentre se va a sovrapporsi da destra nella casella test appare "Da destra".
Riuscito!

giovedì 7 febbraio 2013

Rilevamento della direzione della sovrapposizione di oggetti.

Ecco le due funzioni che rilevano la sovrapposizione verticale e orizzontale, e la loro sintesi:

function horOver(oggHi,oggLo,ost){
 if(oggLo>=alto(ost) && oggHi<=basso(ost)) return true;
}

function vertOver(oggSx, oggDx, ost){
 if(oggDx>=sinistro(ost) && oggSx <destro(ost)) return true;
}

function Over(oggHi,oggLo,oggSx,oggDx,ost){
 if(horOver(oggHi,oggLo,ost) && vertOver(oggSx,oggDx,ost)) return true;
}
Ed eccone l'applicazione, che rileva quando l'oggetto si sovrappone all'ostacolo:
function OnMouseMove(){
 oggetto.style.left=BaseX+event.clientX-MouseX;
 oggetto.style.top=BaseY+event.clientY-MouseY;
 
 
 if (Over(alto(oggetto),basso(oggetto),sinistro(oggetto),destro(oggetto),ostacolo)){
  $("test").innerHTML="sovrapposto";
 }else{
  $("test").innerHTML=" ";
 }
}
Testata, funziona alla perfezione.

Ora bisogna scrivere funzioni che rilevino la direzione della sovrapposizione...
Cerco di ricordare...

Il principio è rilevare la precedente posizione dell'oggetto, quindi una volta effettuato lo spostamento rilevare la posizione attuale dell'oggetto e fare il confronto.

Dichiaro le variabili che ospiteranno le coordinate prima del movimento.
var prevSx,prevDx,prevHi,prevLo;
E poi le pongo prima del movimento a ricevere i valori. Iniziamo solo con quelle orizzontali...
function OnMouseMove(){
 prevSx=sinistro(oggetto);
 prevDx=destro(oggetto);
 
 oggetto.style.left=BaseX+event.clientX-MouseX;
Aggiungo successivamente un codice che se l'oggetto si sovrappone all'ostacolo, se il precedente margine destro era inferiore o uguale al margine sinistro dell'ostacolo, ossia se l'oggetto va a sovrapporsi all'ostacolo da sinistra, scrive nella casella-test "da sinistra", mentre se il precedente margine sinistro dell'oggetto è superiore al margine destro dell'ostacolo, ossia se l'oggetto va a sovrapporsi all'ostacolo da destra scrive nella casella-test "da destra".
function OnMouseMove(){
 prevSx=sinistro(oggetto);
 prevDx=destro(oggetto);
 
 oggetto.style.left=BaseX+event.clientX-MouseX;
 
 if(Over(alto(oggetto),basso(oggetto),sinistro(oggetto),destro(oggetto),ostacolo)){
  if(prevDx<=sinistro(ostacolo)) $("test").innerHTML="da sinistra";
  if(prevSx>=destro(ostacolo)) $("test").innerHTML="da destra";
 }
 
 oggetto.style.top=BaseY+event.clientY-MouseY; 
}
Funziona benissimo! Ho rilevato se l'oggetto si sovrappone all'ostacolo da sinistra o da destra!

martedì 5 febbraio 2013

Collisioni: rilevamento della sovrapposizione fra oggetto e ostacolo con funzioni aventi come parametri le coordinate dell'oggetto anzichè l'oggetto stesso

Ora mi servono delle funzioni per stabilire quando l'oggetto si sovrappone all'ostacolo

Per la sovrapposizione orizzonale le condizioni sono che il limite inferiore dell'oggetto sia maggiore o uguale al limite superiore dell'ostacolo e il limite superiore dell'oggetto sia minore o uguale al limite inferiore dell'ostacolo.
Rendiamolo...
function horOver(ogg,ost){
 if(basso(ogg)>=alto(ost) && alto(ogg)<=basso(ost)) return true;
}
Adesso, per provare questo, mi creo un div "spia" nella pagina principale.
<div id="test"></div>
con il suo stile:
#test{
 width:100px;
 height:20px;
 border:2px solid black;
 top:0px;
 left:0px;
 position:absolute;
}


Bene.
Ora testiamo la funzione...

Ci sono stati un po' di problemi perchè non ricordavo come gestire la proprietà position se absolute o relative.

Ecco che ho sistemato la questione... Sì.
Nella DIV denominata "test" ottengo se è vero o falso che oggetto e ostacolo si sovrappongono in orizzontale, con questa aggiunta alla funzione OnMouseMove:
function OnMouseMove(){
 oggetto.style.left=BaseX+event.clientX-MouseX;
 oggetto.style.top=BaseY+event.clientY-MouseY;
 $("test").innerHTML=horOver(oggetto,ostacolo);
}
Ora però voglio inserire, come parametri, non l'oggetto ma le sue coordinate. Mi servirà successivamente per superare i grossi problemi che ho incontrato nei miei tentativi precedenti che mi hanno fatto ammattire...
Ci provo.

Ecco! come parametri pongo oggHi che corrisponde al limite alto dell'oggetto, e oggLo che ne è il limite basso.

function horOver(oggHi,oggLo,ost){
 if(oggLo>=alto(ost) && oggHi<=basso(ost)) return true;
}
E funziona lo stesso: la mia casella test mi segnala ugualmente true quando si ha la sovrapposizione orizzontale dell'oggetto.

Ora vediamo pure con la sovrapposizione verticale...
function vertOver(oggSx, oggDx, ost){
 if(oggDx>=sinistro(ost) && oggSx <destro(ost)) return true;
}
che viene correttamente svelata dalla mia casella test con il seguente codice nella funzione OnMouseMove:
function OnMouseMove(){
 oggetto.style.left=BaseX+event.clientX-MouseX;
 oggetto.style.top=BaseY+event.clientY-MouseY:
 $("test").innerHTML=vertOver(sinistro(oggetto),destro(oggetto),ostacolo);
}
Perfetto.
Quindi la sovrapposizione completa dell'oggetto all'ostacolo sarà data dalla contemporanea condizione di true per le due funzioni horOver e vertOver.

Ecco, infatti le due funzioni:
function horOver(oggHi,oggLo,ost){
 if(oggLo>=alto(ost) && oggHi<=basso(ost)) return true;
}

function vertOver(oggSx, oggDx, ost){
 if(oggDx>=sinistro(ost) && oggSx <destro(ost)) return true;
}
e il codice che ne rileva il risultato nella casella test.
function OnMouseMove(){
 oggetto.style.left=BaseX+event.clientX-MouseX;
 oggetto.style.top=BaseY+event.clientY-MouseY;
 if(horOver(alto(oggetto),basso(oggetto),ostacolo) && vertOver(sinistro(oggetto),destro(oggetto),ostacolo)) {
  $("test").innerHTML="sovrapposto";
 }else{
  $("test").innerHTML=" ";
 }
}
Bene.

Per oggi è sufficiente!

lunedì 4 febbraio 2013

Continuo a disegnarmi lo scenario per le mie collisioni

Bene, ripetere un po' le cose già fatte riscrivendole da capo aiuta a memorizzare la tecnica...

Ora materializziamo un nuovo oggetto sulla pagina, mediante il CSS:
#ostacolo1{
 width:100px;
 height:100px;
 top:100px;
 left:100px;
 background-color:red;
 position:relative;
}
Un quadrato rosso.
Anch'esso è mobile, dato che ha la proprietà position impostata su relative...

Ora vediamo il da farsi...
Impostiamo le funzioni che definiscono il limite destro e sinistro e alto e basso, più la larghezza, dei vari oggetti, così il codice si semplifica...
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));
}
Ecco, così il codice è più scrivibile.

Per il momento fermiamoci qua...

Ricominciamo daccapo con le collisioni...

Procediamo, con calma...

Buttiamo giù di nuovo il DragDrop? Ma no... prendiamocelo già confezionato, vah...

Ecco: ho deciso di riscrivermelo
Mi sono riscritto lo scheletro:
var BaseX, BaseY;
var MouseX, MouseY;
var oggetto;

function OnMouseDown(){
 oggetto=event.srcElement;
 BaseX=EN(oggetto.currentStyle.left);
 BaseY=EN(oggetto.currentStyle.top);
 MouseX=event.clientX;
 MouseY=event.clientY;
 document.onmousemove=OnMouseMove;
 document.onmouseup=OnMouseUp;
}

function OnMouseMove(){
 oggetto.style.left=BaseX+event.clientX-MouseX;
 oggetto.style.top=BaseY+event.clientY-MouseY;
}

function OnMouseUp(){
 document.onmousemove=null;
}
Questo è il complesso di funzioni che permette a un oggetto con la proprietà position impostata a relative di venir trascinato.

venerdì 1 febbraio 2013

Ricominciamo a prendere d'assalto le tecniche per le collisioni

VAI!

Mi ricostruisco la pagina, piano piano...
<html>
<head>
<style>
#oggetto{
 width:50px;
 height:50px;
 background-color:green;
 position:relative;
} 

</style>
<script>
</script>
</head>
<body>
<div id="oggetto"></div>
<div id="ostacolo1"></div>
<div id="ostacolo2"></div>
</body>
</html> 
Per il momento ho dato una forma solo all'oggetto.
Un po' poco per ricominciare, ma continuo domani...

Per il momento ho ricominciato!