레이블이 개발스토리인 게시물을 표시합니다. 모든 게시물 표시
레이블이 개발스토리인 게시물을 표시합니다. 모든 게시물 표시

2018년 10월 18일 목요일

NodeJS+FileServer+Angular+ChartJS 로 개발하기

0) Node 설치
  > curl -sL https://deb.nodesource.com/setup_11.x | sudo -E bash -
  > sudo apt-get install nodejs
  > sudo apt-get install npm

1) Node 를 최신버젼으로 업그레이드 한다.
  > sudo npm install -g n
  > sudo n stable

2) Angular CLI 를 설치한다.
  > sudo npm install -g @angular/cli

3) 프로젝트 폴더 생성
  > ng new U2ReportServer

4) 프로젝트 폴더로 진입
  > cd U2ReportServer

5) express , multer , cors 모듈 추가
  > npm install express multer cors chart.js --save

6) 생성된 package.json 파일을 확인한다.
----------------------------------------------------------
{
  "name": "u2-report-server",
  "version": "1.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^6.1.0",
    "@angular/common": "^6.1.0",
    "@angular/compiler": "^6.1.0",
    "@angular/core": "^6.1.0",
    "@angular/forms": "^6.1.0",
    "@angular/http": "^6.1.0",
    "@angular/platform-browser": "^6.1.0",
    "@angular/platform-browser-dynamic": "^6.1.0",
    "@angular/router": "^6.1.0",
    "chart.js": "^2.7.3",
    "core-js": "^2.5.4",
    "cors": "^2.8.4",
    "express": "^4.16.4",
    "multer": "^1.4.1",
    "rxjs": "~6.2.0",
    "zone.js": "~0.8.26"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.8.0",
    "@angular/cli": "~6.2.4",
    "@angular/compiler-cli": "^6.1.0",
    "@angular/language-service": "^6.1.0",
    "@types/jasmine": "~2.8.8",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "~8.9.4",
    "codelyzer": "~4.3.0",
    "jasmine-core": "~2.99.1",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~3.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.1",
    "karma-jasmine": "~1.1.2",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.4.0",
    "ts-node": "~7.0.0",
    "tslint": "~5.11.0",
    "typescript": "~2.9.2"
  }
}
----------------------------------------------------------

7) ./backend/config/multer.config.js 파일을 생성한다.
----------------------------------------------------------
const multer = require('multer');

var storage = multer.diskStorage({
destination: (req, file, cb) => {
  cb(null, __basedir + '/uploads/')
},
filename: (req, file, cb) => {
  cb(null, file.originalname)
}
});

var upload = multer({storage: storage});

module.exports = upload;
----------------------------------------------------------

8) ./backend/routers/file.router.js 파일을 생성한다.
----------------------------------------------------------
let express = require('express');
let router = express.Router();
let upload = require('../config/multer.config.js');

let fileWorker = require('../controllers/file.controller.js');

router.post('/api/file/upload', upload.single("file"), fileWorker.uploadFile);
router.get('/api/file/all', fileWorker.listUrlFiles);
router.get('/api/file/:filename', fileWorker.downloadFile);

module.exports = router;
----------------------------------------------------------

9) ./backend/controllers/file.controller.js 파일을 생성한다.
----------------------------------------------------------
const uploadFolder = __basedir + '/uploads/';
const fs = require('fs');

exports.uploadFile = (req, res) => {
res.send('File uploaded successfully! -> filename = ' + req.file.filename);
}

exports.listUrlFiles = (req, res) => {
fs.readdir(uploadFolder, (err, files) => {
for (let i = 0; i < files.length; ++i) {
files[i] = "http://localhost:8080/api/file/" + files[i];
}

res.send(files);
})
}

exports.downloadFile = (req, res) => {
let filename = req.params.filename;
res.download(uploadFolder + filename);
}
----------------------------------------------------------

10) ./server.js 파일을 생성한다. (main 파일임)
----------------------------------------------------------
var express = require('express');
var app = express();

