Profile
Experience

2018.12.18

인벤토리 만들기 - 1

조회 수 47 추천 수 2
애드블럭을 꺼주시면 서버 운영에 도움이 됩니다.
부탁드립니다.

인벤토리를 만들려면 배열 변수에 대해 알아야 합니다.

 

아니면 엄청난 노가다를 통해 만드셔도 되고요.

 

고로 배열변수가 뭔지 모르신다면, 폭풍 검색을 하신 뒤에 인벤토리에 손을 대시는 걸 추천합니다.

 

왜냐면 더럽게 복잡하거든요

 

 

이 인벤토리 제작 강좌에서는, 아이템을 배열변수 형식으로 저장할겁니다.

 

간단히 3가지 종류의 저장방식 중 하나를 소재로 강좌를 쓸 것입니다.

 

아래로 내려갈수록 난이도가 높아집니다.

 

A방식 [1차원 배열]

 

 

1번째 칸과 18번째 칸엔 사과(아이템 코드:4)가 있습니다.

2번째 칸과 16번째 칸엔 바나나(아이템 코드:2)가 있습니다…

 

0은 아이템이 없는 상태입니다.

 

가장 단순한 방식이며, 몇 번째 슬롯에 어떤 아이템이 있는지 정도만 표시 가능합니다.

 

응용하지 않으면 아이템 수량같은 보조적인 수치를 넣을 수 없습니다.

 

장점 : 엄청 심플해서 간단히 다룰 수 있습니다.

 

단점 : 엄청 심플해서 기능이 굉장히 제한적입니다.

 

 

B방식 [2차원 배열]

 

 

1번째 칸엔 소비템(종류 1) 중 사과(종류 1 중 아이템 코드:1)가 30개 만큼 있습니다.

7번째 칸엔 장비템(종류 3) 중 불곰의 방탄복(종류 1 중 아이템 코드 :1)이 +3만큼 강화된 상태로 있습니다…

 

종류 1을 소비템, 종류 2를 기타템, 종류 3을 장비템으로 가정해 둔 겁니다.

 

간단히 아이템의 종류를 구분할 수 있으며, 장비템은 장비템끼리 스프라이트 하나에 몰아둘수도 있는 등...

 

꽤나 응용 범위가 넓은 방식입니다.

 

이 예시용 인벤토리 표에서의 수치는 종류 1,2에서는 아이템의 갯수를 나타내지만, 종류 3에서는 강화 수치로 쓰일 수 있습니다.

 

장점 : 좀 덜 심플해서 응용 범위가 넓습니다.

 

단점 : 변수의 갯수가 더럽게 많아지므로 메모리적으로 비효율적입니다. 온라인 시스템엔 적극 비추

 

 

C방식 [1차원 배열]

 

 

1번째 칸엔 소비템(종류 1) 중 사과(종류 1 중 아이템 코드:1)가 20개 만큼 있습니다.

4번째 칸엔 장비템(종류 3)중 충격탄(종류 3 중 아이템 코드:10)가 +2만큼 강화된 상태로 있습니다…

 

헐 도로 1차원 배열로 돌아왔군요.

 

00000000은 아이템이 없는 상태인데, 사실 비워둬도 상관은 없습니다.

 

위 인벤토리 형식에서 10021004라는 아이템코드가 있다면,

 

1 0021 004

 

빨간색 : 종류

파란색 : 아이템코드

초록색 : 수치

 

같은 형식을 붙여서 문자형 변수로 저장합니다.

 

변수 갯수가 적으나 사용하기 어렵다는 단점이 있습니다.

 

장점 : 1차원 배열이므로 온라인 인벤토리로 쓰기에 적합합니다.

   게다가 응용 범위 또한 넓습니다.

 

단점 : 실수형이 아닌 문자형이다 보니, 중간에 특수문자라도 끼워주지 않는 이상 저 지정된 자리를 넘어서는 아이템코드를 쓰지

   못합니다.

   사용할때마다 스트링 관련 함수로 열심히 짤라줘서 써야 하므로 쓰기가 어렵습니다.

 

 

 

이 세 가지 방식 중 B방식을 사용하도록 하겠습니다.

 

가장 무난하고 이해하기 쉬우니까 말이죠.

 

 

 

먼저, 인벤토리의 핵심인 배열 변수를 선언해야 합니다.

 

B방식에서는 굉장히 많은 변수를 선언해야 하므로, 다중 반복문을 써야 합니다

 

 

 

는 개뿔 게임 설정 들어가셔서 저거 하나 체크하시면 끝납니다 !

 

 

