Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Version 2.4.0
- local termX, termY = term.getSize()
- local midX = math.floor(termX/2)
- print("Loading API")
- os.loadAPI("projectalpha/gameutils")
- os.loadAPI("projectalpha/gui")
- print("Loading game")
- local player = gameutils.loadSprite("projectalpha/.sprites/player.nfp", math.floor(termX/2)-2, termY-2)
- local quit = false
- local timer = nil
- local timerID = nil
- local buffer = {}
- local drawn = {}
- local oldPix = paintutils.drawPixel
- local gameSpeed = 0.1 --in second
- local pause = false
- local score = 0
- local lives = 3
- local dodging = false
- local projID = 0
- local ennemyID = 0
- local invincible = false
- local devmode = false
- local _log = "****Game initialized****\n"
- local Args = ...
- local firstLaunch = false
- local sendScore = false
- local file = fs.open("projectAlpha/game.log", "w")
- file.write("Version 2.4.0 Indev\n")
- file.close()
- gameutils.initializeBuffer()
- gui.initializeLog()
- local playerPos = {
- x = math.floor(termX/2)-2,
- y = termY-2,
- }
- local missile = {
- gameData = { exist = false,}
- }
- local entities = {
- projectile = {},
- ennemy = {},
- }
- --Initialize buffer
- for i=1, termY do
- buffer[i] = {}
- for u=1, termX do
- buffer[i][u] = colors.black
- end
- end
- local backbuffer = buffer
- print("Loading done")
- local function flush()
- local file = fs.open("projectAlpha/game.log", "a")
- file.write(_log)
- file.close()
- end
- local function log(_string)
- _log = _log.."\n".._string
- end
- local function exit()
- gui.clear()
- print("Thanks you for playing project alpha :)")
- log("****Game exited****")
- for i=1, #entities.ennemy do
- log("Ennemy still alive : "..entities.ennemy[i].id)
- end
- log("Total ennemies alive : "..#entities.ennemy)
- log("Total ennemies spawned : "..ennemyID)
- flush()
- local f = fs.open("projectAlpha/score", "a")
- f.write("Score on "..tostring(os.clock).." is : "..score.."\n")
- f.close()
- paintutils.drawPixel = oldPix
- end
- --MENU FUNCTION
- local function selectMain()
- local select = gui.getSelection()
- gui.clearBuffer()
- if select == 1 then
- log("Launching game")
- main()
- elseif select == 2 then
- load()
- elseif select == 3 then
- optionMenu()
- elseif select == 4 then
- exit()
- else
- error("An error occured on variable : select from function main")
- end
- end
- local function mainMenu()
- gui.clear()
- gui.setButton(midX - 2, 4, "PLAY", colors.cyan, colors.blue)
- gui.setButton(midX - 2, 8, "LOAD", colors.cyan, colors.blue)
- gui.setButton(midX - 3, 12, "OPTION", colors.cyan, colors.blue)
- gui.setButton(midX - 2, 16, "QUIT", colors.cyan, colors.blue)
- gui.setHeader(" MAIN MENU", colors.cyan)
- gui.render()
- selectMain()
- end
- local function selectOption()
- local select = gui.getSelection()
- gui.clearBuffer()
- if select == 1 then
- return
- --Choose difficulty via a box
- elseif select == 2 then
- gui.clear()
- term.setCursorPos(1,5)
- print("Bjornir90, coder, artist (kind of :p)")
- print("GravityScore for luaide, an amazing program")
- print("NitrogenFinger for his amazing gameutils API, and NpaintPro")
- print("And i want to say that i had much fun doing this game, i learned a lot thanks to it, and i hope you will like it as much as i do, and that you'll maybe learn something from it (feel free to read it or use it in your program, just please give credit)")
- elseif select == 3 then
- mainMenu()
- else
- error("An error has occured on variable select in function option")
- end
- end
- function optionMenu()
- gui.clear()
- gui.setButton(midX - 5, 5, "DIFFICULTY", colors.cyan, colors.blue)
- gui.setButton(midX - 3, 9, "CREDITS", colors.cyan, colors.blue)
- gui.setButton(midX - 3, 13, "CANCEL", colors.cyan, colors.blue)
- gui.setHeader(" Options", colors.cyan)
- gui.render()
- selectOption()
- end
- --Optimize drawing of pixel
- --/!\ WARNING : do not write things or it will mess up everything !
- function paintutils.drawPixel(x,y,colour)
- buffer[y][x] = colour
- end
- --Save and load function
- function save()
- local file = fs.open("projectAlpha/saves/LastSave.sve", "w")
- file.writeLine(playerPos.x)
- file.writeLine(playerPos.y)
- file.writeLine(score)
- file.close()
- print("Game successfully saved !")
- log("Game saved")
- end
- function load()
- local file = fs.open("projectAlpha/saves/LastSave.sve", "r")
- playerPos.x = tonumber(file.readLine())
- playerPos.y = tonumber(file.readLine())
- score = tonumber(file.readLine())
- file.close()
- print("Game loaded !")
- log("Game loaded")
- end
- --Hostile ship related functions
- local function spawn()
- local posx = math.random(1, termX)
- local rand = math.random(1,100)
- if rand > 75 and #entities.ennemy < 5 then
- local newEnnemy = gameutils.loadSprite("projectalpha/.sprites/ennemy.nfp", posx, 1)
- newEnnemy.id = ennemyID
- newEnnemy.gameData = {
- x = posx,
- y = 1,
- speed = 1,
- health = 1,
- exist = true,
- }
- log("Ennemy loaded : "..ennemyID)
- ennemyID = ennemyID + 1
- table.insert(entities.ennemy, newEnnemy)
- log("Ennemy spawned")
- end
- end
- local function handler()
- for i=1, #entities.projectile do
- if entities.projectile[i].gameData.y < 1 then
- entities.projectile[i].gameData.exist = false
- end
- if entities.projectile[i].gameData.exist == true then
- entities.projectile[i]:moveTo(entities.projectile[i].gameData.x, entities.projectile[i].gameData.y-2)
- entities.projectile[i].gameData.y = entities.projectile[i].gameData.y-2
- end
- end
- if missile.gameData.exist == true then
- local x = {}
- local y = {}
- for i=1, #entities.ennemy do
- local ennemy = entities.ennemy[i].gameData
- --determine closest ennemy
- y[i] = math.abs(missile.gameData.y-ennemy.y)
- --Save every value in table
- for u=1, #y do
- --Check if it is the closest in table
- missile.gameData.target.y = ennemy.y
- missile.gameData.target.x = ennemy.x
- if math.abs(missile.gameData.target.y-missile.gameData.y) > math.abs(missile.gameData.y-ennemy.y) then
- if math.abs(missile.gameData.target.x-missile.gameData.x) > math.abs(missile.gameData.x-ennemy.x) then
- missile.gameData.target.y = ennemy.y
- missile.gameData.target.x = ennemy.x
- end
- end
- end
- end
- --movement of missile
- local _speed = 1
- if missile.gameData.target.x+4 < missile.gameData.x then --missile on the right
- missile.gameData.going = "left"
- missile.currentFrame = 1
- missile:moveTo(missile.gameData.x-_speed, missile.gameData.y)
- missile.gameData.x=missile.gameData.x-_speed
- elseif missile.gameData.target.x-1 > missile.gameData.x then --missile on the left
- missile.gameData.going = "right"
- missile.currentFrame = 5
- missile:moveTo(missile.gameData.x+_speed, missile.gameData.y)
- missile.gameData.x=missile.gameData.x+_speed
- else
- missile.gameData.going = "nowhere"
- end
- if missile.gameData.y < missile.gameData.target.y+1 then --missile above ennemy
- if missile.gameData.going == "left" then
- missile.currentFrame = 6
- elseif missile.gameData.going == "right" then
- missile.currentFrame = 8
- else
- missile.currentFrame = 7
- end
- missile:moveTo(missile.gameData.x, missile.gameData.y+_speed)
- missile.gameData.y = missile.gameData.y + _speed
- elseif missile.gameData.y > missile.gameData.target.y+1 then --missile below ennemy
- if missile.gameData.going == "left" then
- missile.currentFrame = 2
- elseif missile.gameData.going == "right" then
- missile.currentFrame = 4
- else
- missile.currentFrame = 3
- end
- missile:moveTo(missile.gameData.x, missile.gameData.y-_speed)
- missile.gameData.y = missile.gameData.y-_speed
- end
- end
- for i=1, #entities.ennemy do
- local ennemy = entities.ennemy[i]
- _speed = ennemy.gameData.speed
- if playerPos.x+4 < ennemy.gameData.x then --ennemy on the right
- ennemy:moveTo(ennemy.gameData.x-_speed, ennemy.gameData.y)
- ennemy.gameData.x=ennemy.gameData.x-_speed
- elseif playerPos.x-1 > ennemy.gameData.x+4 then --ennemy on the left
- ennemy:moveTo(ennemy.gameData.x+_speed, ennemy.gameData.y)
- ennemy.gameData.x=ennemy.gameData.x+_speed
- elseif ennemy.gameData.y < playerPos.y+1 then --ennemy above player
- ennemy:moveTo(ennemy.gameData.x, ennemy.gameData.y+_speed)
- ennemy.gameData.y = ennemy.gameData.y + _speed
- elseif ennemy.gameData.y > playerPos.y+2 then --ennemy below player
- ennemy:moveTo(ennemy.gameData.x, ennemy.gameData.y-_speed)
- ennemy.gameData.y = ennemy.gameData.y-_speed
- end
- end --End of the ennemy for boucle
- --Collisions
- for i=1, #entities.projectile do
- for u=1, #entities.ennemy do
- if entities.projectile[i]:pCollidesWith(entities.ennemy[u]) then
- entities.projectile[i].gameData.exist = false
- entities.ennemy[u].gameData.exist = false
- score = score + 100
- log("Ennemy Killed with lasers")
- end
- end
- end
- for i=1, #entities.ennemy do
- if missile.gameData.exist then
- if missile:pCollidesWith(entities.ennemy[i]) then
- missile.gameData.exist = false
- entities.ennemy[i].gameData.exist = false
- score = score + 75
- log("Missile hit ennemy "..entities.ennemy[i].id)
- end
- end
- if player:pCollidesWith(entities.ennemy[i]) then
- lives = lives-1
- entities.ennemy[i].gameData.exist = false
- log("Player hit")
- log("Player lives : "..lives)
- if lives == 0 and invincible == false then
- quit = true
- end
- end
- end
- end
- --Player movement
- local function movementHandler(param1)
- log("Key pressed : "..param1)
- if param1 == keys.right then
- player:moveTo(playerPos.x + 2, playerPos.y)
- playerPos.x = playerPos.x + 2
- elseif param1 == keys.left then
- player:moveTo(playerPos.x - 2, playerPos.y)
- playerPos.x = playerPos.x - 2
- elseif param1 == keys.up then
- player:moveTo(playerPos.x, playerPos.y-2)
- playerPos.y = playerPos.y - 2
- elseif param1 == keys.down then
- player:moveTo(playerPos.x, playerPos.y+2)
- playerPos.y = playerPos.y + 2
- elseif param1 == keys.p then
- pause = true
- elseif param1 == keys.space then
- local newProj = gameutils.loadSprite("projectalpha/.sprites/pPlayer.nfp", playerPos.x+2, playerPos.y - 3)
- newProj.id = projID
- newProj.gameData = {
- x = playerPos.x + 2,
- y = playerPos.y - 3,
- exist = true
- }
- log("Projectile loaded : "..projID)
- projID = projID + 1
- table.insert(entities.projectile, newProj)
- elseif param1 == keys.f and missile.gameData.exist == false then
- missile = gameutils.loadAnimation("projectAlpha/.sprites/mPlayer.nfa", playerPos.x+2, playerPos.y-3)
- missile.gameData = {
- x=playerPos.x+2,
- y=playerPos.y-3,
- exist = true,
- target = {
- x=0,
- y=0
- },
- going = "somewhere",
- }
- log("Missile loaded")
- elseif param1 == keys.q then
- quit = true
- return "exited"
- elseif param1 == keys.c and devmode == true and invincible == false then
- invincible = true
- elseif param1 == keys.c and devmode == true and invincible == true then
- invincible = false
- end
- return "ended"
- end
- local function tutorial()
- gui.clear()
- print("Thanks for installing projectalpha !")
- print("This is my first game and i hope you will enjoy it :)")
- print("Keys :")
- print("arrows = move")
- print("space = lasers")
- print("f = missile")
- print("p = pause")
- print("q = quit")
- term.setTextColor(colors.red)
- print("I would like to collect score using http API, for balance purpose")
- print("Do you allow me to send your score ? (y/n)")
- print("This can be changed in the meta.conf file, located in projectAlpha dir")
- local input = read()
- if input == "y" or input == "yes" then
- gui.clear()
- term.setTextColor(colors.white)
- print("Thanks you for your help :)")
- local f = fs.open("projectAlpha/meta.conf", "a")
- f.write("sendscore=true;\n")
- f.close()
- end
- gui.clear()
- end
- function main()
- if firstLaunch == true then
- tutorial() -- Need to write it
- end
- local timerID = os.startTimer(gameSpeed)
- while quit == false do
- flush()
- _log = ""
- gui.clear()
- local currentTime = tostring(os.clock())
- log("Draw a frame at "..currentTime)
- log("Player position : "..playerPos.x.." "..playerPos.y)
- log("Missile is active : "..tostring(missile.gameData.exist))
- if missile.gameData.exist then
- log("Missile target x : "..tostring(missile.gameData.target.x).." y : "..tostring(missile.gameData.target.y))
- end
- --Draw entities
- for i=1, #entities.ennemy do
- gameutils.writeToBuffer(entities.ennemy[i])
- end
- for i=1, #entities.projectile do
- gameutils.writeToBuffer(entities.projectile[i])
- end
- if missile.gameData.exist == true then
- gameutils.writeToBuffer(missile)
- end
- gameutils.writeToBuffer(player)
- if devmode == true then
- paintutils.drawPixel(playerPos.x-1, playerPos.y, colors.red)
- paintutils.drawPixel(playerPos.x+5, playerPos.y, colors.red)
- end
- gameutils.drawBuffer()
- -- Function that refresh screen using buffer
- for i=1, termY do
- for u=1, termX do
- if buffer[i][u] ~= backbuffer[i][u] then
- oldPix(u, i, buffer[i][u])
- end
- end
- end
- if devmode == true then
- term.setCursorPos(1,1)
- print(timerID)
- print(playerPos.x.." "..playerPos.y)
- print("SCORE : "..score)
- print("ENNEMIES ON SCREEN : "..tostring(#entities.ennemy))
- print("INVINCIBLE : "..tostring(invincible))
- end
- gameutils.clearBuffer()
- local event, param, param1, param2 = os.pullEvent()
- if event == "key" then
- movementHandler(param)
- elseif event == "timer" then
- if param == timerID then
- local rand = math.random(0,1000)
- if second == 0 and rand >= 900 then
- gui.clear() term.setCursorPos(1,1) term.setTextColor(colors.red) print("Keep an eye out for an invasion from the Outside...") term.setTextColor(colors.white) sleep(0.5) gui.clear() second = 1
- end
- spawn()
- handler()
- timerID = os.startTimer(gameSpeed)
- end
- end
- tempProjectile = entities.projectile
- entities.projectile = {}
- for i=1, #tempProjectile do --Remake the table every time so no problem with ghosts projectiles
- if tempProjectile[i].gameData.exist == true then
- table.insert(entities.projectile, tempProjectile[i])
- end
- end
- tempEnnemy = entities.ennemy
- entities.ennemy = {}
- for i=1, #tempEnnemy do --Same here
- if tempEnnemy[i].gameData.exist == true then
- table.insert(entities.ennemy, tempEnnemy[i])
- end
- end
- if pause then
- log("Game paused")
- term.setBackgroundColor(colors.black)
- term.clear()
- term.setCursorPos(5,3)
- write("Press P to resume game")
- term.setCursorPos(5,4)
- write("Press S to save game")
- term.setCursorPos(5,5)
- write("Press L to load game")
- term.setCursorPos(5,6)
- write("Press Q to quit game")
- while true do
- local event, key = os.pullEvent("key")
- if key == keys.p then
- pause = false
- if gameSpeed == nil then
- flush()
- error("A needed variable is empty ! (gameSpeed)")
- end
- timerID = os.startTimer(gameSpeed)
- break
- elseif key == keys.s then
- save()
- elseif key == keys.l then
- load()
- elseif key == keys.q then
- quit = true
- break
- end
- end
- end
- end
- mainMenu()
- end
- gui.clear()
- mainMenu()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement