# 用Java打造自己的Minecraft伺服器 - 自學java筆記 與 程式紀錄 ###### tags: `Java` `Minecraft` `E-Portfolio` # 第一周 Java 基礎語法 * ## 學習內容 * 輸出 * 部分資料型態的宣告 * (整數,浮點數,字串,字元),以及簡單的運算子 * ## 觀看的影片 * https://youtu.be/3yH2PgmUecI * https://youtu.be/0tbJh5LovJM * https://youtu.be/uFkDzWSWh1Y * ## 學習重點 * 如何輸出 ```java= System.out.println(); ``` * 宣告整數(***int***),浮點數(***float***),字元(***chr***),字串(***String***) * 若想將兩個整數相除,並且除到小數位,需先將變數使用 ***(float)[變數名]*** 轉為浮點數 ```java= int num = 1; int num2 = 2; float result2 = ((float)num + (float)num2)/ 2; ``` * 每行結尾需要加上 ***;*** * ## 本周撰寫的程式碼: ```java= public class pro1 { public static void main(String[] args) { char myChar = 'c'; int num = 10; float num2 = 7.5f; //float型態的數字後面需要加上 f float result1 = num + num2; int result2 = (int)(num + num2); String myString = "hello"; System.out.println("hi"); System.out.println(num+ " " +myString); System.out.println(result1); System.out.println(result2); } } ``` # 第二周 Java if-else與switch * ## 學習內容 * if-else語法 * switch * ## 觀看的影片 * https://youtu.be/wZ_ey2wsA0k * https://youtu.be/eoFAL5OQl14 * https://youtu.be/x258Z_cCZLA * ## 學習重點 * ## 如何輸入變數 * 1. 先引入 java.util.Scanner ```java= import java.util.Scanner; ``` * 2. ```java= Scanner scanner = new Scanner(System.in); String word = scanner.nextLine(); ``` * ## if-else 語法 ```java= int price = 51; if(price <= 50) { System.out.println("y"); } else { System.out.println("n"); } ``` * ## switch 語法 ```java= import java.util.Scanner; public class myswitch { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int num = scanner.nextInt(); switch(num) { case 1: System.out.println("this is 1"); break; case 2: System.out.println("this is 2"); break; case 3: System.out.println("this is 3"); break; case 4: System.out.println("this is 4"); break; case 5: System.out.println("this is 5"); break; case 6: System.out.println("this is 6"); break; } } } ``` # 第三周 Java for與while迴圈 * ## 觀看教學影片認識基本的Jave語法 * 指派運算子的用法 * for 迴圈的用法 * while 迴圈的用法 * ## 學習重點 * ## 指派運算子 * #### 加法 ```java= i += a; //和 i = i + a有同樣功能 ``` * #### 減法 ```java= i -= a; //和 i = i - a有同樣功能 ``` * #### 乘法 ```java= i *= a; //和 i = i * a有同樣功能 ``` * #### 除法 ```java= i /= a; //和 i = i / a有同樣功能 ``` * #### 求餘數 ```java= i %= a; //和 i = i % a有同樣功能 ``` * ## for 迴圈範例 ```java= public class myFor{ public static void main(String[] args) { for(int i=0;i<5;i++) { System.out.println(i); } } } ``` * ## while 迴圈範例 ```java= public class myWhile{ public static void main(String[] args) { int result = 0, i = 1; while(i <= 10000) { result += i; i++; } System.out.println(result); } } ``` * ## 九九乘法表實作 ```java= public class myNine{ public static void main(String[] args) { for(int i=1;i<=9;i++) { for(int j=1;j<=9;j++) { System.out.print(i+"x"+ j+ "=" + i*j+" "); } System.out.println(); } } } ``` # 第四周 Java 陣列語法 * ## 學習內容 * Java 陣列宣告與使用 * ## 觀看影片 * https://youtu.be/Mi-03bwSKsU * https://youtu.be/9WhFYRZvP7s * ## 學習重點 * ## 陣列宣告 * 宣告法 範例1 ```java= int[] x = new int[10]; ``` * 宣告法 範例2 ```java= int[] y = new int[]{1, 3, 4, 10}; ``` * ## 輸入/輸出陣列值 ```java= System.out.println(y[0]); ``` # 第五周 method與參考 * ## 學習內容 * method的宣告與應用 * 物件存取的核心: 參考(reference) * 基本資料型態的存取 * ## 觀看影片 * https://youtu.be/mbqLp9UlHHQ * https://youtu.be/5Gl3wHI0pnI * https://youtu.be/t2h6C-nTJ2U * ## 學習重點 * ### 物件是透過參考來存取資料 * ### 不同的物件可以連上同一個參考(如下圖) ![](https://i.imgur.com/BQR0PWp.png) # 第六周 物件的建立與使用方法 * ## 學習內容 * 如何建立一個物件與成員變數 * 認識靜態變數與動態變數 * 在物件內撰寫一個方法 * ## 觀看影片 * https://youtu.be/WA7ZiKZ5qqA * https://youtu.be/aKGGH0IIIec * https://youtu.be/wncoQQGF-ho * ## 學習重點 * ### 建立建構子 ```java= public class Obj1 { public Obj1() { } } //Obj1 為此建構子名稱 ``` * ### 宣告動態變數 ```java= public float mem1; //float 為資料型態 mem1為變數名稱 ``` * ### 宣告靜態變數 ```java= public static int x; //int 為資料型態 為變數名稱 ``` * ### 宣告物件 ```java= Obj1 fisrt_obj = new Obj1(); //fisrt_obj 為宣告物件之名稱 Obj1 為建構子名稱 ``` * ### 非靜態變數v.s. 靜態變數 * #### 靜態變數屬於建構子,非靜態變數則屬於物件 * 舉例 ```java= public class Obj1 { public float mem1; public static int x; public Obj1() { } } ``` ```java= public class MyObj{ public static void main(String[] args) { Obj1 first_obj = new Obj1(); first_obj.mem1 = 30; Obj1.x = 10; } } ``` # 第七周 物件封裝與修飾子(public與private) * ## 學習內容 * 修飾子public與private的差別 * ## 觀看影片 * https://youtu.be/ue1E1EZxrgY * ## 學習重點 * ### public * 在 public 後面宣告的變數或方法,可以在任意的地方進行存取,*Ex:* * 同一類別 * 同一套件 * 不同套件的子類別 * 不同套件且非子類別 * ### private * 在 private 後面宣告的變數或方法,僅能在同一類別才可以存取 * ### 應用 * 資料方法的隱藏性很常使用private修飾子 # 第八周 pakage,import 與 overloading * ## 觀看影片 * https://youtu.be/AK8xVD3ds4U * https://youtu.be/RWA1eQXIFZA * ## 學習重點 * ### 1. overloading(以下面程式為範例做說明) :::info 在java中,在同一個類別(class)中,有多個相同名稱,但參數(Parameter)不同的函式(Method)時,稱為多載(Overloading)。 ::: > ### 在下面的程式範例裡,可以看到,在建構子NumMod中有三個Method的名稱都是 **set** ,但是三個的參數都不同,在這種情況下,在主程式Main呼叫set時,java依照呼叫的參數不同,把三個Method視為不同的Medtod。 * 範例程式 * 主程式 MyMain ```java= public class MyMain{ public static void main(String[] args) { NumMod myNum1 = new NumMod(); NumMod myNum2 = new NumMod(); NumMod myNum3 = new NumMod(); NumMod myNum4 = new NumMod(); myNum1.set(15); myNum2.set(87.87); myNum3.set("101"); myNum1.myPrint(); myNum2.myPrint(); myNum3.myPrint(); } } ``` * 建構子NumMod ```java= public class NumMod{ private long num; public NumMod() { num = 30; } public void set(long input) { num = input; } public void set(double input) { num = (long)input; } public void set(String input) { num = Long.valueOf(input); } public void myPrint() { System.out.println(num); } } ``` * ### 2. Pakage 和 import > ### 如同下面範例,在myPackage裡的Class(mySub1)中的變數 x 在被import到MyMian之後,依然可以正常輸出正確的值 * 範例程式 :::info 在default package下 ::: * 主程式 MyMain ```java= import myPackage.mySub1; public class myMain{ public static void main(String[] args) { System.out.println(mySub1.x); } } ``` :::info 在myPackage下 ::: ```java= package myPackage; public class mySub1 { public static int x = 10; } ``` # 第九周 建立插件與自訂指令(Command) * ## 學習內容 * 插件基本架構 * plugin.yml設定 * minecraft 指令建立 * ## 觀看影片 * https://www.youtube.com/playlist?list=PL3xWWZG57KfhP7uCqRcAU1EwnXt-iScXK * ## 撰寫程式 * ### 主程式(Main) ```java= package ed.tester.fstPlugin; import org.bukkit.plugin.java.JavaPlugin; import ed.tester.fstPlugin.Commands.example public class Main extends JavaPlugin { public void onEnable() { setupCommands(); getLogger().info("plugin opened"); } public void onDisable() { getLogger().info("plugin closed"); } public void setupCommands() { getCommand("example").setExecutor(new example(this)); } } ``` * ### 指令Class-example ```java= package ed.tester.fstPlugin.Commands; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import ed.tester.fstPlugin.Main; public class example implements CommandExecutor { public example(Main main) { } @Override public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { if(cmd.getName().equalsIgnoreCase("example")) { if(args[0].equals("arg1")) { sender.sendMessage("OAO"); return true; } } return false; } } ``` * ### plugin.yml ```yml= name: MyPlugin //插件名稱 main: ed.tester.fstPlugin.Main //主程式相對路徑 version: 1.0 //插件版本 author: xCallmeEDtw //作者名稱 api-version: 1.13 //使用SPIGOT-api版本 commands: example: //指令名稱 description: example //指令介紹 usage: /<command> [arg1|arg2] //指令使用方式 ``` * ## 遊戲執行成果 ![](https://i.imgur.com/QZqDcIc.png) ![](https://i.imgur.com/NPBECUs.png) # 第十周 First Time Join / Player Teleportation / Crafting recipe * ## 學習內容 * 在玩家第一次加入伺服器時,會有訊息顯示加入 * 將玩家傳送至世界重生點 * 自訂義合成配方 * ## 觀看影片 * https://youtu.be/zpSpLvycd1E * 撰寫程式 :::spoiler 主程式 Main ```java= package ed.plugin.test; import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.plugin.java.JavaPlugin; import ed.plugin.test.Commands.hello; import ed.plugin.test.Commands.SpawnEntity; import ed.plugin.test.Commands.tpspawn; import ed.plugin.test.Entity.ZombieDamage; import ed.plugin.test.ItemStack.GiveItemz; import ed.plugin.test.PlayerCode.PlayerInteract; import ed.plugin.test.PlayerCode.PlayerMove; import ed.plugin.test.recipes.Saddle; public class Main extends JavaPlugin implements Listener { @Override public void onEnable() { getServer().getPluginManager().registerEvents(this, this); setupRecipes(); setupCommands(); } @Override public void onDisable() { } @EventHandler public void onPlayerJoin(PlayerJoinEvent e) { Player p = e.getPlayer(); if (p.hasPlayedBefore()) { e.setJoinMessage(ChatColor.YELLOW + p.getName() + ChatColor.GREEN + " joined"); } else { e.setJoinMessage(ChatColor.YELLOW + p.getName() + ChatColor.GREEN + " welcome to my server"); } } @EventHandler public void onPlayerQuit(PlayerQuitEvent e) { Player p = e.getPlayer(); e.setQuitMessage(ChatColor.YELLOW +p.getName() + ChatColor.GREEN + " has left the server :("); } public void setupCommands() { getCommand("tpspawn").setExecutor(new tpspawn(this)); } public void setupRecipes() { getServer().addRecipe(new Saddle().recipeSaddle()); } } ``` ::: :::spoiler 自訂合成配方 Saddle ```java= package ed.plugin.test.recipes; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ShapedRecipe; public class Saddle { public ShapedRecipe recipeSaddle() { ItemStack saddle = new ItemStack(Material.SADDLE); ShapedRecipe recipe = new ShapedRecipe(saddle); recipe.shape("LLL","SSS","SIS"); recipe.setIngredient('L', Material.LEATHER); recipe.setIngredient('S', Material.STICK); recipe.setIngredient('I', Material.IRON_INGOT); return recipe; } } ``` ::: :::spoiler plugin.yml ```yml= name: TestPlugin //插件名稱 main: ed.plugin.test.Main //主程式相對路徑 version: 1.0 //插件版本 author: ED //插件作者 api-version: 1.13 //使用spigot-api版本 commands: //指令 hello: description: hi usage: /hello tpspawn: description: tptp usage: /tpspawn ``` ::: * ## 學習成果 ### 1. 第一次進入伺服器的歡迎 ![](https://i.imgur.com/jzVTYDZ.png) ### 2. 利用自製指令回到重生點(tpspawn) :::info 再輸入 **/tpspawn**,玩家會回到世界重生點 ::: ![](https://i.imgur.com/FltuUM0.jpg) ![](https://i.imgur.com/To1jb0j.png) ### 3. 自訂合成配方 ![](https://i.imgur.com/JKECoPU.png) # 第十一周 ItemStack 與 ItemMeta * ## 學習內容 * 如何使plugin 給予玩家指定物品(Item) * 認識物品的ItemStack * 如何更改Item的ItemMeta使物品有不同的屬性(ex.名子,附魔) * ## 觀看影片 * https://youtu.be/XeLrw9MGbic * https://youtu.be/0af4wvb67h0 * https://youtu.be/gjMEsYAHNJ4 * 撰寫程式 :::spoiler ItemStack ```java= package ed.plugin.test.ItemStack; import java.util.ArrayList; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; public class GiveItemz implements Listener { @EventHandler public void onPlayerJoin(PlayerJoinEvent e) { Player p = e.getPlayer(); if (p.hasPlayedBefore()) { ItemStack food = new ItemStack(Material.LEGACY_GRILLED_PORK); ItemStack sword = new ItemStack(Material.STONE_SWORD); //meta ItemMeta swordMeta = sword.getItemMeta(); //name swordMeta.setDisplayName(ChatColor.GREEN + "noob sword"); //lore ArrayList<String> lore = new ArrayList<String>(); lore.add("for noob"); lore.add("Enjoy and go DIE!"); swordMeta.setLore(lore); //enchantment swordMeta.addEnchant(Enchantment.DAMAGE_ALL, 1, false); //set the meta sword.setItemMeta(swordMeta); ItemStack chestplate = new ItemStack(Material.LEATHER_CHESTPLATE); p.getInventory().addItem(food); p.getInventory().addItem(sword); p.getInventory().setChestplate(chestplate); e.setJoinMessage(ChatColor.GREEN + "已獲得新手裝備"); } else { } } } ``` ::: * 成果 # 第十三周 * ## 學習內容 * 讓程式碼被延遲執行 * * ## 新增程式碼 1. ### 延遲執行 ```java= new BukkitRunnable(){ @Override public void run() { e.getPlayer().sendMessage("You have been joined 4 sec"); } }.runTaskLater(plugin, 20*4); ``` * ## 成果 1. ### 延遲執行(請注意左下角) :::info 可以發現白字相較有色字晚出現,因為白字是有延遲顯示 ::: * ![](https://i.imgur.com/ltIGlDA.gif) * ![](https://s1.gifyu.com/images/1622526339497.gif) 2. ### # 第十四周 * ## 學習內容 * 自訂物品攔 * 自訂記分板 * ## 成果 ### 1. 自訂物品欄 :::info 自訂一個可以透過輸入指令 **/inventory** 來開啟的物品欄,並且上面有兩個**無法被拿起的蘋果** ::: ![](https://i.imgur.com/NGRAEz7.gif) ### 2. 自訂記分板 ![](https://i.imgur.com/nUEEDyA.png) ### 3. 自製地雷 :::info 上圖為下圖側視圖,當玩家採到TNT上面的方塊時,TNT會爆炸 ::: ![](https://i.imgur.com/iFPsZ13.png) ![](https://i.imgur.com/VPQvf8g.gif) ### 4. 攜帶式坐騎 ### 5. 傳送棍棒&傳送弓箭 # 第十五周 # 第十六周