中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

動(dòng)態(tài)網(wǎng)站建設(shè)簡介谷歌排名網(wǎng)站優(yōu)化

動(dòng)態(tài)網(wǎng)站建設(shè)簡介,谷歌排名網(wǎng)站優(yōu)化,wordpress文章url原理,網(wǎng)站可以做多少優(yōu)化關(guān)鍵詞簡介 canvas 是HTML5 提供的一種新標(biāo)簽,它可以支持 JavaScript 在上面繪畫,控制每一個(gè)像素,它經(jīng)常被用來制作小游戲,接下來我將用它來模仿制作一款叫flappy bird的小游戲。flappy bird(中文名:笨鳥先飛&am…

簡介

canvas 是HTML5 提供的一種新標(biāo)簽,它可以支持 JavaScript 在上面繪畫,控制每一個(gè)像素,它經(jīng)常被用來制作小游戲,接下來我將用它來模仿制作一款叫flappy bird的小游戲。flappy bird(中文名:笨鳥先飛)是一款由來自越南的獨(dú)立游戲開發(fā)者Dong Nguyen所開發(fā)的作品,于2013年5月24日上線,并在2014年2月突然暴紅。

游戲規(guī)則

玩家只需要用一根手指來操控,點(diǎn)擊或長按屏幕,小鳥就會往上飛,不斷的點(diǎn)擊就會不斷的往高處飛。放松手指,則會快速下降。所以玩家要控制小鳥一直向前飛行,然后注意躲避途中高低不平的管子。小鳥安全飛過的距離既是得分。當(dāng)然撞上就直接掛掉,只有一條命。

游戲素材

鏈接:pan.baidu.com/s/1JZR27H1K…

提取碼:02ii

開始制作

初始化canvas畫布

這里主要是創(chuàng)建畫布,并調(diào)整畫布大小,畫布自適應(yīng)屏幕大小。

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style> body {margin: 0;padding: 0;overflow: hidden;} </style>
</head>
<body><canvas id="canvas">當(dāng)前瀏覽器不支持canvas,請更換瀏覽器查看。</canvas>
?<script> /** @type {HTMLCanvasElement} */
?const canvas = document.querySelector('#canvas')const ctx = canvas.getContext('2d')
?canvas.width = window.innerWidthcanvas.height = window.innerHeight
?window.addEventListener('resize', () => {canvas.width = window.innerWidthcanvas.height = window.innerHeight}) </script>
</body>
</html> 

加載資源

圖片等資源的加載是異步的,只有當(dāng)所有的資源都加載完了才能開始游戲,所以這里需要對圖片等資源進(jìn)行統(tǒng)一的監(jiān)控和管理。 將圖片資源用json進(jìn)行描述,通過fetch進(jìn)行統(tǒng)一加載。

// 資源管理器
class SourceManager {static images = {};static instance = new SourceManager();constructor() {return SourceManager.instance;}
?loadImages() {return new Promise((resolve) => {fetch("./assets/images/image.json").then((res) => res.json()).then((res) => {res.forEach((item, index) => {const image = new Image();image.src = item.url;image.onload = () => {SourceManager.images[item.name] = image;ctx.clearRect(0, 0, canvas.width, canvas.height);ctx.font = "24px 黑體";ctx.textAlign = "center";ctx.fillText(`資源加載中${index + 1}/${res.length}...`, canvas.width / 2, (canvas.height / 2) * 0.618);if (index === res.length - 1) {console.log(index, "加載完成");resolve();}};});});});}
}
?
async function main() {// 加載資源await new SourceManager().loadImages();
}
main(); 

背景

為了適應(yīng)不同尺寸的屏幕尺寸和管子能正確渲染到對應(yīng)的位置,不能將背景圖片拉伸,要定一個(gè)基準(zhǔn)線固定背景圖片所在屏幕中的位置。我們發(fā)現(xiàn)背景圖并不能充滿整個(gè)畫面,上右下面是空缺的,這個(gè)時(shí)候需要使用小手段填充上,這里就用矩形對上部進(jìn)行填充。接下來,需要讓背景有一種無限向左移動(dòng)的效果,就要并排繪制3張背景圖片,這樣在渲染的時(shí)候,當(dāng)背景向左移動(dòng)的距離dx等于一張背景圖的寬度時(shí),將dx=0,這樣就實(shí)現(xiàn)了無限向左移動(dòng)的效果,類似于輪播圖。

// 背景
class GameBackground {constructor() {this.dx = 0this.image = SourceManager.images.bg_daythis.dy = 0.8 * (canvas.height - this.image.height)this.render()}
?update() {this.dx -= 1 if (this.dx + this.image.width <= 0) {this.dx = 0}this.render()}
?render() {ctx.fillStyle = '#4DC0CA'ctx.fillRect(0, 0, canvas.width, 0.8 * (canvas.height - this.image.height) + 10)ctx.drawImage(this.image, this.dx, this.dy)ctx.drawImage(this.image, this.dx + this.image.width, this.dy)ctx.drawImage(this.image, this.dx + this.image.width * 2, this.dy)}
}
?
let gameBg = null
?
main();
?
// 渲染函數(shù)
function render() {ctx.clearRect(0, 0, canvas.width, canvas.height);gameBg.update();requestAnimationFrame(render)
}
?
async function main() {// 加載資源await new SourceManager().loadImages();
?// 背景gameBg = new GameBackground()
?// 渲染動(dòng)畫render()
} 

地面

地面要在背景的基礎(chǔ)上將地面圖上邊對齊基準(zhǔn)線(canvas.height * 0.8),并把下面空缺的部分通過和填補(bǔ)背景上半部分一致的方式填上。同時(shí)使用與背景無限向左移動(dòng)一樣的方法實(shí)現(xiàn)地面的無限向左移動(dòng)。

// 地面
class Land {constructor() {this.dx = 0;this.dy = canvas.height * 0.8;this.image = SourceManager.images.land;this.render();}
?update() {this.dx -= 1.5;if (this.dx + this.image.width <= 0) {this.dx = 0;}this.render();}
?render() {ctx.fillStyle = "#DED895";ctx.fillRect(0,canvas.height * 0.8 + this.image.height - 10,canvas.width,canvas.height * 0.2 - this.image.height + 10);ctx.drawImage(this.image, this.dx, this.dy);ctx.drawImage(this.image, this.dx + this.image.width, this.dy);ctx.drawImage(this.image, this.dx + this.image.width * 2, this.dy);}
}
?
let land = null
?
main();
?
// 渲染函數(shù)
function render() {ctx.clearRect(0, 0, canvas.width, canvas.height);gameBg.update();requestAnimationFrame(render)
}
?
async function main() {// 加載資源await new SourceManager().loadImages();
?// 此處省略其他元素// 地面land = new Land()
?// 渲染動(dòng)畫render()
} 

管道

管道有上下兩部分,上部分管道需要貼著屏幕的頂部渲染,下部分要貼著地面也就是基準(zhǔn)線渲染,上下兩部分的管道長度要隨機(jī)生成,且兩部分之間的距離不能小于80(我自己限制的);管道渲染速度為2s一次,并且也需要無限向左移動(dòng),這個(gè)效果和背景同理。

// 管道
class Pipe {constructor() {this.dx = canvas.width;this.dy = 0;this.upPipeHeight = (Math.random() * canvas.height * 0.8) / 2 + 30;this.downPipeHeight = (Math.random() * canvas.height * 0.8) / 2 + 30;
?if (canvas.height * 0.8 - this.upPipeHeight - this.downPipeHeight <= 80) {console.log("///小于80了///");this.upPipeHeight = 200;this.downPipeHeight = 200;}
?this.downImage = SourceManager.images.pipe_down;this.upImage = SourceManager.images.pipe_up;}
?update() {this.dx -= 1.5;// 記錄管道四個(gè)點(diǎn)的坐標(biāo),在碰撞檢測的時(shí)候使用this.upCoord = {tl: {x: this.dx,y: canvas.height * 0.8 - this.upPipeHeight,},tr: {x: this.dx + this.upImage.width,y: canvas.height * 0.8 - this.upPipeHeight,},bl: {x: this.dx,y: canvas.height * 0.8,},br: {x: this.dx + this.upImage.width,y: canvas.height * 0.8,},};this.downCoord = {bl: {x: this.dx,y: this.downPipeHeight,},br: {x: this.dx + this.downImage.width,y: this.downPipeHeight,},};this.render();}
?render() {ctx.drawImage(this.downImage,0,this.downImage.height - this.downPipeHeight,this.downImage.width,this.downPipeHeight,this.dx,this.dy,this.downImage.width,this.downPipeHeight);ctx.drawImage(this.upImage,0,0,this.upImage.width,this.upPipeHeight,this.dx,canvas.height * 0.8 - this.upPipeHeight,this.upImage.width,this.upPipeHeight);}
}
?
let pipeList = []
?
main();function render() {ctx.clearRect(0, 0, canvas.width, canvas.height);// 此處省略其他元素渲染步驟
?pipeList.forEach((item) => item.update());requestAnimationFrame(render)
}
?
async function main() {// 此處省略其他元素渲染步驟// 管道setInterval(() => {pipeList.push(new Pipe());
?// 清理移動(dòng)過去的管道對象,一屏最多展示3組,所以這里取大于3if (pipeList.length > 3) {pipeList.shift();}}, 2000);
?// 渲染動(dòng)畫render()
} 

笨鳥

小鳥要有飛行的動(dòng)作,這個(gè)通過不斷重復(fù)渲染3張小鳥不同飛行姿勢的圖片來實(shí)現(xiàn);還要通過改變小鳥的在Y軸的值來制作上升下墜的效果,并且能夠通過點(diǎn)擊或長按屏幕來控制小鳥的飛行高度。

// 小鳥
class Bird {constructor() {this.dx = 0;this.dy = 0;this.speed = 2;this.image0 = SourceManager.images.bird0_0;this.image1 = SourceManager.images.bird0_1;this.image2 = SourceManager.images.bird0_2;
?this.loopCount = 0;
?this.control();
?setInterval(() => {if (this.loopCount === 0) {this.loopCount = 1;} else if (this.loopCount === 1) {this.loopCount = 2;} else {this.loopCount = 0;}}, 200);}
?// 添加控制小鳥的事件control() {let timer = true;canvas.addEventListener("touchstart", (e) => {timer = setInterval(() => {this.dy -= this.speed;});e.preventDefault();});canvas.addEventListener("touchmove", () => {clearInterval(timer);});canvas.addEventListener("touchend", () => {clearInterval(timer);});}
?update() {this.dy += this.speed;
?// 記錄小鳥四個(gè)點(diǎn)的坐標(biāo),在碰撞檢測的時(shí)候使用this.birdCoord = {tl: {x: this.dx,y: this.dy,},tr: {x: this.dx + this.image0.width,y: this.dy,},bl: {x: this.dx,y: this.dy + this.image0.height,},br: {x: this.dx + this.image0.width,y: this.dy + this.image0.height,},};
?this.render();}
?render() {// 渲染小鳥飛行動(dòng)作if (this.loopCount === 0) {ctx.drawImage(this.image0, this.dx, this.dy);} else if (this.loopCount === 1) {ctx.drawImage(this.image1, this.dx, this.dy);} else {ctx.drawImage(this.image2, this.dx, this.dy);}}
}
?
let bird = null
?
main();function render() {ctx.clearRect(0, 0, canvas.width, canvas.height);// 省略其他元素渲染bird.update();requestAnimationFrame(render);
}
?
async function main() {// 省略其他元素渲染// 笨鳥bird = new Bird()
?// 渲染動(dòng)畫render()
} 

我們發(fā)現(xiàn)小鳥好像是只美國鳥,有點(diǎn)太freedom了~,不符合我們的游戲規(guī)則,要想辦法控制一下。

碰撞檢測

碰撞檢測的原理就是不斷檢測小鳥圖四個(gè)頂點(diǎn)坐標(biāo)是否在任一管道所占的坐標(biāo)區(qū)域內(nèi)或小鳥圖下方的點(diǎn)縱坐標(biāo)小于地面縱坐標(biāo)(基準(zhǔn)線),在就結(jié)束游戲。上面管道和小鳥類中記錄的坐標(biāo)就是為了實(shí)現(xiàn)碰撞檢測的。

let gameBg = null
let land = null
let bird = null
let pipeList = []
?
main();function render() {ctx.clearRect(0, 0, canvas.width, canvas.height);gameBg.update();land.update();bird.update();pipeList.forEach((item) => item.update());requestAnimationFrame(render);
?// 碰撞檢測-地面if (bird.dy >= canvas.height * 0.8 - bird.image0.height + 10) {gg();}//碰撞檢測-管道pipeList.forEach((item) => {if (bird.birdCoord.bl.x >= item.upCoord.tl.x - 35 &&bird.birdCoord.bl.x <= item.upCoord.tr.x &&bird.birdCoord.bl.y >= item.upCoord.tl.y + 10) {gg();} else if (bird.birdCoord.tl.x >= item.downCoord.bl.x - 35 &&bird.birdCoord.tl.x <= item.downCoord.br.x &&bird.birdCoord.tl.y <= item.downCoord.bl.y - 10) {gg();}});
}
?
async function main() {// 加載資源await new SourceManager().loadImages();
?// 背景gameBg = new GameBackground()
?// 地面land = new Land()
?// 笨鳥bird = new Bird()
?// 管道setInterval(() => {pipeList.push(new Pipe());
?// 清理移動(dòng)過去的管道對象,一屏最多展示3組,所以這里取大于3if (pipeList.length > 3) {pipeList.shift();}}, 2000);
?// 渲染動(dòng)畫render()
}
?
function gg() {const ggImage = SourceManager.images.text_game_over;ctx.drawImage(ggImage,canvas.width / 2 - ggImage.width / 2,(canvas.height / 2) * 0.618);
}; 

效果

增加碰撞檢測后,小鳥碰到管道或地面就會提示失敗。 此篇展示了基本的核心邏輯,完整游戲地址和源碼在下方鏈接。

最近還整理一份JavaScript與ES的筆記,一共25個(gè)重要的知識點(diǎn),對每個(gè)知識點(diǎn)都進(jìn)行了講解和分析。能幫你快速掌握J(rèn)avaScript與ES的相關(guān)知識,提升工作效率。



有需要的小伙伴,可以點(diǎn)擊下方卡片領(lǐng)取,無償分享

http://www.risenshineclean.com/news/36055.html

相關(guān)文章:

  • 廣西專業(yè)做網(wǎng)站的公司軟件排名工具
  • 網(wǎng)站建設(shè)技術(shù)服務(wù)清單網(wǎng)絡(luò)營銷有哪些
  • 企業(yè)介紹微網(wǎng)站怎么做短視頻營銷推廣策略
  • c 網(wǎng)站開發(fā)框架百度小說風(fēng)云榜今天
  • 企業(yè)網(wǎng)站建設(shè)合同書模板可以引流推廣的app
  • 云瓣科技做網(wǎng)站本地網(wǎng)絡(luò)seo公司
  • 網(wǎng)站后臺登陸代碼百度關(guān)鍵詞seo排名
  • 用js做跳轉(zhuǎn)到其他網(wǎng)站優(yōu)化公司怎么優(yōu)化網(wǎng)站的
  • 大場網(wǎng)站建設(shè)seo最好的工具
  • 國外做的比較好看的網(wǎng)站2022年度最火關(guān)鍵詞
  • 西安網(wǎng)站建設(shè)開發(fā)查派谷歌seo排名公司
  • 依波手表價(jià)格 官方網(wǎng)站360搜索優(yōu)化
  • 網(wǎng)站建設(shè)客戶告知書長春網(wǎng)站優(yōu)化團(tuán)隊(duì)
  • 鄭州區(qū)塊鏈數(shù)字錢包網(wǎng)站開發(fā)多少錢廣州網(wǎng)頁制作
  • 網(wǎng)站管理建設(shè)的總結(jié)抖音代運(yùn)營
  • 做定制校服的網(wǎng)站煙臺seo快速排名
  • 網(wǎng)站開發(fā)服務(wù)費(fèi)記賬個(gè)人網(wǎng)站制作源代碼
  • 如何購買域名建網(wǎng)站網(wǎng)絡(luò)營銷推廣技巧
  • 咖啡公司網(wǎng)站建設(shè)策劃書網(wǎng)絡(luò)推廣需要多少錢
  • 做電影網(wǎng)站為什么查封不了沈陽seo整站優(yōu)化
  • 上海城建設(shè)計(jì)院網(wǎng)站網(wǎng)絡(luò)營銷策劃案范本
  • 創(chuàng)業(yè)如何進(jìn)行網(wǎng)站建設(shè)百度推廣云南總代理
  • 網(wǎng)站seo問題診斷工具網(wǎng)絡(luò)營銷的概念及內(nèi)容
  • 企業(yè)網(wǎng)絡(luò)營銷策劃案例seo網(wǎng)站推廣軟件
  • 做美工比較好的網(wǎng)站seo搜索引擎營銷工具
  • 優(yōu)化 導(dǎo)航網(wǎng)站幽默軟文廣告經(jīng)典案例
  • 有趣的網(wǎng)站知乎黑龍江seo關(guān)鍵詞優(yōu)化工具
  • 國外家具設(shè)計(jì)網(wǎng)站大全指數(shù)網(wǎng)站
  • 蘇州手機(jī)app開發(fā)公司seo排名優(yōu)化什么意思
  • 一個(gè)服務(wù)器做一樣的網(wǎng)站嗎精準(zhǔn)引流的網(wǎng)絡(luò)推廣方法