摘要:文章首發于我的博客前言上一篇文章小恐龍游戲源碼探究二讓地面動起來實現了地面的移動。街機模式的效果就是游戲開始后,進入全屏模式。例如可以看到,進入街機模式之前,有一段開場動畫。
文章首發于我的 GitHub 博客前言
上一篇文章:《Chrome 小恐龍游戲源碼探究二 -- 讓地面動起來》 實現了地面的移動。這一篇文章中,將實現效果:1、瀏覽器失焦時游戲暫停,聚焦游戲繼續。 2、開場動畫。 3、進入街機模式。
街機模式的效果就是:游戲開始后,進入全屏模式。例如:
可以看到,進入街機模式之前,有一段開場動畫。我們先來實現一下這個開場動畫。
這里先只實現地面的開場動畫,小恐龍的后續再去實現。實現開場動畫
首先修改 CSS 樣式:
.offline .runner-container { position: absolute; top: 35px; - width: 100%; + width: 44px; max-width: 600px; height: 150px; overflow: hidden; }
讓 canvas 初始只顯示 44px 的寬度。
然后在 Runner 的原型鏈上添加方法:
Runner.prototype = { // 游戲被激活時的開場動畫 // 將 canvas 的寬度調整到最大 playIntro: function () { if (!this.activated && !this.crashed) { this.playingIntro = true; // 正在執行開場動畫 // 定義 CSS 動畫關鍵幀 var keyframes = "@-webkit-keyframes intro { " + "from { width:" + Trex.config.WIDTH + "px }" + "to { width: " + this.dimensions.WIDTH + "px }" + "}"; // 將動畫關鍵幀插入頁面中的第一個樣式表 document.styleSheets[0].insertRule(keyframes, 0); this.containerEl.style.webkitAnimation = "intro .4s ease-out 1 both"; this.containerEl.style.width = this.dimensions.WIDTH + "px"; // 監聽動畫。當觸發結束事件時,設置游戲為開始狀態 this.containerEl.addEventListener(Runner.events.ANIMATION_END, this.startGame.bind(this)); this.setPlayStatus(true); // 設置游戲為進行狀態 this.activated = true; // 游戲彩蛋被激活 } else if (this.crashed) { // 這個 restart 方法的邏輯這里先不實現 this.restart(); } }, // 設置游戲為開始狀態 startGame: function () { this.playingIntro = false; // 開場動畫結束 this.containerEl.style.webkitAnimation = ""; }, };
補充數據:
Runner.events = { // ... + ANIMATION_END: "webkitAnimationEnd", };
這里用到了小恐龍類里的數據,我們先臨時定義一下(后面講到小恐龍那一章時,需要把這段臨時代碼刪除):
function Trex() {} Trex.config = { WIDTH: 44, };
然后在 Runner 的 update 方法中調用上面定義的 playIntro 方法:
Runner.prototype = { update: function () { // ... if (this.playing) { this.clearCanvas(); + // 剛開始 this.playingIntro 未定義 !this.playingIntro 為真 + if (!this.playingIntro) { + this.playIntro(); // 執行開場動畫 + } + // 直到開場動畫結束再移動地面 + if (this.playingIntro) { + this.horizon.update(0, this.currentSpeed); + } else { + deltaTime = !this.activated ? 0 : deltaTime; this.horizon.update(deltaTime, this.currentSpeed); + } } // ... }, };
解釋一下這段代碼:
if (this.playingIntro) { this.horizon.update(0, this.currentSpeed); } else { deltaTime = !this.activated ? 0 : deltaTime; this.horizon.update(deltaTime, this.currentSpeed); }
當程序走 if 邏輯的時候,this.horizon.update 接收到的第一個參數為 0,這樣在這個方法內部計算出來的位移也是 0。所以只要還在執行開場動畫,地面就不會移動。當程序走 else 邏輯的時候,開場動畫執行完畢,此時 playIntro 函數已經執行結束,this.activated 值為 true,deltaTime 值大于零,計算出的地面位移就不再為 0。
這樣,就實現了地面的開場動畫:
查看添加或修改的代碼,戳這里監聽窗口 blur、focus 事件
接下來要實現的效果是:瀏覽器窗口失焦時游戲暫停,聚焦時游戲繼續。
在 Runner 原型鏈上添加方法,來判斷瀏覽器窗口是否失焦:
Runner.prototype = { // 當頁面失焦時,暫停游戲,否則進行游戲 onVisibilityChange: function (e) { if (document.hidden || document.webkitHidden || e.type == "blur" || document.visibilityState != "visible") { this.stop(); } else if (!this.crashed) { this.play(); } }, play: function () { if (!this.crashed) { this.setPlayStatus(true); this.paused = false; this.time = getTimeStamp(); this.update(); } }, stop: function () { this.setPlayStatus(false); this.paused = true; cancelAnimationFrame(this.raqId); this.raqId = 0; }, };
在 startGame 方法中添加對 blur、focus 事件的監聽:
Runner.prototype = { startGame: function () { // ... + window.addEventListener(Runner.events.BLUR, + this.onVisibilityChange.bind(this)); + window.addEventListener(Runner.events.FOCUS, + this.onVisibilityChange.bind(this)); }, };
補充數據:
Runner.events = { // ... + BLUR: "blur", + FOCUS: "focus" };
效果如下:
查看添加或修改的代碼,戳這里實現街機模式
在 Runner 原型鏈上添加方法:
Runner.prototype = { // 設置進入街機模式時 canvas 容器的縮放比例 setArcadeModeContainerScale: function () { var windowHeight = window.innerHeight; var scaleHeight = windowHeight / this.dimensions.HEIGHT; var scaleWidth = window.innerWidth / this.dimensions.WIDTH; var scale = Math.max(1, Math.min(scaleHeight, scaleWidth)); var scaledCanvasHeight = this.dimensions.HEIGHT * scale; // 將 canvas 橫向占滿屏幕,縱向距離頂部 10% 窗口高度處 var translateY = Math.ceil(Math.max(0, (windowHeight - scaledCanvasHeight - Runner.config.ARCADE_MODE_INITIAL_TOP_POSITION) * Runner.config.ARCADE_MODE_TOP_POSITION_PERCENT)) * window.devicePixelRatio; this.containerEl.style.transform = "scale(" + scale + ") translateY(" + translateY + "px)"; }, // 開啟街機模式(全屏) setArcadeMode: function () { document.body.classList.add(Runner.classes.ARCADE_MODE); this.setArcadeModeContainerScale(); }, };
補充數據:
Runner.config = { // ... + ARCADE_MODE_INITIAL_TOP_POSITION: 35, // 街機模式時,canvas 距頂部的初始距離 + ARCADE_MODE_TOP_POSITION_PERCENT: 0.1, // 街機模式時,canvas 距頁面頂部的距離,占屏幕高度的百分比 }; Runner.classes = { // ... + ARCADE_MODE: "arcade-mode", };
定義 CSS 類 arcade-mode 里的樣式:
.arcade-mode, .arcade-mode .runner-container, .arcade-mode .runner-canvas { image-rendering: pixelated; max-width: 100%; overflow: hidden; } .arcade-mode .runner-container { left: 0; right: 0; margin: auto; transform-origin: top center; transition: transform 250ms cubic-bezier(0.4, 0.0, 1, 1) .4s; z-index: 2; }
最后調用 setArcadeMode 方法,就可以進入街機模式:
Runner.prototype = { startGame: function () { + this.setArcadeMode(); // 進入街機模式 // ... }, };
效果如下:
查看添加或修改的代碼,戳這里
Demo 體驗地址:https://liuyib.github.io/blog/demo/game/google-dino/arcade-mode/
上一篇 | 下一篇 | Chrome 小恐龍游戲源碼探究二 -- 讓地面動起來 | Chrome 小恐龍游戲源碼探究四 -- 隨機繪制云朵 |
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/103883.html
摘要:文章首發于我的博客前言上一篇文章小恐龍游戲源碼探究三進入街機模式實現了開場動畫和街機模式。 文章首發于我的 GitHub 博客 前言 上一篇文章:《Chrome 小恐龍游戲源碼探究三 -- 進入街機模式》 實現了開場動畫和街機模式。這一篇文章中,將實現云朵的隨機繪制。 云朵類 Cloud 定義云朵類 Cloud: /** * 云朵類 * @param {HTMLCanvasEle...
摘要:首先是繪制靜態的地面。上一篇下一篇無小恐龍游戲源碼探究二讓地面動起來 文章首發于我的 GitHub 博客 目錄 Chrome 小恐龍游戲源碼探究一 -- 繪制靜態地面 Chrome 小恐龍游戲源碼探究二 -- 讓地面動起來 Chrome 小恐龍游戲源碼探究三 -- 進入街機模式 Chrome 小恐龍游戲源碼探究四 -- 隨機繪制云朵 Chrome 小恐龍游戲源碼探究五 -- 隨機繪...
摘要:例如,將函數修改為小恐龍眨眼這樣小恐龍會不停的眨眼睛。小恐龍的開場動畫下面來實現小恐龍對鍵盤按鍵的響應。接下來還需要更新動畫幀才能實現小恐龍的奔跑動畫。 文章首發于我的 GitHub 博客 前言 上一篇文章:《Chrome 小恐龍游戲源碼探究七 -- 晝夜模式交替》實現了游戲晝夜模式的交替,這一篇文章中,將實現:1、小恐龍的繪制 2、鍵盤對小恐龍的控制 3、頁面失焦后,重新聚焦會重置...
摘要:文章首發于我的博客前言上一篇文章小恐龍游戲源碼探究六記錄游戲分數實現了游戲分數最高分數的記錄和繪制。這一篇文章中將實現晝夜模式交替的的效果。原來的游戲中,晝夜交替每米觸發一次,這里為了演示,改成了米觸發一次。 文章首發于我的 GitHub 博客 前言 上一篇文章:《Chrome 小恐龍游戲源碼探究六 -- 記錄游戲分數》實現了游戲分數、最高分數的記錄和繪制。這一篇文章中將實現晝夜模式...
摘要:文章首發于我的博客前言上一篇文章小恐龍游戲源碼探究八奔跑的小恐龍實現了小恐龍的繪制以及鍵盤對小恐龍的控制,這一篇文章中將實現游戲的碰撞檢測。 文章首發于我的 GitHub 博客 前言 上一篇文章:《Chrome 小恐龍游戲源碼探究八 -- 奔跑的小恐龍》實現了小恐龍的繪制以及鍵盤對小恐龍的控制,這一篇文章中將實現游戲的碰撞檢測。 碰撞檢測原理 這個游戲采用的檢測方法是盒子碰撞,這種檢...
閱讀 1459·2021-09-02 13:57
閱讀 1874·2019-08-30 15:55
閱讀 2413·2019-08-30 15:54
閱讀 2250·2019-08-30 15:44
閱讀 2737·2019-08-30 13:18
閱讀 486·2019-08-30 13:02
閱讀 645·2019-08-29 18:46
閱讀 1669·2019-08-29 11:25