Scene 전환

CJB_ny·2022년 10월 19일
0

JumpKing

목록 보기
5/8
post-thumbnail

전체 코드는 제 깃허브에 있습니다.

https://github.com/starkshn/JumpKing



에러 1

해상도 조절 문제

지금 해상도 조절 해서 실행을 하면은 그대로 적용이 안되는데

원인을 조금 찾자면은 프로젝트 속성문제인거같다.

=> 모든 코드들을 아직 다 구현을 하지 못해서 발생한 문제이다.

Scene 전환 - 1

글의 제일 윗부분에 씬들이 넘어가는 부분을 구현을 해보도록 하겠습니다.

현재 모든 Stage를 SceneManager에 동적으로 할당한 StageScene주소를 관리하도록 구현하고있습니다.

SceneManager의 p_scenes라는 Scene* 타입의 Array안에 END가 아마 44라 크기가 44짜리 배열입니다.

그렇다면은 p_scenes의 [0] 의 의미는 8바이트짜리 하나의 빈공간인데, 이곳에는 Scene* 타입이 들어올 수 있다는 말입니다.

vector VS array ❗

현재 둘의 가장 큰 차이점은 '배열'은 크기가 고정이고 'vector'는 크기가 유동적으로 변한다! 는 것입니다.

현재 게임의 씬은 43개로 정해져있고 씬을 삭제를 하는 일이 없기 때문에

굳이 vector를 사용할 필요가 없어서 배열을 사용하도록 하겠습니다.

다만, 구현을 하다가 저장할 데이터의 갯수를 알 수 없는 경우가 생긴다면은 vector를 적극 활용해주도록 합시다.

또한 중간 삽입삭제가 발생할 경우, 또는 push_front가 발생해야 하는 경우가 생긴다면은

vector는 O(n)의 타입 complex를 가지기 때문에 list나 Hashmap을 사용해보도록 할 것입니다.

https://www.hanbit.co.kr/channel/category/category_view.html?cms_code=CMS7393457320#:~:text=%EB%B0%B0%EC%97%B4%EA%B3%BC%20vector%EC%9D%98%20%EA%B0%80%EC%9E%A5,%EB%A5%BC%20%EC%82%AC%EC%9A%A9%20%ED%95%98%EB%8A%94%20%ED%8E%B8%EC%9D%B4%20%EC%A2%8B%EC%8A%B5%EB%8B%88%EB%8B%A4.

구현 한 부분

SceneManager작업 ❗❗ double free

현재 SceneManager에 전역 멤버 변순인 g_stageNumber 변수를 선언을 해주도록 합시다.

이후 34~35줄의 UpStageNum, DownStageNum 함수를 각각 파주고 ++, -- 구현해주도록 합니다.

SceneManaer에 이러한 함수들을 추가를 해주도록 합니다.

현재 인자로 포인터변수인 scene을 받았는데 분석을 하면은

주소 값변수명데이터 (값)
0x100scene0x200

이러한 식으로 구성이 되어있습니다. 데이터 부분에 StartScene에서 동적할당한 주소값이 들어가 있겠지요.

현재 동적할당만하고 인자로 넘겨주었으니

만약 p_scenes에 해당 type의 인덱스에 데이터가 있다면 그대로 놔두고 없다면 StartScene에서 넘겨받은 주소로 채워 줄 것입니다.

있는 경우 scene의 데이터 부분을 delete해주었습니다.

double free 현상은 신경을 안써주었는데, 이유는

nextStage변수는 스택에 올라갈것이라 해당 함수 호출이 종료가 되면 사라질 것이기 때문에

nextStage까지 nullptr로 채우는 작업은 하지 않았습니다.

스택메모리에서 알아서 날아갈 것이기 때문에

https://ansohxxn.github.io/cpp/chapter6-10/


Scene 전환 - 2

현재 이부분을 수정을 할 것인데

씬이 넘어갈 경우 전환은 이루어지지만 플레이어 정보를 받아서 그대로 다음 씬에 그려내지 못하는 상황이다.

StartScene에서 테스트 용도로 Update에 해당 기능을 구현해 두었는데

Scene만 변경이 되고 플레이어가 그대로 사라진다.

생각해낸 방법이 플레어의 정보를 구조체로 감싸서 다음씬에 전달을 해주는 것이다.

일단 다음씬 넘어갈때 다음씬의 정중앙에 배치를 할 수 있도록 수정하였습니다.

(코드 분석및 설명은 내일)


Scene 전환 - 3

문제점 (다형성)

  • Scene 전환시 double free 현상

현재 double free 현상이 게임을 종료를 할 경우 발생을 하고있다.

이유는

Scene의 소멸자 부분 때문인데

게임을 종료를 하면서 Scene의 소멸자가 호출이 되는데 StartScene에서 player를 delete를 해버리고

StatgeScene에서 plyaer를 다시 delete 해버리는 상황이 발생하기 때문이다.

따라서 게임을 종료를 했을 때의 마지막 씬 (즉 현재씬)의 이름과 SceneManaege에서 관리를 하는데 curScene의 이름과 같다면,

그 경우에만 Player를 delete해주어야 한다.

다형성

모든 StageScene들은 Scene을 상속을 받기에 Scene의 소멸자부터 호출이 된다.

(정확히는 StageScene의 소멸자가 호출 되는데 호출 되자마자 부모 소멸자 호출하러감)

일단 씬을

SceneManager에서 먼저 다 생성을 해주었다.

