0Pricing
Lua Academy · Lezione

Movimento e collisioni

Crei una scena giocabile.

Movimento e collisioni è una lezione Lua Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Lua Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Lua Academy include 4 lezioni in totale.

Posizione e velocità

Il movimento in LÖVE consiste nel cambiare la posizione di un oggetto nel tempo. Memorizzi x e y, poi aggiunga la velocità in love.update dopo averla moltiplicata per dt.

Mantenere la velocità come dx e dy al secondo rende il movimento diagonale e la fisica semplici e indipendenti dalla frequenza dei fotogrammi.

function love.update(dt)
  player.x = player.x + player.dx * dt
  player.y = player.y + player.dy * dt
end

Movimento controllato dall'input

Combini il polling con la velocità per guidare un oggetto. Legga i tasti direzionali in love.update e applichi velocità moltiplicata per dt.

Poiché love.keyboard.isDown viene verificato a ogni frame, il giocatore si muove fluidamente finché il tasto resta premuto.

function love.update(dt)
  if love.keyboard.isDown('left') then player.x = player.x - player.speed*dt end
  if love.keyboard.isDown('right') then player.x = player.x + player.speed*dt end
end

Normalizzazione della velocità diagonale

Premere contemporaneamente due tasti direzionali rende più veloce il movimento diagonale, perché entrambi gli assi aggiungono la velocità completa. Per correggere il problema, normalizzi il vettore di movimento.

Divida la direzione per la sua lunghezza in modo che il suo modulo sia 1, poi la moltiplichi per la velocità. In questo modo lo spostamento diagonale equivale a quello in linea retta.

local dx, dy = ix, iy
local len = math.sqrt(dx*dx + dy*dy)
if len > 0 then
  player.x = player.x + (dx/len) * player.speed * dt
end

Restare all'interno dello schermo

Limiti la posizione in modo che gli oggetti restino sullo schermo. Legga le dimensioni della finestra con love.graphics.getWidth e getHeight, poi limiti le coordinate.

math.max e math.min insieme limitano in modo semplice un valore tra un minimo e un massimo.

local w = love.graphics.getWidth()
player.x = math.max(0, math.min(player.x, w - player.size))

Bounding box allineate agli assi

La collisione più semplice utilizza rettangoli, chiamati AABB, ovvero bounding box allineate agli assi. Ogni oggetto ha x, y, width e height.

Due box si sovrappongono quando si intersecano contemporaneamente sia sull'asse orizzontale sia su quello verticale. Questo controllo è veloce e sufficiente per la maggior parte dei giochi 2D.

-- box: { x, y, w, h }

Test di sovrapposizione delle AABB

Due rettangoli si sovrappongono quando non sono separati lungo nessuno dei due assi. Il test classico combina quattro confronti.

Se tutti e quattro sono veri, le box si intersecano. Questa singola condizione è il principale strumento per rilevare le collisioni nei giochi 2D.

function overlaps(a, b)
  return a.x < b.x + b.w and
         b.x < a.x + a.w and
         a.y < b.y + b.h and
         b.y < a.y + a.h
end

Reagire a una collisione

Quando overlaps restituisce true, decida cosa deve accadere: raccolga una moneta, subisca danni o interrompa il movimento. Verifichi le collisioni in love.update dopo aver spostato gli oggetti.

Per gli oggetti da raccogliere, è sufficiente rimuovere l'oggetto o incrementare il punteggio. Per i muri solidi, spinga il giocatore nuovamente all'esterno.

function love.update(dt)
  movePlayer(dt)
  if overlaps(player, coin) then
    score = score + 1
    coin.dead = true
  end
end

Collisioni tra cerchi

Per gli oggetti circolari, una collisione basata sulla distanza è più precisa. Due cerchi collidono quando la distanza tra i loro centri è inferiore alla somma dei rispettivi raggi.

Confrontare le distanze al quadrato evita la costosa radice quadrata: è un'ottimizzazione comune quando si controllano molti oggetti.

function circlesHit(a, b)
  local dx, dy = a.x - b.x, a.y - b.y
  local rsum = a.r + b.r
  return dx*dx + dy*dy < rsum*rsum
end

Risolvere le collisioni con i muri

Per fermare un giocatore contro un muro, un approccio semplice consiste nello spostarlo separatamente su ciascun asse e annullare il passo che causa una sovrapposizione.

Sposti x e verifichi; se c'è una collisione, ripristini x. Ripeta l'operazione per y. Questa risoluzione separata per asse evita che il giocatore resti bloccato negli angoli.

player.x = player.x + vx * dt
if overlaps(player, wall) then player.x = player.x - vx * dt end
player.y = player.y + vy * dt
if overlaps(player, wall) then player.y = player.y - vy * dt end

Applicare la gravità

I platform game aggiungono un'accelerazione costante verso il basso. Aumenti la velocità verticale della gravità moltiplicata per dt a ogni frame, poi applichi la velocità alla posizione.

Quando il giocatore atterra sul terreno, azzeri la velocità verticale in modo che smetta di cadere. Il salto imposta una velocità verticale negativa.

function love.update(dt)
  player.dy = player.dy + GRAVITY * dt
  player.y = player.y + player.dy * dt
end

Rimuovere gli oggetti eliminati

Dopo le collisioni è spesso necessario rimuovere degli oggetti. Scorra una lista a ritroso e chiami table.remove, in modo che gli indici rimangano validi durante l'eliminazione.

L'iterazione a ritroso è l'idioma Lua sicuro per rimuovere elementi nel mezzo di un ciclo ed evita di saltare gli elementi, cosa che accadrebbe con un'iterazione in avanti.

for i = #coins, 1, -1 do
  if coins[i].dead then
    table.remove(coins, i)
  end
end

Verifica rapida

Verifichi la Sua comprensione del movimento e delle collisioni in LÖVE.

Riepilogo

Il movimento combina posizione, velocità e dt, con la normalizzazione per gestire correttamente le diagonali e il limite della posizione per mantenere gli oggetti sullo schermo. Le collisioni iniziano con i test di sovrapposizione delle AABB, mentre per gli oggetti circolari si utilizzano i controlli della distanza tra i cerchi.

Risolva le collisioni con i muri ripristinando gli spostamenti su ciascun asse, aggiunga la gravità per i platform game e rimuova gli oggetti eliminati scorrendo la lista a ritroso con table.remove.

Domande Frequenti

La lezione «Movimento e collisioni» è gratuita?

Sì — il testo completo di «Movimento e collisioni» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Lua Academy, passa a CoddyKit PRO. Il corso Lua Academy include 4 lezioni in totale.

Cosa imparerò in «Movimento e collisioni»?

Crei una scena giocabile. Eserciti Lua Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Lua Academy?

Non è richiesta alcuna esperienza precedente. Lua Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Movimento e collisioni»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Lua Academy?

Sì. Ogni lezione Lua Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Il game loop di LOVE
  2. Disegnare forme e immagini
  3. Gestire l'input
  4. Movimento e collisioni
← Torna a Lua Academy