const bodyParser = require('body-parser');
const path = require('path');
const cors = require('cors')
const corsOptions = {
    origin: 'http://localhost:4200',
    optionsSuccessStatus: 200
}
app.use(cors(corsOptions));

global.__basedir = __dirname;

let router = require('./backend/routers/file.router.js');

// Parsers
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

// Angular DIST output folder
app.use(express.static(path.join(__dirname, 'public')));

// API location
app.use('/api', router);

// Send all other requests to the Angular app
app.get('*', (req, res) => {
  console.log("angular path");
  res.sendFile(path.join(__dirname, 'public/index.html'));
});

// Create a Server
let server = app.listen(8082, () => {

    let host = server.address().address
    let port = server.address().port

    console.log("App listening at http://%s:%s", host, port);
})
------------------------------------------------------------

11) angular.json 파일의 outputPath 를 public 으로 바꾼다.
----------------------------------------------------------
          "options": {
            "outputPath": "public",
            "index": "src/index.html",
----------------------------------------------------------

12) Angular 를 build 한다.
  > ng build

13) Server 를 실행한다.
  > node server.js


2018년 10월 10일 수요일

2018년 10월 7일 일요일

TypeScript 로 개발하기

1) TypeScript 설치
  > npm install -g typescript

  -g 옵션을 주면 global 어디서나 TypeScript 를 사용할 수 있다.
  -g 옵션을 주지 않으면 실행한 folder 에서만 TypeScript 를 사용한다.


2) 테스트용 파일 생성
   index.html
     <html>
       <head lang="ko">
         <title>
            type script test
         </title>
         <meta charset="utf-8" />
         <script src="index.js"></script>
      </head>
      <body>
        <p>type script test on browser environments</p>
      </body>
    </html>

   index.ts
    console.log("type script test on console environments");

3) TypeScript 를 compile
  > tsc index.ts

  TypeScrpt 파일을 compile 하면 js 파일이 생성된다.
  위의 경우 index.js 파일이 생성된다.

4) 생성된 index.js 를 실행해 본다.
  > node index.js
 
5) npm 환경 구성
  > npm init

6) test 를 위한 lite-server 설치
  > npm install lite-server --save-dev

7) lite-server 실행 스크립트 추가
  package.json 에 "start" 라는 명령어를 추가한다.

    "scripts": {
       "test": "echo \"Error: no test specified\" && exit 1",
       "start": "lite-server"
    },

8) lite-server 를 실행한다.
  > npm start

9) TypeScript 컴파일 환경을 설정한다.
  > tsc --init

10) TypeScript 파일 모두 compile 하기
  > tsc

  tsc --init 를 실행하고 나면 tsc 명령으로 모든 ts 파일을 compile 하여 js 파일을 만든다.





2018년 9월 10일 월요일

cordova custom plugin 개발하기

* Plugin 개발
---------------------------------------------------------------------------------------------------
1) Plugin Manager 를 설치한다.
   > npm install -g plugman

2) Cordova 프로젝트 생성
   > cordova create pluginTestApp com.test.plugin PTA


3) Custom Plugin 을 생성한다.
   > plugman create --name myPlugin --plugin_id com.test.myplugin --plugin_version "0.0.1"
   > myPlugin 폴더가 생성된 것을 확인할 수 있다.


4) Android 용 plugin 템플릿을 생성한다.
   > cd myPlugin
   > plugman platform add --platform_name android


* 참조 blog
https://henotia.github.io/MakeCordovaPlugin-1/
https://henotia.github.io/MakeCordovaPlugin-2/



* Custom Plugin 설치
---------------------------------------------------------------------------------------------------
1) Project 폴더에 Custom 플러그인을 위치시킨다.
   > cd myPlugin
   > dir

