Advertisement
Bjornir90

Project alpha test

Aug 5th, 2013
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.91 KB | None | 0 0
  1. --Version 2.4.0
  2.  
  3.  
  4. local termX, termY = term.getSize()
  5. local midX = math.floor(termX/2)
  6.  
  7. print("Loading API")
  8. os.loadAPI("projectalpha/gameutils")
  9. os.loadAPI("projectalpha/gui")
  10. print("Loading game")
  11.  
  12. local player = gameutils.loadSprite("projectalpha/.sprites/player.nfp", math.floor(termX/2)-2, termY-2)
  13. local quit = false
  14. local timer = nil
  15. local timerID = nil
  16. local buffer = {}
  17. local drawn = {}
  18. local oldPix = paintutils.drawPixel
  19. local gameSpeed = 0.1 --in second
  20. local pause = false
  21. local score = 0
  22. local lives = 3
  23. local dodging = false
  24. local projID = 0
  25. local ennemyID = 0
  26. local invincible = false
  27. local devmode = false
  28. local _log = "****Game initialized****\n"
  29. local Args = ...
  30. local firstLaunch = false
  31. local sendScore = false
  32.  
  33. local file = fs.open("projectAlpha/game.log", "w")
  34. file.write("Version 2.4.0 Indev\n")
  35. file.close()
  36.  
  37.  
  38. gameutils.initializeBuffer()
  39. gui.initializeLog()
  40.  
  41. local playerPos = {
  42.     x = math.floor(termX/2)-2,
  43.     y = termY-2,
  44. }
  45.  
  46. local missile = {
  47.  gameData = { exist = false,}
  48. }
  49.  
  50. local entities = {
  51.     projectile = {},
  52.     ennemy = {},
  53. }
  54.  
  55. --Initialize buffer
  56. for i=1, termY do
  57.  buffer[i] = {}
  58.  for u=1, termX do
  59.   buffer[i][u] = colors.black
  60.  end
  61. end
  62.  
  63.  
  64. local backbuffer = buffer
  65.  
  66. print("Loading done")
  67.  
  68.  
  69. local function flush()
  70.     local file = fs.open("projectAlpha/game.log", "a")
  71.     file.write(_log)
  72.     file.close()
  73. end
  74.  
  75. local function log(_string)
  76.     _log = _log.."\n".._string
  77. end
  78.  
  79. local function exit()
  80.     gui.clear()
  81.     print("Thanks you for playing project alpha :)")
  82.     log("****Game exited****")
  83.     for i=1, #entities.ennemy do
  84.         log("Ennemy still alive : "..entities.ennemy[i].id)
  85.     end
  86.     log("Total ennemies alive : "..#entities.ennemy)
  87.     log("Total ennemies spawned : "..ennemyID)
  88.     flush()
  89.     local f = fs.open("projectAlpha/score", "a")
  90.     f.write("Score on "..tostring(os.clock).." is : "..score.."\n")
  91.     f.close()
  92.     paintutils.drawPixel = oldPix
  93. end
  94.  
  95. --MENU FUNCTION
  96.  
  97. local function selectMain()
  98.     local select = gui.getSelection()
  99.     gui.clearBuffer()
  100.     if select == 1 then
  101.         log("Launching game")
  102.         main()
  103.     elseif select == 2 then
  104.         load()
  105.     elseif select == 3 then
  106.         optionMenu()
  107.     elseif select == 4 then
  108.      exit()
  109.     else
  110.         error("An error occured on variable : select from function main")
  111.     end
  112. end
  113.  
  114. local function mainMenu()
  115.     gui.clear()
  116.     gui.setButton(midX - 2, 4, "PLAY", colors.cyan, colors.blue)
  117.     gui.setButton(midX - 2, 8, "LOAD", colors.cyan, colors.blue)
  118.     gui.setButton(midX - 3, 12, "OPTION", colors.cyan, colors.blue)
  119.     gui.setButton(midX - 2, 16, "QUIT", colors.cyan, colors.blue)
  120.     gui.setHeader("                 MAIN MENU", colors.cyan)
  121.     gui.render()
  122.     selectMain()
  123. end
  124.  
  125. local function selectOption()
  126.     local select = gui.getSelection()
  127.     gui.clearBuffer()
  128.     if select == 1 then
  129.         return
  130.         --Choose difficulty via a box
  131.     elseif select == 2 then
  132.         gui.clear()
  133.         term.setCursorPos(1,5)
  134.         print("Bjornir90, coder, artist (kind of :p)")
  135.      print("GravityScore for luaide, an amazing program")
  136.      print("NitrogenFinger for his amazing gameutils API, and NpaintPro")
  137.      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)")
  138.     elseif select == 3 then
  139.         mainMenu()
  140.     else
  141.         error("An error has occured on variable select in function option")
  142.     end
  143. end
  144.  
  145.  
  146. function optionMenu()
  147.     gui.clear()
  148.     gui.setButton(midX - 5, 5, "DIFFICULTY", colors.cyan, colors.blue)
  149.     gui.setButton(midX - 3, 9, "CREDITS", colors.cyan, colors.blue)
  150.     gui.setButton(midX - 3, 13, "CANCEL", colors.cyan, colors.blue)
  151.     gui.setHeader("                 Options", colors.cyan)
  152.     gui.render()
  153.     selectOption()
  154. end
  155.  
  156.  
  157.  
  158. --Optimize drawing of pixel
  159. --/!\ WARNING : do not write things or it will mess up everything !
  160.  
  161.  
  162. function paintutils.drawPixel(x,y,colour)
  163.  buffer[y][x] = colour
  164. end
  165.  
  166. --Save and load function
  167.  
  168. function save()
  169.     local file = fs.open("projectAlpha/saves/LastSave.sve", "w")
  170.     file.writeLine(playerPos.x)
  171.     file.writeLine(playerPos.y)
  172.     file.writeLine(score)
  173.     file.close()
  174.     print("Game successfully saved !")
  175.     log("Game saved")
  176. end
  177.  
  178.  
  179. function load()
  180.     local file = fs.open("projectAlpha/saves/LastSave.sve", "r")
  181.     playerPos.x = tonumber(file.readLine())
  182.     playerPos.y = tonumber(file.readLine())
  183.     score = tonumber(file.readLine())
  184.     file.close()
  185.     print("Game loaded !")
  186.     log("Game loaded")
  187. end
  188.  
  189. --Hostile ship related functions
  190.  
  191. local function spawn()
  192.     local posx = math.random(1, termX)
  193.     local rand = math.random(1,100)
  194.     if rand > 75 and #entities.ennemy < 5 then
  195.         local newEnnemy = gameutils.loadSprite("projectalpha/.sprites/ennemy.nfp", posx, 1)
  196.         newEnnemy.id = ennemyID
  197.         newEnnemy.gameData = {
  198.         x = posx,
  199.         y = 1,
  200.         speed = 1,
  201.         health = 1,
  202.         exist = true,
  203.     }
  204.         log("Ennemy loaded : "..ennemyID)
  205.         ennemyID = ennemyID + 1
  206.         table.insert(entities.ennemy, newEnnemy)
  207.         log("Ennemy spawned")
  208.     end
  209. end
  210.  
  211.  
  212.  
  213. local function handler()
  214.     for i=1, #entities.projectile do
  215.   if entities.projectile[i].gameData.y < 1 then
  216.    entities.projectile[i].gameData.exist = false
  217.         end
  218.      if entities.projectile[i].gameData.exist == true then
  219.         entities.projectile[i]:moveTo(entities.projectile[i].gameData.x, entities.projectile[i].gameData.y-2)
  220.         entities.projectile[i].gameData.y = entities.projectile[i].gameData.y-2
  221.      end
  222.     end
  223.     if missile.gameData.exist == true then
  224.      local x = {}
  225.      local y = {}
  226.      for i=1, #entities.ennemy do
  227.       local ennemy = entities.ennemy[i].gameData
  228.         --determine closest ennemy
  229.       y[i] = math.abs(missile.gameData.y-ennemy.y)
  230.         --Save every value in table
  231.       for u=1, #y do
  232.         --Check if it is the closest in table
  233.         missile.gameData.target.y = ennemy.y
  234.         missile.gameData.target.x = ennemy.x
  235.         if math.abs(missile.gameData.target.y-missile.gameData.y) > math.abs(missile.gameData.y-ennemy.y) then
  236.             if math.abs(missile.gameData.target.x-missile.gameData.x) > math.abs(missile.gameData.x-ennemy.x) then
  237.                 missile.gameData.target.y = ennemy.y
  238.                 missile.gameData.target.x = ennemy.x
  239.             end
  240.         end
  241.        end
  242.      end
  243.      --movement of missile
  244.      local _speed = 1
  245.      if missile.gameData.target.x+4 < missile.gameData.x then --missile on the right   
  246.       missile.gameData.going = "left"
  247.       missile.currentFrame = 1
  248.       missile:moveTo(missile.gameData.x-_speed, missile.gameData.y)
  249.       missile.gameData.x=missile.gameData.x-_speed
  250.      elseif missile.gameData.target.x-1 > missile.gameData.x then --missile on the left
  251.       missile.gameData.going = "right"
  252.       missile.currentFrame = 5
  253.       missile:moveTo(missile.gameData.x+_speed, missile.gameData.y)
  254.       missile.gameData.x=missile.gameData.x+_speed
  255.      else
  256.       missile.gameData.going = "nowhere"
  257.      end
  258.      if missile.gameData.y < missile.gameData.target.y+1 then --missile above ennemy
  259.       if missile.gameData.going == "left" then
  260.        missile.currentFrame = 6
  261.       elseif missile.gameData.going == "right" then
  262.        missile.currentFrame = 8
  263.       else
  264.        missile.currentFrame = 7
  265.       end
  266.       missile:moveTo(missile.gameData.x, missile.gameData.y+_speed)
  267.       missile.gameData.y = missile.gameData.y + _speed
  268.      elseif missile.gameData.y > missile.gameData.target.y+1 then --missile below ennemy
  269.       if missile.gameData.going == "left" then
  270.        missile.currentFrame = 2
  271.       elseif missile.gameData.going == "right" then
  272.        missile.currentFrame = 4
  273.       else
  274.        missile.currentFrame = 3
  275.       end
  276.       missile:moveTo(missile.gameData.x, missile.gameData.y-_speed)
  277.       missile.gameData.y = missile.gameData.y-_speed
  278.      end
  279.  end
  280.  
  281.     for i=1, #entities.ennemy do
  282.      local ennemy = entities.ennemy[i]
  283.     _speed = ennemy.gameData.speed
  284.      if playerPos.x+4 < ennemy.gameData.x then --ennemy on the right   
  285.       ennemy:moveTo(ennemy.gameData.x-_speed, ennemy.gameData.y)
  286.       ennemy.gameData.x=ennemy.gameData.x-_speed
  287.      elseif playerPos.x-1 > ennemy.gameData.x+4 then --ennemy on the left
  288.       ennemy:moveTo(ennemy.gameData.x+_speed, ennemy.gameData.y)
  289.       ennemy.gameData.x=ennemy.gameData.x+_speed
  290.      elseif ennemy.gameData.y < playerPos.y+1 then --ennemy above player
  291.        ennemy:moveTo(ennemy.gameData.x, ennemy.gameData.y+_speed)
  292.        ennemy.gameData.y = ennemy.gameData.y + _speed
  293.      elseif ennemy.gameData.y > playerPos.y+2 then --ennemy below player
  294.        ennemy:moveTo(ennemy.gameData.x, ennemy.gameData.y-_speed)
  295.        ennemy.gameData.y = ennemy.gameData.y-_speed
  296.      end
  297.     end --End of the ennemy for boucle
  298.     --Collisions
  299.     for i=1, #entities.projectile do
  300.         for u=1, #entities.ennemy do
  301.             if entities.projectile[i]:pCollidesWith(entities.ennemy[u]) then
  302.                 entities.projectile[i].gameData.exist = false
  303.                 entities.ennemy[u].gameData.exist = false
  304.                 score = score + 100
  305.                 log("Ennemy Killed with lasers")
  306.             end
  307.         end
  308.     end
  309.     for i=1, #entities.ennemy do
  310.      if missile.gameData.exist then
  311.      if missile:pCollidesWith(entities.ennemy[i]) then
  312.        missile.gameData.exist = false
  313.        entities.ennemy[i].gameData.exist = false
  314.        score = score + 75
  315.        log("Missile hit ennemy "..entities.ennemy[i].id)
  316.       end
  317.   end
  318.         if player:pCollidesWith(entities.ennemy[i]) then
  319.             lives = lives-1
  320.             entities.ennemy[i].gameData.exist = false
  321.             log("Player hit")
  322.             log("Player lives : "..lives)
  323.             if lives == 0 and invincible == false then
  324.                 quit = true
  325.             end
  326.         end
  327.     end
  328. end
  329.  
  330.  
  331. --Player movement
  332.  
  333. local function movementHandler(param1)
  334.     log("Key pressed : "..param1)
  335.     if param1 == keys.right then
  336.         player:moveTo(playerPos.x + 2, playerPos.y)
  337.         playerPos.x = playerPos.x + 2
  338.     elseif param1 == keys.left then
  339.         player:moveTo(playerPos.x - 2, playerPos.y)
  340.         playerPos.x = playerPos.x - 2
  341.     elseif param1 == keys.up then
  342.         player:moveTo(playerPos.x, playerPos.y-2)
  343.         playerPos.y = playerPos.y - 2
  344.     elseif param1 == keys.down then
  345.         player:moveTo(playerPos.x, playerPos.y+2)
  346.         playerPos.y = playerPos.y + 2
  347.     elseif param1 == keys.p then
  348.         pause = true
  349.     elseif param1 == keys.space then
  350.      local newProj = gameutils.loadSprite("projectalpha/.sprites/pPlayer.nfp", playerPos.x+2, playerPos.y - 3)
  351.         newProj.id = projID
  352.        
  353.         newProj.gameData = {
  354.             x = playerPos.x + 2,
  355.             y = playerPos.y - 3,
  356.             exist = true
  357.         }
  358.        
  359.         log("Projectile loaded : "..projID)
  360.         projID = projID + 1
  361.         table.insert(entities.projectile, newProj)
  362.  elseif param1 == keys.f and missile.gameData.exist == false then
  363.   missile = gameutils.loadAnimation("projectAlpha/.sprites/mPlayer.nfa", playerPos.x+2, playerPos.y-3)
  364.  
  365.   missile.gameData = {
  366.    x=playerPos.x+2,
  367.    y=playerPos.y-3,
  368.    exist = true,
  369.    target = {
  370.     x=0,
  371.     y=0
  372.    },
  373.    going = "somewhere",
  374.   }
  375.  
  376.   log("Missile loaded")
  377.     elseif param1 == keys.q then
  378.         quit = true
  379.         return "exited"
  380.     elseif param1 == keys.c and devmode == true and invincible == false then
  381.         invincible = true
  382.     elseif param1 == keys.c and devmode == true and invincible == true then
  383.         invincible = false
  384.     end
  385.     return "ended"
  386. end
  387.  
  388. local function tutorial()
  389.  gui.clear()
  390.  print("Thanks for installing projectalpha !")
  391.  print("This is my first game and i hope you will enjoy it :)")
  392.  print("Keys :")
  393.  print("arrows = move")
  394.  print("space = lasers")
  395.  print("f = missile")
  396.  print("p = pause")
  397.  print("q = quit")
  398.  term.setTextColor(colors.red)
  399.  print("I would like to collect score using http API, for balance purpose")
  400.  print("Do you allow me to send your score ? (y/n)")
  401.  print("This can be changed in the meta.conf file, located in projectAlpha dir")
  402.  local input = read()
  403.  if input == "y" or input == "yes" then
  404.   gui.clear()
  405.   term.setTextColor(colors.white)
  406.   print("Thanks you for your help :)")
  407.   local f = fs.open("projectAlpha/meta.conf", "a")
  408.   f.write("sendscore=true;\n")
  409.   f.close()
  410.  end
  411.  gui.clear()
  412. end
  413.  
  414.  
  415. function main()
  416.  if firstLaunch == true then
  417.   tutorial() -- Need to write it
  418.  end
  419.  local timerID = os.startTimer(gameSpeed)
  420. while quit == false do
  421.     flush()
  422.     _log = ""
  423.     gui.clear()
  424.     local currentTime = tostring(os.clock())
  425.     log("Draw a frame at "..currentTime)
  426.     log("Player position : "..playerPos.x.." "..playerPos.y)
  427.     log("Missile is active : "..tostring(missile.gameData.exist))
  428.     if missile.gameData.exist then
  429.         log("Missile target x : "..tostring(missile.gameData.target.x).." y : "..tostring(missile.gameData.target.y))
  430.     end
  431.     --Draw entities
  432.     for i=1, #entities.ennemy do
  433.         gameutils.writeToBuffer(entities.ennemy[i])
  434.     end
  435.     for i=1, #entities.projectile do
  436.         gameutils.writeToBuffer(entities.projectile[i])
  437.     end
  438.     if missile.gameData.exist == true then
  439.      gameutils.writeToBuffer(missile)
  440.     end
  441.     gameutils.writeToBuffer(player)
  442.     if devmode == true then
  443.         paintutils.drawPixel(playerPos.x-1, playerPos.y, colors.red)
  444.         paintutils.drawPixel(playerPos.x+5, playerPos.y, colors.red)
  445.     end
  446.     gameutils.drawBuffer()
  447.    
  448.     -- Function that refresh screen using buffer
  449.     for i=1, termY do
  450.      for u=1, termX do
  451.       if buffer[i][u] ~= backbuffer[i][u] then
  452.        oldPix(u, i, buffer[i][u])
  453.       end
  454.      end
  455.     end
  456.  
  457.     if devmode == true then
  458.         term.setCursorPos(1,1)
  459.         print(timerID)
  460.         print(playerPos.x.." "..playerPos.y)
  461.         print("SCORE : "..score)
  462.         print("ENNEMIES ON SCREEN : "..tostring(#entities.ennemy))
  463.         print("INVINCIBLE : "..tostring(invincible))
  464.     end
  465.    
  466.     gameutils.clearBuffer()
  467.     local event, param, param1, param2 = os.pullEvent()
  468.    
  469.     if event == "key" then
  470.         movementHandler(param)
  471.     elseif event == "timer" then
  472.         if param == timerID then
  473.        
  474.             local rand = math.random(0,1000)
  475.             if second == 0 and rand >= 900 then
  476.                 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
  477.             end
  478.            
  479.             spawn()
  480.             handler()
  481.             timerID = os.startTimer(gameSpeed)
  482.         end
  483.     end
  484.    
  485.     tempProjectile = entities.projectile
  486.     entities.projectile = {}
  487.     for i=1, #tempProjectile do     --Remake the table every time so no problem with ghosts projectiles
  488.         if tempProjectile[i].gameData.exist == true then
  489.             table.insert(entities.projectile, tempProjectile[i])
  490.         end
  491.     end
  492.     tempEnnemy = entities.ennemy
  493.     entities.ennemy = {}
  494.     for i=1, #tempEnnemy do     --Same here
  495.         if tempEnnemy[i].gameData.exist == true then
  496.             table.insert(entities.ennemy, tempEnnemy[i])
  497.         end
  498.     end
  499.    
  500.     if pause then
  501.         log("Game paused")
  502.         term.setBackgroundColor(colors.black)
  503.         term.clear()
  504.         term.setCursorPos(5,3)
  505.         write("Press P to resume game")
  506.         term.setCursorPos(5,4)
  507.         write("Press S to save game")
  508.         term.setCursorPos(5,5)
  509.         write("Press L to load game")
  510.         term.setCursorPos(5,6)
  511.         write("Press Q to quit game")
  512.         while true do
  513.             local event, key = os.pullEvent("key")
  514.             if key == keys.p then
  515.                 pause = false
  516.                 if gameSpeed == nil then
  517.                     flush()
  518.                     error("A needed variable is empty ! (gameSpeed)")
  519.                 end
  520.                 timerID = os.startTimer(gameSpeed)
  521.                 break
  522.             elseif key == keys.s then
  523.                 save()
  524.             elseif key == keys.l then
  525.                 load()
  526.             elseif key == keys.q then
  527.                 quit = true
  528.                 break
  529.             end
  530.         end
  531.     end
  532. end
  533. mainMenu()
  534.  
  535. end
  536.  
  537.  
  538. gui.clear()
  539. mainMenu()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement