Hey its me again with another doubt, the last one (i hope) for this proyect, so i finally pretty much ended the game phase of my game (thanks to Rob and Burhan!) and i decided to try this Storyboard thing to add a few menus, a retry button and that kind of things, i was following a tutorial to try to understand what to do with it, and was able to make the welcome screen, and the main menu, but then i find myself with 300ish lines of code that should go to my scene_game.lua and i have no idea on how to put that thing inside the storyboard, im a bit messy myself to construct the code, there are functions here and there, variables here and there, everyone calling or using or modifying each other wich makes it almost imposible to write in a clean way (variables here, functions there) so im not really sure if i can put my game into the storyboard as if.
I still dont understand where every thing goes into the storyboard, all those small blocks, also saw some functions and variables beeing declared outside those blocks, everything seems chaotic to me, add my code to that mix, and i really dont know where to start.
I will submit my game code here (feel free to play it :P), i dont expect anyone to do my homework, but if you could at least guide me a bit on where should i put the things or explain me a bit better i would be really grateful.
Thanks in advance and sorry to bother you with this stuff.
local widget = require( "widget" ) -- Libs used local physics = require("physics") local json = require("json") physics.start() -- Start engine physics.setGravity( 0, 0 ) -- 0 Grav display.setStatusBar( display.HiddenStatusBar ) -- Hide phone bar local runtime = 0 --physics.setDrawMode("hybrid") -- Enable for testing physics relations function saveTable(t, filename) -- Function to save a table into a json file local path = system.pathForFile( filename, system.DocumentsDirectory) local file = io.open(path, "w") if file then local contents = json.encode(t) file:write( contents ) io.close( file ) return true else return false end end function loadTable(filename) -- Function to load a table from a json file local path = system.pathForFile( filename, system.DocumentsDirectory) local contents = "" local myTable = {} local file = io.open( path, "r" ) if file then local contents = file:read( "\*a" ) myTable = json.decode(contents); io.close( file ) return myTable end return nil end local function getDeltaTime() -- Get DT local temp = system.getTimer() local dt = (temp-runtime) / (1000/60) --60fps o 30fps as base runtime = temp return dt end local floors={} -- Covers the screen with floor tiles for i=1,display.contentWidth/30+1 do for j=1,display.contentHeight/30+1 do f={} f.x=i\*30 f.y=j\*30 f.typef=math.random(1,10) table.insert(floors,f) end end function lelx() -- Randomize Ghost x position a=math.random(1,3) if a == 1 then return -40 end if a == 2 then return display.contentWidth/2 end if a == 3 then return display.contentWidth+40 end end function lely() -- Randomize Ghost y position a=math.random(1,3) if a == 1 then return -60 end if a == 2 then return display.contentHeight+60 end if a == 3 then return display.contentHeight/2 end end local ghosts={} local dt = getDeltaTime() local life=1 local score=0 local kills=0 function newGhost(dt) -- Creates a new ghost local ghos= display.newImageRect("ghost.png",76,105) ghos.speed=14 repeat ghos.x=lelx() ghos.y=lely() until(ghos.x~=display.contentWidth/2 or ghos.y~=display.contentHeight/2) return ghos end local function distance(x,y) -- Distance to center return math.sqrt( (x-display.contentWidth/2)^2 + (y-display.contentHeight/2)^2 ) end local walls={} -- Replaces floor tiles with wall tiles when distance to center is \> than width\*0.445 for i,v in ipairs(floors) do if distance(v.x,v.y)\>display.contentWidth\*0.445 then table.remove(floors,i) w={x=v.x,y=v.y,typew=math.random(1,10)} table.insert(walls,w) end end for i,v in ipairs(floors) do -- Draw floor local lel = display.newImageRect( "floor"..v.typef..".png", 31, 31) lel.x=v.x lel.y=v.y lel.alpha=1-distance(v.x,v.y)\*0.0016 end for i,v in ipairs(walls) do -- Draw walls local lel = display.newImage( "wall"..v.typew..".png", 31, 31) lel.x=v.x lel.y=v.y lel.alpha=1-distance(v.x,v.y)\*0.0016 end local guy = display.newImageRect( "guylant.png", 345, 110 ) -- The GUY guy.x, guy.y = display.contentWidth/2, display.contentHeight/2 guy.speed=10 local function distance2guy(x,y) -- Distance to guy return math.sqrt( (x-guy.x)^2 + (y-guy.y)^2 ) end function chaseGuy(event) -- Ghost chase the guy stallchase = math.random(2) for i,v in ipairs(ghosts) do v.alpha=math.cos(math.random(0,2\*math.pi))^2 if stallchase == 1 then if v.x \> guy.x then v.x = v.x - v.speed elseif v.x \< guy.x then v.x = v.x + v.speed end end stallchase = math.random(2) if stallchase == 1 then if v.y \> guy.y then v.y = v.y - v.speed elseif v.y \< guy.y then v.y = v.y + v.speed end end end end local moveButton = display.newCircle(guy.x,guy.y,30) moveButton.alpha=0.008 local ran = false function ghostGuyColli(event) -- Ghost and Guy Collision [[GAME OVER]] for i,v in ipairs(ghosts) do if (distance2guy(v.x,v.y)\<=65)then physics.stop() --[[HERE I SHOULD CALL THE NEXT SCENE OF THE STORYBOARD]]-- local ulose = display.newImageRect( "ulose.png",display.contentWidth,display.contentHeight) ulose.x=display.contentWidth/2 ulose.y=display.contentHeight/2 Runtime:removeEventListener("enterFrame", keep) Runtime:removeEventListener("enterFrame", chaseGuy) Runtime:removeEventListener("enterFrame", ghostGuyColli) Runtime:removeEventListener("enterFrame", ghostKiller) local t = display.newText( "Killed "..kills.." ghosts.", display.contentWidth/2, 7\*display.contentHeight/10, "AmericanTypewriter-Bold", 100 ) local x = display.newText( "Score: "..score+kills\*5, display.contentWidth/2, 8\*display.contentHeight/10, "AmericanTypewriter-Bold", 100 ) myGameSettings = {} myGameSettingsOut={} myGameSettings.highScore = score+kills\*5 if loadTable("mygamesettings.json") then myGameSettingsOut = loadTable("mygamesettings.json") if (myGameSettings.highScore \> myGameSettingsOut.highScore) then saveTable(myGameSettings, "mygamesettings.json") local txt = display.newText( "New Best: "..myGameSettings.highScore.."!!!", display.contentWidth/2, 9\*display.contentHeight/10, "AmericanTypewriter-Bold", 100 ) else local txt = display.newText( "Best: "..myGameSettingsOut.highScore, display.contentWidth/2, 9\*display.contentHeight/10, "AmericanTypewriter-Bold", 100 ) end else saveTable(myGameSettings, "mygamesettings.json") local txt = display.newText( "New Best: "..myGameSettings.highScore.."!!!", display.contentWidth/2, 9\*display.contentHeight/10, "AmericanTypewriter-Bold", 100 ) end end end end local ext1 = display.newCircle(guy.x+290,guy.y+70,10) local ext2 = display.newCircle(guy.x+290,guy.y-30,10) ext1.alpha=0.008 ext2.alpha=0.008 physics.addBody(guy,kinematic,0,0,0) physics.addBody(ext1,static,0,0,0) physics.addBody(ext2,static,0,0,0) local ext1j = physics.newJoint( "weld", ext1, guy, guy.x, guy.y ) local ext2j = physics.newJoint( "weld", ext2, guy, guy.x, guy.y) guy.anchorX=0.06 guy.anchorY=0.32 local function triangleArea(p1x,p1y,p2x,p2y,p3x,p3y) -- Calculate area of a triangle local d1 = p1x-p3x local d2 = p1y-p3y local d3 = p2x-p3x local d4 = p2y-p3y return 0.5\*math.abs((d1\*d4)-(d2\*d3)) end local function pointInTriangle(px,py,p1x,p1y,p2x,p2y,p3x,p3y) -- Calculate if px,py is inside the triangle local area0 = triangleArea(p1x,p1y,p2x,p2y,p3x,p3y) local area1 = triangleArea(px,py,p1x,p1y,p2x,p2y) local area2 = triangleArea(px,py,p1x,p1y,p3x,p3y) local area3 = triangleArea(px,py,p2x,p2y,p3x,p3y) return (area0==(area1+area2+area3)) end local scoreText = display.newText(("Score: "..score+kills\*5 .." Kills: "..kills), display.contentWidth/3, display.contentHeight/10, "AmericanTypewriter-Bold", 60 ) scoreText.alpha = 0.8 function ghostKiller(event) -- Lantern and Ghost Collision scoreText.text=("Score: "..score+kills\*5 .." Kills: "..kills) for i,v in ipairs(ghosts) do if pointInTriangle(v.x,v.y,guy.x,guy.y,ext1.x,ext1.y,ext2.x,ext2.y)==true then kills=kills+1 v.speed=v.speed+1 repeat v.x=lelx() v.y=lely() until(v.x~=display.contentWidth/2 or v.y~=display.contentHeight/2) end end end if life==1 then -- Add 1st Ghost ghosts[life]=newGhost(dt) life=life+1 end local function addLife(event) -- Add ghosts every 15 seconds ghosts[life]=newGhost(dt) life=life+1 end local function addScore(event) -- Add 1 score point every second score=score+1 end local function keep(event) -- Movement of the guy and wall collision if ran == true and distance(guy.x,guy.y)\<display.contentWidth\*0.428 then guy.x=guy.x+math.cos(math.rad(guy.rotation))\*7 guy.y=guy.y+math.sin(math.rad(guy.rotation))\*7 end if distance(guy.x,guy.y)\>=display.contentWidth\*0.428 then ran=false guy.x=guy.x-math.cos(math.rad(guy.rotation))\*7 guy.y=guy.y-math.sin(math.rad(guy.rotation))\*7 end if distance(guy.x,guy.y)\>=display.contentWidth\*0.429 then guy.x=guy.x+math.cos(math.rad(guy.rotation))\*20 guy.y=guy.y+math.sin(math.rad(guy.rotation))\*20 end end local function movin(event) -- Rotation of the guy moveButton.x,moveButton.y=guy.x,guy.y display.getCurrentStage():setFocus(event.target) if event.y \> guy.y and event.x \> guy.x then guy.rotation=math.deg(math.atan((event.y-guy.y)/(event.x-guy.x))) ran=true elseif event.y \> guy.y and event.x \< guy.x then guy.rotation=180+ math.deg(math.atan((event.y-guy.y)/(event.x-guy.x))) ran=true elseif event.y \< guy.y and event.x \< guy.x then guy.rotation=180+math.deg(math.atan((event.y-guy.y)/(event.x-guy.x))) ran=true elseif event.y \< guy.y and event.x \> guy.x then guy.rotation=math.deg(math.atan((event.y-guy.y)/(event.x-guy.x))) ran=true elseif event.y == guy.y and event.x \> guy.x then guy.rotation=0 guy.x=guy.x+3 elseif event.y == guy.y and event.x \< guy.x then guy.rotation=180 guy.x=guy.x-3 elseif event.y \< guy.y and event.x == guy.x then guy.rotation=270 guy.y=guy.y-3 else guy.rotation=270 guy.y=guy.y+3 end if event.phase=="ended" or event.phase == "cancelled" then ran=false display.getCurrentStage():setFocus(nil) end return true end Runtime:addEventListener("enterFrame", keep) -- Updates movement and wall collision moveButton:addEventListener("touch", movin) -- Updates rotation when moveButton is touched (also allowing movement) Runtime:addEventListener("enterFrame", chaseGuy) -- Updates ghosts position Runtime:addEventListener("enterFrame", ghostGuyColli) -- Updates for a game over Runtime:addEventListener("enterFrame", ghostKiller) -- Updates ghostkillah timer.performWithDelay(15000,addLife,-1) -- Add ghosts every 15 seconds timer.performWithDelay(1000,addScore,-1) -- Add score every second
I know there’s probably a lot of stuff that’s bad or probably you would do in another way, im still learning so im open to any advice you could give me.
Thanks again and excuse my english.
By the way, i already tried breaking it into pieces and placing it where i think it would be ok, and got one error after another (problems with runtime, problems when doing the group:insert(x) getting some sort of message about tables and doing . instead of :, problems not beeing able to call some variables, etc), thats what frustrates me the most.
I also tried placing everything just like that inside function scene:createScene( event ), and it worked but i wasnt able to remove the objects when i went to the next scene, and if i tried to insert them in the group to remove them i would get more errors.
And when i gave up I even tried to move from one menu to another by just using flags, wich resulted in a lot of nested code and overlapping stuff aswell.
Sorry for the wall of text, i really dont know what to do and dont want to give up on this project beeing so close to finish it u.u
tl:dr = i really dont know how to fuse my already made game with the Storyboard template without breaking everything