✨개요
게임개발동아리에서 약 3~4주간 Lua
언어와 Solar 2D
사용법을 학습하였다.
점검 차원으로 그동안 학습한 내용들을 토대로 자신만의 미니게임을 만들어 보는 시간을 가졌다.
나는 쥬니버 플래시게임에서 흔히 볼 수 있는 날아다니는 장애물 피하기 + 떨어지는 아이템 수집 형식을 골랐다.
✨프로젝트 기간
2019.01.03~2019.01.19
✨플레이 영상
실패 영상으로 촬영하였다.
✨구현 내용 및 코드
좌우 화살표(◀, ▶) 버튼을 클릭하여 캐릭터를 움직인다.
벽을 맞고 튕겨다니는 가시열매에 맞으면 점수가 20점 깎이고,
캐릭터가 하늘에서 떨어지는 사과를 받으면 100점이 추가된다.
제한 시간(1분) 내에 1500점 이상을 달성하면 클리어.
가시열매와 사과가 충돌하면 사과는 사라져버리니 주의.
선언부
이 게임을 구현하는 데 가장 중요한 역할을 하는 physics
라이브러리를 호출한다.
physics
물리엔진을 사용하는 객체들은 모두 시뮬레이션 구동 후 자동으로 상호작용 한다.
모든 physics
시뮬레이션을 실행하기 앞서, 반드시 physics.start()
함수를 호출해야 한다.
math.randomseed( os.time() )
local widget = require( "widget" )
local composer = require( "composer" )
local physics = require("physics")
physics.start()
physics.setGravity(0, 9.8*0.75) //중력가속도
local scene = composer.newScene()
local i, j, score = 0, 0, 0
-- GUI
local background
local gameUI = {} //게임에 필요한 UI 오브젝트를 배열에 담아서 사용
//가시열매가 맞고 튕겨나갈 수 있는 벽을 생성하는 함수
function createWalls()
local wallThickness = 10
//Left wall
local wall = display.newRect(0, display.contentHeight/2, wallThickness, display.contentHeight)
physics.addBody(wall, "static", {friction=0, bounce = 1})
//Top wall
wall = display.newRect(display.contentWidth/2, 0, display.contentWidth, wallThickness)
physics.addBody(wall, "static", {friction=1, bounce = 1})
//Right wall
wall = display.newRect(display.contentWidth - wallThickness + 10, display.contentHeight/2, wallThickness, display.contentHeight)
physics.addBody(wall, "static", {friction=1, bounce = 1})
//Bottom wall
wall = display.newRect(display.contentWidth/2, display.contentHeight - wallThickness + 10, display.contentWidth, wallThickness)
physics.addBody(wall, "static", {friction=1, bounce = 1})
// bounce 값이 한 쪽 벽에서만 커지면 가속도가 붙는다 ==> 속도 무한대로 증가!
// 따라서 bounce 값은 4면에서 모두 일정하게 유지
end
CreateApple() 함수
임의의 위치에 사과를 생성하여 드롭한다.
오브젝트 간의 충돌효과 를 위해 physics.addBody
를 적용한다.
사과는 땅으로 가까워질 수록 투명해진다.
사과에 collision
이라는 EventListner
를 추가해주었다. 이제 충돌을 인식할 수 있다.
function createApple() // 새로운 사과 생성
local apple = display.newImageRect("Fruit/나며꾼사과.png", 70, 70)
apple.x, apple.y = player.x + math.floor(math.random(-500, 500)), player.y/8 // 위치는 랜덤
apple.alpha = 1
physics.addBody(apple, "dynamic", {friction = 0, bounce = 1.25})
apple:addEventListener("collision", apple)
// 만약 사과가 플레이어와 충돌(collision)한다면? ==> 점수 획득
apple.collision = function(self, event)
if(event.other.type == "destructible") then
self:removeSelf() // 사과 사라짐
score = score + 100 // 점수 증가
gameUI[7].text = string.format("%05d", score) // 점수를 다섯자리로 표시
end
end
local moveApple = transition.to( apple, { time=2500, alpha=0.2, y=(player.y+500), onComplete = createApple } )
end
local onTimerComplete = function(event)
createApple()
end
Main 함수
플레이어 캐릭터와 장애물(가시열매)를 배치하고, 오브젝트 간의 충돌효과 를 위해 physics.addBody
를 적용한다.
사과와의 collision
이벤트를 관리하기 위해 플레이어 캐릭터에 destructible
타입을 지정해주었다.
이렇게 type
을 지정해주면 오브젝트가 무슨 타입인지 식별하고, 타입별로 다른 액션 을 취할 수 있게 된다.
가시 열매에 collision
이라는 EventListner
를 추가해주었다. 이제 충돌을 인식할 수 있다.
local player = display.newImageRect("Fruit/나며꾼.png", 300*0.6, 480*0.6)
player.x, player.y = display.contentWidth/2-100, display.contentHeight/2+200
player.alpha = 1
physics.addBody(player, "static", {friction = 0, bounce = 1})
player.type = "destructible"
local thorn = display.newImageRect("Fruit/나며꾼가시.png", 90, 90)
thorn.x, thorn.y = player.x+200, player.y/8
thorn.alpha = 1
physics.addBody(thorn, "dynamic", {friction = 0, bounce = 1})
thorn:addEventListener("collision", thorn)
// 만약 플레이어가 가시열매와 충돌한다면?
thorn.collision = function(self, event)
if(event.other.type == "destructible") then
score = score - 20 // 점수 감소
gameUI[7].text = string.format("%05d", score) // 점수를 다섯자리로 표시
end
end
✨소감
아무튼 이런 느낌
좋았던 점
학부생 1학년 과정을 막 마친 수준에서 만들게 된 첫 게임이다. 루아 문법이 간단해서 진입장벽이 높지는 않았다.
이제 겨우 C
문법 기초를 떼고 Java
를 드문드문 배우는 수준이었던지라 API 라는 것 자체에 익숙하지 않았다. 그렇기에 Solar 2D API Reference 사이트를 열심히 뒤져가며 한땀한땀(...) 만든 경험은 굉장히 값지다고 생각한다.
캐릭터와 오브젝트, 시작화면과 결과화면까지 직접 그려서 게임에 적용해보는 과정이 큰 성취감을 느끼게 해주었다.
이 경험을 바탕으로 Unity
게임 제작에도 도전해볼 용기를 얻었다. (하지만 C#
앞에서 처참하게 패배했다.)
아쉬운 점
다시 말하지만 막 Java
를 배운지 얼마 되지 않은 시기에 만든 게임이다. 객체 지향 프로그램을 구현하지 못했던 탓에 Main 스크립트 파일에 모든 기능을 때려넣었고, Main 파일이 불필요하게 길고 복잡했다.
자료구조
나 데이터베이스
관련 지식이 없었기 때문에, 단순한 미니게임 이상의 수준을 구현할 수는 없었다.
실력 부족으로 인해 누락된 기능이 몇 가지 있다. (결과 화면에서 처음으로 돌아가기, 키보드로 이동하기 등)
이제는 이 기능들을 구현할 수 있을 정도의 실력은 되었으니, 기회가 된다면 부족한 부분을 보완해서 한 번 더 만들어보고싶다.