🎉 祝大家 9/24 中秋 4 天連假快樂! 放假前夕準備好烤肉與休假的心情了嗎?就算連假開始,我們的鐵人賽技術分享依然不間斷!
今天我們要深入遊戲大廳的核心功能 —— 動態家具擺設與空間裝飾系統。玩家在「青花瓷豆花怪」與「雪花冰極速挑戰」獲得的點數,可以用來解鎖大廳中的家具與貼紙,並自由擺設屬於自己的風格門市。
在 Cocos Creator 中,畫面的構建是以**樹狀節點(Node Tree)**為核心。當玩家在手機螢幕上拖曳家具時,傳回的是螢幕世界座標(World Space),我們必須將其轉換為大廳背景節點下的本地座標(Local Space):
// FurnitureItem.ts - 拖曳與座標轉換實作
import { _decorator, Component, Node, EventTouch, Vec3, Vec2 } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('FurnitureItem')
export class FurnitureItem extends Component {
onEnable() {
this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
}
private onTouchMove(event: EventTouch) {
// 1. 取得觸控的世界座標
const worldPos = event.getUIComponentsWorldLoc();
// 2. 轉換為大廳背景 Node 的本地座標
const parentNode = this.node.parent!;
const localPos = parentNode.getComponent(UITransform)!.convertToNodeSpaceAR(new Vec3(worldPos.x, worldPos.y, 0));
// 3. 更新家具位置
this.node.setPosition(localPos);
// 4. 動態 Y-Sorting:Y 軸越低(越靠近螢幕下方),siblingIndex 越大(顯示在越上層)
this.updateZOrdering();
}
private updateZOrdering() {
// 將 Y 座標取負值作為排序依據
const sortedIndex = Math.floor(-this.node.position.y);
this.node.setSiblingIndex(sortedIndex);
}
}
傳統關聯式資料庫(RDBMS)如果要把每個玩家擺放的幾十件家具拆成 user_furniture 資料表,每次載入都要執行多表 JOIN。我們採用 PostgreSQL 的 JSONB (Binary JSON) 欄位型態:
// Ktor Exposed ORM - UserTable.kt
object UsersTable : Table("users") {
val id = integer("id").autoIncrement()
val lineUserId = varchar("line_user_id", 64).uniqueIndex()
val totalPoints = integer("total_points").default(0)
// 使用 JSONB 欄位儲存動態家具陣列
val roomLayout = jsonb