한성대학교 3학년 2학기 네트워크프로그래밍 프로젝트
팀원
- 이경석 – 2171073 (Server Architecture & Core Logic)
- 김준현 – 2171062 (Client GUI & Item Features)
본 프로젝트는 Java(Swing GUI) 와 TCP 소켓 통신(ServerSocket/Socket) 기반으로 제작한
2인 네트워크 러시안 룰렛 게임입니다.
LAN/Wi-Fi 환경에서 두 명의 플레이어가 서버에 접속하여
턴 기반 러시안 룰렛 전투를 실시간으로 진행하도록 구현되었습니다.
- Java 17 ~ Java 21
- Eclipse IDE / IntelliJ IDEA
- Windows / macOS 지원
- Swing GUI 기반 HUD 인터페이스
- TCP Socket + UTF-8 스트림
- 멀티스레드 서버 구조(ClientHandler)
- 텍스트 기반 커스텀 통신 프로토콜
- 이미지 렌더링 기반 HP/Life/Item 표시
- 서버 1대 + 클라이언트 2대
- 동일 LAN 환경에서 IP·포트 입력 후 접속
- Server Authoritative 구조로 모든 판정을 서버가 담당
🎯 Final Phase 목표: 전투 시스템 + 아이템 전략 + GUI 연동 완성
- 2인 매칭 및 닉네임 교환
- READY 동기화
- 코인토스 기반 초기 턴 배정
- 6칸 탄창(BULLET/BLANK 랜덤)
- 조준(AIM) SELF / ENEMY
- 발사(FIRE) → HP 감소 + 턴 교대
- SELF + BLANK → 턴 유지
- HP UI / 라이프 이미지 표시
- 총 이미지 회전 애니메이션(상·하·좌·우)
- 아이템 3종 (Heal, Search, Bomb) 구현
- 채팅 기능
- EXIT_ROOM 처리
- 사운드 효과
- 카드 시스템 → 아이템 시스템으로 대체
| 조준 대상 | 탄 종류 | 결과 | 턴 변화 |
|---|---|---|---|
| SELF | BLANK | 생존(Risk Success) | 유지 |
| SELF | BULLET | HP -1 | 교대 |
| ENEMY | BLANK | 아무 일 없음 | 교대 |
| ENEMY | BULLET | 상대 HP -1 | 교대 |
- HP 초기값: 5
- HP가 0 이하 → 즉시 패배
- 탄창 6칸 모두 소모 → 서버가 자동으로 재장전
| 코드 | 아이템명 | 효과 |
|---|---|---|
| H | Heal | HP +1 회복 (최대 5) |
| S | Search | 다음 탄환이 BULLET/BLANK인지 확인 |
| B | Bomb | 다음 실탄 명중 시 피해 2배 |
- HUD 슬롯 최대 6개
- 사용 키: 1~6번
- Search 결과는 본인에게만 비공개 메시지로 전달
- Bomb 효과는 다음 발사(FIRE) 1회에만 적용됨
src/
├─ server/
│ ├─ ServerGuiMain.java # 서버 GUI 진입점
│ ├─ ServerFrame.java # 서버 로그 및 제어 창
│ ├─ Room.java # ★ 핵심 로직 (턴, 판정, 동기화)
│ ├─ ClientHandler.java # 클라이언트별 통신 스레드
│ ├─ Protocol.java # 통신 명령어 정의
│ └─ ServerCore.java # 소켓 Accept 관리
└─ client/
├─ ClientMain.java # 클라이언트 진입점
├─ StartFrame.java # 접속 UI
├─ RoomFrame.java # 대기실 UI
├─ GameRoomFrame.java # ★ 인게임 UI & 키 입력 처리
├─ ImageLoader.java # 리소스 로딩 유틸리티
└─ NetworkClient.java # 서버 송수신 스레드
resources/
└─ images/ # 배경/플레이어/총/라이프/아이템 이미지 리소스
본 게임은 Event-Driven 아키텍처를 기반으로 하며,
클라이언트 입력(Input) →
NetworkClient전송(Command) →
서버ClientHandler수신 →Room에서 로직 처리(Logic) →
결과를 모든 클라이언트에 브로드캐스트(Broadcast)
라는 흐름으로 동작합니다.
ServerGuiMain→ServerFrame에서 포트 입력 후 Start 클릭ServerCore가ServerSocket을 열고acceptLoop()로 클라이언트 2명을 기다림- 클라이언트가 접속하면 각각에 대해
ClientHandler스레드를 생성
ClientMain실행 →StartFrame에서 Host / Port / Name 입력- 내부적으로
NetworkClient가 서버와 소켓 연결 - 연결 직후 서버에서
HELLO를 보내고, 클라이언트는 닉네임 문자열을 전송 ClientHandler가 이 닉네임을 읽어Room에 등록
- 서버에서 두 명이 모두 접속하면
Room객체를 생성 Room이 각 클라이언트에게ENTER_ROOM,ROOM_STATUS등을 보내
둘 다RoomFrame(대기실 화면) 으로 진입- 이 시점부터 각
ClientHandler는- 클라이언트 → 서버: 텍스트 한 줄씩 읽기
- 서버 → 클라이언트:
Room.broadcast()/sendTo()로 전송
구조로 고정됨
- 사용자가
RoomFrame의 READY 버튼 클릭 RoomFrame→NetworkClient.sendLine()을 통해- Client → Server :
READY문자열 전송
- Client → Server :
ClientHandler가READY를 수신Room의onReady()(또는 이에 해당하는 메서드) 에 전달Room은 내부에isReadyP1,isReadyP2같은 플래그를 갱신- 각 상태 변경 시
- Server → All :
READY_STATE ...를 전송하여
두 클라이언트의 대기실 화면에 “준비 완료” 상태를 표시
- Server → All :
- 두 명 모두 Ready 상태가 되면
Room.startGame()실행- 6칸 탄창 랜덤 생성 (실탄/공탄 배열)
- 초기 HP, 턴, 조준 방향, 아이템 목록 등 초기 상태 셋업
- 이후 아래 순서로 메시지들을 브로드캐스트
GAME_START:RoomFrame→GameRoomFrame으로 화면 전환RELOAD: 새 탄창 정보 동기화AIM_UPDATE: 기본 조준(SELF) 설정TURN: 첫 턴 플레이어 지정ITEM_UPDATE: 처음 지급된 아이템 목록 전송
핵심 원칙: 모든 판정은 서버
Room이 담당한다.
클라이언트는 “입력 + 화면 표시”에만 집중한다.
인게임 동안 주요 이벤트는 조준(AIM), 아이템 사용(USE_ITEM), 발사(FIRE) 세 가지입니다.
GameRoomFrame에서KeyListener가 방향키 입력을 감지↑ / ↓입력에 따라 현재 조준 대상을 SELF / ENEMY 로 바꾸고- Client → Server :
AIM SELF또는AIM ENEMY를 전송 - 이 전송은 항상
NetworkClient.sendLine()으로 이루어짐
- Client → Server :
ClientHandler가 수신한 문자열이Protocol.AIM으로 시작하는지 확인Room.onAim(player, target)과 같은 메서드에 위임- 내부에서 해당 플레이어의 조준 상태를 변경
- 턴 검사(자기 턴이 아닌 경우 무시 등)가 이 안에서 이루어짐
- 처리 결과를 바탕으로
- Server → All :
AIM_UPDATE WHO=P1 TARGET=SELF형식으로 전송
- Server → All :
- 각 클라이언트의
NetworkClient가 이를 수신하여GameRoomFrame.applyAimUpdate()같은 메서드를 호출- 총 이미지 각도/방향을 갱신하여 회전 애니메이션 과 HUD 를 일치시키게 됨
- 플레이어가
1~6숫자 키를 누르면GameRoomFrame의 키 이벤트 → 선택된 아이템 슬롯 인덱스를 계산- Client → Server :
USE_ITEM SLOT=n문자열 전송
ClientHandler가USE_ITEM메시지를 읽어Room.onUseItem(player, slot)호출Room내부 로직:- 해당 슬롯에 아이템이 없으면 무시
Heal(H)인 경우 → HP +1 (최대 5), 변경된 HP를 저장Search(S)인 경우 → 현재/다음 탄 정보를 확인Bomb(B)인 경우 → “다음 실탄 명중 시 2배 피해” 플래그 설정
- 공통적으로, 아이템은 사용 후 슬롯에서 제거 처리
- HP/아이템 상태 변화:
- Server → All :
ITEM_UPDATE WHO=P2 ITEMS=H---B-같은 형식으로 전체 HUD 를 갱신
- Server → All :
- Search 처럼 비공개 정보는:
- Server → 해당 플레이어에게만 :
PEEK_RESULT TYPE=BULLET - 상대 플레이어에게는 전송하지 않음
- Server → 해당 플레이어에게만 :
GameRoomFrame의KeyListener가Spacebar입력 감지- 자기 턴일 때만
- Client → Server :
FIRE전송
- Client → Server :
- 턴 검증
- 현재 턴이 아닌 플레이어가 쏘면 무시 또는 에러 처리
- 탄창 판정
currentIndex위치의 탄이BULLET인지BLANK인지 확인- Bomb 플래그가 켜져 있으면 데미지 2배 적용
- HP/게임 상태 변경
- SELF / ENEMY 조준에 따라 피해 대상 결정
- HP 감소 후
hp <= 0이면 승패 판정
- 턴/인덱스 갱신
- ENEMY + BLANK 인 경우에도 턴 교대
- SELF + BLANK 인 경우에는 턴 유지
- 사용한 탄을 기준으로
currentIndex++ - 6발 모두 사용 시 새 탄창을 만들고
RELOAD브로드캐스트
- 결과 패킷 생성
FIRE_RESOLVE RESULT=BULLET TARGET=ENEMY HP1=4 HP2=3 INDEX=2형태로 결과 문자열 구성
- Server → All : 위
FIRE_RESOLVE메시지 전송 - 각 클라이언트에서
NetworkClient가 메시지를 읽고GameRoomFrame.applyFireResult()에 전달- HP 바 / 라이프 이미지 / 탄창 인덱스 / 로그 텍스트 등을 갱신
- 서버에서 Search 판정을 한 뒤
- Server → 해당 플레이어 :
PEEK_RESULT TYPE=BULLET
- Server → 해당 플레이어 :
GameRoomFrame은 이 패킷을 받아- 화면 하단 로그 또는 팝업으로
“다음 탄: 실탄 / 공탄” 을 표시하지만 - 반대편 클라이언트는 아무 정보도 받지 못함
- 화면 하단 로그 또는 팝업으로
Room.onFire()안에서 HP가 0 이하가 되는 순간- 승자/패자를 결정하고
- Server → All :
GAME_OVER WINNER=P1형식의 패킷을 전송
- 클라이언트는
- 팝업 또는 HUD 메시지로 “P1 승리” 등을 표시하고
- 입력을 막은 뒤, 종료 또는 다시 접속을 유도하도록 처리
- 사용자가 게임 도중 창을 닫거나 나가기 버튼을 누르면
- Client → Server :
EXIT_ROOM전송
- Client → Server :
- 서버
Room.onExit()에서- 해당 플레이어를 제거하고
- 남은 플레이어에게
- Server → Other :
EXIT_ROOM알림 전송
- Server → Other :
- 남은 클라이언트는
- 팝업 “상대방이 퇴장했습니다.” 표시 후
- 메인 화면 또는 종료 상태로 돌아감
요약하면,
GameRoomFrame에서 발생한 모든 입력 →NetworkClient→ClientHandler→Room→ 다시NetworkClient→GameRoomFrame
으로 순환하는 구조이며,
실제 판정과 수치는 항상Room에서만 계산되도록 설계되어
동기화 문제와 치트 가능성을 줄이는 구조입니다.
ServerGuiMain실행- 포트 입력 (예: 7777)
- Start 클릭
- 로그에 아래 표시되면 준비 완료
[Server] Listening on 7777
ClientMain두 번 실행- Host / Port / Name 입력
- Connect 클릭
- 두 명 READY → GAME_START
| 키 | 설명 |
|---|---|
| ↑ / ↓ | 조준 방향 변경 (SELF / ENEMY) |
| SPACE | 발사 |
| 1~6 | 아이템 사용 |
| Chat 버튼 | 채팅 열기 |
| 창 닫기(X) | EXIT_ROOM 후 종료 |
| 구성 | 설명 |
|---|---|
| 통신 방식 | TCP 기반, UTF-8 텍스트 프로토콜 |
| 서버 구조 | ClientHandler 스레드 + Room에서 모든 로직 관리 |
| 클라이언트 | 입력 처리 / 이미지 렌더링 / HUD 담당 |
| 게임 로직 | 턴, HP, 탄창, AIM/FIRE, 아이템 모두 서버에서 판정 |
| 확장성 | 멀티룸, 로그, 관전자 모드 등 확장 가능 |
본 프로젝트는 네트워크 통신 + 실시간 게임 로직 + GUI 렌더링 + 아이템 전략 시스템을
하나의 구조로 통합한 실전형 턴제 네트워크 게임입니다.
- HP / 턴 / 탄창 / 아이템 등 모든 상태를 단일하게 관리
- 클라이언트는 그 결과만 반영
- 동기화 문제 없이 안정적
- 입력 처리
- HUD 렌더링
- 이미지 로딩
- 애니메이션
에 집중하도록 설계되었습니다.
학습 목적 + 실전 구조를 모두 갖춘 완성도 높은 네트워크 게임 프로젝트입니다.