왠만한 잡일 다 맡으실 인벤토리 오브젝트를 하나 생성해줍시다.

 

이 강좌에서는 인벤토리 슬롯을 8x4 사이즈만큼 32개의 슬롯을 만들어보겠습니다.

 

왠만하면 오브젝트 1개로 처리해놓고 클릭 위치 판정한다던가... 하는 복잡한 방법으로 할 수도 있지만

 

편리한 이벤트인 Mouse Pressed를 쓰기 위해 무식하게 오브젝트를 32개 생성해버립시다

 

 

인벤토리 슬롯 역할을 해줄 오브젝트도 하나 생성합시다

 

 

그리고 맨 처음 생성했던 오브젝트에, 방금 만든 슬롯 오브젝트를 반복 생성하는 코드를 써 줘야 합니다.

 

코드를 되도록 적게 쓰도록 하겠지만, 이 같은 경우에는 오브젝트로 했다간 아주 죽어나가므로 코드로 합시다 ;

 

for (i=1; i<= 32; i+=1)
{
inst=instance_create(x, y, InventorySlot)
inst.slot=i
}

 

i 변수를 1로 선언하고, 32보다 작거나 같을때까지 반복합니다. 반복할때마다 i는 1씩 상승합니다.

{

InventorySlot 오브젝트를 생성하며, 생성한 인스턴스 id를 inst 변수에 반환합니다

inst 변수의 인스턴스 id를 가진 오브젝트의 slot 변수를 i 변수로 설정합니다

}

 

복잡하니까 굳이 전부 다 이해하실 필요는 없고, 필요에 따라 수정하실 부분은 세 가지입니다.

32→ 인벤토리의 최대 슬롯 수

InventorySlot → 인벤토리 슬롯의 오브젝트 이름

slot → 이 슬롯이 몇 번째 아이템 슬롯인지 저장해줄 변수 이름

 

여기서 slot 변수는 이후에도 계속 쓰일 굉장히 중요한 변수입니다.

 

인벤토리가 32개라면, 1 2 3 4 5 6 7 8 9 10 11 12 … 31 32 형식으로 절대 겹치지 않는 변수임을 기억해두셔야 합니다.

 

 

룸을 하나 생성하고, 맨 처음 생성했던 오브젝트를 하나 깔아줍시다.

 

인벤토리 슬롯으로 쓰일 오브젝트는 배치할 필요가 없습니다.

 

그리고 이제 32개의 인벤토리 슬롯 오브젝트를 생성하게 해 줬는데.

 

시각적으로 겹치지 않게 표시해주기 위해 이 슬롯 오브젝트들의  좌표 정체성을 찾아주어야 합니다.

 

위에서 말했지만 8x4의 인벤토리를 만들려고 합니다.

 

 

               
               
               
               

 

 

이런 모양이 된단 말이죠.

 

슬롯 오브젝트를 이렇게 배치해준 것이 아니니, 슬롯 오브젝트들의 좌표 정체성을 찾아주어야 합니다.

 

일단 그 전에 테스트용으로도 필요할테니, 인벤토리 슬롯을 그려줍시다.

 

 

일단 이건 도트강좌가 아니므로 슬롯 그리는 방법은 생략합니다.

 

그냥 적당히 버튼화시키되, 굵기를 줄여주면 대충 느낌은 납니다 ;

 

이 스프라이트를 인벤토리 슬롯 오브젝트에 장착시켜 주시면 됩니다.

 

그리고 이제 좌표 정체성을 찾아주도록 하죠.

 

 

 

변수 선언따위 필요 없습니다.

 

우리는 무적의 옵션 변경을 했으니까요

 

 

 1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

 

 

8x4로 보이지만 사실 각각의 슬롯이 가지고 있는 slot 변수는 저런 식으로 배열되어 있습니다.

 

즉 slot 변수만을 이용해 이 슬롯이 가로 몇 번째 칸인지, 세로 몇 번째 칸인지 구해줘야 합니다.

 

위 액션을 해석하면,

 

slotx 변수가 0일때

{

 slotx 변수를 slot 변수로 바꿉니다.

 아래 괄호안 내용을 3번 반복합니다.

 {

  slotx 변수가 8초과일때

  {

  slotx 변수를 8 감소시킵니다.

  sloty 변수를 1 증가시킵니다.

  }

 }

}

좌표 이동을 합니다 ( 아래서 설명 )

 

x : 1

y : 0

x : 2

y : 0

x : 3

y : 0

x : 4

y : 0

x : 5

y : 0

x : 6

y : 0

x : 7

y : 0

x : 8

