반응형

로고

시연영상



1. 소개

- 원터치 2D 캐쥬얼
- 스테이지 클리어 방식

- SQL, PHP

- Unity 2017.3.0f

- 메인 프로그래머

- 모바일

- 제작기간: 1개월

 

 

2. 핵심 컨텐츠



물고기 잡기


원하는 물고기 선택


랭킹등록

 

3. 구현

3.1 물고기 세팅(메모리 풀링)

 


메모리 풀링 시 로딩전환


SQL에 저장된 물고기 정보들 가져오기 (Cafe24)

 음수 값들의 물고기들은 잘못된 것이 아니다.
내 기획이다 ^^;;

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
 
$code = $_POST['code'];
 
$con = mysql_connect("localhost","hki234","안알랴쥼");
 
 
 
if(!$con)
    die('Could not Connect:' .mysql_error());
 
mysql_select_db("hki234"$con) or die("could not load the database" .mysql_error());
 
$check = mysql_query("SELECT NAME_KOR, NAME_ENG, HEALTH, ARMOR, PLASTIC, PRICE FROM LOF_FISHES WHERE CODE = '".$code."'");
 
 
$numrows = mysql_num_rows($check);
if($numrows == 0)
{
    die("".$code." does not exist. \n");
}
 
else
{
 
//fetch_assoc - 가져온 변수 배열저장
    while($row = mysql_fetch_assoc($check))
    {
        if($code == $row['CODE'])
        {
            echo(""$row['NAME_KOR']." \n");
            die("Log in - Success!!");
        }
        else
        {    
            die("Name does not Match. \nConnect Success!!");
        }
    }
 
}
?>
cs

 

Cafe24쪽에 올라간 PHP

연동되어있는 FileZila로 불러왔던 걸로 기억한다.

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
 
 
 
public class DataManager : MonoBehaviour {
    
    private string fishUrl = "https://hki234.cafe24.com/LoadFish.php";
 
    //프레임당 한 번만 불러오도록 하는 변수
    private bool                loadData = false;
    public bool                 Load_Data       { get { return loadData; } }
 
    //데이터 불러오면 참으로 변환
    private bool                dataOn = false;
    public bool                 Data_On         { get { return dataOn; } }
 
    //지정된 해안의 모든 물고기 저장
    [SerializeField]
    private List<Fish>          fishDataList;
    public List<Fish>           Fish_Data_List  { get { return fishDataList; } }
    
    private LoadFishManager     loadFishManager;
    private GameObject          fish;
 
 
    public void Load_FIsh(OCEAN_TYPE ocean, LoadFishManager _l, GameObject _f)
    {
        loadData = true;
        //물고기 전체 수가 맞아 떨어지는 지 체크
        //맞아 떨어지면 Load에서 다음으로 전환
        loadFishManager = _l; fish = _f;
        StartCoroutine(WWW_FISH(ocean));
    }
 
 
    private IEnumerator WWW_FISH(OCEAN_TYPE ocean)
    {
        WWWForm form = new WWWForm();
        string oceanText;
 
        switch(ocean)
        {
            case OCEAN_TYPE.PACIFIC:
                oceanText = "PACIFIC";
                break;
            case OCEAN_TYPE.INDIA:
                oceanText = "INDIA";
                break;
            case OCEAN_TYPE.ANTARCTIC:
                oceanText = "ANTARCTIC";
                break;
            case OCEAN_TYPE.ATLANTIC:
                oceanText = "ATLANTIC";
                break;
            case OCEAN_TYPE.ARCTIC:
                oceanText = "ARCTIC";
                break;
            default:
                oceanText = "PACIFIC";
                break;
        }
        form.AddField("ocean""PACIFIC");
 
        WWW webRequest = new WWW(fishUrl, form);
 
 
        //데이터 받아오기
        do
        {
            yield return null;
        }
        while (!webRequest.isDone);
 
        if (webRequest.error != null)
        {
            yield break;
        }
 
 
        //데이터 저장 - 컨테이너로 옮기기
        //크게 *로 자른뒤 뒤에서 |로 개별데이터를 자른다.
        string fishData = webRequest.text;
        var dataContainer = fishData.Split("*"[0]);
 
        //가상 물고기 생산
        //좌표는 아예 안보이게 셋엑티브 끔
        for (int i = 0; i < dataContainer.Length - 1; i++)
        {
            GameObject clone = Instantiate(fish);
            clone.transform.parent = this.transform;
            clone.SetActive(false);
 
            /******************나름의 직렬화*******************/
            var fishContainer = dataContainer[i].Split("|"[0]);
            OCEAN_TYPE _ocean;
 
            if (fishContainer[1].Contains("PACIFIC"))
            { _ocean = OCEAN_TYPE.PACIFIC; }
            else
            if (fishContainer[1].Contains("ANTARCTIC"))
            { _ocean = OCEAN_TYPE.ANTARCTIC; }
            else
            if (fishContainer[1].Contains("ARCTIC"))
            { _ocean = OCEAN_TYPE.ARCTIC; }
            else
            if (fishContainer[1].Contains("INDIA"))
            { _ocean = OCEAN_TYPE.INDIA; }
            else
            if (fishContainer[1].Contains("ATLANTIC"))
            { _ocean = OCEAN_TYPE.ATLANTIC; }
            else
            { _ocean = OCEAN_TYPE.PACIFIC; }
 
            clone.GetComponent<Fish>().InitInfo(
            int.Parse(fishContainer[0]),
            _ocean,
            fishContainer[2],
            fishContainer[3],
            int.Parse(fishContainer[4]),
            int.Parse(fishContainer[5]),
            int.Parse(fishContainer[6]),
            int.Parse(fishContainer[7]));
 
            fishDataList.Add(clone.GetComponent<Fish>());
        }
 
        //여기까지 왔다면 데이터가 모두 준비되었을 경우다.
        dataOn = true;
    }
}
 
