当前位置: 首页 > news >正文

广西网站建设汕头网络推广团队

广西网站建设,汕头网络推广团队,汕头潮南网站建设,wordpress添加音乐播放器之前学习了几篇的ts基础#xff0c;今天我们就使用ts来完成一个贪吃蛇的小游戏。 游戏拆解 我们将我们的任务进行简单拆解分析。 首先我们应该有一个窗口#xff0c;我们叫做屏幕。让蛇在里面移动#xff0c;所有我们应该想到要设计一个大盒子当作地图。考虑到食物以及蛇…之前学习了几篇的ts基础今天我们就使用ts来完成一个贪吃蛇的小游戏。 游戏拆解 我们将我们的任务进行简单拆解分析。 首先我们应该有一个窗口我们叫做屏幕。让蛇在里面移动所有我们应该想到要设计一个大盒子当作地图。考虑到食物以及蛇的绘制我们可以使用canvas来实现。其次我们还会在地图随机投放食物这里还可以考虑食物该不该出现在蛇的身体节点上本文不做考虑所以我们大概率会创建一个类这个类用来诞生一个随机方块也就是食物。接着我们考虑蛇蛇在最开始应该也是一个随机方块然后通过移动吃到食物长长。 代码实现 接下来我们根据上面的拆解做详细的需求梳理以及代码实现。 屏幕的实现 屏幕的实现是最为简单的我们决定了使用canvas来绘制食物与蛇那么我们直接创建一个canvas标签当作屏幕即可。 canvas width500 height500/canvas食物的实现 接下来我们思考食物应该如何实现。既然决定在canvas绘制食物那么最简单的方式就是把食物绘制会一个矩形。而矩形的绘制需要四个参数分别是起始点坐标以及宽高食物的宽高我们就设定为10所以不确定的也就至于起始点的坐标了。这个坐标决定了他会出现在屏幕的哪个位置。 还需要注意的是他的起始位置一定要在蛇的移动路径上例如我们蛇的宽度为10如果你的食物起始点在1111这个坐标上那么他就无法一次吃掉这个食物。 所以食物的坐标应该是10的倍数且不能超过屏幕的边界。 我们还要思考到食物被吃掉后应该就会自动消失所以蛇这个类还应该有个清除方法可以清除掉自己。 代码展示 class Drop {width: number 10height: number 10x: numbery: numbercolor: stringconstructor(x: number Math.floor(Math.random() * 49) * 10,y: number Math.floor(Math.random() * 49) * 10,color: string black) {this.color colorthis.x xthis.y y}del() {const ctx: CanvasRenderingContext2D canvasEle.getContext(2d)!ctx.clearRect(this.x, this.y, this.width, this.height)} }蛇的实现 蛇的实现相对来说就要复杂很多。 首先我们思考蛇的身体应该是怎样的为了他的灵活转向最简单的方式就是他的身体应该是一个一个的矩形拼接起来的。既然如此我们就可以直接使用上面的食物类这也是我将上面类的名字叫做Drop而不是Food的原因并且我在类里面添加了颜色进行蛇与食物的区别。接下来我们想到蛇既然是多个矩形拼接起来的那么应该有一个容器来有序的存放这些矩形所以我们定义个数组list来进行存放身体的数据。class Snake {list: ArrayDropconstructor() {this.list [new Drop(250, 250, red)]}}我们让他在地图中心点生成并使用红色进行与食物进行区分。接下来我们思考移动方法。蛇在移动的时候首先需要确认方法我们可以设定一个方向属性初始化的时候默认一个方向值。接着就是朝着方向移动如何移动呢如果简单的使用平移会发现蛇好像并不能灵活的转向蛇的身体也不会发生弯曲。这个时候我们就需要换一个思路。既然蛇是有一个个的矩形组成那么我们只需要控制里面的矩形就行了。当然也不是控制里面的矩形平移而是进行矩形的增加与删除操作。想象一下当蛇向上走一格这里我们设定基础格子就是10 x 10单位的是不是意味着我们将这个矩形的起点坐标的y值减去10所以我们直接创建一个蛇头部盒子的起点坐标y值减去10的盒子然后在直接删除蛇的最后一个盒子是不是就可以看作移动了一格。 当然我们也要考虑到吃到食物的情况这种情况下我们是不需要删除尾部矩形的。然后我们的类就补充成这样class Snake {list: ArrayDropdirection: stringconstructor(direction: string ArrowUp, speed: number 100) {this.list [new Drop(250, 250, red)]this.direction direction}move() {let newHeader JSON.parse(JSON.stringify(this.list[0]))const { x: newHeaderX, y: newHeaderY } newHeaderconst { x: foodX, y: foodY } foodlet isEatFood: boolean falseif (newHeaderX foodX foodY newHeaderY) {isEatFood true}switch (this.direction) {case ArrowUp:newHeader.y - 10breakcase ArrowDown:newHeader.y 10breakcase ArrowLeft:newHeader.x - 10breakcase ArrowRight:newHeader.x 10break}this.addHead(newHeader)// 判断是否吃到食物if (isEatFood) {food.del()food new Drop()renderDorp(food)} else {this.delFooter()}}addHead(dorp: Drop) {this.list.unshift(dorp)}delFooter() {const endDrop: Drop this.list.pop()!const { x, y, width, height } endDropconst ctx: CanvasRenderingContext2D canvasEle!.getContext(2d)!ctx.clearRect(x, y, width, height)} }我还还应该考虑一些特殊情况例如移动到屏幕边缘会不会吃到自己得身体我们新增一个状态属性来判断他是否出局所以我们继续填充这个方法class Snake {list: ArrayDropdirection: stringisOut: booleanconstructor(direction: string ArrowUp, speed: number 100) {this.list [new Drop(250, 250, red)]this.direction directionthis.boolean false}move() {let newHeader JSON.parse(JSON.stringify(this.list[0]))const { x: newHeaderX, y: newHeaderY } newHeaderconst { x: foodX, y: foodY } foodlet isEatFood: boolean falseif (newHeaderX foodX foodY newHeaderY) {isEatFood true}if (this.direction) {}switch (this.direction) {case ArrowUp:newHeader.y - 10breakcase ArrowDown:newHeader.y 10breakcase ArrowLeft:newHeader.x - 10breakcase ArrowRight:newHeader.x 10break}// 是否吃到自己const isEatSelf this.list.some(({ x, y }) {if (x newHeader.x y newHeader.y) {return true}})if (isEatSelf) {alert(吃到自己了)return }this.addHead(newHeader)// 判断是否吃到食物if (isEatFood) {food.del()food new Drop()renderDorp(food)} else {this.delFooter()}// 判断是否达到边界if (newHeaderX 500 ||newHeaderY 500 ||newHeaderX 0 ||newHeaderY 0) {return alert(撞墙了)}renderDorp(this.list)}addHead(dorp: Drop) {this.list.unshift(dorp)}delFooter() {const endDrop: Drop this.list.pop()!const { x, y, width, height } endDropconst ctx: CanvasRenderingContext2D canvasEle!.getContext(2d)!ctx.clearRect(x, y, width, height)} }渲染蛇与食物 我们写了食物与蛇的类但是还没有真正在canvas上进行绘制。接下来我们使用ts的重载进行渲染类的绘制。 // 创建渲染函数 function renderDorp(dorp: Drop): void function renderDorp(dorps: ArrayDrop): void function renderDorp(dorps: Drop | ArrayDrop) {if (Array.isArray(dorps)) {dorps.forEach((element: Drop) {const { x, y, width, height, color } elementconst ctx: CanvasRenderingContext2D canvasEle!.getContext(2d)!ctx.fillStyle colorctx.fillRect(x, y, width, height)})} else {const { x, y, width, height, color } dorpsconst ctx: CanvasRenderingContext2D canvasEle!.getContext(2d)!ctx.fillStyle colorctx.fillRect(x, y, width, height)} }键盘监听 我么使用方向键来控制蛇的移动那么就需要监听键盘事件。需要注意的是我们在身体长度为1的时候通常是可以随意移动的比如直接从右往左或者从上到下但是当身体长度不为1的时候我们的有了头尾的定义就不应该在随意的上下或者左右移动了。毕竟他不像火车一样前后都有一个车头。 window.addEventListener(keydown, function (e) {const { code } econst keys: string[] [ArrowUp, ArrowDown, ArrowLeft, ArrowRight]if (keys.includes(code)) {if (snake.list.length 1) {snake.direction codereturn}if (snake.direction ArrowUp code ArrowDown) {return}if (snake.direction ArrowDown code ArrowUp) {return}if (snake.direction ArrowLeft code ArrowRight) {return}if (snake.direction ArrowRight code ArrowLeft) {return}snake.direction code} })最后补充完整的实现代码 const canvasEle document.querySelector(canvas)! let food: Drop let snake: Snake class Drop {width: number 10height: number 10x: numbery: numbercolor: stringconstructor(x: number Math.floor(Math.random() * 49) * 10,y: number Math.floor(Math.random() * 49) * 10,color: string black) {this.color colorthis.x xthis.y y}del() {const ctx: CanvasRenderingContext2D canvasEle.getContext(2d)!ctx.clearRect(this.x, this.y, this.width, this.height)} }class Snake {list: ArrayDropdirection: stringisOut: booleanconstructor(direction: string ArrowUp, speed: number 100) {this.list [new Drop(250, 250, red)]this.direction directionthis.isOut false}move() {let newHeader JSON.parse(JSON.stringify(this.list[0]))const { x: newHeaderX, y: newHeaderY } newHeaderconst { x: foodX, y: foodY } foodlet isEatFood: boolean falseif (newHeaderX foodX foodY newHeaderY) {isEatFood true}if (this.direction) {}switch (this.direction) {case ArrowUp:newHeader.y - 10breakcase ArrowDown:newHeader.y 10breakcase ArrowLeft:newHeader.x - 10breakcase ArrowRight:newHeader.x 10break}// 是否吃到自己const isEatSelf this.list.some(({ x, y }) {if (x newHeader.x y newHeader.y) {return true}})if (isEatSelf) {this.isOut truereturn alert(吃到自己了)}this.addHead(newHeader)// 判断是否吃到食物if (isEatFood) {food.del()food new Drop()renderDorp(food)} else {this.delFooter()}// 判断是否达到边界if (newHeaderX 500 ||newHeaderY 500 ||newHeaderX 0 ||newHeaderY 0) {this.isOut truereturn alert(撞墙了)}renderDorp(this.list)}addHead(dorp: Drop) {this.list.unshift(dorp)}delFooter() {const endDrop: Drop this.list.pop()!const { x, y, width, height } endDropconst ctx: CanvasRenderingContext2D canvasEle!.getContext(2d)!ctx.clearRect(x, y, width, height)} }// 创建渲染函数 function renderDorp(dorp: Drop): void function renderDorp(dorps: ArrayDrop): void function renderDorp(dorps: Drop | ArrayDrop) {if (Array.isArray(dorps)) {dorps.forEach((element: Drop) {const { x, y, width, height, color } elementconst ctx: CanvasRenderingContext2D canvasEle!.getContext(2d)!ctx.fillStyle colorctx.fillRect(x, y, width, height)})} else {const { x, y, width, height, color } dorpsconst ctx: CanvasRenderingContext2D canvasEle!.getContext(2d)!ctx.fillStyle colorctx.fillRect(x, y, width, height)} };(function () {food new Drop()snake new Snake()renderDorp(food)let timer setInterval(() {snake.move()if (snake.isOut) {clearInterval(timer)}}, 100)window.addEventListener(keydown, function (e) {const { code } econst keys: string[] [ArrowUp, ArrowDown, ArrowLeft, ArrowRight]if (keys.includes(code)) {if (snake.list.length ! 1) {if (snake.direction ArrowUp code ArrowDown) {return}if (snake.direction ArrowDown code ArrowUp) {return}if (snake.direction ArrowLeft code ArrowRight) {return}if (snake.direction ArrowRight code ArrowLeft) {return}}snake.direction code}}) })() 这只是一个简单版贪吃蛇效果没有经过严格测试肯定会有bug希望可以留言交流 再推一个自己插件element-ui的拓展组件库还在不断完善希望大家支持
http://wiki.neutronadmin.com/news/425563/

