본문 바로가기
GameMaker강좌[GMS2]/DnD강좌-코딩

[게임메이커 강좌-DnD][GMS2] 가까운 거리순으로 인스턴스 목록화

by 타락카얀 2021. 10. 9.
728x90

 

 

 

 

 

◈ 가까운 거리순으로 인스턴스 목록화하기

 

 

지정한 오브젝트의 인스턴스를 체크하여 가까운 거리순으로 목록화하는 것에 대해 알아봅시다.

 

(▲ 가까운 거리순으로 목록화)

 

필요한 기능은 가까운 거리순으로 인스턴스 ID를 목록화에 리스트 데이터 구조체를 사용할 거에요.

Create 이벤트[Create List] 액션을 사용하여 리스트 데이터 구조체를 생성합니다.

 

(▲ 리스트 데이터 구조체 생성)

 

거리순으로 ID를 정렬할 기능으로 우선도 큐 데이터 구조체(ds_priority)사용할 필요가 있어요.

우선도 큐는 우선도에 따라 값을 정렬할 수 있는 데이터 구조체입니다.

여기서 우선도는 거리가 되겠죠.

 

(▲ 우선도 큐 데이터 구조체 생성)

 

우선도 큐는 액션에 없기 때문에 Common[Function Call] 액션으로 ds_priority_create( ) 함수를

호출하여 우선도 큐를 생성합니다.

 

   ◎ ds_priority_create( ) : 우선도 큐를 생성합니다.

 

인자(Argument)는 없기 때문에 비워둡니다.

 

목록화를 어디에서 실행시킬지를 정해야합니다.

지금 만들 이벤트는 실시간으로 체크가 가능하기 때문에 Step 이벤트나 매 회 실행되는 이벤트 또는

이 기능이 필요한 특정 이벤트에 추가하시면 됩니다.

 

이제 가까운 인스턴스를 거리순으로 분류해봅시다.

 

   1. 우선도 큐 데이터 구조체를 통해 거리순으로 인스턴스 분류

   2. 분류된 인스턴스의 ID들을 리스트 데이터 구조체에 저장

 

먼저 [Function Call] 액션을 사용하여 우선도 큐 데이터 구조체를 클리어합니다.

 

   ◎ ds_priority_clear(ind) : ind의 우선도 큐를 클리어합니다.

 

(▲ 우선도 큐 데이터 구조체 클리어)

 

다음은 현재 오브젝트에서 거리를 측정하고 싶은 오브젝트까지의 거리를 분류해야합니다.

현재 오브젝트에서 다른 오브젝트의 좌표에 접근해야 하는데, 모든 오브젝트를 체크해야하므로

[Apply To] 액션을 사용하여 거리를 체크하려는 모든 오브젝트의 좌표에 접근할 필요가 있습니다.

[Apply To] 액션[Apply To] 액션이 실행되는 오브젝트에서 지정한 모든 오브젝트를 통해 코드를

실행시킬 수 있는 액션입니다.

Common[Apply To] 액션을 추가하고, 액션의 [▼] 버튼을 눌러 거리를 측정할 오브젝트를

지정합니다.

 

(▲ 거리 분류)

 

[Function Call] 액션을 사용하여 ds_priority_add 함수를 호출하고, 거리를 우선도로 분류합니다.

이 액션은 [Apply To] 액션에 연결된 오브젝트에서 실행합니다.

 

   ◎ ds_priority_add(ind, value, priority) : 값(value)을 지정한 우선도(priority)로 우선도 큐에 추가합니다.

   ◎ point_distance(x1, y1, x2, y2) : (x1,y1) 에서 (x2,y2) 까지의 거리를 반환합니다.

 

여기까지하면 분류가 끝난거에요.

이제 분류된 ID를 다시 리스트 데이터 구조체에 목록화하는 것만 남았네요.

 

우선도 큐는 우선도가 최소인 값과, 최대인 값 2가지에만 접근할 수 있습니다.

리스트 데이터 구조체는 모든 값에 접근할 수 있기 때문에 우선도 큐에 있는 값을 리스트 데이터 구조체에

