EngineJS
開始
這個章節將會一步一步帶你做出一個完整的小遊戲,所有的步驟都會附上程式碼與實際範例,可以點擊範例程式執行並觀察成果。
設定背景
setBackdrop(path, x, y, width, height);path: 素材的網址
x: 背景圖左上角 x 座標
y: 背景圖左上角 y 座標
width: 長度
height: 寬度
setBackdrop("./assets/background.png", 0, 0, 470, 400);
範例程式
創造角色
創造出小鳥,預設位置為場景中央
var bird = createSprite("./assets/bird.png");
創造出上下水管,並設定座標位置
var tubeUp = createSprite({
costumes: "./assets/up-tube.png",
x: 450,
y: -30
});
var tubeDown = createSprite({
costumes: "./assets/down-tube.png",
x: 450,
y: 430
});
範例程式
遊戲迴圈
forever(fn) | aways(fn) | update(fn) fn: 遊戲迴圈,重複不斷執行的函式
在遊戲迴圈裡不斷移動水管,如果水管移動超出邊界就重置水管的位置
forever(function() {
tubeUp.x -= 2;
tubeDown.x -= 2;
if(tubeUp.x < 0) {
resetTube();
}
});
重置水管的函式,將水管移到右邊遊戲場景外,並隨機水管的位置
function resetTube () {
var pos = Math.random()*300 + 50;
tubeUp.x = 450;
tubeDown.x = 450;
tubeUp.y = pos - 230;
tubeDown.y = pos + 230;
}
範例程式
遊戲事件
幫鳥加上重力,創造變數 vx 表示鳥的下降速度
var vy = 0;
forever(function() {
bird.y + vy;
vy += 0.2;
});
當滑鼠點擊時,鳥要往上飛行
when('click', function() {
vy = -5;
});
小鳥碰撞水管時停止遊戲
bird.when('touch', [tubeUp, tubeDown], function() {
stop();
});
範例程式
遊戲音效
當滑鼠點擊銀幕時,播放跳耀的音效
when('click', function() {
vy = -5;
sound.play('./assets/jump.ogg');
});
進入遊戲後就不斷重複播放背景音樂
var bgm = sound.play('./assets/bgm.ogg');
bgm.loop = true;
範例程式
顯示文字
設計計分板並顯示在畫面左上方
var scores = 0;
forever(function() {
if(tubeUp.x < 0) {
scores += 1;
}
print(scores, 10, 10, 'white', 45);
});
範例程式
完成
創造開始按鈕與遊戲結束Logo,並隱藏結束Logo
var startBtn = createSprite("./assets/start-button.png");
var gameOverLogo = createSprite({
costumes: "./assets/gameOver.png",
hidden: true,
y: 100
});
當點擊開始按鈕時,執行初始化函式 start,遊戲初始化函式會初始角色的座標與歸零分數,並將飛行狀態改為 true
startBtn.when('click', start);
var flying = false;
function start () {
startBtn.hidden = true;
gameOverLogo.hidden = true;
flying = true;
bird.y = 200;
scores = 0;
}
當玩家撞到水管或是超出上下的邊界,執行遊戲結束的函式 gameOver,將會顯示結束 logo 和重新開始的按鈕,並修改飛行狀態為 false
bird.when('touch', [tubeUp, tubeDown], gameOver);
forever(function() {
if(bird.y > 400 || bird.y < 0) {
gameOver();
}
});
function gameOver () {
gameOverLogo.hidden = false;
startBtn.hidden = false;
flying = false;
}
改寫遊戲迴圈的判斷式
forever(function() {
if(!flying) {
return;
}
}
範例程式
角色屬性
座標
Sprite.x, Sprite.y角色的 x, y 座標
bird.x = 50;
bird.y = 50;
範例程式
方向
Sprite.direction角色面向的方向,值介於 0 ~ 359 度
bird.direction = 180;
範例程式
縮放
Sprite.sacle角色大小縮放比例,預設為 1
bird.scale = 0.5;
範例程式
旋轉方式
Sprite.rotationStyle角色旋轉的方式,三種方式
full (預設)
flipped (左右翻轉)
fixed (固定不旋轉)
Sprite.rotationStyle = 'fixed'
範例程式
透明度
Sprite.opacity值介於 0 ~ 1
Sprite.opacity
範例程式
造型編號
Sprite.costumeId角色當前造型,造型列表的索引
Sprite.costumeId = 1;
範例程式
圖層
Sprite.layer角色當前所在的圖層
Sprite.layer = 2;
範例程式
Sprite.hiddentrue 設為隱藏,false 設為不隱藏
Sprite.hidden = true;
範例程式
角色方法
移動到
Sprite.moveTo(x, y);x: 目的位置 x 座標
y: 目的位置 y 座標
bird.moveTo(100, 100);
範例程式
移動
Sprite.move(vx, vy);vx: 水平移動距離 vx
vy: 垂直移動距離 vy
Sprite.move(100, 100);
範例程式
朝向前移動
Sprite.stepForward(d);d: 移動的步數
Sprite.stepForward(50);
範例程式
碰到邊界就反彈
Sprite.bounceEdge();
bird.forever(function() {
this.stepForward(10);
this.bounceEdge();
});
範例程式
朝向
Sprite.toward(target);target: Sprite 角色對象
Sprite.toward(target);
範例程式
綁定事件
Sprite.when(eventName, fun);eventname: "click", "touched", "hover"
fun: 事件觸發執行的函式
bird_1.when('touch', bird_2, function() {
bird_2.moveTo(10, 10);
});
範例程式
碰撞檢測
sprite.touched(target);target: 若 sprite 碰撞到 target 返回 true
Sprite.touched(target);
範例程式
角色迴圈
Sprite.forever(fun);fun: 不斷執行的函式,this 綁定角色對象
bird.forever(function() {
this.stepForward(1);
});
範例程式
播放動畫
Sprite.animate(frames, time, callback);frames: 動畫造型的順序
time: 動畫每一秒切換的幀數
callback: 動畫結束後執行的回呼函式
bird.animate([0, 1, 2, 3, 4, 5], 100);
範例程式
銷毀
Sprite.destroy();
bird.destroy();
範例程式
廣播
Sprite.destroy();
bird.when('listen', 'gameOver', function () {
this.destroy();
});
broadcast("gameOver");
範例程式
角色之間的距離
Sprite.distanceTo();
bird_1.distanceTo(bird_2);
範例程式
事件
when | on綁定遊戲的事件的方法
碰撞
Sprite.when("touch", target, callback);單一對象的碰撞
bird.when("touch", bird, callback);
範例程式
Sprite.when("touch", [target], callback);多個對象的碰撞,可以傳入陣列
bird.when("touch",[bird_1, bird_2], callback);
範例程式
點擊事件
when("click", sprite, callback);當滑鼠點擊 sprite 執行函式
when("click", bird, function () {
bird.scale += 0.5;
});
範例程式
Sprite.when("click", callback);當滑鼠點擊 sprite 執行函式
bird.when("click", function () {
this.scale += 0.5;
});
範例程式
滑鼠按下
when("mousedown", callback);
when("mousedown", function() {
bird.scale += 1;
});
範例程式
Sprite.when("mousedown", callback);
bird.when("mousedown", function() {
this.scale += 1;
});
範例程式
滑鼠放開
when("mouseup", callback);
when("mouseup", function() {
bird.scale += 1;
});
範例程式
Sprite.when("mouseup", callback);
bird.when("mouseup", function() {
bird.scale += 1;
});
範例程式
鍵盤按下
when("keydown", keyName, callback);
當按下特定按鍵,觸發執行函式
when('keydown', "space", function() {
bird.scale += 0.2;
});
範例程式
when("keydown", keyName, callback);
當按下任意按鍵,觸發執行函式,觸發執行函式,可以傳入 "any" 或是省略參數
when('keydown', function() {
bird.scale += 0.2;
});
範例程式
鍵盤放開
when("keyup";, keyName, callback);
當放開特定按鍵,觸發執行函式
when("keyup", "space" , function() {
bird.scale += 0.5;
});
範例程式
when("keyup";, keyName, callback);
當放開任意按鍵,觸發執行函式,可以傳入 "any" 或是省略參數
when("keyup", function() {
bird.scale += 0.5;
});
範例程式
按鍵持續按壓
when("holding", keyName, callback);
持續按壓特定按鍵,觸發執行函式
when("holding", "right", function() {
bird.x += 1;
});
範例程式
when("holding", callback);
持續按壓任意按鍵,觸發執行函式,可以傳入 "any" 或是省略參數
when("holding", function() {
bird.direction += 3;
});
範例程式
鍵盤&滑鼠
滑鼠
cursor.x, cursor.y滑鼠 x,y 座標 cursor.left, cursor.right滑鼠左右鍵狀態 cursor.isDown滑鼠是否被按住
var cursor = cursor;
forever(function(){
var y = 80
print('**滑鼠測試**', 30, y, 'white');
print('cursor.x: ' + cursor.x, 30, y+ 20, 'white');
print('cursor.y: ' + cursor.y, 30, y + 2*20, 'white');
print('cursor.left: ' + cursor.left, 30, y + 3*20, 'white');
print('cursor.right: ' + cursor.right, 30, y + 4*20, 'white');
print('cursor.isDown: ' + cursor.isDown, 30, y + 5*20, 'white');
});
範例程式
鍵盤
key[keyName] 鍵盤中特定鍵的狀態
forever(function(){
var y = 80
print('**鍵盤測試**', 30, y + 8*20, 'white');
print('key.q: ' + key.q, 30, y + 9*20, 'white');
print('key.w: ' + key.w, 30, y + 10*20, 'white');
print('key.e: ' + key.e, 30, y + 11*20, 'white');
print('key.r: ' + key.r, 30, y + 12*20, 'white');
});
範例程式
聲音
播放
sound.play(fileName, loop);fileName: 音效素材的路徑
loop: 非必要參數,傳入 true 則音效會不斷反覆播放
sound.play("shoot.mp3");
範例程式
範例程式
設定音量
sound.setVolume(num);num: 0 ~ 1 的音量大小
sound.setVolume(0.5);
範例程式
靜音
sound.mute(bool);bool: 若為 true 則將所有音效靜音
sound.mute(true);
範例程式
停止播放
sound.stop();停止所有的音效
sound.stop();
範例程式
繪筆
畫筆的屬性
設定繪筆的顏色、大小
pen.color繪筆線條的顏色 pen.size繪筆線條的寬度尺寸 pen.fillColor幾何圖形的填充的顏色
var pen = pen;
pen.color = "red";
pen.size = 30;
pen.fillColor = "blue";
範例程式
線條
pen.drawLine(x1, y1, x2, y2);
x1: 起點 x 座標
y1: 起點 y 座標
x2: 終點 x 座標
y2: 終點 y 座標
pen.drawLine(10, 10, 150, 150);
範例程式
矩形
pen.drawRect(x, y, width, height);
x: x 座標
y: y 座標
width: 長
height: 寬
pen.drawRect(400, 40, 200, 100);
範例程式
圓形
pen.drawCircle(x, y, r);
x: 圓心 x 座標
y: 圓心 y 座標
r: 半徑長
pen.drawCircle(200, 100, 100);
範例程式
三角形
pen.drawTriangle(x1, y1, x2, y2, x3, y3);
x1, y1: 角 1 的座標
x2, y2: 角 2 的座標
x3, y3: 角 3 的座標
pen.drawTriangle(200, 200, 300, 300, 200, 300);
範例程式
多邊形
pen.drawCircle(x1, y1, x2, y2, x3, y3, ...);
pen.drawPolygon(320, 240, 520, 120, 520, 420, 100, 400, 100, 200);
範例程式
文字
pen.drawText(text, x, y, font);
text: 文字的內容
x: X 座標
y: Y 座標
font: 字型,預設為 "Arial"
pen.drawText('測試123', 100, 100);
範例程式
雲端變數
設定雲端變數
DB.variables.set(variableName, value);
variableName: 變數名稱
value: 值
DB.variables.set("bestPlayer", USER_NAME);
DB.variables.set("bestScore", 300);
讀取雲端變數
DB.variables[variableName]
variableName: 變數名稱
forever(function () {
print("最高分玩家:" + DB.variables.bestPlayer, 10, 10);
print("得分:" + DB.variables.bestScore, 40, 10);
});
資料庫
初始化
DB.table(tableName)
tableName: 資料表的名稱
var users = DB.table("users");
新增
table.insert(data, callback);
data: 新增資料
callback: 回呼函式
// 新增五筆個人資料
users.insert({name: "David", age: 22});
users.insert({name: "Lily", age: 18});
users.insert({name: "Kevin", age: 25});
users.insert({name: "Allen", age: 18});
users.insert({name: "Williams", age: 21});
讀取
table.find(query, callback);
query: 符合條件的資料
callback: 回呼函式
// 讀取所有資料
users.find({}, console.log);
// 讀取符合名字為 David 的資料
users.find({name: "David"}, console.log);
// 讀取符合年齡為 18 歲的資料
users.find({age: 18}, console.log);
更新
table.update(query, data, callback);
query: 符合條件的資料
data: 更新的資料
// 符合名字為 Lily 的資料,年齡改成 17 歲
user.update({"name": "Lily"}, {age: 17});
刪除
table.remove(query, callback);
query: 符合條件的資料
callback: 回呼函式
user.remove({}, console.log); // 刪除所有的資料
Socket
發送訊息
DB.broadcast(port, message);
port: 接口名稱
message: 廣播的訊息
when("click", function () {
var msg = prompt();
DB.broadcast("say", msg);
});
接收訊息
DB.onMessage(port, handler);
port: 接口名稱
handler: 接收到訊息執行的回呼函式
DB.onMessage("say", console.log);