문제는 Player는 게임이 종료되는 동안 사라지면 안되기 때문에

DeleteAllGroups 함수에서 제외를 시켰고

게임이 종료될 때, 소멸자에서 delete로 memory leak이 발생하지 않도록 해주어야한다.

그런데 STAGE_1 에서 소멸자가 ~Scene이 호출이 되면서 현재 게임씬에 남아있는 녀석들을 delete해주고 그 다음

STAGE_2에서 delete를 해주어 버리기 때문에

이를 걸러낼 수 있는 방법으로 각 Scene의 이름을 불러와 비교할려고 했는데

이름을 비교하려니 이미 삭제된 Scene의 이름에 접근을 해버리는 문제가 발생하여

data 영역에 SceneNumber라는 정수값을 넣어두어 정수값으로 씬을 판별하여 delete할 수 있도록 수정하였다.

소멸자 코드를 혹시 모를 상황에 대비해 조금 수정하자면 이런식으로 수정이 가능하다.


Scene 전환 - 4

문제점 ❗❗

현재 씬을 올라가는 부분은 문제가 없는데

떨어질 경우 문제가 생긴다.

조건을 체크를 해야할 부분이

  • 현재 resolution에서의 playerPos를 기준으로 씬을 위로변경할지 밑으로 변경할지

  • 씬변경시 resolution과 playerPos를 구분 해주는 좌표는 어떻게 되는지

  • SceneManager의 p_scenes의 인덱스 범위를 초과하지 않는지

수정 - 1

모든 스테이지 비트맵 파일 0번 부터

이렇게 수정함.

코드에서도 그냥 0번 인덱스 Stage_0이런식으로 접근 할려고 수정함.

다르니까 뭐가뭔지 계속 햇갈림.

수정 - 2

현재

모든 씬 list로 관리를 하도록 변경하겠다.

코드를 현재 이렇게 수정을 하면 위 아래 씬으로 이동 잘한다.

문제점은 player가 위로 갈때에는 문제가 안되는데

아래로 떨어질때 문제가 생긴다.

StageScene의 Update부분에서

아래로 떨어질 경우 좌표값이 900 -> 1200 -> 이런식으로 증가해서

매 프레임에서 걸리게 된다.

따라서 다음 프레임이 진행되어서 다시 update돌기전에 player의 위치를 수정해 주어야 한다.

밑/위로 갈 조건이 이렇게 ChangeStandPos 함수내부에는

위로 갈 때의 조건을 보면은

현재 씬 넘버 + 1 == 다음씬 넘버랑 일치할 경우에만 진행을 하도록 해준다.

242번째 줄에서 nullptr이 아닐 경우에만 curPosY를

현재 y 해상도 900 - (플레이어 위치 + 플레이어 절반크기)를 해준다.

그러면은 위로 갈 경우 0 + 50쯤을 빼주면은 다음 씬의 플레이어 위치는 850정도가 되어서

다음씬의 밑에 부분에 그려질 것이다.

아래로 갈 때에는 반대로

떨어질 경우이니까 900보다 플레이어의 위치가 클 것이다.

플레이어 위치 + 플레이어 크기 / 2 => 950정도 된다고 가정을 하면 여기서 900을 빼주면 50정도가 남는데

이것을 다음 씬의 위치에 그릴 플레어의 위치가 된다면은

다음씬에서 y축으로 50정도의 위치에 위치할 것이다.

수정해야할 부분이 속도 부분이다.

너무 빨리 떨어지는데 최대 속력을 낮추어야 된다.


Scene 전환 - 4

수정한 부분

  • AddObject에서 double free 현상 수정함.

수정 및 구현해야할 부분

  • 씬 전환시 충돌 안되는 부분 원인 찾고 수정.

  • Ground 오브젝트 씬마다 생성을 해내야함.

충돌 문제점 찾은 부분

원인 -> 비트 연산

현재 StageScene에서

ColliderManager의 CheckGroup을 호출을 한다.

=> 현재 씬의 충돌할 녀석들을 다 등록해두는 작업인데

ColliderManager의 멤버? 배열 _arrCheck를 비트열로써 계산을 하는 부분이 CheckGroup이다.

Scene 변경될 때마다 호출 할 부분인데

_arrCheck가

이런상황인데

저 한칸에 들어갈 수 있는게 UINT크기 만큼이다.

UINT는 4바이트 양의 정수만들 표시를 하는데

unsigned int 인데

이게 비트가 0~32가지인데

이렇게 비트 연산을 통해서

하나의 양의 정수를

이런식으로 밀어 버리는 것이다.

근데 씬이 바뀔 때마다 들어오는 비트의 연산이 같아서

stage_1에서는 _arrCheck가 정상적으로 비트 연산을 해서 1로 딱 켜주게 되어서

FinalUpdate가 돌때마다 체크가 되는데

stage_2에서는 이 부분이 안되고

다시 Stage_3에서는 되었었는데 이게

같은 비트 연산으로 1 << 4하는 부분을 stage_1에서는 켜두고

stage_2에 진입을 할 때는 껏다가 stage_3에서는 다시 켜지게 되기 때문에

홀수 stage에서만 충돌이 발생하는 것 처럼 보였던 것이다.

그래서

Exit에서

memset함수를 통해서 _arrCheck메모리를 싹다 0으로 밂어주는 작업이 필요하다.

이후 결과를 보면은

일단은 원하던 부분까지는 잘된다.


profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글