日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

原生JS超级马里奥(第九天)

發布時間:2024/1/18 javascript 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 原生JS超级马里奥(第九天) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?上一章講述馬里奧跳躍動作和剎車的動作,本章對Json文件改動較多,我會一一講解,還涉及到了部分代碼重構

本章的提交ID:7419c4a70c772a45795d20ceb6559c1e1e8d8e3a

github地址:ainuo5213的超級馬里奧

本節目錄

?

目錄講解:

? ? ? ? 1. loaders/level.js:原loadLevelAsync方法和loadTiles方法移動到了單獨的文件,用于單獨生成loadLevelAsync

實現效果

?layers.js文件改動

layers.js將原本用于獲取TileResolver從實例中改為了創建實例,并且使用外部傳入的tiles,在redraw方法中用于清空當前臨時創建的bufferContext的內容,避免重復渲染

?Level.js改動

Level.js去掉了tiles、tileCollider的初始化操作,暴露一個方法用于設置馬里奧碰撞檢測實例和tiles

loader.js改動

loader.js刪掉了loadTiles、loadLevelAsync方法,將loadJson暴露了出去

,供loader/level.js使用?

TilCollider碰撞檢測實例改動

因之前遺漏,這里改動一下name為type

?1-1關卡數據json改動

1-1.json改動都標有注釋,各位可以嘗試理解一下