y : 0

x : 1

y : 1

x : 2

y : 1

x : 3

y : 1

x : 4

y : 1

x : 5

y : 1

x : 6

y : 1

x : 7

y : 1

x : 8

y : 1

x : 1

y : 2

x : 2

y : 2

x : 3

y : 2

x : 4

y : 2

x : 5

y : 2

x : 6

y : 2

x : 7

y : 2

x : 8

y : 2

x : 1

y : 3

x : 2

y : 3

x : 3

y : 3

x : 4

y : 3

x : 5

y : 3

x : 6

y : 3

x : 7

y : 3

x : 8

y : 3

 

위 과정을 거치면 각각 이런 값을 가지게 됩니다.

 

slotx값이 8을 초과할 경우 8을 빼버리고 y를 1 증가시키는 과정을 3번 거치죠.

 

만약 8x4 인벤토리가 아닌 10x5의 인벤토리라면, 8을 10으로 고치고, 3을 4로 고치면 됩니다 (5-1)

 

그 다음 시각적으로 이동시키기 위해 좌표 이동을 시켜줍시다.

 

x = POinventoryWER.x+((slotx-1)*26)

y = POinventoryWER.y+(sloty*26)

 

맨 처음 생성했던 오브젝트를 따라가게 해두었습니다.

 

위에서 구한 slotx와 sloty값을 이용해 자신의 위치를 찾죠. 제가 쓴 슬롯 스프라이트는 24*24 사이즈인데,

 

그보다 클 경우 26이란 수치를 반드시 수정해 주어야 합니다.

 

여기서 slotx를 -1 시켜주는 이유는, 위의 xy표를 보시다시피 x는 0이 없습니다.

 

만약 빼주지 않으면 인벤토리가 좀 오른쪽으로 가게 되므로, x = 1을 x = 0처럼 취급하기 위해 썼습니다.

 

 

이대로 테스트해보았습니다.

 

 

그리고 자신의 slot 변수도 표시하게 해 보았습니다.

 

적절하게 정상적으로 돌아가고 있습니다.

 

 

그리고 아이템 슬롯 오브젝트의 드로우 이벤트에 이 코드를 써줍시다.

 

draw_sprite_ext(sprite_index,image_index,x,y,image_xscale,image_yscale,image_angle,image_blend,image_alpha)

 

draw 이벤트를 쓰게 되면 스프라이트가 좀 맛이 갑니다.

 

고로 자기 자신을 또 그려주는 코드입니다.

 

나중에 써야 할 테니 미리 넣어두도록 하죠.

 

 

살짝 이른 감이 있지만, 인벤토리의 정상작동 여부 등을 파악하기 위해 일단 인벤토리 변수부터 건들여보도록 하죠.

 

아래와 같은 설정을 두고 들어간다고 칩시다.

 

global.inventory[슬롯번호,0] = 아이템종류 (1은 소비템, 2는 장비템)

global.inventory[슬롯번호,1] = 아이템 코드

global.inventory[슬롯번호,2] = 아이템 수치 (소비템일 경우 갯수)

 

일단 아이템을 습득하는 코드를 짜야 할 텐데, 이걸 액션으로 했다가는 폭풍 노가다가 되어버릴 수 있으므로...

 

코드로 만들어보겠습니다.

 

getitemtype = 1
getitemcode = 1
getend = 0
for (i=1;i<=32;i+=1)
{
if getitemtype = 1 and global.inventory[i,0] = getitemtype and global.inventory[i,1] = getitemcode and global.inventory[i,2] < 50
{
global.inventory[i,2] += 1
getend = 1
break
}
}

if getend = 0
{
for (i=1;i<=32;i+=1)
{
if global.inventory[i,0] = 0
{
global.inventory[i,0] = getitemtype
global.inventory[i,1] = getitemcode
if getitemtype = 1 {global.inventory[i,2] = 1}
break
}
}
}

 

"헐 이게 뭐시여!"

 

너무 복잡하니까 한줄씩 해석합시다

 

getitemtype = 1 // 습득시킬 아이템의 종류입니다. 소비템 상자를 먹었다고 가정하고, 1번이 소비템이었죠?

getitemcode = 1 // 습득시킬 아이템의 코드입니다. 소비템 중 1번 코드의 아이템을 줄 겁니다.

getend = 0 // 소비템일 경우에 중첩시킬때 쓸 변수입니다. 별로 신경 안 쓰셔도 됩니다.

 

for (i=1;i<=32;i+=1) // 32번 반복돌리는 겁니다. 이쯤 되면 인벤토리 쓸 땐 익숙해지셔야 합니다.

 

