특이하게 생긴 벽돌 깨기 게임이 재미있어서 벽돌깨기 게임은 어떻게 만들면 될까 고민 해봤습니다.
- 깨지기 위한 블럭이 있는데 그건 stage load 처럼 map 마다 다르게 구현합니다. (아마도 block 특성에에 따라 draw 객체를 따로 생성해야 합니다.)
- 공이 있고 공은 시작뒤에는 특정 방향으로 움직이는데 이건 물리 library를 이용합니다.
- 부딧히면 점수가 갂이거나 각도가 변하도록 합니다.
- 아래 bar가 있는데 이건 사용자가 조정할 수 있도록 하고 공과 부딧힐때 어디쯤 부딧쳤느냐에 따라 튕겨나가는 각도를 다르게 처리합니다.
여기까지가 제가 생각해 본 것이고,
인터넷 검색해보니 이미 구현된 소스도 존재해서, 구현된 소스를 분석해서 설명 하도록 하겠습니다.
투토리얼의 내용은 아래 링크 참고하고
https://coronalabs.com/blog/2011/06/07/tutorial-create-a-breakout-game-in-corona-sdk/
소스는 https://github.com/ansca/breakout GIT여기에서 받을 수 있습니다.
확인해보니까 소스가 오래된 소스라 제대로 동작되지 않아서 약간 수정하였습니다.
표현하는 좌표계에 문제가 있어서, 아래와 같이 anchorX =0, anchorY =0 추가 하였습니다.
local paddle = display.newRect( display.contentWidth / 2 - paddleWidth / 2, display.contentHeight - 50, paddleWidth, paddleHeight )
=>
local paddle = display.newRect( display.contentWidth / 2 - paddleWidth / 2, display.contentHeight - 50, paddleWidth, paddleHeight )
paddle.anchorX = 0
paddle.anchorY = 0
여기서 부터는 설명 들어갑니다.
function main() setUpPhysics() -- 물리 library를 사용 createWalls() -- 벽을 만들어 공이 벽에 부딧힘을 감지 1 createBricks() -- 벽을 만듦 2 createBall() -- 공을 만듦 createPaddle() -- 아래쪽 패들 만듦 startGame() -- 게임 시작 end
- 물리 library를 사용
물리 library setup에서 아래와 같은 값을 사용하는데
physics.setGravity( 0, 0 )
블럭 깨기라서 중력 가속도 값은 없습니다. (0,0)
기본값은 (0,9.8) 입니다.
https://docs.coronalabs.com/api/library/physics/setGravity.html
-
벽을 만들기 1
아래와 같은 형태로 만듧니다.
local wall = display.newRect( 0, 0, wallThickness, display.contentHeight )
wall.anchorX = 0
wall.anchorY = 0
physics.addBody(wall, "static", {friction=0, bounce = 1})
-
벽을 만들기 2
아래와 같은 형태로 만듧니다.
특정 위치에 numOfRows * numOfCols 개의 깨질 수 있는 벽을 만듧니다. type을 destructible을 넣습니다.
for row = 0, numOfRows - 1 do
for col = 0, numOfCols - 1 do
-- Create a brick
local brick = display.newRect( topLeft.x + (col * brickWidth), topLeft.y + (row * brickHeight), brickWidth, brickHeight )
brick:setFillColor(math.random(50, 255), math.random(50, 255), math.random(50, 255), 255)
brick.type = "destructible"
physics.addBody(brick, "static", {friction=0, bounce = 1})
end
end
- 공을 만듦
공에만 충돌 처리 루틴을 넣습니다.
아래쪽 벽에 부딧치면 onTimerComplete 함수가 호출되면서 게임을 새로 시작합니다.
destructible 종류의 벽에 부딧치면 벽돌이 사라집니다. event.other:removeSelf()
나머지 벽들은 일반 static 벽들로서 물리작용이 일어나게 됩니다.
즉, ball은 dynamic이고 벽돌은 static으로 부딧히면 dynamic인 물체만 움직이게 됩니다.
- 아래쪽 패들 만듦
static 물체를 만들고 touch 이벤트를 등록해서 움직이도록 해줍니다.
- 게임시작
공을 움직이게 합니다.
공의 x,y의 속도를 설정하면 됩니다.
ball:setLinearVelocity(75, 150)
- 위 소스에서 안되는것
패들을 이용해서 공이 나가는 위치를 조절하는데 그 부분이 안됩니다. (즉 모서리 부분 맞출때 다른 방향으로 나가는 부분을 말합니다.)
아래는 전체 소스 입니다.
-------------------------------------------------------------
-------------------------------------------------------------------------------- -- -- Sample code is MIT licensed, see http://developer.anscamobile.com/code/license -- Copyright (C) 2011 Ansca Inc. All Rights Reserved. -------------------------------------------------------------------------------- require ("physics") function main() setUpPhysics() createWalls() createBricks() createBall() createPaddle() startGame() end function setUpPhysics() physics.start() -- physics.setDrawMode("hybrid") physics.setGravity(0,0) end function createPaddle() local paddleWidth = 100 local paddleHeight = 10 local paddle = display.newRect( display.contentWidth / 2 - paddleWidth / 2, display.contentHeight - 50, paddleWidth, paddleHeight ) paddle.anchorX = 0 paddle.anchorY = 0 physics.addBody(paddle, "static", {friction=0, bounce=1}) local movePaddle = function(event) paddle.x = event.x end Runtime:addEventListener("touch", movePaddle) end function createBall() local ballRadius = 10 ball = display.newCircle( display.contentWidth / 2, display.contentHeight / 2, ballRadius ) ball.anchorX = 0 ball.anchorY = 0 physics.addBody(ball, "dynamic", {friction=0, bounce = 1, radius=ballRadius}) ball.collision = function(self, event) if(event.phase == "ended") then if(event.other.type == "destructible") then event.other:removeSelf() end if(event.other.type == "bottomWall") then self:removeSelf() local onTimerComplete = function(event) createBall() startGame() end timer.performWithDelay(500, onTimerComplete , 1) end end end ball:addEventListener("collision", ball) end function startGame() ball:setLinearVelocity(75, 150) end function createBricks() local brickWidth = 40 local brickHeight = 20 local numOfRows = 4 local numOfCols = 6 local topLeft = {x= display.contentWidth / 2 - (brickWidth * numOfCols ) / 2, y= 50} local row local col for row = 0, numOfRows - 1 do for col = 0, numOfCols - 1 do -- Create a brick local brick = display.newRect( topLeft.x + (col * brickWidth), topLeft.y + (row * brickHeight), brickWidth, brickHeight ) brick:setFillColor(math.random(50, 255), math.random(50, 255), math.random(50, 255), 255) brick.type = "destructible" physics.addBody(brick, "static", {friction=0, bounce = 1}) end end end function createWalls() local wallThickness = 10 -- Left wall local wall = display.newRect( 0, 0, wallThickness, display.contentHeight ) wall.anchorX = 0 wall.anchorY = 0 physics.addBody(wall, "static", {friction=0, bounce = 1}) -- Top wall wall = display.newRect(0,0, display.contentWidth, wallThickness) wall.anchorX = 0 wall.anchorY = 0 physics.addBody(wall, "static", {friction=0, bounce = 1}) -- Right wall wall = display.newRect(display.contentWidth - wallThickness, 0, wallThickness, display.contentHeight) wall.anchorX = 0 wall.anchorY = 0 physics.addBody(wall, "static", {friction=0, bounce = 1}) -- Bottom wall wall = display.newRect(0, display.contentHeight - wallThickness, display.contentWidth, wallThickness) wall.anchorX = 0 wall.anchorY = 0 physics.addBody(wall, "static", {friction=0, bounce = 1}) wall.type = "bottomWall" end main()
댓글 없음:
댓글 쓰기