{"spriteSheet": "overworld",// 模式,用于16x16單位的多個元素拼湊而成的圖片生成"patterns": {// 云,云被劃分為了6個單位,上面3個,下面三個"cloud-single": {"tiles": [{"name": "cloud-1-1","ranges": [[0, 0]]},{"name": "cloud-1-2","ranges": [[1, 0]]},{"name": "cloud-1-3","ranges": [[2, 0]]},{"name": "cloud-2-1","ranges": [[0, 1]]},{"name": "cloud-2-2","ranges": [[1, 1]]},{"name": "cloud-2-3","ranges": [[2, 1]]}]},// 水管體,水管體被劃分為了2個單位,左邊一個,右邊一個"pipe-section-vert": {"tiles": [{"name": "pipe-vert-left","type": "ground","ranges": [[0, 0]]},{"name": "pipe-vert-right","type": "ground","ranges": [[1, 0]]}]},// 水管帽子被劃分為了2個單位,左邊一個,右邊一個"pipe-cap-vert": {"tiles": [{"name": "pipe-insert-vert-left","type": "ground","ranges": [[0, 0]]},{"name": "pipe-insert-vert-right","type": "ground","ranges": [[1, 0]]}]},// 高度為2的水管,被劃分為了2個,上邊1個單位是水管帽,下邊1個單位是水管體"pipe-2h": {"tiles": [{"pattern": "pipe-cap-vert","ranges": [[0, 0]]},{"pattern": "pipe-section-vert","ranges": [[0, 1,1, 1]]}]},// 高度為3的水管,被劃分為了2個,上邊1個單位是水管帽,下邊2個單位是水管體"pipe-3h": {"tiles": [{"pattern": "pipe-cap-vert","ranges": [[0, 0]]},{"pattern": "pipe-section-vert","ranges": [[0, 1,1, 2]]}]},// 高度為4的水管,被劃分為了2個,上邊1個單位是水管帽,下邊3個單位是水管體"pipe-4h": {"tiles": [{"pattern": "pipe-cap-vert","ranges": [[0, 0]]},{"pattern": "pipe-section-vert","ranges": [[0, 1,1, 3]]}]}},// 背景渲染部分,整合了之前的backgrounds,并加入了水管(2h、3h、4h)和云"layers": [{"tiles": [{"name": "sky","ranges": [[0, 212,0, 13]]},{"name": "ground","type": "ground","ranges": [[0, 212,13, 2]]},{"name": "sky","ranges": [[75, 2,13, 2],[92, 2,13, 2],[157, 2,13, 2]]},{"name": "ground","type": "ground","ranges": [[5, 3,9, 1],[29, 5],[5, 7,9],[12, 6,11, 1],[2, 1,11, 1],[10, 2,10, 1],[10, 2,10],[9, 1,0, 7]]}]},{"tiles": [{"name": "bricks","type": "ground","ranges": [[27, 5,9],[83, 3,9],[86, 6,5],[96, 3,5],[99, 9],[105, 2,9],[123, 5],[126, 3,5],[132, 4,5],[133, 2,9],[171, 4,9]]},{"name": "chance","type": "ground","ranges": [[2, 2],[23, 9],[28, 9],[30, 9],[29, 5],[84, 9],[99, 5],[114, 5],[111, 9],[114, 9],[117, 9],[133, 2, 5],[173, 9]]},{"name": "chocolate","type": "ground","ranges": [[141, 1, 9],[140, 2, 10],[139, 3, 11],[138, 4, 12],[144, 1, 9],[144, 2, 10],[144, 3, 11],[144, 4, 12],[155, 2, 9],[154, 3, 10],[153, 4, 11],[152, 5, 12],[159, 1, 9],[159, 2, 10],[159, 3, 11],[159, 4, 12],[191, 2, 5],[190, 3, 6],[189, 4, 7],[188, 5, 8],[187, 6, 9],[186, 7, 10],[185, 8, 11],[184, 9, 12]]},{"pattern": "pipe-2h","ranges": [[35, 11],[167, 11],[182, 11]]},{"pattern": "pipe-3h","ranges": [[45, 10]]},{"pattern": "pipe-4h","ranges": [[53, 9],[64, 9]]},{"pattern": "cloud-single","ranges": [[2, 2],[25, 2],[35, 3],[44, 2],[64, 3],[74, 2],[80, 3],[90, 2],[108, 3],[118, 2],[128, 3],[138, 2]]}]}] }

overworld.json地圖切片數據改動

?地圖切片數據加入了6個單位的云和4個單位的水管,用于切不同的16x16的方格進行渲染,所以說云占6個單位,長3寬2等

loader/level.js

loader/level.js是之前loadTiles和loadAsync的整合,并進行部分優化,將每個循環拆分到了外部,降低主代碼區的代碼長度,利于維護和擴展

import { createBackgroundLayer, createrSpriteLayer } from "../layers.js"; import { Matrix } from "../Math.js"; import { Level } from "../Level.js"; import { loadJson, loadSpriteSheet } from "../loader.js";export function loadLevelAsync(name) {return loadJson(`/src/levels/${name}.json`).then(data => Promise.all([data, loadSpriteSheet(data.spriteSheet)])).then(([levelJson, backgroundSprite]) => {const level = new Level();// 加載level中的matrix每一個格子的數據到tilesconst mergedTiles = levelJson.layers.reduce((mergedTiles, layer) => {return mergedTiles.concat(layer.tiles);}, []);// 動態設置level的碰撞檢測類const collisionGrid = createCollisionGrid(mergedTiles, levelJson.patterns);level.setCollisionGrid(collisionGrid);levelJson.layers.forEach(layer => {const backgroundGrid = createBackgroundGrid(layer.tiles, levelJson.patterns);const backgroundLayer = createBackgroundLayer(level, backgroundGrid, backgroundSprite);level.compositor.layers.push(backgroundLayer);})// 創建馬里奧圖像的回調const marioSpriteLayer = createrSpriteLayer(level.entities);level.compositor.layers.push(marioSpriteLayer);return level;}) }// 一個range范圍內的x和y對象集合 function* expandSpan(xStart, xLen, yStart, yLen) {const xEnd = xStart + xLen;const yEnd = yStart + yLen;for (let x = xStart; x < xEnd; x++) {for (let y = yStart; y < yEnd; y++) {yield { x, y };}} }// 展開一個range,原range.forEach... function expandRange(range) {// 修改渲染邏輯: 當配置中的range為4位數,則其分別為x位置開始xStart、x方向渲染長度xLen、y位置開始yStart、y方向渲染長度yLen// 當配置中的range為2位數,則其分別為x位置開始xStart、y位置開始yStart,此時yLen、xLen均為1// 當配置中的range為3位數,則其分別為x位置開始xStart、x方向渲染長度xLen、y位置開始yStart,此時yLen為1if (range.length === 4) {const [xStart, xLen, yStart, yLen] = range;return expandSpan(xStart, xLen, yStart, yLen);} else if (range.length === 2) {const [xStart, yStart] = range;return expandSpan(xStart, 1, yStart, 1);} else if (range.length === 3) {const [xStart, xLen, yStart] = range;return expandSpan(xStart, xLen, yStart, 1);} }// 展開多個ranges(原tile.ranges.forEach...) function* expandRanges(ranges) {for (const range of ranges) {for (const item of expandRange(range)) {yield item}} }// 展開tiles為制定格式的對象的數組(如果該元素是pattern,就繼續展開pattern對應的那個對象知道展開到底) function expandTiles(tiles, patterns) {const expandedTiles = [];function walkTiles(tiles, offsetX, offsetY) {for (const tile of tiles) {for (const { x, y } of expandRanges(tile.ranges)) {const derivedX = x + offsetX;const derivedY = y + offsetY;if (tile.pattern) {const tiles = patterns[tile.pattern].tiles;walkTiles(tiles, derivedX, derivedY);} else {expandedTiles.push({tile,x: derivedX,y: derivedY});}}}}walkTiles(tiles, 0, 0);return expandedTiles; }// 循環遍歷展開了的tiles,生成matrix function createCollisionGrid(tiles, patterns) {const matrix = new Matrix();for (const { tile, x, y } of expandTiles(tiles, patterns)) {matrix.set(x, y, {type: tile.type,name: tile.name});}return matrix; }// 循環遍歷展開了的tiles,生成matrix function createBackgroundGrid(tiles, patterns) {const matrix = new Matrix();for (const { tile, x, y } of expandTiles(tiles, patterns)) {matrix.set(x, y, {type: tile.type,name: tile.name,});}return matrix; }

本節代碼重構較多,大家多多理解重構部分

總結

以上是生活随笔為你收集整理的原生JS超级马里奥(第九天)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 蜜桃av一区 | 色翁荡息又大又硬又粗又爽 | 激情小说视频在线 | 欧美日韩成人网 | 四虎成人永久免费视频 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 黄色www| 日韩少妇中文字幕 | 日韩欧美99 | 国产伦精品一区二区三区高清 | 亚洲第一区在线播放 | 涩涩视频在线播放 | 日本黄色一区 | 日韩a在线 | 国产日韩欧美视频 | 美女被娇喘视频 | 成人片在线播放 | 森泽佳奈作品在线观看 | 欧美xxxbbb| 日韩免费看 | 国产一级一片免费播放 | 日本不卡视频一区二区三区 | 亚洲精品国产精品国自产网站按摩 | 国产真实乱人偷精品人妻 | 国产一级做a爰片久久毛片男 | 天海翼av| 奇米影视色 | 懂色av中文一区二区三区天美 | 成人午夜在线观看视频 | 亚洲青草视频 | 日韩激情毛片 | 蜜桃视频一区二区在线观看 | 天天鲁| 成人观看 | 人妻 日韩 欧美 综合 制服 | 日日夜夜精品视频免费 | 欧美打屁股 | 国产一二三区av | 亚洲av永久一区二区三区蜜桃 | 丝袜老师办公室里做好紧好爽 | 久章操| 91porn破解版 | 日韩不卡在线 | 九九在线观看视频 | 麻豆国产原创 | 国产福利99 | 丰满熟女一区二区三区 | 久久99视频精品 | 国产日韩欧美专区 | 吊视频一区二区三区 | 国产富婆一区二区三区 | 亚洲精品乱码久久久久久国产主播 | 另类图片亚洲色图 | 欧美精品一区二区性色a+v | 成人一区二 | 欧美视频www | 在线日韩一区二区 | 特级丰满少妇一级aaa爱毛片 | 天天添天天操 | 中文字幕影片免费在线观看 | 欧美极品aaaaabbbbb | 野花视频在线免费观看 | 久久视频一区二区 | 91大神福利视频 | 免费午夜影院 | 国产在线观看精品 | 国产簧片 | 又黄又爽视频 | 黄色中文字幕 | 亚洲av无码国产在丝袜线观看 | 操极品少妇 | 国产黄色三级网站 | 久久久精品人妻一区二区三区色秀 | 黄色欧美在线观看 | 日本狠狠爱 | 天天碰天天 | 能看毛片的网站 | 国产精品国产一区二区 | 亚洲高清毛片 | 中文久久字幕 | 欧美日韩成人一区二区 | 国产一级av毛片 | 久久丁香网 | 狠狠干狠狠撸 | 欧美亚韩一区二区三区 | 久久99精品久久久久久水蜜桃 | 亚洲午夜精品在线观看 | 国产精品剧情av | 免费在线观看一区二区 | 日产精品久久久久久久蜜臀 | 91网站免费观看 | 九九热九九 | 性久久久久久久久久久久 | 免费的黄色大片 | www,五月天,com| 肥臀熟女一区二区三区 | 蝌蚪网在线视频 | 911精品国产一区二区在线 | 韩国成人理伦片免费播放 |