지난번에 이어 주인공을 생성하고 이동하도록 하겠습니다.
일단 dpad를 만들고 move 터치 이벤트 리스너를 등록합니다.
Dpad:addEventListener("touch", move)
그리고 move 함수는 누른 위치에 따라 player.thismovement 변수에 각도값이 들어갑니다. 여기에서는 0,90,180,270이 들어갑니다.
해당소스는 mte sample코드에서 가져왔습니다.
local function move( event ) print("move") if event.phase == "began" then display.getCurrentStage():setFocus(event.target, event.id) event.target.isFocus = true end if event.phase == "began" or event.phase == "moved" then local dirX = event.x - event.target.x local dirY = event.y - event.target.y local angle = math.deg(math.atan(dirY/dirX)) if dirX < 0 then angle = 90 + (90 - (angle * -1)) end angle = angle + 90 angle = math.round(angle / 90) * 90 if angle == 360 then angle = 0 end if angle % 90 ~= 0 then player.thismovement = nil else player.thismovement = tostring(angle) end elseif event.phase == "ended" or event.phase == "cancelled" then player.thismovement = nil display.getCurrentStage():setFocus( event.target, nil ) event.target.isFocus = false end return true end
주인공의 이동은 gameloop에서 이루어집니다. 실제 이동은 mte.moveSpriteTo 함수를 이용하게 되고 이동 가능한지 확인하는 함수는 obstacle 함수를 이용합니다.
local gameLoop = function(event) ... eObject = player if not eObject.isMoving then --MOVE eObject CHARACTER if eObject.thismovement then local result local xTile, yTile xTile, yTile = eObject.locX + atlas[eObject.thismovement][1], eObject.locY + atlas[eObject.thismovement][2] result = obstacle( eObject.level, xTile, yTile ) if( result=="stop" ) then eObject:pause() end if not result then if eObject.sequence ~= eObject.thismovement then eObject:setSequence( eObject.thismovement ) end eObject:play() mte.moveSpriteTo( { sprite = eObject, locX = xTile, locY = yTile, time = eObject.moveTime, transition = easing.linear } ) end else eObject:pause() end end ...
아래는 실행 화면입니다.
전체 소스입니다.
-------------------------------------------------------------------------------- display.setStatusBar(display.HiddenStatusBar) -------------------------------------------------------------------------------- -- TODO -- [o] Move enemy with AI -- [o] Player -- [o] DPAD -- [o] Camera -- [x] Move enemy with AI adv -- [x] Collision -- [x] dig -- [x] score -- [x] level -- [x] main screen -------------------------------------------------------------------------------- -- Localize -------------------------------------------------------------------------------- local mte = require('mte').createMTE() --Load and instantiate MTE. local physics = require ("physics") local LD = require("lib.LD_LoaderG2") system.activate( "multitouch" ) local myLevel = {} local math_ceil = math.ceil local math_abs = math.abs local math_random = math.random local table_insert = table.insert local map local player = {} local dir = 0 local drill = false local gravity = 1 local speed = 60 local printMemUsageCount = 0 local usePhysics = false local TileSize = 32 local enemyProperty = {} enemyProperty["red"] = {} enemyProperty["red"].enemyMoveTime = 300 enemyProperty["red"].chanceChangeDir = 0 -- 움직이면서 방향전환할 확률 0 전환하지 않음 enemyProperty["green"] = {} enemyProperty["green"].enemyMoveTime = 300 enemyProperty["green"].chanceChangeDir = 50 -- 움직이면서 방향전환할 확률 0 전환하지 않음 local enemyTable = {} local enemySize = 0; local atlas = {} atlas["0"] = {0, -1} atlas["90"] = {1, 0} atlas["180"] = {0, 1} atlas["270"] = {-1, 0} atlas["360"] = {0, -1} math.randomseed( os.time() ) -------------------------------------------------------------------------------- -- Functions -------------------------------------------------------------------------------- local distanceBetween = function(x1, y1, x2, y2) return (((x2 - x1) ^ 2) + ((y2 - y1) ^ 2)) ^ 0.5 end local getPointsAlongLine = function(x1, y1, x2, y2, d) local points = {} local diffX = x2 - x1 local diffY = y2 - y1 local distBetween = math_ceil(distanceBetween(x1, y1, x2, y2) / d) local x, y = x1, y1 local addX, addY = diffX / distBetween, diffY / distBetween for i = 1, distBetween do table_insert(points, {x, y}) x, y = x + addX, y + addY end return points end local clamp = function(v, l, h) return (v < l and l) or (v > h and h) or v end -------------------------------------------------------------------------------- -- Physics -------------------------------------------------------------------------------- if usePhysics then physics.start() physics.setGravity(0, 9.8) mte.enableBox2DPhysics() end -------------------------------------------------------------------------------- -- Load Map -------------------------------------------------------------------------------- mte.loadMap("resource/hitnrun.tmx") --Load a map. myLevel = LD:loadLevel("LoadRes") -------------------------------------------------------------------------------- -- Physics -------------------------------------------------------------------------------- --physics.setDrawMode( "hybrid" ) -------------------------------------------------------------------------------- -- SETUP D-PAD -------------------------------------------------------------------------------- local controlGroup = display.newGroup() local Dpad = display.newImageRect(controlGroup, "resource/ui_dpad.png", 256, 256) Dpad.x = 120 Dpad.y = display.viewableContentHeight - 120 Dpad:toFront() -------------------------------------------------------------------------------- -- Engine dependency code -------------------------------------------------------------------------------- ------------------------------------ local function spawnObject(pname,px,py,passetName,physicsTrue) ------------------------------------ local function mteSpriteSetup(object,pname,px,py) local setup = { kind = "sprite", layer = mte.getSpriteLayer(1), levelPosX = px, levelPosY = py, name = pname, level = 1 } mte.addSprite(object, setup) end local objProps = { name = pname, x = px, y = py, xScale = 1, yScale = 1, assetName = passetName, } -- For LD -- createObject param nil need not remove object. -- That is changed. local object = myLevel:createObject(nil, objProps).view -- For Map Engine mteSpriteSetup(object,pname,px,py); if usePhysics then if( physicsTrue ~= nil ) then if( physicsTrue == true ) then physics.addBody(object, "dynamic", { density=10.0, friction=0.1, bounce=0.1 }) object.isFixedRotation = true end end end return object end local function removeObject(displayObject) -- body mte.removeSprite(displayObject, true) -- For Dust map.layer["Object Layer 1"]:remove(displayObject) end local function getTileInfo( screenX, screenY, layer ) local loc = mte.convert("levelPosToLoc", screenX, screenY, layer) print("Tile Loc",loc.x, loc.y) local tile = mte.getTileObj(loc.x, loc.y, layer) -- For Dust --map.layer["Tile Layer 1"].tileByPixels(screenX, screenY) return tile end local function engineLoop(track) -- For MTE --mte.setCamera({sprite = track, scale = 1}) mte.update() --Required to process the camera and display the map. mte.debug() --Displays onscreen position/fps/memory text. -- For Dust --map.updateView() end local function getTileId(tile) local id = tile.index return id end local function getTileXY(tile) local x = tile.locX local y = tile.locY return x , y end local function removeTile( tileX, tileY ) mte.updateTile({locX = tileX, locY = tileY, layer = 1, tile = 0}) -- For Dust --map.layer["Tile Layer 1"].lockTileErased(tile.tileX, tile.tileY) end local function setCamera(track) mte.constrainCamera({}) mte.setCamera({sprite = track, scale = 1}) mte.setCameraFocus(track) -- For Dust map.setCameraFocus(track,true,true) end local function setLocalCamera() local mapObj = mte.setCamera({locX = 15, locY = 15, scale = 1}) end --DETECT OBSTACLES ------------------------------------------------------------ local obstacle = function(level, locX, locY) local detect = mte.getTileProperties({level = level, locX = locX, locY = locY}) for i = 1, #detect, 1 do if detect[i].properties then if detect[i].properties.solid and i == 2 then detect = "stop" return detect end end end end -------------------------------------------------------------------------------- -- Engine dependency code END -------------------------------------------------------------------------------- ------------------------------------ local monitorMem = function() ------------------------------------ collectgarbage() print( "MemUsage: " .. collectgarbage("count") ) local textMem = system.getInfo( "textureMemoryUsed" ) / 1000000 print( "TexMem: " .. textMem ) end local function move( event ) print("move") if event.phase == "began" then display.getCurrentStage():setFocus(event.target, event.id) event.target.isFocus = true end if event.phase == "began" or event.phase == "moved" then local dirX = event.x - event.target.x local dirY = event.y - event.target.y local angle = math.deg(math.atan(dirY/dirX)) if dirX < 0 then angle = 90 + (90 - (angle * -1)) end angle = angle + 90 angle = math.round(angle / 90) * 90 if angle == 360 then angle = 0 end if angle % 90 ~= 0 then player.thismovement = nil else player.thismovement = tostring(angle) end elseif event.phase == "ended" or event.phase == "cancelled" then player.thismovement = nil display.getCurrentStage():setFocus( event.target, nil ) event.target.isFocus = false end return true end ------------------------------------ ------------------------------------ ------------------------------------ ------------------------------------ local gameLoop = function(event) ------------------------------------ ------------------------------------ ------------------------------------ ------------------------------------ local eObject local inputDir for i=1, enemySize-1 do eObject = enemyTable[i] inputDir = tonumber(eObject.thismovement)%360 if not eObject.isMoving then if math_random(100) < enemyProperty[eObject.enemyType].chanceChangeDir then if math_random(4)<=2 then eObject.thismovement = tostring((tonumber(eObject.thismovement)+90+(math_random(2)-1)*180)%360) end end --MOVE eObject CHARACTER if eObject.thismovement then local result local xTile, yTile for i=1,4 do xTile, yTile = eObject.locX + atlas[eObject.thismovement][1], eObject.locY + atlas[eObject.thismovement][2] result = obstacle( eObject.level, xTile, yTile ) if( result ~= "stop" ) then break end eObject.thismovement = tostring(math_random(4)*90) if( inputDir%180 == tonumber(eObject.thismovement)%180 ) then eObject.thismovement = tostring(math_random(4)*90) if( inputDir%180 == tonumber(eObject.thismovement)%180 ) then eObject.thismovement = tostring(math_random(4)*90) if( inputDir%180 == tonumber(eObject.thismovement)%180 ) then eObject.thismovement = tostring(math_random(4)*90) end end end end if not result then if eObject.sequence ~= eObject.thismovement then eObject:setSequence( eObject.thismovement ) end eObject:play() mte.moveSpriteTo( { sprite = eObject, locX = xTile, locY = yTile, time = enemyProperty[eObject.enemyType].enemyMoveTime, transition = easing.linear } ) end else eObject:pause() end end end eObject = player if not eObject.isMoving then --MOVE eObject CHARACTER if eObject.thismovement then local result local xTile, yTile xTile, yTile = eObject.locX + atlas[eObject.thismovement][1], eObject.locY + atlas[eObject.thismovement][2] result = obstacle( eObject.level, xTile, yTile ) if( result=="stop" ) then eObject:pause() end if not result then if eObject.sequence ~= eObject.thismovement then eObject:setSequence( eObject.thismovement ) end eObject:play() mte.moveSpriteTo( { sprite = eObject, locX = xTile, locY = yTile, time = eObject.moveTime, transition = easing.linear } ) end else eObject:pause() end end engineLoop(player) printMemUsageCount = printMemUsageCount + 1; if( printMemUsageCount > 100 ) then printMemUsageCount = 0 --monitorMem() end end local function spawnEnemyNPlayerObject() enemyTable = {} enemySize = 1; local objects = mte.getObject({}) for key,value in pairs(objects) do --print(value.name, value.type, value.x, value.y, value.properties) if( value.type=="red" )then local enemy = spawnObject("red",value.x+TileSize/2,value.y+TileSize/2,"enemy_32_1_red.png") enemy:setSequence("move") enemy:play() enemy.enemyType = "red" enemy.thismovement = tostring(math_random(4)*90) enemyTable[enemySize] = enemy; enemySize=enemySize+1 end if( value.type=="green" )then local enemy = spawnObject("green",value.x+TileSize/2,value.y+TileSize/2,"enemy_32_1.png") enemy:setSequence("move") enemy:play() enemy.enemyType = "green" enemy.thismovement = tostring(math_random(4)*90) enemyTable[enemySize] = enemy; enemySize=enemySize+1 end if( value.type=="player" )then player = spawnObject("player",value.x+TileSize/2,value.y+TileSize/2,"player32_1.png") player.moveTime = 300 player:setSequence("180") player:play() end end end ------------------------------------ local function spawnPlayerObject() ------------------------------------ end -------------------------------------------------------------------------------- spawnEnemyNPlayerObject() setCamera(player) Runtime:addEventListener("enterFrame", gameLoop) Dpad:addEventListener("touch", move)
소스 링크
https://drive.google.com/file/d/0B9vAKDzHthQIeFlpMmt4aDhZOWc/view?usp=sharing
댓글 없음:
댓글 쓰기