Forumet - Math fail, pong

Math fail, pong

88 0 12
Jag håller på att göra ett enkelt pong-spel i Lua med hjälp av Löve. Allt tycks än så länge fungera ungefär som det var tänkt, men bollen beter sig ibland väldigt, väldigt underligt. Tyvärr är mina matematikkunskaper inte tillräckligt vassa för att se var problemet ligger, även om jag misstänker att det är bollens förflyttning längs Y-axeln som är problemet.

Det hela måste ses för att förstås.

Pong: http://www.speedyshare.com/578757674.html
Källkod: http://www.speedyshare.com/990491562.html

Ladda ned och kör den övre filen. Jag vet inte om det fungerar i Windows, då jag satt ihop den i Linux. Gör det inte det så ladda istället ned källkoden, installera Löve och dra mappen till love.exe för att köra spelet.

Den mest intressanta delen är troligen det som körs vid varje uppdatering:
function update(dt)

ball.x = ball.x + (ball.dir.x * bspeed * dt * ball.hits)
ball.y = ball.y + (ball.dir.y * bspeed * dt * ball.hits)
print ((ball.dir.x * bspeed * dt * ball.hits) + (ball.dir.y * bspeed * dt * ball.hits))

if ball.x <= 10 then
score[2] = score[2] + 1
text = "Player 2 scored!"
ball.x = screenWidth/2
ball.y = screenHeight/2
ball.dir.y = 0
ball.dir.x = -1
ball.hits = 1
elseif ball.x >= screenWidth-10 then
score[1] = score[1] + 1
text = "Player 1 scored!"
ball.x = screenWidth/2
ball.y = screenHeight/2
ball.dir.y = 0
ball.dir.x = -1
ball.hits = 1
elseif ball.y <= 20 then
ball.dir.y = math.abs(ball.dir.y)
elseif ball.y >= screenHeight-20 then
ball.dir.y = -math.abs(ball.dir.y)
end

if ball.x <= p[1].x + paddleWidth and ball.x >= p[1].x and ball.y <= p[1].y + paddleHeight/2 and ball.y >= p[1].y - paddleHeight/2 then
ball.dir.x = math.abs(ball.dir.x)
ball.dir.y = ball.dir.y + (ball.y - p[1].y) / paddleHeight
ball.hits = ball.hits + 0.01
elseif ball.x >= p[2].x - paddleWidth and ball.x <= p[2].x and ball.y >= p[2].y - paddleHeight/2 and ball.y <= p[2].y + paddleHeight/2 then
ball.dir.x = -math.abs(ball.dir.x)
ball.dir.y = ball.dir.y + (ball.y - p[2].y) / paddleHeight
ball.hits = ball.hits + 0.01
end
end

Spana också in:

sylar:

Vad bör man installera för paket för att kunna köra spelet?


Jag vet faktiskt inte vad det är för dependencies om man kör spel som packats tillsammans med Löve. Men annars så kan du installera Löve från hemsidan så bör din pakethanterare hantera det åt dig.

Hur som helst så löste jag tillsammans med de i #loveclub problemen.

Det hela kom från att uppdateringarna kom så ofta att bollen ibland hamnade >1 pixel "in" i paddle:n eller kanten. Lösningen var att använda math.abs() (returnerar absoluta nummer) för att ange förändringen i ball.dir.x när den kommer "in" i paddle:n. Sedan kunde ibland uppdateringarna komma så sällan att bollen "hoppade" fram mer än 16 pixlar vid högre hastigheter, vilket innebar att den hoppade över paddle:n helt. Lösningen på det var helt enkelt detta:
dt = (dt < 0.1 and dt) or 0.1
Åtta:

Skiter jag väl i! Vill ha hjälp med varför mitt program failar! [mad][mad][cute]


kej då <:

alla

var = var +1

kan set ut såhär:

var +=1

Inget nödvändigt men ser finare ut, om nu språket klarar en sån operatör [blush]