2018-09-14  오후 03:07    <DIR>          .
2018-09-14  오후 03:07    <DIR>          ..
2018-09-08  오전 12:48               363 .editorconfig
2018-09-08  오전 12:48               439 .gitignore
2018-09-14  오후 02:54    <DIR>          .sourcemaps
2018-09-14  오후 03:07             6,338 config.xml
2018-09-14  오후 03:06    <DIR>          TestCustomPlugin
2018-09-14  오후 02:48                93 ionic.config.json
2018-09-14  오후 03:07    <DIR>          node_modules
2018-09-14  오후 03:07           244,029 package-lock.json
2018-09-14  오후 03:07             1,834 package.json
2018-09-14  오후 03:00    <DIR>          platforms
2018-09-14  오후 03:07    <DIR>          plugins
2018-09-14  오후 03:04    <DIR>          resources
2018-09-14  오후 02:47    <DIR>          src
2018-09-08  오전 12:48               519 tsconfig.json
2018-09-08  오전 12:48               178 tslint.json
2018-09-14  오후 02:53    <DIR>          www
               8개 파일             253,793 바이트
              10개 디렉터리  150,516,252,672 바이트 남음

2) custom plugin 을 설치한다.
   > ionic cordova plugin add [경로] --save
   > ionic cordova plugin add TestCustomPlugin --save

2018년 8월 30일 목요일

ionic framework 으로 개발하기

1) ionic 과 cordova 설치
    > npm install -g ionic cordova

2) ionic 프로젝트 생성
    > ionic start TestApp

3) Platform 추가하기
    > ionic cordova platform add android
    > ionic cordova platform add ios

4) android 로 build
    > ionic cordova build android

5) Android Studio 를 실행하고  Import Project 를 선택한 후 platform/android 폴더를 선택하여 Project 를 loading 한다.



6) Web Browser 에서 화면 테스트하기

   > ionic serve
   
      안드로이드/아이폰 형태로 보고싶으면...
   > ionic serve --lab

7) 화면 수정후 prepare 를 해야 android 에 반영됨. 왜냐하면 ionic 은 화면 loading 속도를 빠르게하기 위해서 여러페이지를 build 를 통해 하나의 페이지로 만든다.

   > ionic cordova prepare android

8) 배포용 build 하기

   > Android Studio 에서 아래 메뉴를 사용하여 signed apk 를 생성한다.



8) ios 의 경우 emulator 에서 테스트하기

   > ionic cordova build ios
   > ionic cordova emulate ios

2018년 4월 15일 일요일

2018년 3월 25일 일요일

Jenkins Plugin 개발환경 구축

1) Maven 을 다운받아 환경변수로 Path 를 설정한다.

https://maven.apache.org/download.cgi 




2) [사용자이름]/.m2 폴더에 settings.xml 파일을 생성하고 아래내용을 추가한다.

    참조 : https://wiki.jenkins.io/display/JENKINS/Plugin+tutorial




3) console 창에서 Jenkins Plugin 프로젝트 생성한다.
$> mvn -U org.jenkins-ci.tools:maven-hpi-plugin:create 또는
$> mvn archetype:generate -Dfilter=io.jenkins.archetypes:plugin
중간에 몇가지 선택하는 항목이 나타난다. Hello world 프로젝 타입으로 생성하면 Sample 코드가 포함된 프로젝트가 생성된다.


4) package 를 생성한다.
프로젝트 폴더(pom.xml 이 있는 위치)에서 아래 명령어를 실행하여 package 를 만든다.
$> cd com.kimssoft.jenkins
$> mvn package -Dmaven.test.skip=true





5) Eclipse 의 Maven project 로 converting 한다.
$> mvn -DdownloadSources=true -DdownloadJavadocs=true -DoutputDirectory=target/eclipse-classes eclipse:eclipse




6) Eclipse 프로젝트에서 Import 하여 개발한다.





7) maven package 명령어로 build 하여 Jenkins Plugin 파일을 생성한다.
$> mvn package -Dmaven.test.skip=true




8) project 폴더의 target 에 있는 hpi 파일을 Jenkins 에 올려서 테스트 진행한다.



2018년 2월 6일 화요일

Ajax cross domain 처리 - Android Phonegap

Andorid 프로젝트에서 다음 명령을 사용하여 whitelist plugin 을 추가한다.

