본문 바로가기
마인크래프트/플러그인 제작 강좌(자바)

[인텔리제이로 마크 플러그인 개발하기] 3. 흙을 캐면 다이아가 나오게 해보자! (이벤트와 리스너에 관하여)

by Zepelown 2022. 8. 18.

이 강좌는 spigot 기준으로 작성되었습니다.

 

이전 화

https://zepelown.tistory.com/37

 

[인텔리제이로 플러그인 개발하기] 2. 인텔리제이 한글인코딩

약 2년 전에 멈췄던 강의를 다시 시작하고자 합니다. 공지글을 쓰는 겸 미처 알려드리지 못한 내용을 짧게 알려드리겠습니다. 먼저 1강은 지금도 여전히 문제없습니다. 그대로 쭉 진행하시면 됩

zepelown.tistory.com

 


이번 강좌에선 이벤트에 대해 알아보겠습니다.

 

이벤트란? 게임에서 일어난 모든 어떤 사건(행동)을 말합니다.

 

예를 들어보겠습니다.

 

어느 한 플레이어가 걷고 있다가 돌을 발견했습니다. 그리고 돌을 캐서 돌 하나를 획득하였습니다.

 

위 문장에서 이벤트가 과연 어떤 걸까요?

 

답은 플레이어가 걷는 행동, 돌을 시야 내에서 발견, 돌을 , 돌 하나를 획득 이 모든 것이 이벤트입니다.

 

이와 같이 마크에서 사건(행동)은 정말 너무나도 많습니다.

 

그만큼 많기 때문에 플러그인 입문자분들이 쉽게 알 수가 없습니다.

 

따라서 spigot 제작자들은 공식 사이트에 친절히 올려두었습니다.

 

여러분은 앞으로 어떤 플긴을 만들던 이 사이트를 반드시 확인하셔야 됩니다.

 

구글에 바로 검색하여 다른 사람들이 질문 올려둔 글을 참고하는 것도 좋지만

 

먼저 공식 사이트에 들어가 api에 대해 확인하시는 것을 기본으로 가져가셔야 합니다.

 

https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/package-summary.html

 

org.bukkit.event (Spigot-API 1.19.2-R0.1-SNAPSHOT API)

package org.bukkit.event Classes dedicated to handling triggered code executions. Copyright © 2022. All rights reserved.

hub.spigotmc.org

이를 참고하여 흙을 부스면 다이아를 플레이어에게 주는 플러그인을 간단하게 제작해볼 겁니다.

 


지금 우리가 무슨 플러그인을 만든다고 했었죠?

 

흙을 부스면 다이아를 해당 플레이어에게 준다.

 

그러면 저희는 블록을 부섰을 때를 관리하는 이벤트를 찾으면 되는 겁니다.

위 사이트에서 org.bukkit.event.block 들어갑니다.

 

 

BlockBreakEvent 들어갑시다.

 

 

위와 같이 친절하게 설명이 되어있습니다.

 

이제 본격적으로 만들어보겠습니다.

 


인텔리제이를 열고 Event를 모두 저장할 패키지를 만들어주겠습니다.

 

1강에서 만들었던 클래스(TestPlugin.java)가  있는 패키지를 우클릭 후 위 사진과 같이 해줍시다.

이름은 event로 하였습니다. 이제 event를 우클릭하고 클래스를 만들어줍시다.

클래스 이름은 BreakEvent로 하였습니다.

 

만들어졌다면 이렇게 입력해줍니다.

위와 같이 미리 완성본을 보여줍니다. org.bukkit.event가 맨 위에 있으면 문제가 없이 진행이 된 것이며

 

엔터를 치시면 됩니다.

(앞으로 치게 될 모든 코드에서 똑같이 적용됩니다.)

 

그래서 저 기능이 자동으로 해주는 것이 뭐냐면

 

import를 바로 해주는 겁니다.

 

여기서 implements Listener란 이벤트를 사용하기 위해 Listener를 상속을 받는 겁니다.

 

그냥 이벤트를 사용하기 위한 절차구나

 

지금은 이렇게만 알면 됩니다.

 

그다음 위와 같이 입력해주시면 되는데 중간중간 작성할 때마다

 

빨간색 글씨와 밑줄이 나올 겁니다.

 

import를 해주는 자동완성이므로 Alt+Enter를 누르시면 됩니다.

 

아까 위에서 설명한 것과 똑같은 것이니 전혀 당황하실 필요가 없습니다.

 

