강의 환경 : forge-1.7.10-10.13.4.1517-1.7.10

 

배경 지식

  1. 아이템 이벤트 함수
  2. 아이템 내구도

강의목표

  1. 아이템의 손상 값(Damage)을 이용하여 내구도를 가지는 아이템을 구현할 수 있다.
  2. 이벤트 함수를 이용하여 원하는 기능을 구현할 수 있다.

 

1. 아이템의 내구도(Durability)

내구도라는 것은 도구, 무기, 갑옷과 같이 유용한 기능을 하는 아이템들이 가진 속성입니다. 이 값은 아이템이 파괴되기 전까지 몇 번이나 더 기능을 해낼 수 있는지를 나타냅니다. 도구나 무기의 경우는 앞의 설명과 같이 남은 작동 횟수를 나타내고 갑옷은 조금 달라서 얼마만큼의 피해를 더 경감시킬 수 있는 지를 나타냅니다.

모든 아이템들의 잔여 내구도는 아이콘 아래 부분에 초록색 내구도 막대를 통해 확인 할 수 있습니다. 단, 한 번도 사용되지 않은 아이템은 막대가 그려지지 않습니다. 아이템이 손상될수록 막대의 길이가 짧아지고 색상 또한 붉은 색으로 변해갑니다. 내구도가 거의 다 소진 된 경우에는 내구도가 모두 소진된 것처럼 빈칸만이 그려지기도 합니다. 이것은 내구도가 픽셀의 크기에 맞춰져 그려지기 때문에 일어나는 현상입니다.

수치로서 존재하는 내구도는 게임 내에서 F3+H를 누르면 볼 수 있습니다. 이 옵션은 내구도 뿐만 아니라 몇몇 추가적인 설명(Tooltip)을 가방(Inventory)에서 제공합니다. 여기서 보이는 내구도 값은 실제 내구도보다 1이 작습니다. 왜냐하면 이 수치가 0이 되었을 때, 마지막으로 도구를 한 번 더 사용할 수 있기 때문입니다.

 

 

2. 내구도를 사용하는 아이템 만들기 – 족집게

이번 강의에서는 '족집게'를 만들어보며 도구 구현법을 익혀보도록 하겠습니다. 이 아이템은 닭에게 우 클릭을 통해 사용하면 깃털을 하나 얻고, 닭에게 1의 피해를 줄 수 있습니다. 본 예제를 통해서 내구도를 어떻게 다루는지, 이벤트 함수를 통해 다른 엔티티(Entity)와 어떻게 상호 작용하는지, 마지막으로 어떻게 아이템을 월드(World)에 떨어뜨리는 지 확인해보세요.

먼저 족집게의 아이템 종류를 결정할 아이템 클래스를 작성합니다. 이 클래스는 가위(ItemShears)를 바탕으로 작성됩니다. 참고하시면 도움이 되실 겁니다.

이번 족집게(ItemTweezer)는 해당 클래스에서 단 하나의 객체만 존재하는 싱글톤(Singleton)으로 작성합니다. 즉, 이 클래스에서 단 하나의 아이템 객체만이 생성되는 것을 가정하는 겁니다. 따라서 생성자 부분의 코드가 이전과는 조금 다릅니다. 이렇게 코드를 짜면 ModItems에서 아이템 객체를 생성하고 등록하는 과정이 훨씬 간단해진다는 장점이 있습니다.

ItemTweezer.java

package oortcloud.basictutorial.item;

 

import cpw.mods.fml.common.registry.GameRegistry;

import net.minecraft.creativetab.CreativeTabs;

import net.minecraft.item.Item;

 

public class ItemTweezers extends Item {

 

    public ItemTweezers() {

this.setMaxStackSize(1);

this.setMaxDamage(238);

this.setCreativeTab(CreativeTabs.tabTools);

this.setUnlocalizedName("tweezers");

this.setTextureName("basictutorial:tweezers");

GameRegistry.registerItem(this,"tweezers");

    }

    

}

이 아이템에서는 손상 값(Damage)이 내구도로 사용이 됩니다. 그렇게 때문에 여러 아이템이 겹쳐지게 되면 손상 값 데이터가 소실 될 수 있으므로, 반드시 setMaxStackSize (1)를 통해 최대 개수를 1개로 설정해야 합니다. 이 후 setMaxDamage(63)는 해당 도구의 최대 손상 값을 결정합니다. 내구도로 환산되면 64번 아이템을 사용할 수 있습니다. 생성자에서 바로 등록이 이뤄지고 이름을 생성자 밖에서 지정해줄 수 없으므로 생성자가 2번 이상 불리면 오류가 나게 됩니다.

이제 언어(Language) 파일과 텍스처(Texture)를 추가해서 기본적인 틀을 갖추어 보도록 하겠습니다.

en_US.lang

item.tweezers.name=Tweezers

ModItems는 이렇게 작성 되겠네요. 지난 강의의 코드도 함께 수록되어 있습니다.

ModItems.java

public final class ModItems {

    

    public static Item itemNumber;