----------------------------------------------------------------------------------------------
> cordova plugin add cordova-plugin-whitelist
Fetching plugin "cordova-plugin-whitelist" via npm
Installing "cordova-plugin-whitelist" for android

               This plugin is only applicable for versions of cordova-android gr
eater than 4.0. If you have a previous platform version, you do *not* need this
plugin since the whitelist will be built in.


> cordova prepare

----------------------------------------------------------------------------------------------


만약 아래와 같은 라는 메시지가 출력되면 Android 프로젝트의 폴더 구조가 달라서 발생하는 에러이다.
www 폴더등을 지웠다면 폴더를 다시 생성해야 plugin 을 설치할 수 있다.

----------------------------------------------------------------------------------------------
> cordova plugin add cordova-plugin-whitelist
Current working directory is not a Cordova-based project.

----------------------------------------------------------------------------------------------

2018년 2월 4일 일요일

Fail to load dx.jar 메시지 출력시 - Android Phonegap

에러 메시지 :

Error:Android Dex: [classes.jar] Failed to load dx.jar
Error:Android Dex: [classes.jar] java.lang.ClassNotFoundException: com.android.dx.command.DxConsole
Error:Android Dex: [classes.jar] at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
Error:Android Dex: [classes.jar] at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
Error:Android Dex: [classes.jar] at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Error:Android Dex: [classes.jar] at org.jetbrains.android.compiler.tools.AndroidDxRunner.loadDex(AndroidDxRunner.java:80)
Error:Android Dex: [classes.jar] at org.jetbrains.android.compiler.tools.AndroidDxRunner.runDex(AndroidDxRunner.java:136)
Error:Android Dex: [classes.jar] at org.jetbrains.android.compiler.tools.AndroidDxRunner.main(AndroidDxRunner.java:336)
Error:Android Dex: [classes.jar] Exception in thread "main" java.lang.NullPointerException
Error:Android Dex: [classes.jar] at org.jetbrains.android.compiler.tools.AndroidDxRunner.runDex(AndroidDxRunner.java:139)


해결책 : android SDK Build-Tools 의 버젼을 25.0.3 버젼을 사용한다.

Tools -> Android -> SDK Manager -> SDK Tools tab -> check "Show package details"



2018년 2월 2일 금요일

Phonegap 으로 Android 프로젝트 생성 - windows 환경

1) 아래 링크에서 다운받아 JDK 를 설치한다.
    http://www.oracle.com/technetwork/java/javase/downloads/index.html

2) 아래 링크의 프로그램을 다운받아 Node JS 를 설치한다.
    https://nodejs.org/en/

3) 아래 링크에서 binary 파일을 다운받아 Apache Ant 를 설치한다.
    http://ant.apache.org/bindownload.cgi

4) 아래 링크에서 Android Studio 를 설치한다.
    https://developer.android.com/studio/index.html
    이전버젼 : https://developer.android.com/studio/archive.html

5) Android Studio 를 실행하여 필요한 SDK 를 설치한다.
    Tools -> Android -> SDK Manager
 



6) 환경변수를 잡아준다.
  • JAVA_HOME 설정
       ex) C:\Program Files\Java\jdk1.8.0_60

  • ANT_HOME 설정
       ex) D:\DevTools\apache-ant-1.9.6-bin\apache-ant-1.9.6

  • PATH 설정
       Java : ex) %JAVA_HOME%\bin;
       Android SDK : ex) D:\DevTools\android-sdk\platform-tools;
                               D:\DevTools\android-sdk\tools;

       Node JS : ex) C:\Program Files\nodejs\;
       Apache Ant :  ex) D:\DevTools\apache-ant-1.9.6-bin\apache-ant-1.9.6\bin;
     

7) Phonegap 설치
   window 의 Command 창에서 아래 명령어로 Phonegap 을 설치한다.
   npm install -g phonegap


8) Phonegap 프로젝트 생성
   phonegap create [생성할 폴더] [Package 명] [프로젝트명]
   D:> phonegap create ./MobileWinusApp com.logisall.mobilewinus MobileWinus
       

       
9) 생성된 프로젝트에 Android Library 추가
   cordova platform add android


