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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <tchar.h>
#include <WinSock2.h>
using namespace std;
 
#pragma comment(lib,"ws2_32.LIB")
 
#define SERVERPORT 9000
#define BUFSIZE 512
 
void err_quit(const TCHAR* msg) {
    LPVOID lpMsgBuf;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL, WSAGetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&lpMsgBuf, 0NULL);
    MessageBox(NULL, (LPCTSTR)lpMsgBuf, msg, MB_ICONERROR);
    LocalFree(lpMsgBuf);
    exit(1);
}
 
void err_display(const TCHAR* msg) {
    LPVOID lpMsgBuf;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL, WSAGetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&lpMsgBuf, 0NULL);
    printf("[%s] %s", msg, (char*)lpMsgBuf);
    LocalFree(lpMsgBuf);
    exit(1);
}
 
 
class SocketStart {
    WSADATA wsaData;
    BYTE nMajor, nMinor;
    WORD wVersionRequested;
public:
    SocketStart():nMajor(2),nMinor(2) {
        wVersionRequested = MAKEWORD(nMinor, nMajor);
    };
 
    void Start() {
        if (WSAStartup(wVersionRequested, &wsaData) == SOCKET_ERROR)
            cout << "소켓 초기화 실패" << endl;
 
        Check();
 
        return;
    }
 
    void Check() {
        if (LOBYTE(wsaData.wVersion) != nMinor ||
            HIBYTE(wsaData.wVersion) != nMajor) {
            cout << "소켓 버전 불일치" << endl;
            WSACleanup();
            return;
        }
    }
 
};
 
class ListenSock {
public:
    SOCKET lstnsock;
private:
    struct sockaddr_in addr;
    int addrlen;
    int share_value;
public:
    ListenSock() {}
 
    void Initialize() {
        share_value = 0;
        lstnsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (lstnsock == INVALID_SOCKET) err_quit("listen error");
 
        addr.sin_family = AF_INET;
        addr.sin_port = htons(SERVERPORT);
        addr.sin_addr.s_addr = htonl(INADDR_ANY);
        
        Bind_Listen();
    }
 
    void Bind_Listen() {
        if (bind(lstnsock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) err_quit("bind error");
 
        if (listen(lstnsock, SOMAXCONN) == SOCKET_ERROR) err_quit("listen error");
 
    }
};
int share = 0;
CRITICAL_SECTION cs;
DWORD WINAPI ProcessClient(LPVOID arg);
 
class MultiServer {
    ListenSock Lstnsock;
    HANDLE hThread;
    struct sockaddr_in cliaddr;
    int addrlen;
    
public:
    MultiServer(){
        
    }
    ~MultiServer() {
        DeleteCriticalSection(&cs);
    }
    void Initialize() {
        InitializeCriticalSection(&cs);
        addrlen = sizeof(cliaddr);
        
        Lstnsock.Initialize();
 
    }
 
