GAME MAKER 강좌
KAYAN
◈ 서버 만들기
네트워크에 필요한 주요 오브젝트를 먼저 만듭니다.
- 서버 오브젝트 : obj_server_system (Persistent 체크)
- 클라이언트 오브젝트 : obj_client_system (Persistent 체크)
- 유저 오브젝트(서버 전용) : obj_game_user (Persistent 체크)
- 플레이어 부모 오브젝트 : obj_player_parent
- 플레이어 오브젝트(게임용, 부모 오브젝트 지정) : obj_player_1
- 게임 실행용 오브젝트 : obj_game_stage
- 플레이어 생성 위치용 오브젝트 : obj_start_point
(▲ 주요 오브젝트)
서버 오브젝트(obj_server_system)는 서버 실행룸(Room_waiting_server)에 배치하고,
클라이언트 오브젝트(obj_client_system)는 클라이언트 실행룸(Room_waiting_client)에 미리 배치합니다.
두 오브젝트는 다른 룸으로 이동해도 정보가 계속 유지해야 하기 때문에 [Persistent]를 체크합니다.
유저 오브젝트(obj_game_user)는 서버에서 게임 중일 때, 클라이언트를 제어할 설정을 추가할 겁니다.
보통 Ping 체크나, 플레이어 생성, 플레이어 정보저장에 관련된 기능입니다.
이 오브젝트도 다른 룸으로 이동해도 정보가 계속 유지해야 하기 때문에 [Persistent]를 체크합니다.
게임 실행용 오브젝트(obj_game_stage)는 게임룸에서 게임 제어나 플레이어 생성에 관련된 기능을 설정합니다.
이 오브젝트는 게임룸(Room_game_1)에 미리 배치합니다.
플레이어 생성 위치 오브젝트는 플레이어를 생성할 때 위치를 잡아줍니다.
먼저, 서버 설정부터 시작합니다.
[Create 이벤트]를 추가하고, 서버를 생성하도록 합니다.
★ obj_server_system - Create 이벤트 ★ global.player_max = 5; //클라이언트 최대 접속 수( 서버 유저 제외 ) global.game_room = -1; //게임룸 global.user_id = 0; //현재 서버 유저 ID global.socketlist = ds_list_create( ); //클라이언트 소켓 목록 global.player_map = ds_map_create( ); //클라이언트 정보 global.net_buffer = buffer_create( 256, buffer_grow, 1 ); //버퍼 생성 global.server_socket = network_create_server( network_socket_tcp, 6510, global.player_max ); if global.server_socket<0{ //서버 생성 실패했을 때 } else{ //서버 생성 성공했을 때 } |
다음, 서버 생성에 실패하면, 서버 오브젝트를 파기하고, "서버 생성에 실패했습니다."라고 메시지를 표시합니다.
그리고 메인화면으로 이동하도록 합니다.
★ obj_server_system - Create 이벤트 ★ if global.server_socket<0{ //서버 생성 실패했을 때 instance_destroy( ); show_message_async( "서버 생성에 실패했습니다." ) room_goto( Room_open ); } else{ //서버 생성 성공했을 때 global.select_server = 1; var inst = instance_create_depth( 0, 0, 0, obj_game_user ); global.game_room = Room_game_1; room_goto( Room_game_1 ); } |
서버 생성에 성공하면 서버 유저의 유저 오브젝트(obj_game_user)를 생성하도록 합니다.
그리고 게임 룸으로 이동하는 거죠.
클라이언트 유저는 서버로 접속했을 때, 생성하도록 할 거에요.
서버는 바로 이동해서 클라이언트를 기다리도록 합니다.
유저 오브젝트의 [Create 이벤트]에 유저의 정보를 저장할 변수를 추가합니다.
★ obj_game_user - Create 이벤트 ★ select = 0; //현재 유저 여부 room_sync = 0; //룸 동기화 체크 user_id = 0; //유저 ID user_name = ""; //유저 이름 user_gameplay = noone; //플레이어 새성 인스턴스 ID user_regen = 0; //플레이어 재생성 체크 |
그리고 [Alarm 1 이벤트]에는 플레이어 재생성할 때 필요한 변수를 초기화 시켜놓습니다.
★ obj_game_user - Alarm 1 이벤트 ★ user_regen = 0; |
서버 오브젝트로 돌아가서 서버 유저의 게임 유저 오브젝트를 생성할 때, 변수값을 미리 할당합니다.
★ obj_server_system - Create 이벤트 ★ global.player_max = 5; //클라이언트 최대 접속 수( 서버 유저 제외 ) global.game_room = -1; //게임룸 global.user_id = 0; //현재 서버 유저 ID global.socketlist = ds_list_create( ); global.player_map = ds_map_create( ); global.net_buffer = buffer_create( 256, buffer_grow, 1 ); global.server_socket = network_create_server( network_socket_tcp, 6510, global.player_max ); if global.server_socket< 0{ //서버 생성 실패했을 때 instance_destroy( ); show_message_async( "서버 생성에 실패했습니다." ) room_goto( Room_open ); } else{ //서버 생성 성공했을 때 global.select_server = 1; //---------- ▼ 게임 유저 초기 설정 var inst = instance_create_depth( 0, 0, 0, obj_game_user ); inst.user_name = global.playername; //유저 이름 inst.user_id = 0; //서버의 유저 ID는 0, 클라이언트는 1~ inst.select = 1; //서버 유저 선택 inst.room_sync = 1; //룸 동기화 //---------- ▲ 게임 유저 초기 설정 global.game_room = Room_game_1; room_goto( Room_game_1 ); } |
룸 동기화 체크(room_sync)는 클라이언트가 지정한 룸으로 정확히 이동했는지 체크하는 부분입니다.
서버는 룸을 바로 이동할 수 있지만, 클라이언트는 서버에 어느 룸으로 이동할지 요청하고, 서버에서 지정하면
룸을 이동합니다.
게임 룸의 맵을 업데이트해야 할 때, 서버와의 통신에 지연시간이 발생하면 엉뚱한 룸에서 맵을 업데이트 해버릴 수 있습니다.
이것을 방지하기 위해, 지정한 룸에 완전히 이동한 다음, 서버에 동기화 요청을 하고 룸의 맵을 업데이트하도록 합니다.
[Destroy 이벤트]를 추가하고, 메모리에서 제거해야하는 기능은 파기하도록 합니다.
★ obj_server_system - Destroy 이벤트 ★ if !( global.server_socket<0 ){ network_destroy( global.server_socket ); } buffer_delete( global.net_buffer ); ds_list_destroy( global.socketlist ); ds_map_destroy( global.player_map ); with( obj_game_user ){ instance_destroy( ); } |
서버 오브젝트를 파기할 때, 게임 유저 오브젝트도 같이 삭제하도록 합니다.
그리고 [Game End 이벤트]를 추가하고, 같은 내용을 추가합니다.
★ obj_server_system - Game End 이벤트 ★ if !( global.server_socket<0 ){ network_destroy( global.server_socket ); } buffer_delete( global.net_buffer ); ds_list_destroy( global.socketlist ); ds_map_destroy( global.player_map ); |
게임 화면을 간편하게 설정해봅시다.
아래 스크립트는 어떤 룸으로 이동하든 룸의 카메라의 크기를 지정한 설정으로 자동으로 처리해줍니다.
※ 다만, 처음 실행되는 룸의 크기가 게임화면의 기준이 됩니다.
★ 스크립트 ★ //카메라 자동 설정 function set_carmera_auto( ){ var vw, vh; vw = 800; //게임 화면 너비 vh = 600; //게임 화면 높이 view_enabled = 1; view_set_visible( 0, 1 ); camera_set_view_size( view_camera[0], vw, vh ); view_xport[0] = 0; view_yport[0] = 0; view_wport[0] = vw; view_hport[0] = vh; display_set_gui_size( vw, vh ); if window_get_fullscreen( ) == 0{ window_set_size( vw, vh ); } camera_set_view_border( view_camera[0], vw, vh ); camera_set_view_speed( view_camera[0], -1, -1 ); } //카메라 오브젝트 자동 설정 function set_carmera_target( ){ with( obj_player_parent ){ if select == 1{ camera_set_view_target( view_camera[0], id ); }} } |
[Room Start 이벤트]를 추가하고, 룸으로 이동할 때마다 카메라를 자동으로 설정하도록 합니다.
★ obj_server_system - Room Start 이벤트 ★ set_carmera_auto( ); //카메라 자동 설정 if ( room == Room_open ){ //메인 화면으로 돌아갔을 때는 서버 오브젝트 파기 global.game_room = -1; instance_destroy( ); } |
[Room End 이벤트]에는 유저 오브젝트의 플레이어 재생성에 관련된 변수를 초기화 시킵니다.
★ obj_server_system - Room End 이벤트 ★ with( obj_game_user ){ user_gameplay = noone; user_regen = 0; if user_id > 0{ room_sync = 0; }//클라이언트는 동기화 요청 대기 } |
여기까지 서버 생성을 마쳤습니다.
다음 강좌에서는 본격적으로 게임 캐릭터의 이동에 대해 만들어 봅시다.
'GameMaker강좌[GMS2] > 네트워크강좌' 카테고리의 다른 글
[게임메이커 강좌-네트워크][GMS2] 멀티플레이어 게임 만들기-4-클라이언트 (0) | 2024.12.25 |
---|---|
[게임메이커 강좌-네트워크][GMS2] 멀티플레이어 게임 만들기-3-서버 게임 구성 (0) | 2024.12.25 |
[게임메이커 강좌-네트워크][GMS2] 멀티 플레이어 게임 만들기-1-메인화면 (1) | 2024.12.25 |
[게임메이커 강좌-네트워킹][GMS2] 채팅 프로그램 만들기-6-네트워크 연결 지연에 따른 설정(Ping) (0) | 2024.12.24 |
[게임메이커 강좌-네트워킹][GMS2] 채팅 프로그램 만들기-5-접속자 표시 (0) | 2024.12.24 |
댓글