    public static Item itemFortuneCookie;

    public static Item itemTweezers;

    

    public static final void init() {

        itemFortuneCookie = new ItemFortuneCookie().setUnlocalizedName("fortuneCookie").setCreativeTab(CreativeTabs.tabMisc).setTextureName("basictutorial:fortuneCookie");

        GameRegistry.registerItem(itemFortuneCookie, "fortuneCookie");

        itemNumber = new ItemMetadata().setUnlocalizedName("itemNumber").setCreativeTab(CreativeTabs.tabMisc);

        GameRegistry.registerItem(itemNumber, "itemNumber");

        itemTweezers = new ItemTweezers();

    }

    

}

 

 

3. 내구도를 사용하는 아이템 만들기 – 족집게

이제 이벤트 함수를 이용해서 닭을 우 클릭하면 내구도가 소모되고, 깃털이 나오며, 동시에 닭에게 1의 피해를 주도록 해보겠습니다. 아이템으로 엔티티(Entity)를 우 클릭 했을 때 호출되는 이벤트 함수는 itemInteractionForEntity()입니다.

public boolean itemInteractionForEntity(ItemStack itemStack, EntityPlayer entityPlayer, EntityLivingBase entityLivingBase)

ItemStack itemStack

사용된 아이템 스택입니다.

EntityPlayer entityPlayer

아이템을 사용한 플레이어의 엔티티(Entity) 객체입니다.

EntityLivingBase entityLivingBase

플레이어가 우 클릭을 한 대상 엔티티(Entity)입니다.

반환

상호작용이 일어나면 true, 그렇지 않으면 false를 반환해야 합니다.

 

ItemTweezer.java

    @Override

    public boolean itemInteractionForEntity(ItemStack itemStack, EntityPlayer entityPlayer, EntityLivingBase entityLivingBase) {

        return false;

    }

 

이제 여기에 우리가 원하는 기능을 할 코드를 입력하면 됩니다. 기능을 구현하기 전에, 일반적으로 엔티티(Entity)를 생성하는 코드(아이템 드롭)는 서버에서만 실행 되야 합니다. 따라서 다음과 같이 코드를 작성하여 클라이언트에서는 코드가 실행되지 않도록 합니다.

엔티티는 서버에서만 관리되는 대상입니다. 서버에서만 엔티티를 생성해도 그것이 클라이언트로 바로 반영이 되고, 만약 양 쪽에서 모두 생성해버리면 클라이언트에서는 2개의 엔티티가 생성된 것처럼 보이게 됩니다.

ItemTweezer.java

    @Override

    public boolean itemInteractionForEntity(ItemStack itemStack, EntityPlayer entityPlayer, EntityLivingBase entityLivingBase) {

        if (entityPlayer.worldObj.isRemote) {

            return false;

        }

        // IMPLEMENT HERE, 구현은 이곳에 하세요

        return false;

    }

 

이제 기능 구현에 필요한 코드를 입력하겠습니다. 주석을 참조하세요. 아래 코드에서 핵심은 damageItem ()이라고 할 수 있습니다. 이 함수가 결국 내구도를 소모시키기 때문입니다.

ItemTweezer.java

    @Override

    public boolean itemInteractionForEntity(ItemStack itemStack, EntityPlayer entityPlayer, EntityLivingBase entityLivingBase) {

        if (entityPlayer.worldObj.isRemote) {

            return false;

        }

        if (entityLivingBase instanceof EntityChicken) {

            // entityLivingBase 닭인지 확인합니다.

            

            if (entityLivingBase.getHealth() > 1.0F) {

                // 대상의 체력이 1보다 높을 때만 동작합니다. , 도구를 이용한다 해도 대상이 죽지는 않습니다. 죽기 전까지 털이 뽑힐 .

                

                // 아이템을 드롭하는, 자주 쓰이는 코드입니다.

                Random rand = new Random();

                // 임의의 방향으로 아이템이 튕겨 지도록 랜덤 객체를 만듭니다.

                EntityItem ent = entityLivingBase.entityDropItem(new ItemStack(Items.feather), 1.0F);

                // entityLivingBase 깃털의 EntityItem ent 떨어뜨리도록 하고, y 기본 속도를 1.0으로 설정합니다.

                ent.motionY += rand.nextFloat() * 0.05F;

                ent.motionX += (rand.nextFloat() - rand.nextFloat()) * 0.1F;

                ent.motionZ += (rand.nextFloat() - rand.nextFloat()) * 0.1F;

                // 임의의 속도를 부여합니다.

                

                

                entityLivingBase.attackEntityFrom(DamageSource.causePlayerDamage(entityPlayer), 1.0F);

                // entityLivingBase에게 플레이어(entityPlayer)로부터 피해를 1 받도록 합니다.

                

                itemStack.damageItem(1, entityLivingBase);

                // 내구도를 1 소모시킵니다.

                

                return true;

            }

        }

        return false;

    }

 

원하는 대로 기능 구현이 잘 되었습니다.

 

참고자료

http://minecraft.gamepedia.com/Item_durability

+ Recent posts