본문으로 건너뛰기
버전: v1

InvFX의 기능들

이 페이지는 InvFX의 더 다양한 기능에 대한 내용을 다룹니다.

InvSpace

InvSpace는 인벤토리 상에서 공간을 차지하는 객체가 상속받고 있습니다. InvPane, InvList, InvFrame 모두 이에 상속받습니다. InvSpace의 기능은 아이템을 원하는 좌표에 놓을 수 있도록 하고 클릭이벤트를 핸들링 하는 것입니다.

InvSpace 기능을 이용한 InvFrame

frame(numLines, Component.text(invTitle)) {
item(itemX, itemY, item)
onClick { x, y, clickEvent ->
if (itemX == x && itemY == y) {
// Action
}
}
}

위 코드와 같이, InvSpace의 기능을 활용하면, 아이템의 위치 좌표를 쉽게 파악할 수 있다는 장점이 있습니다.

InvWindow

InvWindow는 앞에서 말했듯이 물리적이지는 않지만 가상의 InventoryHolder입니다. 기본적인 InvFrame은 InvWindow에 상속받기 때문에 InvFrame 자체를 InvWindow라고 보셔도 무관합니다. InvFX에서 InvWindow의 역할은 기본적으로 두가지로 나뉘는데 하나는 InvFX에 의해 만들어진 인벤토리와 다른 인벤토리를 구별하는 것이고, 나머지 하나는 인벤토리에 이벤트를 전달해주는 역할입니다.

InvRegion

InvFX는 InvFrame을 그룹으로 나눌 수 있도록 설계되었습니다. InvRegion은 InvFrame 안의 그룹을 나타냅니다. InvRegion은 InvPane과 InvList, 두가지 종류가 있습니다.

InvPane

InvPane은 특별한 기능이 없는 단순한 인벤토리 칸의 집합입니다. InvPane을 만드는 방법은 다음과 같습니다. 시작점의 x, y 좌표, 너비(w)와 높이(h)를 다음 코드에 대입하면 됩니다.

frame(numLines, Component.text(invTitle)) {
pane(x, y, w, h, init)
}

주의! y + w의 값은 9이하어야 하고, x + h의 값은 numLines이하여야합니다. 또한, x, y, w, h 모두 양수어야합니다.

위 코드의 init에서 InvFrame의 초기 설정과 비슷하게, 핸들러 설정이나 아이템 위치를 할 수 있습니다. 아이템 위치를 설정할 때는, InvFrame 상에서의 좌표가 아닌 위에서 정의한 InvPane의 시작점을 기준으로 상대적인 좌표를 의미하니 주의하세요. onClick 핸들러 또한 x, y 는 시작점 중심 상대적 좌표를 의미합니다.

frame(numLines, Component.text(invTitle)) {
pane(x, y, w, h) {
item(relX, relY, item)
onClick { x, y, clickEvent ->
if (x == relX && y == relX) {
// Action
}
}
}
}

InvList

InvList는 InvPane과 달리, InvList 안에 들어있는 아이템들의 배열의 개념으로 만들어졌습니다. 대표적인 사용 예로는 Psychics의 능력자 책자가 있습니다.

InvFrame에서 InvList를 만드는 방법은 다음과 같습니다.

frame(numLines, Component.text(invTitle)) {
list(x, y, w, h, trim, data, init)
}

x, y, w, h에는 InvPane과 같이 시작 좌표 x, y, 너비(w)와 높이(h)를 대입합니다. data에는 어떠한 객체를 아이템으로 바꾸기 전의, 즉 마인크래프트 상의 아이템가 아닌 날것의 정보를 넣습니다. 예를 들어, 만약 다음과 같은 정보

val sticks = arrayListOf("a", "b", "c")

를 사용 할 경우, data에는 sticks를 반환하는 lambda형{ sticks }를 넣습니다. 이 날것의 정보를 마인크래프트의 아이템화를 시키는 것은 InvList의 init 단계에서 transform 함수가 합니다. 만약 sticks의 모든 값의 이름을 가진 막대기 아이템으로 만든다면 다음과 같은 코드가 필요합니다.

frame(numLines, Component.text(invTitle)) {
list(x, y, w, h, trim, data) {
transform { stickName ->
ItemStack(Material.STICK).apply {
itemMeta = itemMeta.apply {
displayName(Component.text(stickName))
}
}
}
}
}

즉, 이 코드는 sticks를 루프하여 각 항목을 원하는 ItemStack으로 반환하는 코드입니다.

또한, data의 크기가 주어진 InvList의 인벤토리 칸의 개수보다 큰 경우를 대비해 pages가 존재합니다. 이는 책자 처럼 InvList의 pages 값을 수정하면서 모든 아이템을 볼 수 있도록 해줍니다. trim 인수는 내부 코드에서 페이지 변화로 인한 업데이트 시 더 자세한 제한을 두기 위함이므로, 특별한 경우가 아닌 이상 기본적으로 true로 두시는 것이 좋을 것 같습니다.