ball.dir.x = -1

Inget nödvändingt heller men la märke till att bollen startar åt samma håll viket lag som än gör mål :P


print ((ball.dir.x * bspeed * dt * ball.hits) + (ball.dir.y * bspeed * dt * ball.hits))

Efter som "text" verkar vara en variabel som har hand om medelanden så fattar jag inte vad print gör här...
Sen fattar jag inte varför man vill ha ut en uträkning på alla de där variablarna tillsammans? makes no sense to me :(

Riktiga felet är här (tror jag):

elseif ball.y <= 20 then
ball.dir.y = math.abs(ball.dir.y)
elseif ball.y >= screenHeight-20 then
ball.dir.y = -math.abs(ball.dir.y)


Lösning:

elseif ball.y <= 20 or ball.y >= screenHeight-20then
ball.dir.y = ball.dir.y -= ball.dir.y*2


- - - - - - - - - - - - - - - - - Sammanslagning 1 - - - - - - - - - - - - - - - - -


fade:

Riktiga felet är här (tror jag):


För att om jag minns rätt så sätter abs värdet till -1, 0 eller 1 beroende på om den är över, under eller precis på 0

så om man använder:

ball.dir.y = math.abs(ball.dir.y)

och då ball.dir_y = -1 (antar att - flyttar uppåt i de språket)
så blir det det -1 tillbaka och då flyttar den fortfarande uppåt.
fade:

Inget nödvändigt men ser finare ut, om nu språket klarar en sån operatör [blush]


Jo, det vet jag. Dock vet jag inte om Lua gör så.

fade:

Inget nödvändingt heller men la märke till att bollen startar åt samma håll viket lag som än gör mål :P


Har inte ändrat det eftersom jag fortfarande bara försökte få grejer att fungera.

fade:

Efter som "text" verkar vara en variabel som har hand om medelanden så fattar jag inte vad print gör här...


Text är en variabel som skrivs ut mitt på skärmen. Print skriver ut genom standard output.

fade:

Sen fattar jag inte varför man vill ha ut en uträkning på alla de där variablarna tillsammans? makes no sense to me :(


Kombinerad förflyttning i X- och Y-led per uppdatering. Felsökning.

fade:

Riktiga felet är här (tror jag):


Nej. Det där är lösningen på felet.

Kod med fixar: http://www.speedyshare.com/893868246.html (vanligt .zip-arkiv. Bara byt namn och öppna)
Körbar fil med love inkluderat: http://www.speedyshare.com/639456530.html
Åtta:

Text är en variabel som skrivs ut mitt på skärmen. Print skriver ut genom standard output.


aah då förstår jag, trodde den hade med själva spelet att göra :P


Åtta:

Nej. Det där är lösningen på felet.

Kod med fixar: http://www.speedyshare.com/893868246.html (vanligt .zip-arkiv. Bara byt namn och öppna)
Körbar fil med love inkluderat: http://www.speedyshare.com/639456530.html


Vågar inte [blush] men är säkert bra [party]

va vare som var fel då?

fade:

- - - - - - - - - - - - - - - - - Sammanslagning 1 - - - - - - - - - - - - - - - - -


hade jag rätt om den saken? hur abs fungerar?
fade:

vågar inte [sad]


Det hela kom från att uppdateringarna kom så ofta att bollen ibland hamnade >1 pixel "in" i paddle:n eller kanten. Lösningen var att använda math.abs() (returnerar absoluta nummer) för att ange förändringen i ball.dir.x när den kommer "in" i paddle:n. Sedan kunde ibland uppdateringarna komma så sällan att bollen "hoppade" fram mer än 16 pixlar vid högre hastigheter, vilket innebar att den hoppade över paddle:n helt. Lösningen på det var helt enkelt detta:

dt = (dt < 0.1 and dt) or 0.1

(där dt står för "delta time", d.v.s. tiden från senaste uppdatering)