* 해야할 것 *
시작처리
종료처리
이미지 사용할 것:http://m484games.ucoz.com/index/shoot_39_em_up_gfx/0-38
참고 소스:http://www.tandgapps.co.uk/resources/tutorial-space-shooter-in-240-lines/
시작처리,종료처리
전체적으로 스토리 보드로 만듭니다.
지금까지 모든 소스입니다.
호출관계는 아래와 같습니다.
main.lua -> start.lua -> game.lua -> restart.lua -> game.lua -> restart.lua ....
main.lua
starfield를 만들고 start storyboard를 시작합니다.
display.setStatusBar( display.HiddenStatusBar ) bgGroup = display.newGroup() g_score = 0 local storyboard = require "storyboard" local _W = display.contentWidth local _H = display.contentHeight local function loadBGImg() stars1 = display.newImageRect("star1_480_800.png", 480, 800) stars1.x = _W*0.5; stars1.y = _H*0.5 bgGroup:insert(stars1) stars2 = display.newImageRect("star2_480_800.png", 480, 800) stars2.x = _W*0.5; stars2.y = _H*0.5-800 bgGroup:insert(stars2) end function moveStarField() --Move the starfields. stars1:translate(0,2) stars2:translate(0,2) if stars1.y >= (_H*0.5)+800 then stars1.y = (_H*0.5)-800 end if stars2.y >= (_H*0.5)+800 then stars2.y = (_H*0.5)-800 end end function gameLoop(event) moveStarField() end loadBGImg() Runtime:addEventListener("enterFrame", gameLoop) storyboard.gotoScene( "start" )
start.lua
로고를 화면에 출력하고 시작 버튼을 활성화 시킵니다.
local storyboard = require ("storyboard") local scene = storyboard.newScene() local _W = display.contentWidth local _H = display.contentHeight ------------------------------------------------------- local imgGameStart local imgTitle local function startGame(event) if event.phase == "ended" then storyboard.gotoScene("game") end end ------------------------------------------------------- function scene:createScene(event) local screenGroup = self.view imgTitle = display.newImageRect("starfield.png",240,45) imgTitle.anchorX = 0.5 imgTitle.anchorY = 0.5 imgTitle.x = display.contentCenterX imgTitle.y = display.contentHeight*0.2 screenGroup:insert(imgTitle) imgGameStart = display.newImageRect("gamestart.png",240,45) imgGameStart.anchorX = 0.5 imgGameStart.anchorY = 0.5 imgGameStart.x = display.contentCenterX imgGameStart.y = display.contentHeight*0.8 screenGroup:insert(imgGameStart) end function scene:enterScene(event) imgGameStart:addEventListener("touch", startGame) end function scene:exitScene(event) imgGameStart:removeEventListener("touch", startGame) end function scene:destroyScene(event) end scene:addEventListener("createScene", scene) scene:addEventListener("enterScene", scene) scene:addEventListener("exitScene", scene) scene:addEventListener("destroyScene", scene) return scene
game.lua
지금까지 대부분의 내용이 들어가 있습니다.
주인공 움직임 부분이 transition.to에서 바뀌었습니다. transition으로 하게되면 동작이 부자연스러운 현상이 벌어집니다.
local storyboard = require ("storyboard") local scene = storyboard.newScene() local physics = require ("physics") --Require physics physics.start(); physics.setGravity( 0, 0 ) --Start physics ----------------------------------------------- --*** Set up our variables and group *** ----------------------------------------------- local enemyGroup = display.newGroup() local weaponGroup = display.newGroup() local expGroup = display.newGroup() local playerGroup = display.newGroup() local fgGroup = display.newGroup() local _W = display.contentWidth local _H = display.contentHeight local stars1, stars2 --Background moving stars local spawnInt = 0 --Gameloop spawn control local spawnIntMax = 30 --Gameloop max spawn local spawned = 0 --Keep track of enemies local spawnedMax = 10 --Max allowed per level local enemySpeed = 7 --How fast the enemies are local wave = 1 local ship local gameIsActive = true local fireTimer local sheetExp g_score = 0 local goto_x=-1;goto_y=-1 local function loadImgs() local sheetOptions = { width = 20, height = 20, numFrames = 6 } sheetExp = graphics.newImageSheet( "exp_20_20_6.png", sheetOptions ) end local function loadTexts() scoreText = display.newText("Score: "..g_score, 0,0,"Helvetica",18) scoreText:setTextColor(220, 0, 0) scoreText.x = _W*0.5; scoreText.y = 10 fgGroup:insert(scoreText) levelText = display.newText("Level: "..wave, 0,0,"Helvetica",18) levelText:setTextColor(220, 0, 0) levelText.x = _W*0.5; levelText.y = scoreText.y + 20 fgGroup:insert(levelText) end local function moveShip( event ) local phase = event.phase if gameIsActive == false then return end print(event.x,event.y,phase) goto_x = event.x goto_y = event.y -- if( event.x > ship.x ) then -- transition.cancel( ship ) -- transition.to( ship, {time = (event.x-ship.x)/0.2, x = event.x} ) -- t = d/k -- end -- if( event.x < ship.x ) then -- transition.cancel( ship ) -- transition.to( ship, {time = -(event.x-ship.x)/0.2, x = event.x} ) -- t = d/k -- end end local function registerMoveShip() Runtime:addEventListener("touch", moveShip) end local function loadPlayer() ship = display.newImageRect("my.png", 20, 20) ship.x = _W*0.5; ship.y = _H+30; ship.name = "ship" physics.addBody( ship, { isSensor = true } ) playerGroup:insert(ship) transition.to(ship, {time = 600, y = _H-_H*0.1, onComplete=registerMoveShip}) end local function loadBullet() local function fireNow() local bullet = display.newImageRect( "bullet.png", 10, 15 ) bullet.x = ship.x-5; bullet.y = ship.y-5; bullet.name = "laser" physics.addBody( bullet, { isSensor = true } ) weaponGroup:insert( bullet ) local bullet = display.newImageRect( "bullet.png", 10, 15 ) bullet.x = ship.x +5; bullet.y = ship.y-5; bullet.name = "laser" physics.addBody( bullet, { isSensor = true } ) weaponGroup:insert( bullet ) end fireTimer = timer.performWithDelay(850, fireNow, 0) end local function moveWeapon() --Move our lasers up each frame! for i = weaponGroup.numChildren,1,-1 do local weapon = weaponGroup[i] if weapon ~= nil and weapon.y ~= nil then weapon:translate(0, -10); end end end local function loadBlocker() local laserBlock = display.newRect(0,-80,_W,2) laserBlock.anchorX = 0;laserBlock.anchorY = 0; laserBlock.name = "blocker" physics.addBody( laserBlock, { isSensor = true } ) bgGroup:insert(laserBlock) local shipBlock = display.newRect(0,_H+_H*0.2,_W,2) shipBlock.anchorX = 0;shipBlock.anchorY = 0; shipBlock.name = "blocker" physics.addBody( shipBlock, { isSensor = true } ) bgGroup:insert(shipBlock) end local function spawnEnemy() local imageInt = math.random(1,3) local enemy = display.newImageRect("ship_"..imageInt.."_20_20.png",20,20) enemy.x = math.random( 20, _W-20 ); enemy.y = -30; enemy.rotation = 90 enemy.name = "enemy"; physics.addBody( enemy, { isSensor = true } ) enemyGroup:insert( enemy ) if spawned == spawnedMax then wave = wave + 1 --Increase the wave. if wave <= 18 then --Limit max speed/spawn enemySpeed = enemySpeed + 1 spawnIntMax = math.round(spawnIntMax * 0.9) end spawned = 0 --Reset so that the next wave starts from 0 end spawnInt = 0 end local function checkNSpawnEnemy() --Increase the int until it spawns an enemy.. spawnInt = spawnInt + 1 --change spawnIntMax if you want enemies to spawn --faster or slower. if spawnInt == spawnIntMax then spawnEnemy() spawned = spawned + 1 end end local function moveEnemy() --Move the enemies down each frame! local i for i = enemyGroup.numChildren,1,-1 do local enemy = enemyGroup[i] if enemy ~= nil and enemy.y ~= nil then enemy:translate( 0, enemySpeed) end end end local function updateTexts() scoreText.text = "Score: "..g_score levelText.text = "Level: "..wave end local function movePlayer() if( goto_x < 0 or gameIsActive == false ) then return end if( ship.x > goto_x ) then ship.x = ship.x - 5 end if( ship.x < goto_x ) then ship.x = ship.x + 5 end end local function gameLoop(event) checkNSpawnEnemy() moveStarField() moveEnemy() moveWeapon() movePlayer() updateTexts() end local function gotoRestart() storyboard.gotoScene("restart") end local function gameOver() gameIsActive = false if( fireTimer ~= nil ) then timer.cancel(fireTimer) fireTimer = nil end timer.performWithDelay(1000, gotoRestart, 1) end local function makeExp(x,y) local function expListener( event ) local thisSprite = event.target -- "event.target" references the sprite if ( event.phase == "ended" ) then thisSprite:removeSelf(); thisSprite = nil end end local sequencesExp = { { name = "exp", start = 1, count = 6, time = 200, loopCount = 1, loopDirection = "forward" } } local exp = display.newSprite( sheetExp, sequencesExp ) exp.x = x; exp.y = y exp:play() exp:addEventListener( "sprite", expListener ) expGroup:insert( exp ) print(expGroup.numChildren) end local function onCollision(event) if event.phase == "began" then local obj1 = event.object1; local obj2 = event.object2; if obj1.name == "laser" and obj2.name == "enemy" or obj1.name == "enemy" and obj2.name == "laser" then if( obj2.name =="enemy") then makeExp(obj2.x,obj2.y) else makeExp(obj1.x,obj1.y) end display.remove( obj1 ); obj1 = nil display.remove( obj2 ); obj2 = nil g_score = g_score + 100 --Yay points! elseif obj1.name == "ship" and obj2.name == "enemy" or obj2.name == "ship" and obj1.name == "enemy" then makeExp(obj2.x,obj2.y) makeExp(obj1.x,obj1.y) display.remove( obj1 ); obj1 = nil display.remove( obj2 ); obj2 = nil gameOver()--Weve died so call gameover... elseif obj1.name == "enemy" and obj2.name == "blocker" or obj2.name == "enemy" and obj1.name == "blocker"then if obj1.name == "enemy" then display.remove(obj1); obj1 = nil elseif obj2.name == "enemy" then display.remove( obj2 ); obj2 = nil end elseif obj1.name == "laser" and obj2.name == "blocker" or obj2.name == "laser" and obj1.name == "blocker"then if obj1.name == "laser" then display.remove(obj1); obj1 = nil elseif obj2.name == "laser" then display.remove( obj2 ); obj2 = nil end end end end local function setup() loadTexts() loadImgs() loadBlocker() loadPlayer() loadBullet() end -------------------------------------------------------------------- function scene:createScene(event) storyboard.removeScene("start") storyboard.removeScene("restart") local screenGroup = self.view setup() end function scene:enterScene(event) Runtime:addEventListener("enterFrame", gameLoop) Runtime:addEventListener("collision", onCollision ) end function scene:exitScene(event) display.remove( enemyGroup ) ; enemyGroup = nil display.remove( weaponGroup ) ; weaponGroup = nil display.remove( expGroup ) ; expGroup = nil display.remove( playerGroup ) ; playerGroup = nil display.remove( fgGroup ) ; fgGroup = nil Runtime:removeEventListener("enterFrame", gameLoop) Runtime:removeEventListener("collision", onCollision ) Runtime:removeEventListener("touch", moveShip) end function scene:destroyScene(event) end scene:addEventListener("createScene", scene) scene:addEventListener("enterScene", scene) scene:addEventListener("exitScene", scene) scene:addEventListener("destroyScene", scene) return scene
restart.lua
local storyboard = require ("storyboard") local scene = storyboard.newScene() local score = require( "score" ) local _W = display.contentWidth local _H = display.contentHeight -- background local function startGame(event) if event.phase == "ended" then storyboard.gotoScene("game") end end function showStart() scoreTextTransition = transition.to(scoreText,{time=600, alpha=1}) bestTextTransition = transition.to(bestText,{time=600, alpha=1}) imgGameStartTransition = transition.to(imgGameStart,{time=600, alpha=1}) end function removeStart() transition.cancel(scoreTextTransition) transition.cancel(bestTextTransition) transition.cancel(imgGameStartTransition) end function loadScore() score.init() local prevScore = score.load() if prevScore ~= nil then if prevScore <= g_score then score.set(g_score) score.save() else score.set(prevScore) end else score.set(g_score) score.save() end return score.get() end --------------------------------------------------------------- function scene:createScene(event) local screenGroup = self.view scoreText = display.newText("SCORE:"..g_score,display.contentCenterX, display.contentCenterY-80, native.systemFont, 20) scoreText:setFillColor(100,200,0) scoreText.alpha = 0 --scoreText.x = _W*0.5; scoreText.y = 10 screenGroup:insert(scoreText) bestText = display.newText("HI-SCORE:"..loadScore(),display.contentCenterX, display.contentCenterY-40, native.systemFont, 20) bestText:setFillColor(100,200,0) bestText.alpha = 0 screenGroup:insert(bestText) imgGameStart = display.newImageRect("gamestart.png",240,45) imgGameStart.anchorX = 0.5 imgGameStart.anchorY = 0.5 imgGameStart.x = display.contentCenterX imgGameStart.y = display.contentHeight*0.8 imgGameStart.alpha = 0 screenGroup:insert(imgGameStart) end function scene:enterScene(event) storyboard.removeScene("game") imgGameStart:addEventListener("touch", startGame) showStart() end function scene:exitScene(event) imgGameStart:removeEventListener("touch", startGame) removeStart() end function scene:destroyScene(event) end scene:addEventListener("createScene", scene) scene:addEventListener("enterScene", scene) scene:addEventListener("exitScene", scene) scene:addEventListener("destroyScene", scene) return scene
score.lua
hiscore를 파일에 저장하는 모듈입니다.
-- Score Module -- local M = {} -- create our local M = {} M.score = 0 function M.init( options ) M.filename = "scorefile.txt" end function M.set( value ) M.score = value end function M.get() return M.score end function M.add( amount ) M.score = M.score + amount end function M.save() local path = system.pathForFile( M.filename, system.DocumentsDirectory) local file = io.open(path, "w") if file then local contents = tostring( M.score ) file:write( contents ) io.close( file ) return true else print("Error: could not read ", M.filename, ".") return false end end function M.load() local path = system.pathForFile( M.filename, system.DocumentsDirectory) local contents = "" local file = io.open( path, "r" ) if file then -- read all contents of file into a string local contents = file:read( "*a" ) local score = tonumber(contents); io.close( file ) return score end print("Could not read scores from ", M.filename, ".") return nil end return M
전체소스입니다.
https://drive.google.com/file/d/0B9vAKDzHthQIeHY3M25qTGNMWUU/view?usp=sharing
댓글 없음:
댓글 쓰기