# GameObject ## 建立遊戲物件(GameObject) 遊戲場景(Scene)中出現的互動物件稱之為遊戲物件(GameObject),此類別類別實現遊戲核心(GameKernel)中的邏輯運算介面(UpdateInterface)及畫面渲染介面(PaintInterface)。 GameObject在於提前規範及定義所有遊戲物件必備的屬性及方法,當遊戲中需要創造一個新的遊戲物件時,需要在gameobj套件(package)下新增一個繼承自GameObject的類別: ```java= public class TestObject extends GameObject {//創建一個繼承自GameObject的類別 public TestObject(final double left, final double top) { //遊戲物件建構時需要該物件的生成位置及該物件的寬高,建構子可根據使用者需求來設定 super(left, top, 32, 64); } ``` 建立好類別後,進入遊戲場景中的sceneBegin()方法內產生實例: ```java= public class TestScene extends Scene { private TestObject testObjectA; private TestObject testObjectB; @Override public void sceneBegin() { this.testObjectA = new TestObject(160, 320);//在SceneBegin()方法中產生實例,本範例是將TestObject實例產生在場景中(160,320)的位置 this.testObjectB = new TestObject(400, 500); } ``` 需要在場景內的update及paint方法中更新遊戲物件每一幀的邏輯運算與畫面渲染: ```java= @Override public void update() { this.testObject.update(); //更新當前幀該物件的運算邏輯 ... } public void paint(final Graphics g){ this.testObjectA.paint(); //更新當前幀該幀的畫面渲染,越早繪製的物件圖層在越下面,可根據使用者狀況調整繪製的順序 this.testObjectB.paint(); //圖層在testObjectA之上,若圖片重疊會顯示testObjectB在上方 ... } ``` 當該遊戲場景結束時,透過場景內sceneEnd()方法釋放資源: ```java= @Override public void sceneEnd() { this.testObject = null; } ``` ## 設計遊戲物件(GameObject) ```java= public class TestObject extends GameObject { private final Image img; //若該遊戲物件需要繪圖,則遊戲物件內添加Image屬性 public TestObject(final double left, final double top) { super(left, top, 32, 64); this.img = ImageController.getInstance().tryGet("/Background.png"); //透過tryGet方法取得resource資料夾內的圖片,該圖片為該物件所繪之圖形 } ``` ...中間可根據使用者需求添加方法 最後需要實作遊戲物件的抽象方法(物件的邏輯處理及繪圖): ```java= @Override public void paintComponent(final Graphics g) { g.drawImage(this.img, this.painter().intLeft(), this.painter().intTop(), this.painter().intWidth(), this.painter().intHeight(), null); //paintComponent為繪製物件圖片的方法,依序輸入待繪製的圖片、繪製座標(x,y)、繪製寬高(width,heght)及oberver(null) } @Override public void update() { //update為此物件的邏輯運算 } ``` ## 程式碼說明 以下為GamObject程式碼說明: 1.建構子 註:屬性中的Rect類別詳見[Rect](https://hackmd.io/ChZE3I3TTQ-1rMqfe3VZLA)。 ```java= public abstract class GameObject implements GameKernel.UpdateInterface, GameKernel.PaintInterface { private final Rect collider; //遊戲物件碰撞判定矩形 private final Rect painter; //物件繪圖區域 private int id; //預設以(left, top)為遊戲物件左上角生成物件,預設時碰撞區域與繪圖區域相同 public GameObject(final double left, final double top, final double width, final double height) { this.collider = new Rect(left, top, width, height); this.painter = new Rect(left, top, width, height); } //true:以(x,y)為中心生成遊戲物件 false:使用預設以(x,y)為物件左上角生成物件 public GameObject(final double x, final double y, final double width, final double height, final boolean isGenWithCenter) { if (isGenWithCenter) { this.collider = Rect.genWithCenter(x, y, width, height); this.painter = Rect.genWithCenter(x, y, width, height); } else { this.collider = new Rect(x, y, width, height); this.painter = new Rect(x, y, width, height); } } ``` 2.外部可取得的GameOject資料 | function | 功能 | 回傳資料型態 | |:----------:| -------------------- | --- | | getID() | 取得連線所需之ID | int | | collider() | 取得該物件的碰撞矩形 | Rect | | painter() | 取得該物件的繪圖矩形 | Rect | 3.外部可設定的GameObject資料 | function | 功能 | |:---------------------------:| ------------------------------ | | setID(int id) | 設定連線所需之ID | | offset(Vector vector) | 移動物件位置(根據輸入向量移動) | | offset(double x, double y) | 移動物件位置(水平方向移動x,垂直方向移動y) |offsetX(double x)| 以水平方向移動物件位置(位移量為x) |offsetY(double y)| 以垂直方向移動物件位置(位移量為y) |setLeft(double left)| 將物件左側設定在left |setTop(double top)| 將物件上方設定在top |setRight(double right)| 將物件右側設定在right |setBottom(double bottom)| 將物件下方設定在bottom |setXY(double x, double y)| 將物件設定在(x,y) |setX(double x)| 將物件x座標設定在x |setY(double y)| 將物件y座標設定在y 註:移動物件位置時,是將物件的繪圖矩形及碰撞矩形一起做移動 4.方法 | function | 功能 | |:---------------------------:| ------------------------------ | | isOutOfScreen() | 判斷該物件是超出遊戲邊界,回傳值為boolean | | isCollision(Gameobject gameobject)|判斷該物件是否與輸入物件產生碰撞,回傳值為boolean