Skip to content

JAVA의 GUI를 이용하여 간단한 슈팅게임을 제작. 최대한 캡슐화를 시켜서 깔끔한 코드를 만들어보기 위함.

Notifications You must be signed in to change notification settings

BrandPark/Bullet-Shooting-Game-JAVA_GUI-

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

프로젝트 계기

3학년 때 학교 과제로 엘리베이터 시뮬레이션을 GUI로 만들어 제출한 적이 있다. 모든 과제의 채점을 마친 교수님은 내 과제물을 칭찬을 하며 나와서 발표 해보라고 하셨다.

발표를 마치고 자리로 돌아오자 옆자리 친구가 코드 좀 볼 수 있냐고 물어봤고 흔쾌히 보여주었다. 친구는 내게 "코드가 되게 더럽다" 고 하며 보다가 포기를 하였다. 충격을 받은 나는 객관적으로 코드를 살펴보았고 친구의 피드백에 동의할 수 밖에 없었다.

그 후 나는 읽기 쉬운 코드, OOP, 유지보수성이 높은 코드, 클린 코드가 무엇인지에 대해 알아보기 시작했다. 4학년이 되어 일학습병행제 학습생으로 인턴처럼 실무를 나가게 되었는데 출근 길에는 핸드폰을 통해 블로그 글과 유튜브 강의 영상을 보거나 "Effective JAVA" 책으로 공부를 하였고 개념적으로 감이 잡히자 직접 코드를 작성해 보고 싶었다.

그렇게 퇴근 후에는 프로젝트를 조금씩 만들어보았다. 비행기 게임인 이유는 과제로 만들어 본적이 있었기 때문에 금방 끝낼 수 있을 것 같았기 때문이다.


프로젝트 목표

  • 객체지향적인 사고방식 훈련.
  • 의존성을 관리하여 사이클이 생기지 않게 한다.
  • 객체의 책임과 위임에 대한 이해와 적용 훈련

설계 시 고려사항

  • 응집도를 높여 모듈화하고 모듈간의 결합도는 최소화 한다.
  • 변화가 가능성이 높은 것을 클래스로 만들어 유지보수성을 높인다.
  • 코드의 중복을 제거하여 직관성을 높인 클린코드를 작성한다.
  • 클래스사이의 연관관계가 사이클이 생기지 않도록 한다.
  • 필요하다면 중간객체를 두거나, 추상화를 통해 결합도를 낮춘다.
  • 위임을 이용해 하나의 클래스는 하나의 책임만 갖도록 한다.
  • 메서드는 하나의 기능만을 갖도록 한다.
  • 메서드나 클래스의 접근제어자는 최대한 좁게한다.
  • 메서드안에서의 들여쓰기 값은 되도록 2를 넘기지 않는다.
  • 다형성을 최대한 활용하여 switch문이나 if문의 사용을 최대한 줄인다.
  • 객체들의 의존성의 방향은 항상 변화의 가능성이 적은 쪽을 향하도록 한다.

코딩 규칙

OOP를 글로만 공부를 하고 직접 적용하려고 하니 무엇이 정답인지 모를 때가 많았다. 그래서 반드시 지켜야 할 다음과 같은 규칙을 만들었다.

  1. 의존성 사이클은 생기지 않게 하자.
  2. 코드를 모듈화하여 재사용하기 쉽게 하자.
  3. 되도록 인터페이스를 의존하도록 하자.
  4. 클래스의 가시성을 최대한 작게 하자.
  5. if 문의 사용을 최대한 줄이고 다형성을 활용하자.

프로젝트를 마치고...

최대한 인터페이스를 의존하도록 설계하고 객체들을 잘게 쪼개다 보니 문제가 발생했다.

  • 클래스가 너무 많아져서 헷갈린다.
  • 패키지를 어떻게 나눠야 할 지 잘 모르겠다.
  • 총알 hit 판정과 같은 것을 구현하려면 굉장히 구조가 복잡해졌다.
  • 유지보수성을 위한 응집도를 높이기 힘들다.