이관해야 수시로 접근이 가능합니다.

먼저 [Clear Data Structure] 액션을 사용하여 리스트 데이터 구조체를 클리어 합니다.

 

(▲ 리스트 데이터 구조체 클리어)

 

그리고 우선도 큐 데이터 구조체에 옃 개의 인스턴스 ID가 저장되었는지 확인이 필요합니다.

[Function Call] 액션을 사용하여 ds_priority_size( ) 함수를 호출하여 n 임시변수에 수량을 반환하도록

합니다.

 

(▲ 분류된 인스턴스 ID의 개수를 체크)

 

   ◎ ds_priority_size( ) : 우선도 큐의 크기(저장된 값의 개수)를 반환합니다.

 

[For Loop] 액션을 사용하여 우선도 큐에 저장된 데이터만큼 반복하도록 합니다.

그리고 반복된 수만큼 저장된 데이터를 리스트 데이터 구조체에 이관하는 것이지요.

 

(▲ 분류된 인스턴스 ID를 목록화함)

 

[Add To List] 액션을 사용하여 우선도 큐에서 우선도가 가장 낮은, 즉 거리가 가장 가까운 ID를

리스트에 저장합니다.

 

   ◎ ds_priority_delete_min(ind) : 우선도 큐에서 우선도가 가장 낮은 값을 반환하고, 값을 삭제합니다.

 

※ 참고 : ds_priority_delete_max(ind) 를 사용하면 반대로 가장 먼 거리순으로 ID를 구축할 수 있어요.

 

끝입니다. 간단하죠?

 

Game End 이벤트를 추가하고, 데이터 구조체를 완전히 파기하고 메모리에서 제거합시다.

 

(▲ 필요 없는 데이터 구조체 파기)

 

   ◎ ds_priority_destroy(ind) : 우선도 큐를 파기하고, 메모리에서 제거합니다.

 

이벤트가 완성되었습니다.

 

[Gel List Item At] 액션을 사용하여 거리를 목록화한 리스트 데이터 구조체의 원하는 순위의 ID를 제어하면

됩니다. 참고로 0번이 가장 가까운 ID가 저장되었죠.

 

다만, 이 이벤트를 한 곳에서만 작성하면 몰라도 여러 오브젝트에 이벤트를 구성하는 것도 번거러울 수

있을 거에요.

그럴 때는 사용자 함수로 만들어 사용하는 것도 좋습니다.

 

 

 

 

◈ 사용자 함수로 만들기

 

 

사용자 함수는 Common[Declare A New Fuction] 액션을 스크립트 또는 오브젝트 내의 이벤트에서

추가해 만들 수 있습니다.

이것을 응용하자면, 지금까지 만든 이벤트 상단에 [Declare A New Fuction] 액션을 추가하고, 함수로

만들고 싶은 이벤트를 끌어다 놓기만 하면 됩니다.

 

(▲ 거리 분류 사용자 함수. 강좌에서는 set_instance_nearest_list 로 만듦)

 

이름(Name) 에 함수명을 입력하면 바로 사용할 수 있습니다.

 

만드는 김에 리스트 데이터 구조체에 접근하는 함수도 만들어 봅시다.

 

(▲ 가까운 거리의 ID를 찾는 사용자 함수. 강좌에서는 get_instance_nearest_pos 로 만듦)

 

[Gel List Item At] 액션에서 찾는 위치의 값이 없다면 undefined 상수가 반환되기 때문에

이것을 걸러내고, noone (-4) 값을 반환하도록 해봅시다.

 

(▲ undefined 체크)

 

마지막으로 [Return] 액션을 추가하면 원하는 값을 외부로 반환할 수 있게 됩니다.

지금까지 만든 함수들은 [Function Call] 액션에서 함수명을 호출하면 작동시킬 수 있어요.

 

(▲ 사용자 함수 사용 예 : 0번 순에 있는 인스턴스 ID 제어)

 

 

 

 

 

300x250

댓글