10) Android Studio 를 띄워서 Project 를 Import 한다.
     File -> New -> Import Project







2017년 8월 28일 월요일

애자일 Story point 의 의미

애자일 개발 방법론에 보면 Story Point 라는 것이 있다.
이 점수의 의미에 대해서 한번 생각해보자!

소프트웨어 개발을 하기 위해서는 요구사항을 분석하고 작업목록을 추출해야 한다.
그리고 그 작업내역 각각의 작업량을 추정해야하는데 이 작업량 추정에 Story Point 가 사용된다.

우리는 보통 작업량을 추정할 때 일(Day)을 단위로 사용하여 추정하게 된다.
즉, '이 작업은 몇 일 걸릴 일이다' 라고 추정하는 것이다. 근데 이것은 문제가 존재한다.
예를 들어보면 A라는 작업은 하루 8시간씩 2일동안 작업해야만 끝낼 수 있는 작업이다.
그리고 B라는 업무는 오전에 4시간 작업하고 나머지 4시간은 기다리는 식으로 2일동안 작업해야 한다고 했을 때 A 작업과 B 작업을 모두 2일로 추정한다면 문제가 있다.
왜냐하면 B 작업을 할 때는 오후에 다른 작업을 할 수 있기 때문이다.

즉, 일(Day) 단위로 작업량을 추정하게 되면 B작업의 경우는 오후의 남는 시간이 가려지는 문제가 발생하여 작업량이 과하게 추정되는 문제가 발생한다.
그래서 등장한 것이 Story Point 이다.

Story Point 는 노력(Effort)의 단위라고 생각하면 편할 것이다.
다시말하면 이 작업을 처리하는데 있어서 어떤 방해도 받지않고 한사람이 이 작업만 하루 8시간씩 할 경우 몇 일이 걸리는지 추정하는 것이 Story Point 라고 일단 생각하면 될 것이다.


그래서 위에 얘기했던 A 작업은 Story point 가 2 이고 B는 1이 되는 것이다.

이제 우리는 Story point 를 통해서 작업량을 정확히 추정할 수 있다.
A 작업과 B 작업을 마치는데는 Working day 3일이 필요하다고 추정할 수 있다.
그리고 일정계획을 세운다면 A 작업은 월화수 3일의 기간이 필요하고, B는 월화 2일의 기간이 필요한 것으로 계획을 세울 수 있다.



결국 A 작업은 Working day 3일이 필요하고, B 작업은 Working day 2일이 필요한 작업이 된 것이다. 물론 이 예는 한사람이 작업할 경우를 가정하여 세운 일정계획이다.

이렇게 Story point 는 노력(Effort)의 량이라는 개념으로 작업의 정확한 일정계획을 세울 수 있도록 도와준다.

그리고 또 한가지 Story point 가 가지고 있는 기능은 사람마다 또는 팀마다의 작업량 추정치의 차이를 극복하게 만들어 준다는 것이다.

예를들어서 작업이 A 작업 밖에는 존재하는 않는다는 가정에서 개똥이는 위의 예처럼 A라는 작업의 노력(Effort)를 2 Story point로 추정했다.
근데 소똥이는 A라는 작업의 노력(Effort)를 4 Story point 로 추정한 것이다.
그리고 둘은 모두 정직한 개발자이기 때문에 모두 Working day 2일만에 작업을 모두 끝냈다.


그렇다면 개똥이는 Story point 를 정확히 추정했으니 훌륭한 개발자이고, 소똥이는 2배나 잘못 추정했으니 나쁜 개발자일까?
그렇지않다. Story point 의 단위가 일(Day)이 아니라 노력(Effort)이기 때문에 둘다 훌륭한 개발자이다.
Story point 를 정할 때 우리는 익숙하기 때문에 일(Day)로 노력(Effort)의 단위를 추정한 것이지 엄밀히 따지면 일(Day) 과 노력(Effort)은 1:1 일 필요는 없다.
사람마다 경험이 다 다르기 때문에 당연히 작업량 추정도 다 다르게 할 수 밖에 없기 때문이다.
그래서 개똥이는 일(Day)과 노력(Effort)이 1:1 인 개발자이고, 소똥이는 일(Day)과 노력(Effort)이 1:2 인 개발자인 것이다. 누가 맞고 틀리고가 없는 것이다.
이것을 Story point 의 속도(Velocity)라고 한다.



