Rörelse och kollisioner
Skapa en spelbar scen.
Rörelse och kollisioner är en gratis lektion i Lua Academy på CoddyKit. Detta är lektion 4 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Lua Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Lua Academy innehåller totalt 4 lektioner.
Position och hastighet
Rörelse i LÖVE innebär att ändra ett objekts position över tid. Lagra x och y och lägg sedan till hastigheten i love.update, skalad med dt.
Genom att lagra hastigheten som dx och dy per sekund blir diagonal rörelse och fysik tydliga och oberoende av bildfrekvensen.
function love.update(dt)
player.x = player.x + player.dx * dt
player.y = player.y + player.dy * dt
endIndatastyrd rörelse
Kombinera pollning med hastighet för att styra ett objekt. Läs av riktningsknapparna i love.update och tillämpa hastighet multiplicerad med dt.
Eftersom love.keyboard.isDown kontrolleras i varje bildruta rör sig spelaren jämnt så länge tangenten hålls nedtryckt.
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
endNormalisera diagonal hastighet
När du trycker på två riktningsknappar samtidigt blir den diagonala rörelsen snabbare, eftersom båda axlarna bidrar med full hastighet. Lös detta genom att normalisera rörelsevektorn.
Dela riktningen med dess längd så att dess magnitud blir 1 och multiplicera sedan med hastigheten. Nu motsvarar den diagonala förflyttningen den raka.
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
endHåll objekten innanför skärmen
Begränsa positionen så att objekten stannar på skärmen. Läs av fönstrets storlek med love.graphics.getWidth och getHeight och begränsa sedan koordinaterna.
math.max och math.min begränsar tillsammans ett värde mellan ett minimi- och ett maximivärde på ett enkelt sätt.
local w = love.graphics.getWidth()
player.x = math.max(0, math.min(player.x, w - player.size))Axelparallella begränsningsrutor
Den enklaste kollisionsdetekteringen använder rektanglar, så kallade AABB (axis-aligned bounding boxes). Varje objekt har x, y, bredd och höjd.
Två rutor överlappar varandra när de skär varandra på både den horisontella och vertikala axeln samtidigt. Denna kontroll är snabb och tillräcklig för de flesta 2D-spel.
-- box: { x, y, w, h }Test av AABB-överlappning
Två rektanglar överlappar varandra när den ena inte ligger bortom den andras högra kant på någon av axlarna. Det klassiska testet kombinerar fyra jämförelser.
Om alla fyra är sanna skär rutorna varandra. Detta enda villkor är arbetshästen inom kollisionsdetektering för 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
endReagera på en kollision
När overlaps returnerar true avgör du vad som ska hända: plocka upp ett mynt, ta skada eller stoppa rörelsen. Kontrollera kollisioner i love.update efter förflyttningen.
För upphämtningsobjekt tar du helt enkelt bort objektet eller ökar poängen. För solida väggar flyttar du spelaren ut igen.
function love.update(dt)
movePlayer(dt)
if overlaps(player, coin) then
score = score + 1
coin.dead = true
end
endCirkelkollisioner
För runda objekt är avståndsbaserad kollisionsdetektering mer exakt. Två cirklar kolliderar när avståndet mellan deras mittpunkter är mindre än summan av deras radier.
Genom att jämföra kvadrerade avstånd undviker du den kostsamma kvadratroten, vilket är en vanlig optimering när många objekt kontrolleras.
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
endLös väggkollisioner
För att stoppa en spelare vid en vägg kan du använda en enkel metod: flytta längs varje axel separat och ångra det steg som orsakar en överlappning.
Flytta x och kontrollera; återställ x om en kollision inträffar. Upprepa för y. Denna axelseparerade lösning förhindrar att spelaren fastnar i hörn.
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 endTillämpa gravitation
Plattformsspel lägger till en konstant acceleration nedåt. Öka den vertikala hastigheten med gravitationen multiplicerad med dt i varje bildruta och tillämpa sedan hastigheten på positionen.
När spelaren landar på marken sätter du den vertikala hastigheten till noll så att spelaren slutar falla. Vid hopp sätts den vertikala hastigheten till ett negativt värde.
function love.update(dt)
player.dy = player.dy + GRAVITY * dt
player.y = player.y + player.dy * dt
endTa bort döda objekt
Efter kollisioner tar du ofta bort objekt. Iterera genom en lista bakifrån och anropa table.remove så att indexen förblir giltiga medan du tar bort objekt.
Bakåtriktad iteration är det säkra Lua-idiomet för att ta bort objekt mitt i en loop och undviker överhoppade poster som framåtriktad iteration skulle orsaka.
for i = #coins, 1, -1 do
if coins[i].dead then
table.remove(coins, i)
end
endSnabbtest
Testa dina kunskaper om rörelse och kollisioner i LÖVE.
Sammanfattning
Rörelse kombinerar position, hastighet och dt, med normalisering för rättvisa diagonaler och begränsning för att hålla objekten på skärmen. Kollisioner börjar med AABB-överlappningstester, kompletterade med avståndskontroller för cirklar.
Lös väggkollisioner genom att återställa förflyttningar per axel, lägg till gravitation i plattformsspel och ta bort döda objekt genom att iterera bakifrån med table.remove.
Lär dig Lua med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 40
- Lektioner
- 159
Vanliga frågor
Är lektionen ”Rörelse och kollisioner” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Lua Academy, inklusive ”Rörelse och kollisioner”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Lua Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Rörelse och kollisioner”?
Skapa en spelbar scen. Ni övar på Lua Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Lua Academy?
Du behöver inga förkunskaper. Utbildningen i Lua Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.
Hur lång tid tar lektionen ”Rörelse och kollisioner”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Lua Academy-lektionen?
Ja. Varje Lua Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- LOVE-spelloopen
- Rita former och bilder
- Hantera indata
- Rörelse och kollisioner