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>