cs

 

Unity에선 DataManager 단에서 전체 물고기의 데이터를 관리한다.

원래 기획은 5대양 별 물고기로 기획되었으나, 기간이 줄어 그냥 대양 구분 없이 물고기가 생성된다.

 

3.2 게임 구현

게임구조와 인게임 창

 

단순 터치 방식이며, Raycast를 수직으로 쏴 가리키는 물고기의 체력을 깎는다.

물고기 체력이 다 닳게 되면 잡는 것이다.

시간 제한은 위 창에 존재하며, 좌측 상단에는 잡은 물고기 수다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
//참고 블로그
//http://ateliersera.blog.me/220439790504
 
 
//터치해서 적에게 데미지를 가함
public class PlayerManager : MonoBehaviour
{
    public void Init()
    {
 
    }
 
    public void Updated()
    {
        UpdatedInputs();
    }
 
    public void UpdatedInputs()
    {
        //위는 3D코드 아래는 2D코드
        //ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Input.GetMouseButtonDown(0))
        {
            RaycastHit2D hit = Physics2D.Raycast(
            Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 1.0f)),
            Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 100.0f)));
 
            if (hit.collider != null)
            {
                hit.transform.gameObject.GetComponent<Fish>().Hit();
            }
        }
 
        Debug.DrawLine(
            Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 1.0f)),
            Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 100.0f)), Color.red);
    }
}
cs

 

여타 캐릭터가 없어 걍 PlayerManager 단에서 모든 구현이 끝난다.

RPG 만들다 캐릭터 수에 기겁해서 그냥 다 때려쳤다는 것이 정설...

 

3.3 랭킹등록

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php
 
$id = $_POST['id'];
$price = $_POST['price'];
 
$con = mysql_connect("localhost","hki234","안알랴쥰다용");
 
 
 
if(!$con)
    die('Could not Connect:' .mysql_error());
 
mysql_select_db("hki234"$con) or die("could not load the database" .mysql_error());
 
 
//이름이 있는 경우엔 넣지 못함
$check = mysql_query("SELECT * FROM LOF_RANKING WHERE ID = '$id'");
$numrows = mysql_num_rows($check);
 
 
 
if($numrows != 0)
{    
    echo("ID is Already Existence!!");
    
    while($row = mysql_fetch_assoc($check))
    {
        if($price == $row['PRICE'])
        {
            die("PRICE is Already Existence!! Shut Down!!");
        }
    }
}
 
 
//여기까지 왔다는 것은 1차 검열을 통과했다는 뜻
mysql_query("INSERT INTO LOF_RANKING (ID, PRICE) VALUES ('$id', '$price')");
           echo "Insert Success";
 
 
//아래 정렬로 다시 랭킹을 산출한다.
$rankingCheck = mysql_query("SELECT * FROM LOF_RANKING ORDER BY PRICE DESC");
$minRank = 0;
 
 
while($rankingRow = mysql_fetch_assoc($rankingCheck))
{
    //이 순위 아래는 데이터를 삭제한다.
    //8 - 남아있는 데이터 수
    if($minRank >= 8)
    {
        echo ("$minRank");
        mysql_query("DELETE FROM LOF_RANKING WHERE ID = '".$rankingRow['ID']."' AND PRICE = '".$rankingRow['PRICE']."'");    
    }
    $minRank++;
}
 
?>
cs

 

PHP 소스다.

랭킹을 올릴 때에 필터링을 구현해 보았다.

여기서는 랭킹 밖에 있을 경우 데이터가 삭제된다!

 

4. 정리하기

Server 개념을 게임에 처음 접목시켜보았다. 물론, 지금 만들라면 로컬 서버를 띄워 만들어보겠지만, 자격증(정처기)으로만 남아있던 서버지식을 활용해보는 시간이었다.

 

게임 구현보다는 시스템 이해에 더 시간을 쏟았었다.

반응형
Posted by Lotus' Library
,