# 用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. 傳送棍棒&傳送弓箭
# 第十五周
# 第十六周