我的新書AI 職場超神助手:ChatGPT 與生成式 AI 一鍵搞定工作難題的教材投影片已製作完成
歡迎各位有需要的教師和博碩文化索取教材

[14- Pixi教學] PIXI場景設定



載入所使用的Library

在開發遊戲時我們會使用到PixiJS、SystemJS、和JQuery,因此我們會需要將這幾個library加進html裡。
首先我們新增一個index.html的入口檔案,內容如下:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Test</title>
  <link rel="stylesheet" type="text/css" href="assets/style.css">
  <script src="lib/system.js"></script>
  <script src="lib/jquery.min.js"></script>
  <script src="lib/pixi.min.js"></script>
</head>
<body>
</body>
</html>

打開這個html後,會看到找不到檔案的訊息。
這時我們在gulpfile.js裡增加一個task名為libs,將我們所需的檔案copy到目標資料夾
其內容如下:

gulp.task('libs', () => {
    return gulp
        .src([
            'node_modules/jquery/dist/jquery.min.js',
            'node_modules/jquery/dist/jquery.min.map',
            'node_modules/systemjs/dist/system-polyfills.js',
            'node_modules/systemjs/dist/system-polyfills.js.map',
            'node_modules/systemjs/dist/system.js',
            'node_modules/systemjs/dist/system.js.map',
            'node_modules/pixi.js/dist/pixi.min.js',
            'node_modules/pixi.js/dist/pixi.min.js.map'
        ])
        .pipe(gulp.dest("build/lib"));
});

這樣子就會在每次編譯時自動複製專案在使用的library進入build/lib裡。

設定場景

要設定一個PixiJS的遊戲場景,這個部份可以先參考關網的範例:Basics
範例裡創建場景的方式如下:

var app = new PIXI.Application(800, 600, {backgroundColor : 0x1099bb});
document.body.appendChild(app.view);

PIXI.Application可以建立一個PIXI的canvas遊戲畫面,其相關API說明請見:PIXI.Application
這個類別有兩種建構子,可以達到相似的功能:

在PixiJS v4以後,官方將所有相關參數都整入options物件內,這樣使用上可以僅傳入需要自行設定的值就好。而要先傳入寬高的則是為了兼容舊版寫法。

new PIXI.Application(960, 540, {width:100, backgroundColor : 0x000000, view: gameCanvasContext});

若兩邊都傳入相同的屬性,會以optionst傳入的值為主。如上面程式碼產生的場景的width會是100。

PIXI.Application可用參數

在創建這個類別時,可以傳入的options參數如下:

Name Type Default Description
autoStart boolean true 過去
width number 800 renderers view的寬
height number 600 renderers view的高
view HTMLCanvasElement 遊戲場景要放置的canvas目標,如果沒有傳入,則會新建一個canvas做為回傳
transparent boolean false 是否支援透明可看到底下物件
antialias boolean false 防鋸齒
preserveDrawingBuffer boolean false 是否支援toDataUrl
resolution number 1 解析度
forceCanvas boolean false 即使存在webGL引擎也不使用
backgroundColor number 0x000000 背景顏色
clearBeforeRender boolean true 在繪圖前先清除canvas上所有元素
roundPixels boolean false 使用Math.floor()來處理所有圖像
forceFXAA boolean false 強制使用FXAA,速度會較快,但可能效果較WebGL差
legacy boolean false 確保能與舊裝置相容
powerPreference string 設定要傳給webGL的參數,對雙顯卡的設備而言可提高效能。
sharedTicker boolean false 可以有共用的PIXI.ticker.shared物件
sharedLoader boolean false 可以有共用的PIXI.loaders.shared物件

於專案中建立場景

接下來,我們在index.html新增一個canvas物件,自行建立一個canvas物件的好處是我們可以較方便的在html內設定canvas的位置

<body>
<div id="gameContainer">
  <canvas id="gameCanvas"></canvas>
</div>
</body>

接著建立Main.ts,其內容如下:

import Application = PIXI.Application;

//將application設定為export,這樣可以在專案的任何地方取到這個元件
export let application:Application
/**
 * 主要的 client application.
 *
 */
export class Main {

    public initGame() {
       //設定場景
       let gameCanvasContext = (< HTMLCanvasElement >jQuery("#gameCanvas")[0]);
       application = new PIXI.Application(960, 540, {width:100,backgroundColor : 0x000000, view: gameCanvasContext});

       //貼一張圖片
       var bunny = PIXI.Sprite.fromImage('assets/bunny.png');
       bunny.x = application.screen.width / 2;
       bunny.y = application.screen.height / 2;
       application.stage.addChild(bunny);
    }
}

接著因為我們使用SystemJS,所以必需用SystemJS的方式來啟動遊戲,在index.html加上下面的javascript script

    var game;
    $(function () {
        //設定要載入的js的位置與副檔名
        SystemJS.config({
            baseURL: "/",
            packages: {
                "/": { defaultExtension: "js" }
            }
        });
        //載入Main.js,載完後執行裡面的某個func
        SystemJS.import('Main').then(function (m) {
            m.Main.prototype.initGame();
        });
    });

這時後打開瀏覽器就可以看到下面的畫面

隨螢幕大小改變尺寸

我們可以看到上面的成果裡,右下方有許多的空白,如果沒有特別對Canvas做縮放,Canvas會一直是相同尺寸。這樣就沒辦法在各個平台、尺寸很順利的進行遊戲,因此要自動偵測並縮放canvas以及場景尺寸。

Main.ts加上onResize()

public onResize() {
    var w = window.innerWidth;
    var h = window.innerHeight;
    var scale = Math.min(w/860,h/540);
    application.view.style.left = (w-scale*860)/2 + "px";
    application.view.style.top = (h-scale*540)/2 + "px";
    application.view.style.width = scale*860 + "px";
    application.view.style.height = scale*540 + "px";
}

並在initGame()新增下面兩行

       //設定遊戲大小隨視窗大小改變
       this.onResize();
       window.onresize = this.onResize; 

這樣遊戲畫面就會永遠置中且自動縮放至適合螢幕大小。



今日成果

原始檔請於此下載:ironman20181029
線上展示:http://claire-chang.com/ironman2018/1029/


17年資歷女工程師,專精於動畫、影像辨識以及即時串流程式開發。經常組織活動,邀請優秀的女性分享她們的技術專長,並在眾多場合分享自己的技術知識,也活躍於非營利組織,辦理活動來支持特殊兒及其家庭。期待用技術改變世界。

如果你認同我或想支持我的努力,歡迎請我喝一杯咖啡!讓我更有動力分享知識!