본문 바로가기

플러그인 제작 강의

[마인크래프트 플러그인 제작 강의] 6강 패키지, 클래스 분리

SMALL

 

 

 

안녕하세요.

 

최근 시험과 사이버강의, 과제폭탄으로 인해 많이 바빠서 강의를 자주 올리지 못하네요 ㅠㅠ.

 

 

 

 

이번 강의에서는 패키지, 클래스를 분리하는 방법에 대해서 알아보겠습니다.

 

코드를 작성하기 전에 왜???? 패키지와 클래스를 분리하는지에 대해서 알아보겠습니다.

 

이유는 간단합니다.

 

많은 기능들을 구현하면 당연히 코드는 길어지게 되고, 코드가 길어지게 되면 수정하는데, 기능을 추가하기 어렵기 때문입니다. 

 

클래스와 패키지를 분리한다고 해서 기능적인 차이가 있는 것은 아니지만 좀 더 깔끔하고 보기 좋게 만들어 나중에 오류가 생겼을때 수정을 쉽게 하기 위함이라고 생각하시면 됩니다.

 

 

 

 

아직 커맨드, 이벤트, 파일, 등등 에 대해 충분히 설명하지 않았지만 먼저 패키지, 클래스를 분리해놓으면 배우시기 편하실 거라고 생각합니다.

 

 

 

 

패키지와 클래스를 분리하는 이유에 대해서 이해를 하셨다면 코드작성을 시작해보겠습니다.

 

https://cchplugin.tistory.com/10 에서 마무리된 코드를 기준으로 강의를 하겠습니다.

 

패키지와 클래스를 나누는 기준은 사람마다 다를수 있지만 저는 4가지로 나누어 보겠습니다.

 

1. Main

2. Command

3. Event

4. File

 

아래 사진과 같이 src 폴더 아래에 3개의 패키지를 추가로 만들어줍니다.

 

 

패키지와 클래스 생성하는 방법이 햇갈리신다면 https://cchplugin.tistory.com/7 강의를 참고해서 작성하시길 바랍니다.

 

먼저 Command 클래스를 작성해보겠습니다.

 

처음 클래스를 만들면 이런 형태 일 것 입니다.

 

아래 사진을 보시고 순서대로 따라하시면 됩니다.

 

아래 사진을 봐도 어떻게 하는지 모르겠다 하시는 분들은 

https://cchplugin.tistory.com/11 강의를 먼저 보고 오시길 바랍니다.

 

 

 

Command 클래스 작성은 여기까지 하고 다음 강의에서 command를 다루는 방법에 대해서 자세히 알려드리겠습니다.

 

다음은 Event 클래스를 작성해보겠습니다.

 

Event 클래스를 처음 만들었다면 이런 형태일 겁니다.

 

 

아래 사진을 보고 하나하나 천천히 따라해주세요. 

 

 

 

여기 까지 하셨으면 Main 클래스에서 작성된 Event부분을 옮겨오겠습니다.

 

파란색 부분은 지워주시고 빨간색 부분을 Event 클래스로 옮겨주시면 됩니다.

 

 

옮기고 난 후 Event 클래스는 아래와 같은 코드가 됩니다.

 

package com.tistory.cchplugin.cchlecture.event;

import java.util.HashMap;
import java.util.UUID;

import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;

import com.tistory.cchplugin.cchlecture.Main;

public class CchEvent implements Listener {

	public static Main plugin;

	HashMap<UUID, Integer> map = new HashMap<UUID, Integer>();

	public static void setPlugin(Main MainPlugin) {
		plugin = MainPlugin;

	}

	@EventHandler
	public void join(PlayerJoinEvent e) {

		UUID uuid = e.getPlayer().getUniqueId();

		if (map.containsKey(uuid)) {
			map.put(uuid, map.get(uuid) + 1);
		} else {
			map.put(uuid, 1);
		}

		int count = map.get(uuid);

		e.setJoinMessage(count + "번째 입장했습니다!");

	}

}

 

 

 

다음은 File 클래스를 작성해보겠습니다.

 

File 클래스 역시 아래 사진을 따라 따라해주시길 바랍니다.

 

 

 

 

여기까지 작성하셨으면 Main클래스에 있는 File에 관련된 내용을 옮겨보도록 하겠습니다.

 

 

빨간 동그라미로 표시한 괄호에 주의하셔서 옮겨주세요. 괄호 하나를 남기셔야 에러가 안납니다!

 

