-
서버-클라이언트 연결Programming/DirectX12 2022. 3. 30. 00:39
Graduation Project 졸업작품 게임은 3인이서 플레이하는 게임이다.
우선 서버-클라이언트 네트워크 관련 틀을 잡기 위해 플레이어 이동만 구현해보도록 했다.
void GameFramework::OnInit(HINSTANCE hInstance, HWND hWnd) { m_hInstance = hInstance; m_hWnd = hWnd; LoadPipeline(); LoadAssets(); #ifdef NETWORK ConnectServer(); m_networkThread = thread{ &GameFramework::ProcessClient, this, reinterpret_cast<LPVOID>(g_c_socket) }; #endif }
void Scene::ProcessClient(LPVOID arg) { while (g_isConnected) RecvPacket(); }
클라이언트를 켤 때 네트워크 쓰레드를 만들어서 서버와 통신한다.
void Scene::RecvPacket() { // 생략... switch (recv_buf[1]) { // 생략... case SC_PACKET_UPDATE_CLIENT: { sc_packet_update_client packet; memcpy(reinterpret_cast<char*>(&packet), recv_buf, sizeof(recv_buf)); // 나에 대한 정보는 무시 if (m_player->GetId() == packet.data.id) break; for (auto& p : m_multiPlayers) { if (!p) continue; //if (p->GetId() != packet.data.id) continue; if (AnimationInfo* aniInfo{ p->GetAnimationInfo() }) { switch (packet.data.state) { case eLegState::IDLE: if (p->GetCurrAnimationName() != "IDLE" && p->GetAfterAnimationName() != "IDLE") p->PlayAnimation("IDLE", TRUE); break; case eLegState::WALKING: if (p->GetCurrAnimationName() != "WALKING" && p->GetAfterAnimationName() != "WALKING") p->PlayAnimation("WALKING", TRUE); break; case eLegState::WALKLEFT: if (p->GetCurrAnimationName() != "WALKLEFT" && p->GetAfterAnimationName() != "WALKLEFT") p->PlayAnimation("WALKLEFT", TRUE); break; case eLegState::WALKRIGHT: if (p->GetCurrAnimationName() != "WALKRIGHT" && p->GetAfterAnimationName() != "WALKRIGHT") p->PlayAnimation("WALKRIGHT", TRUE); break; case eLegState::WALKBACK: if (p->GetCurrAnimationName() != "WALKBACK" && p->GetAfterAnimationName() != "WALKBACK") p->PlayAnimation("WALKBACK", TRUE); break; case eLegState::RUNNING: if (p->GetCurrAnimationName() != "RUNNING" && p->GetAfterAnimationName() != "RUNNING") p->PlayAnimation("RUNNING", TRUE); break; } } p->SetPosition(packet.data.pos); p->SetVelocity(packet.data.velocity); FLOAT yaw{ p->GetRollPitchYaw().z }; p->Rotate(0.0f, 0.0f, packet.data.yaw - yaw); } break; } // 생략... } }
서버로부터 'SC_PACKET_UPDATE_CLIENT' 패킷을 받으면 해당 멀티플레이어의 정보를 최신화 해준다.
멀티플레이어의 애니메이션, 위치, 속도, 회전각을 설정해준다.
빨강 : 클라이언트, 파랑 : 서버 만약 속도없이 멀티플레이어의 위치만 받아서 갱신해주게 된다면 위의 그림처럼 된다.
원래는 0 ~ 60FPS까지 부드럽게 이동해야겠지만, 30FPS으로 서버가 클라이언트로 데이터를 보내준다면
멀티플레이어은 30FPS로 움직이는 것처럼 보여지게된다.
따라서 속도도 보내줘서 파랑 점 사이의 구간은 전달받은 속도로 움직이게 한다.
그렇게 되면 서버가 몇 FPS로 보내는지에 상관없이 부드럽게 움직인다.
다만 서버가 보내지는 FPS가 낮아지면 그 사이 움직임이 그만큼 부정확해진다.
움직이면서 화면을 돌리는 중 위의 움짤로는 잘 모르겠지만 실제 인게임 화면에선 회전할 때 조금 끊기는 느낌이 든다.
회전도 이동처럼 부드럽게 할 수 있는지는 잘 모르겠다.
'Programming > DirectX12' 카테고리의 다른 글
케스케이드 그림자맵 (2) 2022.04.12 조명과 그림자 (1) 2022.04.10 스카이박스 구조 변경 (0) 2022.03.15 애니메이션하는 객체가 여러 개일 때 발생하던 문제 해결 (0) 2022.03.07 상하체 애니메이션 분리 (0) 2022.03.01