그래서 애자일에서는 Sprint 를 진행하면서 그 팀의 Story point velocity 를 측정하여 다음번 Sprint 에는 그 Velocity 에 맞는 총점의 Story point 들을 선정하고 작업을 진행하는 것이다.
그러므로 어느 팀이 Velocity 가 높으냐 낮으냐는 아무런 의미가 없고,  매 Sprint 마다 Velocity 가 일정한 팀은 작업량 추정을 잘하고 있다고 할 수 있고, 매 Sprint 마다 Velocity 가 들쭉 날쭉한 팀은 작업량 추정을 잘못하고 있다고 볼 수 있는 것이다.

만약 자신의 팀이 Velocity 가 들쭉 날쭉하다면 작업량 추정방법에 대해서 좀 더 고민하는 팀장이 되어야 할 것이다.




2017년 5월 29일 월요일

점핑프로그 게임이 만들어지기까지

나처럼 게임을 취미로 만들고자 하는 사람들에게 조금이나마 도움이 될까 싶어서 점핑프로그의 탄생에 얽힌 이야기를 해보려한다.

나는 현재 소프트웨어 개발 프리랜서다.
지금은 테스트와 관련된 개발을 주로 진행하고 있으며 경력은 18년 정도 되었다!

이런 내가 처음으로 게임을 만들기 시작하게 된 것은 2013년으로 기억된다.
그때 아들에게 숫자를 재미있게 가르쳐보려고 시작한 것이 계기가 되었다.
당시에 만든 게임은 예전 핸드폰과 함께 사라져서 지금은 찾을 수 없다.