相关文章:

  • 建筑模型设计网站建设wordpress 代码 工具
  • 山东省城乡建设部网站首页南昌网站制作方案定制
  • 石嘴山网站seo谷歌商店下载
  • 西部数码 成品网站想招聘员工去哪个网站
  • vs2015可以做网站么石家庄网站建设今天改网名
  • 广东网站设计工具wordpress postid
  • 做网站的股哥装修广告做哪个网站最好看
  • 建一个网站是不是要开公司株洲做网站
  • 有没有便宜的网站制作seo站群干什么的
  • 六盘水网站建设58同城鞍山招聘信息
  • 网站建设书籍论文页面设计包括什么
  • app与移动网站开发考试资料dedecms网站上传服务器不是空间
  • 中国营销型网站有哪些天蝎网站建设公司
  • 大同网站设计网站域名申请流程
  • 有了网站源代码网站建设视频讲解
  • 陕西专业网站建设公司免费app软件
  • 2003服务器怎么挂网站怎么注册中视频账号
  • 深圳宝安网站推广软件开发公司属于什么企业类型
  • 深圳设计网站推荐中企动力手机邮箱
  • 网站标题分隔符网页制作基础教程简介
  • 东莞网站优化关键词排名响应式网站模板的应用
  • 排版设计网站徐州有哪些制作网站的公司吗
  • 南京平台网站建设设计中国北京
  • 建站网站教程视频教程wordpress主题:yusi
  • 广告项目网站开发wordpress打开超级慢
  • 池州城乡住房建设厅网站长沙网站制作策划
  • 电商网站功能介绍做淘客网站需要多大的空间
  • dede 企业网站模板下载网页设计实训报告主要内容
  • php怎么做搭建网站扬州西区网站建设
  • 找晚上做的工作去哪个网站60个偏门暴利赚钱项目