위 코드로 다시 돌아와서 보면 breakDirt는 함수명입니다.

 

BlockBreakEvent e는 아까 api 사이트에서 확인한 것으로 이제 함수 내에서 e로 줄여서 규정한다고 생각하시면 됩니다.

 


 

플레이어가 어떤 블록을 캘 때마다 위 함수는 실행이 될 겁니다. (단순하게 말하면)

 

근데 돌을 캤을 때 다이아를 주기한 게 아니잖아요? 플레이어가 캔 블록이 흙이 맞는지를 알아야 할 겁니다.

 

따라서 플레이어가 캔 블록이 흙인지 검증해야 합니다.

 

    @EventHandler
    public void breakDirt(BlockBreakEvent e) {
        Material brBlock = e.getBlock().getBlockData().getMaterial();
        if(brBlock == Material.DIRT || brBlock == Material.GRASS_BLOCK){
            
        }
    }

이렇게 작성해두시면 됩니다.

 

함수 내 첫 줄은 brblock이라는 Material 인스턴스를 생성하고 해당 객체에

 

BlockBreakEvent 발생 시 해당 블록의 Material 인스턴스를 넣어주는 겁니다.

 

쉽게 말해 brBlock은 플레이어가 부슨 블록에 대한 정보(Material)를 저장하는 인스턴스입니다.

 

함수 내 두 번째 줄은 그 인스턴스가 흙인지를 알아보는 조건문입니다.

 


이제 검증은 끝났습니다. 이제 다이아만 주면 됩니다.

 

하지만 흙을 캘 때마다 주면 너무 재미없잖아요?

 

확률 요소를 집어넣어 봅시다.

 

여기서 저희는 자바 기본 클래스인 Math을 사용하겠습니다.

 

    @EventHandler
    public void breakDirt(BlockBreakEvent e) {
        Material brBlock = e.getBlock().getBlockData().getMaterial();
        if(brBlock == Material.DIRT || brBlock == Material.GRASS_BLOCK){
            if(Math.floor(Math.random() * 10)< 5){
            }
        }
    }

이로써 약 50% 확률로 제한을 걸어주었습니다.

 

Math에 관하여

더보기

Math.random()은 [0,1) 난수를 생성해줍니다.

 

따라서 10을 곱하면 [0, 10)이 나옵니다.

 

Math.floor()는 소수점을 버리는 겁니다.

 

0.5 -> 0, 1.5 -> 1, 9.5 -> 9

 

따라서 Math.floor(Math.random() * 10) 은 [0, 9]까지 생성되므로 5 미만으로 조건을 걸면

 

약 50 퍼가 나옵니다.

 

이제 플레이어에게 다이아를 줘야 합니다.

 

    private ItemStack dia = new ItemStack(Material.DIAMOND, 1);
    
    @EventHandler
    public void breakDirt(BlockBreakEvent e) {
        Material brBlock = e.getBlock().getBlockData().getMaterial();
        if(brBlock == Material.DIRT || brBlock == Material.GRASS_BLOCK){
            if(Math.floor(Math.random() * 10) < 5){
                Player p = e.getPlayer();
                p.getInventory().addItem(dia);
                p.sendMessage("다이아를 발견하셨습니다.");
            }
        }
    }

첫 번째 줄에 새로운 것이 생겼습니다.

 

플레이어에게 아이템을 주기 위해선 ItemStack이라는 인스턴스를 생성해줘야 합니다.

 

따라서 미리 생성해두었고

 

Player p = e.getPlayer();를 통해 이벤트를 발생시킨 플레이어 정보를 집어넣습니다.

 

그리고 p 인벤토리 정보를 가져온 뒤 다이아를 하나 넣어줍니다.

 

넣어줬다는 것을 알려주기 위해 해당 플레이어에게 메시지도 보내줍니다.

 

이로써 BreakEvent 클래스는 작성이 끝났습니다.

 

하지만 마지막으로 남은 하나가 있습니다.

 

1강에서 작성했던 플러그인 시작을 관리하는 메인 클래스에 가줍니다

(전 TestPlugin입니다)

 

그리고 이 이벤트를 등록을 시켜줘야 합니다.

 

이렇게 작성해주시면 됩니다.

 

 

완성이 됐으므로 이제 빌드해봅시다.

 

 

 

 

정상적으로 작동합니다!

 


다음 화에선 이렇게 얻는 다이아의 아이템 정보를 수정해보겠습니다.

 

댓글