if getitemtype = 1 and global.inventory[i,0] = getitemtype and global.inventory[i,1] = getitemcode and global.inventory[i,2] < 50 // 더럽게 길군요! 습득시킬 아이템이 소비템 종류이고, 반복 돌리는 중인 아이템 슬롯의 칸도 소비템이고, 반복 돌리는 중인 아이템 슬롯의 아이템코드가 같고, 그 아이템 갯수가 50개 미만이면 아래 내용을 돌립니다

 

그냥 포션 48개 있었는데, 1개 습득했다고 1개만 따로 넣기도 뭐하니까 이미 있는지 확인해서 49개로 합친단 소립니다.

 

global.inventory[i,2] += 1 // 두 개 줄거면 +=2 해주시면 됩니다.

 

getend = 1 // 이미 위 코드로 소비템일 경우 이미 있는 아이템 칸의 아이템 갯수를 1 올려줬습니다. 헌데 아래에서 돌릴 반복문은 새로 얻은 소비템이나, 장비템을 위한 것이므로 아래 반복을 막아야 합니다.

 


if getend = 0 // 즉 아이템을 먹었는데 같은 아이템을 발견하지 못해서 겹치지 못했을때 괄호안 내용을 반복시킵니다.

 

for (i=1;i<=32;i+=1) // 32번 반복, 익숙해져야 한다니까요

 

if global.inventory[i,0] = 0 // and를 세번이나 쓴 위의 조건과 다르게 심플합니다. 그냥 가장 첫번째로 빈 인벤토리를 찾는 조건

 

global.inventory[i,0] = getitemtype // 빈 칸에 습득한 아이템 종류를 쑤셔넣습니다

 

global.inventory[i,1] = getitemcode // 코드도 쑤셔넣습니다

 

if getitemtype = 1 {global.inventory[i,2] = 1} // 소비템일 경우 갯수를 1개로 만들어줍니다

 

break // 이미 목적은 달성했으므로, 더 이상 반복할 필요가 없습니다. 반복문을 종료합니다.

 


짱 복잡하군요 -_-;

 

사실 소비템의 개념만 없으면 굉장히 작게 요약시킬수도 있는 부분입니다만...

 

사실 되도록 액션으로 강좌 쓰고 싶었지만 그렇게 하면

 

http://cafe.naver.com/playgm/56286

 

이런 AIM버스터가 탄생하므로 되도록 코드를 익히시는게 편합니다.

 

 

코어 디펜스에서 조합을 액션으로 만들었더니 이렇게 되더랩니다.

 

짱 길어요, 괜히 더 복잡해지거든요.

 

여하튼 다시 본론으로 돌아와서, 아이템 습득하는 코드를 만들어줬습니다.

 

이제 인벤토리 슬롯이 아이템을 표시시켜 줘야겠죠.

 

예시용 아이템을 세 개 만들어두고 시작하겠습니다.

 

 종류 1 - 코드 1 (소비템 1번 아이템)

 종류 1 - 코드 2 (소비템 2번 아이템)

 종류 2 - 코드 1 (장비템 1번 아이템)

 

 

 

스프라이트를 이렇게 넣어주시면 됩니다.

 

 

 

0번부터 시작하시려면 0번 코드부터 시작하셔도 되긴 하는데, 여하튼 스프라이트 생성하면 밑에 image 1... 같은 숫자가 뜨죠?

 

item1 스프라이트 안의 image 1엔 종류 1 - 코드 1인 아이템을, image 2엔 코드 2인 아이템을.

 

대략 저런식으로 넣어주시면 됩니다.

 

 

그리고 슬롯 오브젝트에 드로우 이벤트에 그 슬롯에 있는 아이템을 표시해주도록 합시다.

 

일단 소비템 드로우만 작성해보았습니다.

 

subimage가 아까의 image 숫자와 일치해야 합니다

 

slot,0은 아이템 종류, slot,1은 아이템 코드, slot,2는 아이템 갯수입니다.

 

밑에서는 덤으로 아이템 갯수도 글자로 드로우해주고 있습니다.

 

적절하게 필요에 따라 디자인하시면 됩니다.

 

 

장비템 드로우입니다. 장비템일 경우엔 장비템 스프라이트를 드로우하도록 해 줍시다.

 

 

아까 아이템 습득 코드에서

 

getitemtype = 1
getitemcode = 1

 

두 변수만 고치고 아이템 세 개를 넣고 테스트돌려본 스샷입니다.

 

적절하게 잘 돌아가는군요.

 