    void Run() {
 
        while (1) {
            
            SOCKET commsock = accept(Lstnsock.lstnsock, (struct sockaddr*)&cliaddr, &addrlen);
            if (commsock == INVALID_SOCKET) {
                err_display("accept error");
                break;
            }
 
            printf("\n[TCP Server] Client Connect : IP Address = %s, Port = %d\n ",
                inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
            hThread = CreateThread(NULL0, ProcessClient, (LPVOID)commsock, 0NULL);
            if (hThread == NULL) {
                closesocket(commsock);
            }
            else {
                CloseHandle(hThread);
            }
            
        }
        closesocket(Lstnsock.lstnsock);
 
 
    }
 
};
 
DWORD WINAPI ProcessClient(LPVOID arg) {
    SOCKET serv = (SOCKET)arg;
    int retval;
    int addrlen;
    char buf[BUFSIZE + 1];
 
    addrlen = sizeof(serv);
    while (1) {
        memset(buf, '\0'sizeof(char)*(BUFSIZE + 1));
        retval = recv(serv, buf, BUFSIZE, 0);
        if (retval == SOCKET_ERROR) {
            err_display(_T("recv()"));
            break;
        }
        else if (strcmp(buf,"quit"== 0)
            break;
        cout << "retval : " << retval << endl;
        buf[retval] = '\0';
        
        printf("TCP Client : %s\n", buf);//여기까지는 잘받음
        EnterCriticalSection(&cs);
 
        char sendBuf[100];
        memset(sendBuf, '\0'sizeof(char* 100);
        sprintf(sendBuf, "%d", share);
    //    _itoa(share, sendBuf, 100);
        cout << "SendBuf : " << sendBuf << endl;
        int sendSize = send(serv, sendBuf, 1000);
        cout << "SendSize : " << sendSize << endl;
        char recvBuf[100= { '\0' };
        
        retval = recv(serv, recvBuf, 1000);
        recvBuf[retval] = '\0';
        cout << "how many size ? : " << retval <<" recvBuf : " << recvBuf << endl;
        
        share = atoi(recvBuf);
        
        printf("share : %d", share);
 
        LeaveCriticalSection(&cs);
    }
 
    closesocket(serv);
    printf("[TCP 서버] 클라이언트 종료: IP 주소 = %s\n", buf);
    return 0;
 
}
 
int main(int argc, char* argv[]) {
    SocketStart SockStart;
    MultiServer serv;
 
    SockStart.Start();
    serv.Initialize();
    serv.Run();
 
    return 0;
}
cs


'서버프로그래밍' 카테고리의 다른 글

내 머릿속에 남아있는 HANDlE의 의의  (0) 2018.05.27
가변길이 패킷  (0) 2018.05.27
브로드 캐스트 주소 구하기  (0) 2018.05.27
서버 주소 변환 함수  (0) 2018.05.27
간단한 Multi클라이언트  (0) 2018.05.27

폰 겜에서 빠질 수 없는 출석부 ..


부끄럽지만 1~31 까지 각각 Object의 이름을 이렇게 부여했다. 


그리고 출석 아이템을 받지 않았을 때 현재 와 같이 갈색Sprite 가


출석 아이템을 받았다면 초록색 테두리가


받지 않고 지나쳤다면 회색 스프라이트로 변경된다..


때문에 각각 Late , TodayGet , Not Get 으로 명명하고 알맞는 Sprite를 넣어 줬다.

























아래가 Control Attand Sprite 코드이다..


현재 Object의 Image Component를 가져왔다.


그리고 날짜에 맞게 잘 바꿔둔 현재 object의 이름을 가져온다. 


이름은 String 이기 때문에 int.Parse 로 정수로 바꾸고 day 에 저장한다.


그리고 현재 날짜와 비교해서 만약에 이미 지난 날짜인데 출석 한적이 없다면 Sprite를 Late로


출석했다면 TodayGet으로 미래날짜라면 NotGet으로 변경한다..


여기서 AttandManager.AttandInstance.AttandDay는 AttandManager 스크립트에서 AttnadInstance를 Static으로 설정했다.

 

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using GameManager;
public class ControlAttandSprite : MonoBehaviour {
 
    private Image CurrentSprite;
    
    [SerializeField]
    private Sprite Late;
    [SerializeField]
    private Sprite TodayGet;
    [SerializeField]
    private Sprite NotGet;
 
 
 
    // Use this for initialization
    void Start()
    {
        /*
         * AttandDay 에 대한 정보 복사
         * 
         */
 
        CurrentSprite = GetComponent<Image>();
 
        int day = int.Parse(gameObject.name);
    
        if (day < System.DateTime.Now.Day && AttandManager.AttandInstance.AttandDay[day - 1== false)
            CurrentSprite.sprite = Late;
        else if (day < System.DateTime.Now.Day && AttandManager.AttandInstance.AttandDay[day - 1== true)
            CurrentSprite.sprite = TodayGet;
        else
            CurrentSprite.sprite = NotGet;
 
 
    }
    
    // Update is called once per frame
    void Update () {
        
 
    }
 
    public void UpdateSprite()
    {
        CurrentSprite.sprite = TodayGet;
    }
 
}
 
cs





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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GameManager;
public class AttandManager : MonoBehaviour {
    static protected AttandManager s_AttandInstance;
    static public AttandManager AttandInstance { get { return s_AttandInstance; } }
 
 
   public bool[] AttandDay = new bool[31];
    // Use this for initialization
    void Awake()
    {
        s_AttandInstance = this;
 
        AttandDay[0= true;
        AttandDay[3= true;
        
    }
 
    void Start () {
        
    }
    
    // Update is called once per frame
    void Update () {
        
    }
}
 
cs

이렇게 Static 변수로 해줌으로써 한 씬에서 하나의 변수를 사용 할 수 있어서 다른 오브젝트와 상호 작용 할 수 있다.




마지막으로 수령완료를 누르면


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    private ControlAttandSprite[] rewardSprite;
    [SerializeField]
    private GameObject rewards;
    // Use this for initialization
    void Start () {
 
        rewardSprite = rewards.GetComponentsInChildren<ControlAttandSprite>();
    }
    
    // Update is called once per frame
    void Update () {
        
    }
 
    public void ChangingSprite()
    {
        rewardSprite[System.DateTime.Now.Day - 1].UpdateSprite();
        AttandManager.AttandInstance.AttandDay[System.DateTime.Now.Day - 1= true;
    }
}
cs

이 코드의 ChangingSprite가 실행되고 Sprite가 변경된다.

오늘이 27일이라 요렇게 된당!

'유니티' 카테고리의 다른 글

유니티에서 채팅기능 구현 및 문자열 송수신 문제점  (0) 2019.05.02
중간 발표, 피드백  (0) 2018.05.29
UI OnOff Sprite Change  (0) 2018.05.27
UI : Canvas VS CameraScreen  (0) 2018.05.27

프로젝트 수행 간 OnOff 버튼을 구현해야되는 부분이다.


이런 형식으로 OnClick() 이나  EventTrigger의 PointerClick 에 Button On Off Script 의 ButtonOnOff.ChangeButton 을 실행 하도록 만들었다.


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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ButtonOnOff : MonoBehaviour {
    public bool ButtonOn;
    private SpriteRenderer spriteRenderer;
 
    private Image CurrentImage;
    [SerializeField]
    private Sprite SpriteOn;
    [SerializeField]
    private Sprite SpriteOff;
 
    // Use this for initialization
    void Start()
    {
        CurrentImage = this.GetComponent<Image>();
    }
 
    // Update is called once per frame
    void Update()
    {
        
        if (ButtonOn)
        {
            CurrentImage.sprite = SpriteOff;
            
        }
        else
        {
            CurrentImage.sprite = SpriteOn;
 
        }
    }
 
    public void ChangeButton()
    {
        if (ButtonOn) ButtonOn = false;
        else ButtonOn = true;
    }
    
}
 
cs


public 으로 선언해서 다른 코드에서 접근케 만들고 그에 따라 Update가 ButtonOn의 값을 인식해 Sprite를 바꿔줬다.

'유니티' 카테고리의 다른 글

유니티에서 채팅기능 구현 및 문자열 송수신 문제점  (0) 2019.05.02
중간 발표, 피드백  (0) 2018.05.29
게임 내 출석부 구현  (0) 2018.05.27
UI : Canvas VS CameraScreen  (0) 2018.05.27

+ Recent posts