-- title: asteroids -- author: Bob Grant -- desc: -- script: lua -- game state control STATE_START = 0 STATE_PLAY = 10 STATE_END = 20 gameState = STATE_START SCREEN_MAX_X = 240 SCREEN_MAX_Y = 136 playerShip = { position = { x = 100, y = 60 }, velocity = { speed = 0, direction = 0 }, acceleration = 0.05, deceleration = 0.01, rotation = 0, rotationSpeed = 0.07, points = { {x=8,y=0}, {x=-8,y=6}, {x=-4,y=0}, {x=-8,y=-6}, {x=8,y=0} } } function TIC() if gameState == STATE_START then doStartScreen() elseif gameState == STATE_PLAY then doPlayGame() elseif gameState == STATE_END then doEndScreen() end end function doStartScreen() cls() print ("ASTEROIDS", 80,40) print ("press Z to start", 60,60) if btnp(4) then gameState = STATE_PLAY end end -- doStartScreen() function doEndScreen() cls() print ("GAME OVER", 80,40) print ("press Z to start", 60,60) if btnp(4) then gameState = STATE_PLAY end end -- doEndScreen() function doPlayGame() cls() -- update checkPlayerButtons() movePlayerShip() -- draw drawVectorShape(playerShip) print(playerShip.rotation, 0,0) if btnp(4) then gameState = STATE_END end end -- doPlayGame() function drawVectorShape(shape) local firstPoint = true local lastPoint = 0 local rotatedPoint = 0 for index, point in ipairs(shape.points) do rotatedPoint = rotatePoint(point,shape.rotation) if firstPoint then lastPoint = rotatedPoint firstPoint = false else line(lastPoint.x + shape.position.x, lastPoint.y + shape.position.y, rotatedPoint.x + shape.position.x, rotatedPoint.y + shape.position.y, 8) lastPoint = rotatedPoint end end -- for end -- drawVectorShape function rotatePoint(point, rotation) local rotatedX = (point.x * math.cos(rotation)) - (point.y * math.sin(rotation)) local rotatedY = (point.y * math.cos(rotation)) + (point.x * math.sin(rotation)) return {x=rotatedX, y=rotatedY} end -- rotatePoint function checkPlayerButtons() if btn(2) then -- left playerShip.rotation = playerShip.rotation - playerShip.rotationSpeed end if btn(3) then -- right playerShip.rotation = playerShip.rotation + playerShip.rotationSpeed end playerShip.rotation = keepAngleInRange(playerShip.rotation) end -- checkPlayerButtons function keepAngleInRange(angle) if angle < 0 then while angle < 0 do angle = angle + (2 * math.pi) end end if angle > (2 * math.pi) then while angle > (2 * math.pi) do angle = angle - (2 * math.pi) end end return angle end -- keepAngleInRange function movePointByVelocity(object) components = getVectorComponents(object.velocity) local newPosition = { x = object.position.x + components.xComp, y = object.position.y + components.yComp } return newPosition end -- movePointByVelocity function movePlayerShip() -- thrust if btn(0) then -- up key playerShipThrust() end -- if playerShip.velocity.speed = playerShip.velocity.speed - playerShip.deceleration if playerShip.velocity.speed < 0 then playerShip.velocity.speed = 0 end playerShip.position = movePointByVelocity(playerShip) playerShip.position = wrapPosition(playerShip.position) end -- movePlayerShip function playerShipThrust() local acceleration = { speed = playerShip.acceleration, direction = playerShip.rotation } playerShip.velocity = addVectors(playerShip.velocity, acceleration) end -- playerShipThrust function addVectors(vector1, vector2) v1Comp = getVectorComponents(vector1) v2Comp = getVectorComponents(vector2) resultantX = v1Comp.xComp + v2Comp.xComp resultantY = v1Comp.yComp + v2Comp.yComp local resVector = compToVector(resultantX, resultantY) return resVector end -- addVectors function getVectorComponents(vector) local xComp = vector.speed * math.cos(vector.direction) local yComp = vector.speed * math.sin(vector.direction) local components = { xComp = xComp, yComp = yComp } return components end -- getVectorComponents function compToVector(x, y) local magnitude = math.sqrt( (x * x) + (y * y)) local direction = math.atan2(y, x) direction = keepAngleInRange(direction) local vector = { speed = magnitude, direction = direction } return vector end -- compToVector function wrapPosition(position) if (position.x >= SCREEN_MAX_X) then position.x = 0 elseif (position.x < 0) then position.x = SCREEN_MAX_X - 1 end if (position.y >= SCREEN_MAX_Y) then position.y = 0 elseif (position.y < 0) then position.y = SCREEN_MAX_Y - 1 end return position end -- wrapPosition