객체를 잘게 쪼갤 수록 더 어려워지는 느낌을 받으니 "OOP을 완벽하게 지키는 것이 곧 클린 코드인가?" 완벽한 객체지향보다는 유지보수성을 고려하여 응집도와 결합도간의 타협점을 찾는 것이 클린코드에 더 가까워질 것 같다. 지금 이 고민들은 공부와 경험이 스스로 답을 내리게끔 도와줄 것 같다.

프로젝트를 마치고 여러가지를 느꼈다.

  • OOP도 프로그래밍 도구 중 하나일 뿐이다. 내가 필요할 때 적적한 도구를 꺼내서 사용할 줄 알아야 좋은 코드를 짤 수 있을 것 같다. 그러기 위해서는 깊진 않아도 넓게 아는 것이 필요하다.
  • 완벽하게 설계해서 시작한다는 것은 불가능에 가깝다. 설계를 하나부터 열까지 완벽하게 한다음 하려해도 바뀔 확률이 너무 높고 시간 또한 많이 걸린다.
  • 처음부터 높은 품질의 코드를 만드려는 행위는 어렵다. 빠르게 기능을 동작하게하고 리팩터링하는 것이 훨씬 쉽고 빠른 것 같다.
  • 개인 프로젝트의 규모는 목표에 맞춰 간소화 하는 것이 좋다.
  • 책으로 배우는 것과 직접 만들어 보는 것은 굉장히 다르다.
  • 좋은 코드는 읽기 쉽고 고치기 쉬운 코드다. 책으로 배운 OOP 개념을 적용해 보는 것에만 정신이 팔려 정작 제일 중요한 읽기 쉽고 유지보수성이 높은 코드를 만들지 못했다. 도구는 도구로서 사용하자.

사실 좀 더 게임답게 만들고 싶었지만 생각보다 코드가 점점 복잡해져서 규모를 간소화 하게 되었다. 여러번 코드를 고치다보니 시간도 생각보다 많이 걸려서 처음부터 프로젝트 목표에 맞춰서 GUI 게임보다는 간단한 코드를 짰다면 어땠을까 하는 아쉬움이 있다. 마지막으로 이러한 첫 발을 내딛게 해준 내 친구에게 정말 감사한 마음을 전하고 싶다.


기능 요구사항

  • 유닛
    • 키보드의 방향키로 frame 안에서 움직인다.
    • "Space" or "Z" 키를 누르면 총알을 발사한다.
    • 적의 총알에 3번 맞으면 게임이 끝나고 메인 화면으로 돌아간다.
    • 적의 총알에 맞으면 잠깐 동안 무적 상태가 된다.
  • 적 유닛
    • 총알을 3번 맞으면 사라진다.
    • 두 개체씩 출현하며 총 두 번 출현(Phase)한다.
    • 두 개체가 화면에서 사라지면 다음 페이즈0가 시작된다.
    • 적 유닛은 일정 시간마다 총알을 발사한다.
    • 나올 적 유닛이 없다면 게임은 종료되고 메인 화면으로 돌아간다.
  • 화면 구성
    • 시작화면, 캐릭터 선택화면, 게임 화면 3개로 구성된다.

다이어그램

Game의 객체들의 연관관계를 다이어그램으로 간단히 그려보면 다음과 같다. diagram


해결한 문제


게임 설명

  1. 방향키로 유닛의 움직임이나 버튼의 포커스를 조종할 수 있다.
  2. SPACE_BAR 또는 Z키를 누름으로써 버튼을 누르거나 총알을 발사 할 수 있다.
  3. 총알을 맞으면 캐릭터가 깜박거리며 2초간 무적상태가 된다.
  4. 총알을 3번 맞으면 GAME OVER가 되고 자동으로 Main화면으로 돌아간다.
  5. 적 유닛들은 총알을 3번 맞으면 사라진다.
  6. 두 개체씩 총 두번에 걸쳐서 등장한다.
  7. 모든 유닛들을 제거하고 더이사 나올 유닛이 없다면 GAME CLEAR가 되고 자동으로 Main화면으로 돌아간다.

게임 화면

  • Game Over

game over

  • Game Clear

game clear

About

JAVA의 GUI를 이용하여 간단한 슈팅게임을 제작. 최대한 캡슐화를 시켜서 깔끔한 코드를 만들어보기 위함.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages