Skip to content

Commit

Permalink
구조 문서화 9
Browse files Browse the repository at this point in the history
- 인트로, 발표용 / 제출용 분리
  • Loading branch information
MineEric64 committed Aug 23, 2023
1 parent 16b2ebc commit c9e449d
Show file tree
Hide file tree
Showing 25 changed files with 189 additions and 141 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ python main.py
또는 `main.py` 파일을 실행하시면 됩니다.

## 게임 구조
- [게임 구조를 알고 싶으시다면?](./docs/README.md)
- [발표용](./docs/presentation/README.md): 구조에 관해 되게 간단하고 짧은 설명
- [제출용](./docs/submission/README.md): 구조에 관해 엄청 길고 자세한 설명

## 크레딧
- [2023 전국 청소년 오픈SW GAME 코딩대회](https://histarter0829.wixsite.com/2nd-hygamejam)에 참가한 작품입니다.
Expand Down
Binary file added docs/images/intro_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/intro_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/intro_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions docs/presentation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# 게임 구조 (발표용)
|이름|설명|
|:---:|:---:|
|[동적 카메라](./dynamic_camera.md)|.|
|[업스케일링](./upscailing.md)|.|
|[마우스 좌표](./mouse_position.md)|.|
|[동적 텍스트 애니메이션](./dynamic_text_animation.md)|.|
|[중력 & 점프](./gravity_and_jump.md)|.|
|[무적 시간](./grace_period.md)|.|
|[충돌 감지](./bound.md)|.|
|[스프라이트](./sprite.md)|.|
|[캐릭터](./characters.md)|.|
|[체력](./hp_bar.md)|.|
|[버튼](./button.md)|.|
|[사망 이벤트](./dead_event.md)|.|
|[ESC 화면](./pause_menu.md)|.|
|[설정](./settings.md)|.|
|[인트로](./intro.md)|
|[메인 메뉴](./menu.md)|
|[SFX](./sfx.md)|.|
|[CLI](./cli.md)|.|

- 설명 흐름 기준

## TODO (우선순위 기준)
- [ ] 월드 좌표 + 업스케일링 + 마우스 좌표
- [ ] 동적 텍스트 애니메이션 (+ 자동 newline)
- [ ] 시간 관리 (예정)
- [ ] 중력 + 점프
- [ ] 스프라이트
- [ ] 캐릭터
- [ ] 무적 시간
- [ ] 체력 (+ 체력 회복 (예정))
- [ ] 충돌 감지
- [ ] 버튼
- [ ] 사망 이벤트
- [ ] ESC 화면
- [ ] 설정
- [ ] 인트로
- [ ] 메인 메뉴
- [ ] SFX
- [ ] CLI
12 changes: 7 additions & 5 deletions docs/README.md → docs/submission/README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
# 게임 구조
# 게임 구조 (제출용)
|이름|설명|
|:---:|:---:|
|[동적 카메라](./dynamic_camera.md)|.|
|[업스케일링](./upscailing.md)|.|
|[마우스 좌표](./mouse_position.md)|.|
|[동적 카메라](./dynamic_camera.md)|. (완성)|
|[업스케일링](./upscailing.md)|. (완성)|
|[마우스 좌표](./mouse_position.md)|. (완성)|
|[동적 텍스트 애니메이션](./dynamic_text_animation.md)|. (인게임 제외 완성)|
|[중력 & 점프](./gravity_and_jump.md)|. (인게임 제외 완성)|
|[무적 시간](./grace_period.md)|. (인게임 제외 완성)|
|[충돌 감지](./bound.md)|. (인게임 제외 완성)|
|[스프라이트](./sprite.md)|. (인게임 제외 완성)|
|[캐릭터](./characters.md)|. (인게임 제외 완성)|
|[체력](./hp_bar.md)|.|
|[버튼](./button.md)|.|
|[버튼](./button.md)|. (완성)|
|[사망 이벤트](./dead_event.md)|.|
|[ESC 화면](./pause_menu.md)|.|
|[설정](./settings.md)|.|
|[인트로](./intro.md)|
|[메인 메뉴](./menu.md)|
|[SFX](./sfx.md)|.|
|[CLI](./cli.md)|.|

Expand Down
6 changes: 3 additions & 3 deletions docs/bound.md → docs/submission/bound.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# 충돌 감지
![1](./images/bound_1.png)
![1](../images/bound_1.png)

1. `obj_x` / `obj_y``-1`인 경우, 비교할 좌표를 플레이어 좌표로 설정
2. 그렇지 않은 경우, 비교할 좌표를 사용자 지정 좌표로 설정
Expand All @@ -12,5 +12,5 @@
- 추가 필요

## 참조
- [`characters/__init__.py`](../characters/__init__.py)
- [`ingame.py`](../screens/ingame.py)
- [`characters/__init__.py`](../../characters/__init__.py)
- [`ingame.py`](../../screens/ingame.py)
14 changes: 7 additions & 7 deletions docs/button.md → docs/submission/button.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 버튼
![1](./images/button_1.png)
![2](./images/button_2.png)
![1](../images/button_1.png)
![2](../images/button_2.png)

1. 버튼 이미지 설정
2. 좌표 설정 후 `camera_calibrated` 변수가 `True`인 경우 카메라 보정값 추가
Expand All @@ -11,7 +11,7 @@
7. 텍스트가 지정되어 있는 경우 텍스트 좌표 & 크기 (Rect) 설정, 이 때 오프셋이 있는 경우 오프셋만큼 좌표 이동

## 렌더링
![3](./images/button_3.png)
![3](../images/button_3.png)

1. 이미지가 지정되어 있는 경우 이미지 렌더링
2. 텍스트가 지정되어 있는 경우 텍스트 렌더링
Expand All @@ -20,23 +20,23 @@
텍스트는 덮어씌워지므로 렌더링 순서가 중요함.

## 클릭 확인
![4](./images/button_4.png)
![4](../images/button_4.png)

마우스 커서 좌표가 버튼 Rect 범위에 해당하는지 확인

- 이 때, `check_for_input()` 함수는 마우스 클릭 이벤트가 발생했을 때만 호출됨

## Hovering 시 색상 변경
![5](./images/button_5.png)
![5](../images/button_5.png)

1. 마우스 커서 좌표가 버튼 Rect 범위에 해당하는지 확인
2. 버튼에 마우스 포인터가 올라가면 Hovering 색상으로 변경, 그렇지 않으면 기본 색상으로 변경
3. 안티 에일리어싱 없이 해당 색상으로 폰트 렌더링

## 버튼 이미지 변경
![6](./images/button_6.png)
![6](../images/button_6.png)

- 설정 및 ESC 화면에서 유용하게 쓰임.

## 참조
- [`button.py`](../components/button.py)
- [`button.py`](../../components/button.py)
28 changes: 14 additions & 14 deletions docs/characters.md → docs/submission/characters.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# 캐릭터
## 상속
![1](./images/characters_1.png)
![1](../images/characters_1.png)

`Character`: 플레이어, 적 및 텍스쳐 등 오브젝트의 기본 요소를 포함한 클래스

단일 이미지 / 다중 스프라이트 둘 다 지원하여,
그 중에 하나를 선택할 수 있음.

## 초기화
![2](./images/characters_2.png)
![3](./images/characters_3.png)
![2](../images/characters_2.png)
![3](../images/characters_3.png)

1. 다중 스프라이트로 초기화하는 경우 빈 클래스로 반환 => `Player.get_from_sprite()`에서 이어짐
2. 단일 이미지 생성 및 관련 변수 설정
Expand All @@ -20,20 +20,20 @@
7. 좌표 및 크기 변수 초기화 후 `is_playable` 변수를 통하여 플레이어인 경우 관련 변수 업데이트

## 카메라 (화면) 안 범위 확인
![4](./images/characters_4.png)
![4](../images/characters_4.png)

1. 카메라 범위를 가져온 후 관련 변수 설정
2. 범위 확인 후 보정값 추가, 오차를 보정해야하는 경우 오차 보정값 추가

## 단일 이미지 / 다중 스프라이트 구분
![6](./images/characters_6.png)
![6](../images/characters_6.png)

`__init__()` (생성자 함수)에서 다중 스프라이트로 선택했으면 `image_path` 변수가 기본값으로 설정되었으므로,

`image_path`가 비어있으면 다중 스프라이트인 것을 알 수 있음.

## 렌더링
![5](./images/characters_5.png)
![5](../images/characters_5.png)

1. 최적화가 설정되어있고 카메라 범위에 벗어나있으면 렌더링할 필요 없으므로 종료 (`is_camera_bound()` 함수 이용)
2. 사용자 지정 렌더링할 화면이 없는 경우 렌더링할 화면을 기본값인 `CONFIG.surface` 화면으로 지정
Expand All @@ -43,7 +43,7 @@

## 플레이어
### 움직임
![7](./images/characters_7.png)
![7](../images/characters_7.png)

X 좌표, Y 좌표 각각 속도 매개변수를 이용하여 이동시킴

Expand All @@ -53,20 +53,20 @@ X 좌표, Y 좌표 각각 속도 매개변수를 이용하여 이동시킴
`move_x()`에서 따로 조건문이 있는 것은 세계 좌표 범위 밖을 벗어나지 않기 위함.

### 움직이는 방향으로 이미지 좌우반전
![8](./images/characters_8.png)
![8](../images/characters_8.png)

1. 단일 이미지 / 단일 스프라이트 / 다중 스프라이트인지 확인 후 각자 맞는 형식 지정
2. 속도 방향과 현재 이미지 방향이 같지 않은 경우, 좌우 반전시킴

### 다중 스프라이트를 사용하는 Player 클래스 생성
![9](./images/characters_9.png)
![9](../images/characters_9.png)

1. 기본 생성자 (`__init__()`)에서는 단일 이미지만 지원하므로 빈 클래스로 초기화 후 다중 스프라이트 추가
2. 관련 변수 초기화
3. 플레이어면 플레이어 관련 변수 업데이트

##
![10](./images/characters_10.png)
![10](../images/characters_10.png)

1. 적의 체력이 0 이하인 경우 사망한 것이므로 종료
2. `is_camera_bound()` 함수를 이용하여 플레이어 화면 범위 안에 있는 경우 (이 때, 플레이어 배려를 위하여 약간의 보정값 추가) 속도 추가
Expand All @@ -77,7 +77,7 @@ X 좌표, Y 좌표 각각 속도 매개변수를 이용하여 이동시킴
- 추가 필요

## 참조
- [`characters/__init__.py`](../characters/__init__.py)
- [`characters/player.py`](../characters/player.py)
- [`characters/enemy.py`](../characters/enemy.py)
- [`ingame.py`](../screens/ingame.py)
- [`characters/__init__.py`](../../characters/__init__.py)
- [`characters/player.py`](../../characters/player.py)
- [`characters/enemy.py`](../../characters/enemy.py)
- [`ingame.py`](../../screens/ingame.py)
File renamed without changes.
File renamed without changes.
14 changes: 7 additions & 7 deletions docs/dynamic_camera.md → docs/submission/dynamic_camera.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
# 동적 카메라
## 1
![1](./images/dynamic_camera_1.png)
![1](../images/dynamic_camera_1.png)

화면 (카메라) 크기를 정해준 뒤, 주인공이 돌아다닐 세계 크기도 정함

## 2
![2](./images/dynamic_camera_2.png)
![2](../images/dynamic_camera_2.png)

카메라가 어디까지 움직였는지 저장할 좌표 변수 선언

## 3
![3](./images/dynamic_camera_3.png)
![4](./images/dynamic_camera_4.png)
![5](./images/dynamic_camera_5.png)
![3](../images/dynamic_camera_3.png)
![4](../images/dynamic_camera_4.png)
![5](../images/dynamic_camera_5.png)

1. 매 프레임 업데이트마다 플레이어가 어느만큼 움직였는지 X좌표를 계산
2. 카메라 좌표가 플레이어 중심으로 움직이게 설정
3. 세계 크기에서 오프셋을 카메라 좌표만큼 이동
4. 화면 (카메라) 크기만큼 잘라서 세계 좌표를 카메라 좌표로 변환

## 결과
![6](./images/dynamic_camera_6.gif)
![6](../images/dynamic_camera_6.gif)

세계 좌표는 움직이지 않고 고정이지만
카메라 좌표만 움직임.
Expand All @@ -29,4 +29,4 @@
관리 및 유지 보수가 매우 편함.

## 참조
- [`config.py`](../components/config.py)
- [`config.py`](../../components/config.py)
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# 동적 텍스트 애니메이션
## Mutual Text
![1](./images/dynamic_text_animation_1.png)
![1](../images/dynamic_text_animation_1.png)

**Mutual Text**는 상호작용할 텍스트를 구분하기 위해 만들어진 클래스로,
접두어를 기준으로 나눔

즉, 텍스트에 접두어가 다양할수록 Mutual Text 배열은 많아짐.

## Text
![2](./images/dynamic_text_animation_2.png)
![2](../images/dynamic_text_animation_2.png)

**Text**는 Mutual Text의 배열로, 렌더링할 텍스트 (문자열) 한 단위를 말함.

아래 주석은 각 접두어가 무슨 역할을 하는지 적어놓음.

### 초기화
![3](./images/dynamic_text_animation_3.png)
![3](../images/dynamic_text_animation_3.png)

- `raw`: 접두어가 포함된 텍스트
- `pure`: 접두어가 포함되지 않은 순수 텍스트
Expand All @@ -24,7 +24,7 @@
텍스트 안에 접두어가 있는 경우 `has_prefix``True`로 설정 후,
접두어만 삭제한 순수 텍스트 저장

![4](./images/dynamic_text_animation_4.png)
![4](../images/dynamic_text_animation_4.png)

- `is_started`: 접두어가 있는지 확인
- `mutual_text_`: 각 접두어별 텍스트
Expand All @@ -43,25 +43,25 @@
즉, 상호작용할 텍스트인 `MutualText`의 배열임.

### 문자 렌더링
![5](./images/dynamic_text_animation_5.png)
![6](./images/dynamic_text_animation_6.png)
![5](../images/dynamic_text_animation_5.png)
![6](../images/dynamic_text_animation_6.png)

1. 접두어별 맞는 폰트 지정
2. pt를 픽셀로 변환

![7](./images/dynamic_text_animation_7.png)
![7](../images/dynamic_text_animation_7.png)

1. 줄바꿈 접두어면 좌표를 지정, Carrige Return과 Line Feed 기능과 비슷함
2. 검정색인 문자 생성 후 화면에 렌더링
3. X 좌표를 변환한 픽셀 수만큼 이동
4. 새롭게 갱신된 문자 좌표 (위치) 반환

## TextCollection
![8](./images/dynamic_text_animation_8.png)
![8](../images/dynamic_text_animation_8.png)

`TextCollection`: `Text` 클래스 배열, 여러 말을 해야할 때 쓰이는 클래스

![9](./images/dynamic_text_animation_9.png)
![9](../images/dynamic_text_animation_9.png)

1. `Text``MutualText` 열거
2. 접두어를 확인하여 각 접두어별 맞는 폰트 크기 지정
Expand All @@ -73,24 +73,24 @@
8. 현재 출력할 `Text` 클래스와 다음 출력할 `Text` 클래스 지정

### 대화 (텍스트) 이동
![10](./images/dynamic_text_animation_10.png)
![10](../images/dynamic_text_animation_10.png)

1. 모든 대화 (텍스트)를 다 본 경우 `index` 변수 초기화 후 텍스트 새롭게 지정 (리셋)하고 `False` 반환
2. 아닌 경우 `index`를 더한 후 텍스트 지정하고 `True` 반환

## TextEvent
![11](./images/dynamic_text_animation_11.png)
![11](../images/dynamic_text_animation_11.png)

대화 이벤트 처리

### 다음 대화창 이벤트
![12](./images/dynamic_text_animation_12.png)
![12](../images/dynamic_text_animation_12.png)

각 변수에 따라 대화창 출력을 지연시키지 않고 완성시켜야 할지,
다음 대화창으로 넘겨야할지 이벤트를 처리함

### 대화 애니메이션 이벤트
![13](./images/dynamic_text_animation_13.png)
![13](../images/dynamic_text_animation_13.png)

- `mutual_index`: 현재 `Text` 클래스 속 `MutualText` 배열 index 저장
- `mutual_text_index`: 현재 `MutualText` 클래스의 텍스트 (문자열) index 저장
Expand All @@ -113,15 +113,15 @@
- 추가 필요

## 결과
![14](./images/dynamic_text_animation_14.gif)
![14](../images/dynamic_text_animation_14.gif)

`MutualText`, `Text`, `TextCollection`, `TextEvent` 클래스의 조화로 이루어진 종합적인 결과

- 코드가 많고 복잡한 데도 불구하고 30FPS 유지, 디자인과 성능을 모두 고려한 예술 작품

## 참조
- [`text/mutual_text.py`](../components/text/mutual_text.py)
- [`text/__init__.py`](../components/text/__init__.py)
- [`text/text_collection.py`](../components/text/text_collection.py)
- [`events/text.py`](../components/text.py)
- [`ingame.py`](../screens/ingame.py)
- [`text/mutual_text.py`](../../components/text/mutual_text.py)
- [`text/__init__.py`](../../components/text/__init__.py)
- [`text/text_collection.py`](../../components/text/text_collection.py)
- [`events/text.py`](../../components/text.py)
- [`ingame.py`](../../screens/ingame.py)
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit c9e449d

Please sign in to comment.