自學網頁遊戲開發,參考網頁: Phaser 幫我撐個 30 天、Note of Phaser3、Create a Perloader
利用HTML、CSS和JS對canvas進行調整
<!--HTML、CSS-->
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
margin: 0;
background-color: #000000;
}
canvas {
position: absolute;
/*讓遊戲畫面在中間*/
top: 50%;
left: 50%;
/*translate3d(橫坐標, 縱坐標, 上下層位置)*/
transform: translate3d(-50%, -50%, 0);
}
</style>
</head>
// 網頁開著時,就會自己執行
window.onload = function() {
function resize() {
let canvas = document.querySelector('canvas')
let ww = window.innerWidth
let wh = window.innerHeight
let wRatio = ww / wh
let gameRatio = config.width / config.height
if (wRatio < gameRatio) {
canvas.style.width = ww + 'px'
canvas.style.height = ( ww / gameRatio ) + 'px'
} else {
canvas.style.width = ( wh * gameRatio ) + 'px'
canvas.style.height = wh + 'px'
}
}
resize()
// target.addEventListener(type, listener, options); 觸發視窗改變時,就發起函式
window.addEventListener('resize', resize, false) // 偵聽事件 resize
}
獲取螢幕寬可以用 let width = this.sys.game.config.width,高也用同樣方法。
這裡使用pharse3裡面的Camera
// 假如撞到坦克,會一直呼叫 gameOver,這時候我們還要特別處理不要呼叫多次的 gameOver
scene.init = function() {
.....
this.isGameOver = false
}
scene.update = function() {
if (this.isGameOver) return
if (遊戲失敗條件) {this.gameOver()}
.....
}
// 在這裡加上遊戲結束特效
scene.gameOver = function() {
// 500 ms 相機 shake 效果
this.cameras.main.shake(500)
// 偵聽 shake 動畫結束
this.cameras.main.on('camerashakecomplete', () => {
// 500 ms 相機 fade 效果
this.cameras.main.fade(500)
})
// 偵聽 fade out 動畫結束
this.cameras.main.on('camerafadeoutcomplete', () => {
// 遊戲重新
this.scene.restart()
})
}
## text
scene.create = function () {
// ...
// 加入文字 x y 文字內容
this.text = this.add.text(30, 20, 'x: 50', {
font: '24px Open Sans', // 文字樣式
fill: '#000000' // 顏色
})
this.keyboard = this.input.keyboard.createCursorKeys()
}
// 在 update 這邊,當操作 man 的時候,把 man 的 x 數值,更新到 text 上
scene.update = function () {
//...
if (this.keyboard.right.isDown) {
this.text.setText('x: ' + 2) // 更改顯示文字內容
}
}
## loader
scene.preload = function() {
//...
// 創建 text
let percentText = this.add.text(320, 160, '', {
font: '24px Open Sans',
fill: '#ffffff'
}).setOrigin(0.5, 0.5) // 文字置中
let assetText = this.add.text(320, 200, '', {
font: '18px monospace',
fill: '#ffffff'
}).setOrigin(0.5, 0.5)
// 畫出進度條
var progressBar = this.add.graphics();
var progressBox = this.add.graphics();
progressBox.fillStyle(0x222222, 0.8); // fillStyle(color, alpha)
progressBox.fillRect(150, 135, 320, 50); // fillRect(x, y, width, height)
// 偵聽處理檔案
this.load.on('progress', value => {
percentText.setText(parseInt(value * 100) + '%')
progressBar.clear(); // 避免進度條一直疊加
progressBar.fillStyle(0xffffff, 1);
progressBar.fillRect(160, 145, 300 * value, 30);
console.log(value)
})
// 顯示處理文件
this.load.on('fileprogress', file => {
assetText.setText('Loading asset: ' + file.key);
console.log(file.src);
});
// 偵聽載入檔案結束
this.load.on('complete', () => {
percentText.destroy() // 載入完,把它從畫面上清除
progressBar.destroy();
progressBox.destroy();
})
}
camera 跟隨著 player 的位置
scene.create = function() {
// 設定物理邊界
this.physics.world.setBounds(0, 0, 1000, 1000); // setBounds(x, y, width, height)
//...
// 設定相機邊界
this.cameras.main.setBounds(0, 0, 1000, 1000) // setBounds(x, y, width, height)
this.cameras.main.startFollow(this.player) // 相機跟隨
}
使用SpriteIlluminator來做出normal maps,如果這個效果要用在sprite sheet要特殊方法,這裡就不提了
scene.preload = function () {
//...
// 加載圖像, player02.png 為一般圖像 ; player02_n.png 為 normal map
this.load.image('player02', ['assets/player02.png', 'assets/player02_n.png']);
}
scene.create = function() {
let player02 = this.add.sprite(250, 300, 'player02')
player02.setScale(0.5)
// 讓角色接受光源
player02.setPipeline('Light2D')
// 在 (350, 250) 位置添加半徑 200 的光源
let light = this.lights.addLight(350, 250, 200)
this.lights.enable()
// 設定環境燈
this.lights.setAmbientColor(0x555555)
// 滑鼠移動,變更燈光位置
this.input.on('pointermove', function (pointer) {
light.x = pointer.x;
light.y = pointer.y;
});
}