뭔가 굉장히 이해가 안 가는 부분이 많으실테지만, 적절하게 아이템 옮기기로 넘어가보죠

 

 

이런 걸 넣어줍시다.

 

아이템은 끌어 놓아야 제맛이죠.

 

 

자기가 무슨 아이템 끌고 있는지는 알아야 하니까, 이 내용을 아이템 슬롯 오브젝트의 드로우 이벤트에 추가해줍시다.

 

사실 이런 건 보통 투명도 50% 해놓는 게 보통인데, 그럴려면 draw_sprite_ext로 코드 써야 해서 그냥 드로우하도록 하겠습니다 ;

 

 

인벤토리 슬롯의 마우스 왼쪽버튼 뗌 이벤트에 이런 코드를 써줍시다.

 

사실 이런 건 반복문 돌려버리면 그만이지만, 최대한 편하게 보일 수 있게 하려고 삽질한겁니다 ;

 

if global.drag != 0
{
save0 = global.inventory[slot,0]
save1 = global.inventory[slot,1]
save2 = global.inventory[slot,2]
global.inventory[slot,0] = global.inventory[global.drag,0]
global.inventory[slot,1] = global.inventory[global.drag,1]
global.inventory[slot,2] = global.inventory[global.drag,2]
global.inventory[global.drag,0] = save0
global.inventory[global.drag,1] = save1
global.inventory[global.drag,2] = save2
}

 

드래그 중일 때는 global.drag가 드래그를 시작한 아이템 슬롯의 slot 변수로 바뀌죠.

 

즉 드래그 중일 때 그 슬롯에 놓아 질 경우이죠.

 

save0~2는 마우스를 뗀 위치의 아이템을 일시적으로 저장합니다.

그리고 마우스를 뗀 위치의 슬롯에 마우스를 누르기 시작했던 위치의 아이템을 집어넣습니다.

그리고 마우스를 누르기 시작했던 위치에 일시적으로 저장한 아이템을 집어넣습니다

 

첨부파일 : example.gmk

추천해주신 분들



Profile
2
Lv

0개의 댓글

번호 제목 글쓴이 날짜 조회 수
공지 게임메이커 구체적인 설명과 알면 매우 좋은 팁 30개 [장문] 7 profile 도개걸윷모 2018.11.03 197
64 [팁] <댓글 스티커>, <쿠키 마켓>의 쿠키 반환 비율 (수수료, 이익 비율) 2 profile 며르치 2019.01.21 40
63 [팁] 쿠키 얻기/쓰기 조건 정리 4 profile 며르치 2019.01.17 68
62 [쿠키 API] ini처럼 온라인 데이터 저장/불러오기 구현하기 4 profile 주인장수표 2018.12.26 80
61 [쿠키 API] 구글, 네이버, 카카오톡 로그인 구현하기 profile 주인장수표 2018.12.26 64
인벤토리 만들기 - 1 profile Experience 2018.12.18 47
59 간단한 도트 찍는 방법! profile Experience 2018.12.17 38
58 [자료] 스팀 게임 플레이어의 통상적 컴퓨터 사양 1 profile 주인장수표 2018.12.17 26
57 [변수의 활용] VAR (if) 액션과 컨트롤액션 profile Experience 2018.12.17 10
56 윈도우를 컨트롤하자! profile Experience 2018.12.17 22
55 GML 차근차근 배워보기. [ 4 ] 조건문 profile Experience 2018.12.17 12
54 GML 차근차근 배워보기. [ 3 ] 연산자 (2) profile Experience 2018.12.17 12
53 GML 차근차근 배워보기. [ 3 ] 연산자 (1) profile Experience 2018.12.17 16
52 GML 차근차근 배워보기. [ 2 ] 변수 (2) profile Experience 2018.12.17 13
51 GML 차근차근 배워보기. [ 2 ] 변수 (1) profile Experience 2018.12.17 17
50 GML 차근차근 배워보기. [ 1 ] 강좌 진행 환경 조성 2 profile Experience 2018.12.17 17
49 리얼리티 '뷰' 노이즈 강좌 profile Experience 2018.11.29 25
48 [윈도우] 게임을 실행할 때 다른 윈도우를 모두 최소화시키기 profile Experience 2018.11.29 19
47 간단한 8방향 이동 코드 profile Experience 2018.11.29 16
46 겜스 간단한 페이드인/페이드아웃 profile Experience 2018.11.29 18
45 게임메이커 8 강좌 5화 -룸- END profile Experience 2018.11.29 18
서버에 요청 중입니다. 잠시만 기다려 주십시오...