그때 사용한 게임 엔진이 libGDX(https://libgdx.badlogicgames.com/) 인데 Opensource 게임엔진으로 Cross-Platform 을 지원하여 선택하게 되었다.
그 당시에는 0.9.3 버젼으로 개발했던 걸로 기억되는데 오늘 확인해보니 1.9.6 까지 release 가 되어있다.

libGDX 를 선택한 가장 큰 이유는 Cross-Platform 을 지원하기 때문에 개발하면서 윈도우환경에서 바로 테스트해볼 수 있다는 점이 좋았다.
안드로이드의 느린 에뮬레이터를 사용할 필요도 없고, 윈도우환경에서 돌아가는 모습이 별다른 작업없이 그대로 안드로이드에서도 동일하게 돌아가는 모습에 많이 감탄했던 것으로 기억된다.


그러다가 2015년 3월 Unity(https://unity3d.com) 를 무료로 제공한다는 기사를 접하고 Unity 라는 게임엔진을 처음으로 알게되었다.


Unity를 2015년 말부터 공부하게 되었고, 2016년 6월 첫번째 게임을 만들게 되었다.



  • 첫번째 게임 : 팔로우미(Follow Me)

장르는 아케이드 횡스크롤 게임이다.
조작방식은 버튼 터치(Touch)를 통해 리더 새(Leader bird)를 조정하여야 한다.
게임의 목표는 최대한 많은 새들을 이끌고 도착지까지 날아가는 것이다.



이 게임은 결국 출시를 하지는 못했다.
이유는 Unity 를 처음 사용하다보니 공부하면서 만든 게임이라서 터치감 조절에 실패하였다.
또 이펙트(Effect)가 화려하지 못하여 게임의 재미요소를 주지 못했다.
그래도 Unity에 대한 이해를 높여줬다는 점과 수묵화의 느낌이 풍기는 게임을 시도해 봤다는 것에 의미를 두고있다.




  • 드디어 점핑 프로그 - 나뭇잎 청소부(Jumping Frog - Leaf Cleaner) 출시

점핑 프로그(https://play.google.com/store/apps/details?id=com.kimssoft.jumpingfrog)는 한 붓그리기를 응용한 퍼즐게임이다.
게임의 목표는 개구리가 모든 나뭇잎을 없애면서 도착지까지 가는 것이다.



게임의 장르가 퍼즐이다 보니 퍼즐을 좋아하는 사용자들이 아니면 쉽게 다운받지 않을 것으로 예상했었다.
그런데도 내가 퍼즐 장르를 선택한 이유는 캐릭터 디자인에 있었다.
내가 개발자이다 보니 그림을 그리는 것이 너무 어렵고 시간도 많이 걸렸다.



그래서 생각한 것이 타일기반의 퍼즐게임이다.
타일기반의 퍼즐 게임은 몇가지 종류의 타일만 그리고 나면 모든 스테이지(Stage)에서 타일을 재사용 할 수 있을 것 같았기 때문이다.
다행히 예상은 맞아 떨어져서 그림에 쏟는 시간은 많이 줄일 수 있었다.
하지만 역시 다운로드에는 한계가 있었다.




현재 다운로드수 250명 중 50명은 지인이고, 나머지 200명은 광고를 통해 유입된 사용자들이다.
결국 첫번째 게임은 기대에 미치지 못하는 성과를 거두었다.

나름대로 의미를 찾는다면 첫번째 출시작이라는 점과 만들고 싶은 기능은 모두 만들었다는 점이다.
아이템 판매를 위해서 Unity 의 IAP 라이브러리를 사용하여 아이템 구매 기능을 추가하였고, Unity Ads 를 사용하여 동영상 광고도 넣었다.
그리고 배너(Banner)나 전면(Full Screen) 광고를 위해 Admob 광고도 부착하였다.
또한 무료와 유료 게임을 모두 출시해 보았다.




  • 두번째 출시작 점핑 프로그-어둠의 강(Jumping Frog - Dark River) 출시

점핑 프로그-어둠의 강(https://play.google.com/store/apps/details?id=com.kimssoft.jumpingfrog.darkriver.free) 은 메모리 게임이다.
게임의 목표는 어둠이 내린 강에서 장애물(Tornado)을 피해서 목표 지점까지 도달하는 것이다.



"점핑 프로그 - 어둠의 강" 부터 게임에 부제(Sub-title)를 붙이기 시작하였다.
원래 첫번째 출시작인 "점핑 프로그 - 나뭇잎 청소부" 의 원 제목은 그냥 "점핑 프로그" 였다.
그런데 두번째 게임도 개구리를 테마로 만들다 보니 부제(Sub-title)를 붙이게 되었고, 그래서 첫번째 게임에도 부제(Sub-title) "나뭇잎 청소부(Leaf Cleaner)" 를 붙이게 되었다.

조금은 예상을 했겠지만 그림을 또 그리는 것이 너무 힘들 것 같아서 첫번째 게임의 디자인을 재활용할 방법을 찾게 되었고, 자연스럽게 점핑 프로그 시리즈로 게임을 만들어 보자는 생각으로 두번째 게임을 만들게 되었다.



"어둠의 강(Dark River)" 은 "나뭇잎 청소부(Leaf Cleaner)" 보다는 성적이 좋았다.
광고를 시작하고 몇 일 지나지 않아서 다운로드 수가 450명에 도달하였다.
다운로드 국가 랭킹은 이라크 -> 몽골 -> 방글라데시 순이었다.



"어둠의 강" 과 "나뭇잎 청소부" 는 구글 플레이(Google Play)에 있는 광고 켐페인을 통해 각각 50,000원씩 광고비를 지출하였다.
그랬을 때 "어둠의 강" 이 "나뭇잎 청소부" 보다 2배 많은 다운로드 수를 기록하였다.
왜 "어둠의 강"이 2배 더 많은 다운로드를 기록했는지 정확한 이유는 알 수 없다.
다만 추측하기로는 게임 아이콘이 좀 더 눈에 확 들어왔을 것으로 생각한다.



현재 점핑 프로그 3탄을 준비중에 있으며 이번에는 퍼즐장르를 벗어난 게임을 만들어 보려하고 있다.