# 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