本文主要為大家介紹了關於利用原生js實現html5小遊戲之打磚塊的相關資料,這是最近工作遇到的一個小需求,文中透過範例程式碼介紹的非常詳細,並分享了完整的原始碼供大家參考學習,需要的朋友們下面隨著小編來一起學習學習吧,希望能幫助大家。
前言
PS:本次項目中使用了大量 es6 語法,故對於 es6 語法不太熟悉的小伙伴最好能先了解一些基本的原理再繼續閱讀。
首先,先說明一下做這個系列的目的:其實主要源自於部落客希望熟練使用canvas 的相關api ,同時對小遊戲的實現邏輯比較感興趣,所以希望透過這一系列的小遊戲來提升自身程式能力;關於es6 語法,個人認為以後es6 語法會越來越普及,所以算是提前熟悉語法使用技巧。小遊戲的實現邏輯上可能不完善,也許會有一些bug ,但畢竟只是為了提升程式設計能力與技巧,希望大家不要太較真
作為第一次分享,我選擇打磚塊這個邏輯不算太複雜的小遊戲。同時,為了接近真實遊戲效果,在遊戲中也添加了關卡,磚塊血量,以及物理碰撞模型的簡單實現。其實專注於遊戲實現邏輯就好了
先上一個遊戲完成後的截圖
遊戲工程目錄如下
. ├─ index.html // 首页html │ ├─ css // css样式资源文件 ├─ images // 图片资源文件 └─ js ├─ common.js // 公共js方法 ├─ game.js // 游戏主要运行逻辑 └─ scene.js // 游戏场景相关类
遊戲實現邏輯
這裡對遊戲中需要繪製的擋板、小球、磚塊、計分板都進行了實例化,並將遊戲主要運行邏輯單獨進行實例化
擋板Paddle
class Paddle { constructor (_main) { let p = { x: _main.paddle_x, // x 轴坐标 y: _main.paddle_y, // y 轴坐标 w: 102, // 图片宽度 h: 22, // 图片高度 speed: 10, // x轴移动速度 ballSpeedMax: 8, // 小球反弹速度最大值 image: imageFromPath(allImg.paddle), // 引入图片对象 isLeftMove: true, // 能否左移 isRightMove: true, // 能否右移 } Object.assign(this, p) } // 向左移动 moveLeft () { ... } // 向右移动 moveRight () { ... } // 小球、挡板碰撞检测 collide (ball) { ... } // 计算小球、挡板碰撞后x轴速度值 collideRange (ball) { ... } }
擋板類別:主要定義其座標位置、圖片大小、x 軸位移速度、對小球反彈速度的控制等,再根據不同按鍵響應moveLeft 和moveRight 移動事件,collide 方法檢測小球是否與擋板碰撞,並返回布林值
小球Ball
class Ball { constructor (_main) { let b = { x: _main.ball_x, // x 轴坐标 y: _main.ball_y, // y 轴坐标 w: 18, // 图片宽度 h: 18, // 图片高度 speedX: 1, // x 轴速度 speedY: 5, // y 轴速度 image: imageFromPath(allImg.ball), // 图片对象 fired: false, // 是否运动,默认静止不动 } Object.assign(this, b) } move (game) { ... } }
小球類:其大部分屬性與擋板類似,主要透過move 方法控制小球運動軌跡
磚塊Block
class Block { constructor (x, y, life = 1) { let bk = { x: x, // x 轴坐标 y: y, // y 轴坐标 w: 50, // 图片宽度 h: 20, // 图片高度 image: life == 1 ? imageFromPath(allImg.block1) : imageFromPath(allImg.block2), // 图片对象 life: life, // 生命值 alive: true, // 是否存活 } Object.assign(this, bk) } // 消除砖块 kill () { ... } // 小球、砖块碰撞检测 collide (ball) { ... } // 计算小球、砖块碰撞后x轴速度方向 collideBlockHorn (ball) { ... } }
磚塊類別:會有兩個屬性不同,分別是life 和是否存活。然後,在小球和磚塊撞擊時,呼叫 kill 方法扣除目前磚塊血量,當血量為0時,清除磚塊。 collide 方法偵測小球與磚塊是否有碰撞,並傳回布林值
計分板Score
class Score { constructor (_main) { let s = { x: _main.score_x, // x 轴坐标 y: _main.score_y, // y 轴坐标 text: '分数:', // 文本分数 textLv: '关卡:', // 关卡文本 score: 200, // 每个砖块对应分数 allScore: 0, // 总分 blockList: _main.blockList, // 砖块对象集合 blockListLen: _main.blockList.length, // 砖块总数量 lv: _main.LV, // 当前关卡 } Object.assign(this, s) } // 计算总分 computeScore () { ... } }
分數類別:會記錄目前分數、關卡數,其中computeScore 方法會在小球碰撞磚塊且磚塊血量為0時調用,並累加總分
場景Scene
class Scene { constructor (lv) { let s = { lv: lv, // 游戏难度级别 canvas: document.getElementById("canvas"), // canvas 对象 blockList: [], // 砖块坐标集合 } Object.assign(this, s) } // 实例化所有砖块对象 initBlockList () { ... } // 创建砖块坐标二维数组,并生成不同关卡 creatBlockList () { ... } }
場景類別:主要根據遊戲難度級別,繪製不同關卡及磚塊集合(目前只產生了三個關卡)。其中creatBlockList 方法先生成所有磚塊的二維座標數組,再呼叫initBlockList 方法進行所有磚塊的實例化
遊戲主邏輯Game
class Game { constructor (fps = 60) { let g = { actions: {}, // 记录按键动作 keydowns: {}, // 记录按键 keycode state: 1, // 游戏状态值,初始默认为1 state_START: 1, // 开始游戏 state_RUNNING: 2, // 游戏开始运行 state_STOP: 3, // 暂停游戏 state_GAMEOVER: 4, // 游戏结束 state_UPDATE: 5, // 游戏通关 canvas: document.getElementById("canvas"), // canvas 元素 context: document.getElementById("canvas").getContext("2d"), // canvas 画布 timer: null, // 轮询定时器 fps: fps, // 动画帧数,默认60 } Object.assign(this, g) } ... }
遊戲核心類別:這裡包括遊戲主要運行邏輯,包括但不限於以下幾點
繪製遊戲整個場景
呼叫定時器逐幀繪製動畫
遊戲通關及遊戲結束判定
綁定按鈕事件
邊界偵測處理函數
碰撞偵測處理函數
入口函數_main
let _main = { LV: 1, // 初始关卡 MAXLV: 3, // 最终关卡 scene: null, // 场景对象 blockList: null, // 所有砖块对象集合 ball: null, // 小球对象 paddle: null, // 挡板对象 score: null, // 计分板对象 ball_x: 491, // 小球默认 x 轴坐标 ball_y: 432, // 小球默认 y 轴坐标 paddle_x: 449, // 挡板默认 x 轴坐标 paddle_y: 450, // 挡板默认 y 轴坐标 score_x: 10, // 计分板默认 x 轴坐标 score_y: 30, // 计分板默认 y 轴坐标 fps: 60, // 游戏运行帧数 game: null, // 游戏主要逻辑对象 start: function () { let self = this /** * 生成场景(根据游戏难度级别不同,生成不同关卡) */ self.scene = new Scene(self.LV) // 实例化所有砖块对象集合 self.blockList = self.scene.initBlockList() /** * 小球 */ self.ball = new Ball(self) /** * 挡板 */ self.paddle = new Paddle(self) /** * 计分板 */ self.score = new Score(self) /** * 游戏主要逻辑 */ self.game = new Game(self.fps) /** * 游戏初始化 */ self.game.init(self) } }
入口函數:實作了遊戲中所需的所有類別的實例化,並進行遊戲的初始化
相關推薦:
以上是原生js實作html5打磚塊小遊戲的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!