Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2018
    Messaggi
    211

    Istruzione dy=-dy non viene eseguita

    Nel programma qui sotto viene eseguita l'istruzione if (x>=1290 || x<=200){dx=-dx}, cioè se
    (x>=1290 || x<=200) è true si ha dx=-dx.
    Stranamente invece, non viene eseguita l'istruzione if (y>= 550 || y<=10){dy=-dy}, cioè se
    (y>= 550 || y<=10) è true non sia dy=-dy, ma dy resta dy.
    Dando un valore alla velocità, per es. 10, e un altro all'angolo, per es. 30, la pallina rimbalza tra sinistra(200px) e destra(1290px), ma non rimbalza sotto(top 550px) e va oltre. Lo stesso in alto(top 10).
    Per controllare quanto ho detto, in alto ho scritto in due caselle di testo i valori di y(top) e della condizione true o false di (y>= 550 || y<=10).
    Desidererei sapere il perché di questa anomalia. Grazie

    lanvoel


    codice:
    <!DOCTYPE html PUBLIC>
    <html>
    <head>
    <script language=JavaScript>
    var oggetto;
    var intervallo;
       var x=200;var y=250;
       var dx=1;var dy=1;
    function avvia()
    {
       velo=testo1.value;
       intervallo=window.setInterval("muovi()",velo);
    }
    function muovi()
    {
       oggetto=document.getElementById("para1");
       x=x+dx;
       var alfa=angolo.value;
       dy=dx*Math.tan(alfa*3.14159/180);
       y=y+dy;
              if (x>=1290  || x<=200){dx=-dx}
              if (y>= 550 || y<=10){dy=-dy}
       oggetto.style.position="absolute";
       oggetto.style.top =y;
       oggetto.style.left =x;
    testo2.value=y;
    testo3.value= (y>= 550 || y<=10);
    }  
    function ferma1()
    {
    clearInterval(intervallo);
    }
    </script
    </head>
    <body>
    controllo valori di y (top)<input type="text" name="testo2" id="testo2" size=25>
    controlollo condizione (y>= 550 || y<=10)<input type="text" name="testo3" id="testo3" size=15><br><br>
    <input type="button" name="pulsanre1" id="pulsante1" value="avvia" onclick="avvia()"><br> <br>
    velocità (alta:1 bassa:200)<br>
    <input type="text" name="testo1" id="testo1" size=20><br><br>
    angolo di partenza in gradi:<br>
    <input type="text" name="angolo" id="angolo" size=10><br><br>
    <input type="button" name="pulsante2" id="pulsante2" value="ferma" onclick="ferma1()">
    <P style="background:yellow; width:1100; height:550; border:3px red double; position:absolute; left:200px; top:10px;"></P>
    <P Style="background:red; width:10px; height:10px; border:3px blue solid; position:absolute; left:200px; top:250px;" id="para1">
    </body>
    </html>

  2. #2
    Moderatore di JavaScript L'avatar di br1
    Registrato dal
    Jul 1999
    Messaggi
    19,998
    Sbagli a ricalcolare ogni volta dy su dx invece di cambiare solo il segno.
    codice:
    <!DOCTYPE html PUBLIC>
    <html>
    <head>
    <script language=JavaScript>
    var oggetto;
    var intervallo;
    var x=200;var y=250;
    var dx=1;var dy=1;
    function avvia()
    {
    velo=testo1.value;
    var alfa=angolo.value;
    dy=dx*Math.tan(alfa*3.14159/180);
    intervallo=window.setInterval("muovi()",velo);
    }
    function muovi()
    {
    oggetto=document.getElementById("para1");
    x=x+dx;
    y=y+dy;
    if (x>=1290 || x<=200){dx=-dx}
    if (y>= 550 || y<=10){dy=-dy}
    oggetto.style.position="absolute";
    oggetto.style.top =y;
    oggetto.style.left =x;
    testo2.value=y;
    testo3.value= (y>= 550 || y<=10);
    } 
    function ferma1()
    {
    clearInterval(intervallo);
    }
    </script
    </head>
    <body>
    controllo valori di y (top)<input type="text" name="testo2" id="testo2" size=25>
    controlollo condizione (y>= 550 || y<=10)<input type="text" name="testo3" id="testo3" size=15><br><br>
    <input type="button" name="pulsanre1" id="pulsante1" value="avvia" onclick="avvia()"><br> <br>
    velocità (alta:1 bassa:200)<br>
    <input type="text" name="testo1" id="testo1" size=20><br><br>
    angolo di partenza in gradi:<br>
    <input type="text" name="angolo" id="angolo" size=10><br><br>
    <input type="button" name="pulsante2" id="pulsante2" value="ferma" onclick="ferma1()">
    <P style="background:yellow; width:1100; height:550; border:3px red double; position:absolute; left:200px; top:10px;"></P>
    <P Style="background:red; width:10px; height:10px; border:3px blue solid; position:absolute; left:200px; top:250px;" id="para1">
    </body>
    </html>
    Il guaio per i poveri computers e' che sono gli uomini a comandarli.

    Attenzione ai titoli delle discussioni: (ri)leggete il regolamento
    Consultate la discussione in rilievo: script / discussioni utili
    Usate la funzione di Ricerca del Forum

  3. #3
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,674
    Non per demoralizzarti ma ho l'impressione che tu stia sbagliando approccio in tutti i sensi.

    Punto primo:
    L'algoritmo che stai usando ha sicuramente qualche difetto. Se è frutto di un tuo personale lavoro e lo stai facendo a motivo di studio, ti consiglierei piuttosto di partire da qualcosa di già sviluppato e funzionante, in modo da capirne i meccanismi di funzionamento ed eventualmente procedere poi alle tue modifiche/personalizzazioni/implementazioni.

    Vedi ad esempio qualche tutorial come questo:
    https://developer.mozilla.org/en-US/..._off_the_walls

    Nota che si tratta di un gioco ispirato al classico "breakout"; quel tutorial ha 10 step che illustrano lo sviluppo fino ad ottenere un gioco completo, ma ho linkato il 3° che riguarda la parte in cui si deve determinare la collisione della pallina con i limiti dell'area di gioco e quindi il rimbalzo nel verso opposto (che è ciò che stai cercando di ottenere).


    Punto secondo :
    A prescindere dallo sviluppo in sé, il modo che stai usando per determinare possibili "bug" nel codice è alquanto impreciso perché non può darti conferma sulla causa del malfunzionamento.

    Stranamente invece, non viene eseguita l'istruzione if (y>= 550 || y<=10){dy=-dy}, cioè se
    (y>= 550 || y<=10) è true non sia dy=-dy, ma dy resta dy.
    Per controllare quanto ho detto, in alto ho scritto in due caselle di testo i valori di y(top) e della condizione true o false di (y>= 550 || y<=10).
    Tu stai semplicemente monitorando il risultato di quella condizione (che restituisce un valore corretto) e da questo hai arbitrariamente determinato che la precedente condizione non viene eseguita. In realtà stai tralasciando quello che effettivamente deve essere considerato per capire se quella condizione è vista oppure no, che più che altro è ciò che sta al suo interno (la variabile dy).

    Sarebbe quindi più opportuno monitorare quella variabile (oltre al valore restituito dall'espressione nella condizione).

    Ti posso assicurare infatti che quella condizione sta funzionando e fa esattamente quello che gli hai detto di fare; per cui disapprovo la tua conclusione.

    Per farla semplice, puoi verificare inserendo una cosa del genere subito dopo quella stessa condizione:
    codice:
    console.log(dy)
    Controllando sulla console del tuo browser potrai verificare che il valore diventa negativo appena si verifica quella condizione.

    Tutto quindi funziona come tu gli hai detto di fare; ciò che hai affermato nell'oggetto della discussione non è corretto.

    Per il resto, quando dici che la condizione per dx viene eseguita ma stranamente non hai lo stesso risultato per dy, questo è legato al fatto che il valore di dy viene "alterato" da un'ulteriore espressione prima di quella condizione, a differenza del valore di dx che resta tale prima che sia eseguita la relativa condizione.

    Questa è l'espressione che stai usando per variare dy:
    codice:
    dy=dx*Math.tan(alfa*3.14159/180);
    Sinceramente non so a cosa ti serva messa lì; se infatti la tolgo mi pare che il tutto funzioni come dovrebbe

    In conclusione, stai sbagliando qualcosa da qualche parte nel tuo algoritmo, che non riguarda la condizione da te incriminata; per questo sarebbe meglio considerare di iniziare da un qualche tutorial (vedi punto primo), sempre che tu non lo abbia fatto e magari ti sei perso poi nella personalizzazione

    Perdona la divagazione, ma chiaramente i miei vogliono essere solo dei consigli, poi vedi tu come ritieni sia meglio procedere.

    Buon proseguimento.


    EDIT: scusami br1 non avevo visto il tuo intervento e che avevi già fornito la soluzione
    Ultima modifica di KillerWorm; 16-03-2018 a 18:32
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  4. #4
    Utente di HTML.it
    Registrato dal
    Jan 2018
    Messaggi
    211
    Sbagli a ricalcolare ogni volta dy su dx invece di cambiare solo il segno
    Questa è l'espressione che stai usando per variare dy: dy=dx*Math.tan(alfa*3.14159/180);

    Sinceramente non so a cosa ti serva messa lì; se infatti la tolgo mi pare che il tutto funzioni come dovrebbe
    Grazie br1 e KillerWorm per le vostre risposte. Ma scrivendo solo:
    x=x+dx;
    y=y+dy;
    dx e dy sono sempre uguali ad 1 e il punto mobile si sposta sempre di 45 gradi e il punto "rimbalza" sia orizzontalmente che verticalmente.
    Ma ho voluto (per esercizio) che il punto si muovesse con un angolo a scelta alfa=angolo.value (e quindi dy dipende da alfa)
    x=x+dx;
    var alfa=angolo.value;
    dy=dx*Math.tan(alfa*3.14159/180);
    y=y+dy
    e così il punto "rimbalza" orizzontalmente, ma non verticalmente come dovrebbe con le condizioni poste:
    if (y>= 550 || y<=10){dy=-dy}
    Mi scuso, ma non ho uso la console e dovrei imparare ad usarla.
    Un saluto

    lanvoel

  5. #5
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,674
    Ciao, capisco ora come vorresti che funzionasse lo script. Ad ogni modo, dal momento che si tratta per te di un esercizio a scopo didattico, per risponderti in maniera esaustiva bisognerebbe andare in ordine e vedere punto per punto l'intero codice perché ci sono diversi strafalcioni a prescindere dalla parte javascript.

    Mi scuso in anticipo per la lungaggine della risposta.


    Punto 1, validazione del codice:

    Correggi gli errori strutturali e sintattici del codice HTML/CSS, in modo da avere un codice valido a tutti gli effetti. Cerca di essere più ordinato durante la stesura del codice, sicuramente ne troverai giovamento tu stesso.

    Come già ti avevo consigliato in altre discussioni, nel momento in cui sviluppi un documento html sarebbe utile usare un validatore (vedi questo) per verificare che il codice sia valido ed eventualmente correggerlo laddove non lo fosse. Questo, anche prima di provare l'elaborato sul browser.

    Nello specifico:

    - Correggi il DTD (definizione del tipo di documento). <!DOCTYPE html PUBLIC> non è valido. Hai mischiato un po' di cose tra HTML5 e altre versioni. Se si tratta di HTML5 allora PUBLIC non ci sta a fare nulla, diversamente vanno inserite opportune specifiche (obbligatorie) dopo quel PUBLIC.

    Il DTD per HTML5 è semplicemente questo :
    codice:
    <!doctype html>
    Da tener presente che è case insensitive, cioè non c'è distinzione tra maiuscole o minuscole, per cui è valido anche se lo scrivi, ad esempio, in questo modo:
    codice:
    <!DOCTYPE html>

    - In HTML5 nel tag <script> non serve specificare language=JavaScript perché questo è il linguaggio di default; il validatore segnala un "warning", meglio se lo togli così da avere una migliore pulizia del codice.


    - Correggi la chiusura del tag </script>; hai dimenticato una parentesi angolare.


    - Inserisci un opportuno tag <title> dentro <head>, obbligatorio in un documento HTML. Anche se dovesse trattarsi di un semplice e banale esempio è sempre meglio che il codice risulti valido.


    - La parentesi angolare aperta < (segno di minore) non può essere usata liberamente nel corpo del documento perché va in conflitto con il carattere usato per la scrittura dei tag HTML.

    Il validatore infatti segnala questo errore:
    Bad character = after <. Probable cause: Unescaped <. Try escaping it as &lt;.
    La parte incriminata è questa:
    codice:
    controlollo condizione (y>= 550 || <=10)<input...
    in particolare quel carattere < nel testo <=10 genera chiaramente un conflitto per il parsing HTML che normalmente dovrebbe andare a considerarlo come apertura di un tag.

    In tal caso, per risolvere è possibile sostituire tale caratter con la corrispondente entità HTML:
    codice:
    controlollo condizione (y>= 550 || &lt;=10)<input...
    Poi anche l'italiano vuole la sua parte, eventualmente correggi pure "controlollo".

    - Occhio al CSS. Nel tag <p> hai specificato width:1100; height:550; ma ovviamente per quei valori manca l'unità di misura che in questo caso è obbligatoria. Dovrebbe essere width:1100px; height:550px;
    Probabile che alcuni browser riescano a "risolvere" comunque questo tipo di errore ma, a scanso di equivoci, e sempre meglio avere un codice valido.


    Punto 2, pulizia del codice (consigli):

    A prescindere dalla validazione è sempre meglio organizzare il proprio elaborato in maniera pulita e usando opportunamente i vari elementi. Prendi comunque, questi a seguire, come consigli.

    - Script alla fine del body.
    Prendi per buono ciò che ti indico anche se magari al momento potresti non afferrare bene questo concetto. Non è una regola fissa ma a volte può risultare comodo avere il blocco <script> alla fine del <body> piuttosto che dentro <head>. In particolare, in questo esercizio può tornare utile tale impostazione perché potresti definire più facilmente delle variabili a livello globale, le quali fanno riferimento agli elementi del DOM da manipolare attraverso script stesso, i quali risultano infatti già creati nella pagina quando lo script viene eseguito, a differenza di quanto avverrebbe se lo stesso script (senza particolari accorgimenti) fosse inserito ed eseguito dentro <head>.

    Nello specifico, ad esempio, potresti definire e inizializzare già a livello globale la variabile oggetto in questo modo:
    codice:
    var oggetto = document.getElementById("para1");
    così da non dover eseguire l'assegnazione stessa all'interno della funzione muovi(). Fondamentalmente (seppure in maniera alquanto minima in questo caso) si va ad ottimizzare il processo di esecuzione perché tale variabile viene valorizzata una prima e unica volta all'inizio dello script, evitando quindi l'esecuzione di una istruzione in più che diversamente sarebbe ripetuta di continuo dentro la funzione.

    Sia chiaro, risultano essere comunque dei minimi accorgimenti, forse anche irrilevanti da un punto di vista del funzionamento in questo semplice caso, ma personalmente preferisco sempre un approccio più pulito possibile durante lo sviluppo di codice, semplice o complesso che sia.

    - Separazione del CSS dal codice HTML.
    Se non ricordo male ti avevo già fatto presente questo aspetto in qualche altra discussione. Ad ogni modo sarebbe più ottimale, a livello di organizzazione del progetto (semplice o complesso che sia), definire tutto il CSS (nei limiti del possibile) in modo separato dal codice HTML, così da evitare possibili situazioni di "disordine" nel codice stesso, che a lungo andare possono influire negativamente sullo sviluppo e/o sullo studio del progetto in questione.

    Meglio se tutto sta al proprio posto. Quindi il mio consiglio è: apriti un tag <style> e, in maniera accuratamente ordinata, schiaffaci dentro tutte le regole degli elementi in gioco.

    - Separazione dello script dal codice HTML.
    Anche in questo caso, come il precedente, vedo più ottimale, tenere distinta l'azione (JavaScript) dalla struttura (HTML). Mi riferisco alle funzioni richiamata direttamente sui tag attraverso gli eventi HTML. Personalmente preferisco definire tutto ciò che riguarda lo script, compresa l'assegnazione di funzioni come gestori degli eventi, esattamente dove sta il resto dello script (dentro il tag <script>).

    - Uso più consono degli elementi HTML.
    Per definizione, il tag <p> identifica un "paragrafo", cioè un contenitore specifico per elementi inerenti il contesto testuale della pagina. Per tale motivo, un elemento <p> possiede anche dei valori di default di alcune regole CSS, come il margin, che servono ad impaginare opportunamente il contenuto di tipo testuale.
    Ora, hai qualche particolare motivo per usare dei paragrafi come elementi del tuo gioco?

    Forse in questo contesto sarebbe più opportuno usare un tipo di contenitore generico come il <div>, sia a livello logico che dal punto di vista del CSS, perché partiresti da elementi "puliti" a livello di impaginazione, cioè privi di eventuali regole con valori di default che potrebbero, ad esempio, generare dei risultati inattesi nel posizionamento degli elementi in gioco.

    - Usare sempre nomi autodescrittivi.
    Sia per i riferimenti degli elementi HTML (name, id, class) sia per i nomi delle variabili nello script, è una tra quelle best practice (della programmazione in generale) utilizzare dei termini che identifichino le cose in modo esplicito, diretto, intelligibile, facilmente comprensibile; così da non doversi fermare ad un certo punto della programmazione e dire "oh, ma che acciderbolina era testo1, porca paletta!", perdendo il filo di ciò che si stava facendo per andare magari a recuperarne l'identità chissà dove nel resto del progetto.

    Questo è valido in particolar modo durante la fase di sviluppo dove è preferibile che ogni cosa sia identificabile nel modo più rapido e semplice possibile, anche a costo di ottenere delle righe di codice maggiormente estese per via della lunghezza dei nomi, ma chiaramente per una futura ed eventuale fase di pubblicazione del progetto si potrà sempre fare uso di opportuni strumenti atti alla compressione/minimizzazione del codice.


    Punto 3, studio di un opportuno algoritmo:

    Arrivando al dunque; come già detto, mi pare che qualcosa non vada nell'algoritmo che stai usando per il calcolo dello spostamento da applicare all'oggetto.

    Ma ho voluto (per esercizio) che il punto si muovesse con un angolo a scelta alfa=angolo.value (e quindi dy dipende da alfa)
    Non mi è chiaro perché stai calcolando dy in funzione di dx e della tangente dell'angolo, ma la stessa dx la stai lasciando invariata. Teoricamente anche questa dovrebbe variare in funzione dell'angolo, no?
    e così il punto "rimbalza" orizzontalmente, ma non verticalmente come dovrebbe con le condizioni poste:

    Questo infatti è il motivo per cui la condizione su dx viene vista mentre quella su dy no, proprio perché dy viene ricalcolata ogni volta (falsando il risultato ottenuto dalla condizione) mentre dx no.

    Teoricamente dovresti ricalcolarle comunque entrambe quelle due variabili.

    Dalle mie rimembranze nell'uso remoto di calcoli trigonometrici a motivo ludico, ricordo che dato un angolo usavo seno e coseno per calcolare il relativo spostamento di y e x da un punto.

    Detto questo, dovresti eseguire il calcolo per entrambi i valori ma in modo "preventivo" così da valutare le due condizioni è solo dopo ricalcolare i valori finali in base alla direzione che può variare dopo le condizioni.

    La cosa è impostata più o meno allo stesso modo nel tutorial che ti ho linkato, cioè nella condizione viene usato un calcolo preventivo dove ad esempio la variabile dx è sommata al valore di x per stabilire se l'oggetto supera i "muri" e, nel caso, viene invertito il segno di dx per poi riapplicare il calcolo che determina l'effettivo spostamento dell'oggetto. Tu stai saltando questo passaggio.

    Ad ogni modo ho voluto provare a rielaborare il tutto in base a tutti i punti che ho riportato su questa discussione. Sia chiaro, non ho nulla da dimostrare a nessuno, l'ho fatto principalmente per tenere in esercizio il cervello e perché, prendendolo magari come base di partenza, spero possa essere utile a te o ad altri nello studio di applicazioni del genere.

    Riporto il codice completo nel post seguente.

    Mi scuso, ma non ho uso la console e dovrei imparare ad usarla.
    Tra parentesi: ho visto anche il tuo PM, ma preferisco risponderti qui.
    Per quanto riguarda l'uso della console web e relativi strumenti di sviluppo del browser, per il momento posso giusto consigliarti di iniziare col metodo console.log() che puoi inserire direttamente all'interno dei tuoi script per monitorare ad esempio il valore di qualche variabile, così come ti ho indicato nel post precedente.

    Chiaramente una volta aperta la console (F12) puoi vedere ciò che viene restituito in output (cioè nel pannello della console) attraverso i console.log() che avrai inserito nel codice. Ovviamente l'output salta fuori quando quell'istruzione viene eseguita, cioè durante la normale esecuzione dello script e nel punto in cui l'istruzione stessa è stata inserita.

    Se piazzi dei console.log() che sono eseguiti inizialmente all'apertura della pagina, e non avevi ancora aperto la console, ricorda di fare un refresh della pagina (f5) per vederne gli output dopo che avrai aperto la console.

    Qui puoi trovare qualche altra indicazione a riguardo:
    http://www.html.it/pag/45639/gli-str...avoro/#console

    Al momento penso sia sufficiente iniziare con queste semplici azioni di debug giusto per iniziare ad ambiantarti con lo strumento, poi eventualmente potrai sempre approfondire a tempo debito.
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  6. #6
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,674
    Qui il codice rielaborato:
    codice HTML:
    <!doctype html>
    <html>
       <head>
          <title>Esercizio JavaScript - Movimento oggetto dentro un'area limitata</title>
          <style>
             body {
                margin: 0;
                font-family: Arial, Helvetica, sans-serif;
             }
             
             #intestazione {
                background: RebeccaPurple;
                color: white;
                padding: 1px 0 1px 10px;
                margin: 0 0 20px;
                font-size: .7rem;
                line-height: 1.1;
                font-weight: bold;
                text-transform: uppercase;
             }
             
             #controlli fieldset {
                float: left;
                width: 200px;
                height: 500px;
                padding: 10px 5px;
                font-size: .8rem;
                text-align: center;
             }
             
             #controlli label {
                display: block;
                margin: 15px;
             }
             
             #controlli .txt {
                text-align: center;
             }
             
             #controlli .btn {
                margin: 15px;
             }
             
             #area_gioco {
                float: left;
                position: relative;
                width: 1100px;
                height: 550px;
                background: yellow;
                border: 10px red double;
             }
             
             #giocatore {
                position: absolute;
                width: 10px;
                height: 10px;
                background: red;
                border: 3px blue solid;
                border-radius: 50%;
             }
          </style>
       </head>
       <body>
          <h1 id="intestazione">Esercizio JavaScript - I Like to Move It</h1>
          
          <form name="controlli" id="controlli">
             <fieldset>
                
                <legend>Controlli di gioco</legend>
                
                <label>Velocità (0 - 100):<br><input type="text" class="txt" id="inp_velocita" size="10" value="10"></label>
                <label>Angolo iniziale (gradi):<br><input type="text" class="txt" id="inp_angolo" size="10" value="0"></label>
                
                <hr>
                <input type="button" class="btn" name="btn_avvia" id="btn_avvia" value="Avvia">
                <input type="button" class="btn" id="btn_ferma" value="Ferma">
                <hr>
                <input type="reset" class="btn" id="btn_reimposta" value="Reimposta">
                <hr>
                
             </fieldset>
          </form>
          
          <div id="area_gioco">
             <div id="giocatore"></div>
          </div>
    
          <script>
             
             // --- DEFINIZIONE DELLE VARIABILI GLOBALI ---
             
             var areaGioco = document.getElementById("area_gioco")
               , giocatore = document.getElementById("giocatore")
               
               , limitiArea = {                                    // Definisco un oggetto per i limiti dell'area (interna) di gioco considerando anche l'ingombro del giocatore
                   sup: 0
                 , dx: areaGioco.clientWidth - giocatore.offsetWidth 
                 , inf: areaGioco.clientHeight - giocatore.offsetHeight
                 , sx: 0
                }
               
               , posizione_x
               , posizione_y
               
               , spostamento_x
               , spostamento_y
               , spostamentoMax = 5                                // Quando velocità è 100%, questo è lo spostamento massimo (in px) che il giocatore compie ad ogni intervallo
               
               
               , direzione_x = 1
               , direzione_y = 1
               
               , intervalloMovimento
               , inEsecuzione                                      // Flag di controllo che sostanzialmente determina quando il gioco è in esecuzione (l'intervallo è già attivo)
             ;
             
             
             // --- GESTIONE CONTROLLI ---
             
             controlli.btn_avvia.onclick = function(){ avvia(); };
             
             controlli.btn_ferma.onclick = function(){ ferma(); };
             
             controlli.btn_reimposta.onclick = function(){
                ferma();
                init();
             };
             
             
             // --- FUNZIONI DI GIOCO ---
             
             function avvia() {
                if (inEsecuzione) return;                          // Esco dalla funzione se il gioco è già avviato
                inEsecuzione = true;                               // inEsecuzione         : (true) il gioco è avviato
                intervalloMovimento = setInterval(muovi, 33);      // intervalloMovimento  : stabilisco una frequenza fissa di ~30fps (1000ms / 33)
                                                                   //
                                                                   // NOTA:
                                                                   // piuttosto che stabilire la velocità variando la frequenza d'intervallo,
                                                                   // che per valori alti genera un movimento a scatti, imposto una frequenza fissa
                                                                   // e uso invece una variabile % (velocità) come fattore per il calcolo dello spostamento
             }
             
             function muovi() {
                
                var angolo = +controlli.inp_angolo.value || 0;                                      // angolo         : mi assicuro che sia un valore di tipo numerico
                var velocita = Math.max(0, Math.min(100, +controlli.inp_velocita.value || 0));      // velocita       : mi assicuro che sia un numero tra 0 e 100 (%)
                
                spostamento_x = Math.cos(angolo * Math.PI / 180) * velocita * .1 * spostamentoMax;  // spostamento_x  : calcolato in base ad angolo e velocità
                spostamento_y = Math.sin(angolo * Math.PI / 180) * velocita * .1 * spostamentoMax;  // spostamento_y  : calcolato in base ad angolo e velocità
                
                var posizionePrevista_x = posizione_x + spostamento_x * direzione_x;                // Variabili di supporto per il controllo del posizionamento nei limiti dell'area di gioco
                var posizionePrevista_y = posizione_y + spostamento_y * direzione_y;                // 
                
                if (posizionePrevista_x > limitiArea.dx || posizionePrevista_x < limitiArea.sx)
                   direzione_x = -direzione_x;                                                      // direzione_x    : inverto direzione per determinare il rimbalzo sui lati verticali 
                   
                if (posizionePrevista_y > limitiArea.inf || posizionePrevista_y < limitiArea.sup)
                   direzione_y = -direzione_y;                                                      // direzione_y    : inverto direzione per determinare il rimbalzo sui lati orizzontali
                
                posizione_x += spostamento_x * direzione_x;                                         // posizione_x    : calcolo la nuova posizione x
                posizione_y += spostamento_y * direzione_y;                                         // posizione_y    : calcolo la nuova posizione y
                
                giocatore.style.left = posizione_x+"px";                                            // Applico la nuova posizione x
                giocatore.style.top = posizione_y+"px";                                             // Applico la nuova posizione y
                
             }
             
             function ferma() {
                inEsecuzione = false;                                                               // inEsecuzione   : (false) il gioco è fermo
                clearInterval(intervalloMovimento);
             }
             
             
             // --- INIZIALIZZAZIONE ---
             
             function init() {
                posizione_x = limitiArea.sx;
                posizione_y = limitiArea.inf / 2;
                
                giocatore.style.left = posizione_x+"px";
                giocatore.style.top = posizione_y+"px";
             }
             
             init();
             
          </script>
       </body>
    </html>
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

  7. #7
    Utente di HTML.it
    Registrato dal
    Jan 2018
    Messaggi
    211
    Grazie KillerWorm! Farò tesoro di tutte le tue correzioni e suggerimenti un po' alla volta.
    Intanto ho usato per la prima volta console.log(dy) e ho constato che effettivamente dy cambia segno al verificarsi delle condizioni. Questo fatto mi ha spinto a provarle tutte! Ho, tra l'altro, usato i valori assoluti Math.round(y) e ho spostato le condizioni prima di y=y+dy;

    x=x+dx;
    var alfa=angolo.value;
    dy=dx*Math.tan(alfa*3.14159/180);
    if (x==1290 || x==200){dx=-dx}
    if (Math.round(y)==550 || Math.round(y)==10){dy=-dy}

    y=y+dy;

    ottenendo che il punto mobile strisci lungo la linea in alto e quella in basso, perché, logicamente, la condizione diventa alternativamente True e False.
    Ho poi notato che se, come mi suggerisci, tolgo PUBLIC in <!DOCTYPE html PUBLIC> non vengono eseguite alcune istruzioni come
    <P style="background:yellow; width:1100; height:550; border:3px red double; position:absolute; left:200px; top:10px;"></P>
    e scompare il rettangolo giallo.
    Penso che convenga tralasciare questo mio esercizio e studiare il programma che tu gentilmente mi hai inviato.
    Ma ho ancora bisogno del tuo aiuto perché quando copio il tuo programma e poi lo incollo viene "sdentato" nel senso che perde la indentatura. C'è qualche modo che, incollando, permetta di conservare la indentatura? O c'è per caso anche il modo di provarlo direttamente nel Forum? Grazie

    lanvoel

    codice:
    <!DOCTYPE html PUBLIC>
    <html>
    <head>
    <script language=JavaScript>
    var oggetto;
    var intervallo;
       var x=200;var y=250;
       var dx=1;var dy=1;
    function avvia()
    {
       velo=testo1.value;
       intervallo=window.setInterval("muovi()",velo);
    }
    function muovi()
    {
       oggetto=document.getElementById("para1");
       x=x+dx;
       var alfa=angolo.value;
       dy=dx*Math.tan(alfa*3.14159/180);
              if (x==1290  || x==200){dx=-dx}
              if (Math.round(y)==550 || Math.round(y)==10){dy=-dy}
       y=y+dy;
       oggetto.style.position="absolute";
       oggetto.style.top =y;
       oggetto.style.left =x;
    testo2.value=Math.round(y);
    testo3.value= (Math.round(y)==550 || Math.round(y)==10);
    }  
    function ferma1()
    {
    clearInterval(intervallo);
    }
    </script
    </head>
    <body>
    controllo valori di y (top)<input type="text" name="testo2" id="testo2" size=25>
    controllo condizione (Math.round(y)==550 || Math.round(y)==10)<input type="text" name="testo3" id="testo3" size=15><br><br>
    <input type="button" name="pulsanre1" id="pulsante1" value="avvia" onclick="avvia()"><br> <br>
    velocità (alta:1 bassa:200)<br>
    <input type="text" name="testo1" id="testo1" size=20><br><br>
    angolo di partenza in gradi:<br>
    <input type="text" name="angolo" id="angolo" size=10><br><br>
    <input type="button" name="pulsante2" id="pulsante2" value="ferma" onclick="ferma1()">
    <P style="background:yellow; width:1100; height:550; border:3px red double; position:absolute; left:200px; top:10px;"></P>
    <P Style="background:red; width:10px; height:10px; border:3px blue solid; position:absolute; left:200px; top:250px;" id="para1">
    </body>
    </htm>

  8. #8
    Moderatore di CSS L'avatar di KillerWorm
    Registrato dal
    Apr 2004
    Messaggi
    5,674
    Quote Originariamente inviata da lanvoel
    Grazie KillerWorm! Farò tesoro di tutte le tue correzioni e suggerimenti un po' alla volta.
    Prego, è un piacere. Ti consiglio comunque (quantomeno per questo specifico tuo esercizio) di considerare già da subito tutte le varie indicazioni che ho fornito (anche se ci vorrà magari del tempo per assimilarle); non per mia presunzione, assolutamente, ma perché i problemi che stai continuando a riscontrare trovano già risposta nel complesso di quelle stesse indicazioni.

    Quote Originariamente inviata da lanvoel
    Intanto ho usato per la prima volta console.log(dy)
    Perfetto, un po' alla volta (qui ci può stare)

    Quote Originariamente inviata da lanvoel
    Questo fatto mi ha spinto a provarle tutte! Ho, tra l'altro, usato i valori assoluti Math.round(y) e ho spostato le condizioni prima di y=y+dy;
    Il problema principale, a mio parere (e come già indicato), sta nel fatto che in quella condizione (così come per quella della x) devi considerare in modo preventivo l'aggiunta del valore dy a quello di y (quindi nella condizione devi valutare y+dy anziché solo y), e rieseguire poi lo stesso calcolo solo dopo tale condizione (dove però dy può essere stato invertito di segno).

    Vedi indicazioni:
    Quote Originariamente inviata da KillerWorm
    dovresti eseguire il calcolo per entrambi i valori ma in modo "preventivo" così da valutare le due condizioni è solo dopo ricalcolare i valori finali in base alla direzione che può variare dopo le condizioni.

    La cosa è impostata più o meno allo stesso modo nel tutorial che ti ho linkato, cioè nella condizione viene usato un calcolo preventivo dove ad esempio la variabile dx è sommata al valore di x per stabilire se l'oggetto supera i "muri" e, nel caso, viene invertito il segno di dx per poi riapplicare il calcolo che determina l'effettivo spostamento dell'oggetto. Tu stai saltando questo passaggio.
    ---
    Riguardo questo:
    Quote Originariamente inviata da lanvoel
    Ho poi notato che se, come mi suggerisci, tolgo PUBLIC in <!DOCTYPE html PUBLIC> non vengono eseguite alcune istruzioni come
    <P style="background:yellow; width:1100; height:550; border:3px red double; position:absolute; left:200px; top:10px;"></P>
    e scompare il rettangolo giallo.
    Chiariamo subito che bisognerebbe correggere TUTTI gli errori segnalati dal validatore (che sono quelli che già ti ho elencato). Correggendo "a campione" qualche errore si corre il rischio di creare una catena di altri problemi (come in questo caso).

    Posso spiegarti a grandi linee cosa sta accadendo in questo caso:

    1. Quel tuo DTD (che cos'è) non è valido (secondo gli standard W3C), per cui il browser legge il documento in "quirks mode" (vedi qui). Questa modalità costringe il browser a considerare il codice del documento con una certa retrocompatibiltà (ogni tipo di browser può farlo però in modo arbitrario, per cui con questa modalità si possono ottenere risultati imprevedibili).

    2. Il CSS su quel tag ha degli errori in base alle specifiche standard, ma non sono considerati tali (meglio, vengono risolti attraverso una interpretazione) con il "quirks mode". Nello specifico, qui: "width:1100; height:550;" mancano le unità di misura che sono obbligatorie secondo lo standard.

    Vedi indicazioni:
    Quote Originariamente inviata da KillerWorm
    Correggi gli errori strutturali e sintattici del codice HTML/CSS, in modo da avere un codice valido a tutti gli effetti.
    [...]
    - Correggi il DTD (definizione del tipo di documento). <!DOCTYPE html PUBLIC> non è valido.
    [...]
    - Occhio al CSS. Nel tag <p> hai specificato width:1100; height:550; ma ovviamente per quei valori manca l'unità di misura che in questo caso è obbligatoria. Dovrebbe essere width:1100px; height:550px;
    Probabile che alcuni browser riescano a "risolvere" comunque questo tipo di errore ma, a scanso di equivoci, è sempre meglio avere un codice valido.
    Chiaramente, correggendo entrambi questi errori (e tutti gli altri) il problema si risolve.

    Quote Originariamente inviata da lanvoel
    Penso che convenga tralasciare questo mio esercizio e studiare il programma che tu gentilmente mi hai inviato.
    Bene, tieni comunque presente che si tratta sempre di questo stesso tuo esercizio, ho solo reimpostato il tutto con un certo criterio.

    Quote Originariamente inviata da lanvoel
    Ma ho ancora bisogno del tuo aiuto perché quando copio il tuo programma e poi lo incollo viene "sdentato" nel senso che perde la indentatura. C'è qualche modo che, incollando, permetta di conservare la indentatura?
    L'indentazione (o indentatura), così come tutto il resto del contenuto testuale copiato negli appunti, dovrebbe restare tale se fai un normale copia incolla di quella porzione di testo.

    Giusto una nota: l'indentazione che ho usato su quel codice è formata da spazi (e non da caratteri di tabulazione). Potrei pensare che la perdita/modifica di una eventuale formattazione del testo (tra cui l'indentazione stessa) sia causata dall'editor che stai usando per riportare/scrivere il codice; magari da qualche sua impostazione. Che editor usi?

    Quote Originariamente inviata da lanvoel
    O c'è per caso anche il modo di provarlo direttamente nel Forum? Grazie
    Mi spiace ma l'attuale piattaforma di questo forum purtroppo non è così evoluta, non ha strumenti del genere che permettano il test o la visualizzazione del risultato di un qualsivoglia codice.

    Quello che si può fare è pubblicare l'elaborato su un qualche playground esterno (come CodePen e simili).

    Se poi il problema sta solo nel fatto di perdere l'indentazione col copia incolla, potrei tuttalpiù postare il file di testo in allegato, sperando che aprendolo col tuo editor non venga comunque "riformattato".
    Ultima modifica di KillerWorm; 18-03-2018 a 17:22
    Installa Forum HTML.it Toolset per una fruizione ottimale del Forum

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.