옮긴 후 File 클래스의 코드는 아래와 같습니다.

 

package com.tistory.cchplugin.cchlecture.file;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.UUID;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;

import com.tistory.cchplugin.cchlecture.Main;

public class CchFile {

	public static Main plugin;
	
	public static void setPlugin(Main MainPlugin) {
		plugin = MainPlugin;

	}
	
	public void makeFile(File f) {
		if (!f.exists() || !f.isFile()) {
			try {
				f.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	@SuppressWarnings("deprecation")
	public void mapToFile(File f, HashMap<UUID, Integer> map) {
		Bukkit.getScheduler().scheduleAsyncRepeatingTask(this, new Runnable() {

			@Override
			public void run() {
				try {
					consol.sendMessage(ChatColor.GREEN + "데이터를 저장 했습니다");
					FileWriter writer = new FileWriter(f, false); // Map to File
					for (UUID uuid : map.keySet()) {
						writer.write(uuid.toString() + "|" + map.get(uuid) + "\n");
					}
					writer.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}, 20 * 30, 20 * 30);

	}

	public void fileToMap(File f, HashMap<UUID, Integer> map) {
		try {
			BufferedReader reader = new BufferedReader(new FileReader(f)); // File to Map
			String fileLine = null;
			while ((fileLine = reader.readLine()) != null) {

				UUID uuid = UUID.fromString(fileLine.split("\\|")[0]);
				String str = fileLine.split("\\|")[1];

				map.put(uuid, Integer.parseInt(str));
			}
		} catch (FileNotFoundException e3) {
			e3.printStackTrace();
		} catch (IOException e4) {
			e4.printStackTrace();
		}
	}
	
}

 

정상적으로 옮기셨으면 아래 사진과 같이 빨간줄로 에러가 표시될 것입니다.

 

 

에러가 나는 이유는 Main함수에서 사용 하던 방식 그대로 가지고 왔기때문입니다.

 

위에서 작성했던 

 

public static Main plugin; 이라는 코드를 이용하여 에러를 없애보겠습니다.

 

 

 

 

어떻게 작동하는지 설명을 해드리면 머리가 아프실겁니다... 혹시나 궁금하시다면 댓글을 통해 질문해주세요.

 

여기까지 따라 오셨다면 Command, Event, File 클래스 작성이 끝났습니다.

 

이제 마지막으로 Main클래스를 조금만 수정하면 끝이납니다.

 

잘 따라하셨다면 Main 클래스는 아래와 같은 상태 일 겁니다.

 

 

Main 클래스를 아래와 같은 코드로 바꾸시고, 에러가 나는 부분은 스스로 한번 고쳐보시길 바랍니다. 

 

위 내용을 참고하신다면 쉽게 바꾸실수 있을 겁니다. 

 

package com.tistory.cchplugin.cchlecture;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.plugin.java.JavaPlugin;

import com.tistory.cchplugin.cchlecture.event.CchEvent;
import com.tistory.cchplugin.cchlecture.file.CchFile;

public class Main extends JavaPlugin {

	public ConsoleCommandSender consol = Bukkit.getConsoleSender();
	
	@Override
	public void onEnable() {
		consol.sendMessage(ChatColor.AQUA + "[플러그인 활성화 중 입니다.]");
		
		CchEvent.setPlugin(this);
		CchFile.setPlugin(this);
		
		CchEvent cchEvent = new CchEvent();
		CchFile cchFile = new CchFile();
		
		getServer().getPluginManager().registerEvents(cchEvent, this);
		cchFile.makeFile(cchFile.f);
		cchFile.mapToFile(cchFile.f, cchEvent.map);
		cchFile.fileToMap(cchFile.f, cchEvent.map);
	}

	@Override
	public void onDisable() {
		consol.sendMessage(ChatColor.AQUA + "[플러그인 비활성화 중 입니다.]");
	}

}

 

수정한 플러그인을 적용하면 똑같이 작동하는 것을 확인 하실 수 있을겁니다!

 

 

 

다음 강좌는 Command 클래스에 대해서 자세히 알려드리겠습니다.

 

혹시나 질문사항이 있으시다면 댓글을 남겨주세요.

 

댓글을 남기시면 작성자 핸드폰으로 알림이 가게 됩니다.

 

알림을 받게 되면 최대한 빨리 답변 해드리겠습니다.

 

감사합니다.

LIST