-
2022-03-23 15:10:52
【H5核心Canvas游戏制作视角学习笔记】系列文章目录
目录
前言
制作一款当代的基于web的文字图形类游戏或者其他web应用,自然是绕不开canvas这个充满活力的标签。本文就来讲述笔者在学习道路上的心得和体会。
一、Canvas是什么?
<canvas>
是HTML5
新增的,一个可以使用脚本(通常为JavaScript
) 在其中绘制图像的HTML
元素。它可以用来制作照片集或者制作简单(也不是那么简单)的动画,甚至可以进行实时视频处理和渲染。它最初由苹果内部使用自己
MacOS X WebKit
推出,供应用程序使用像仪表盘的构件和Safari
浏览器使用。后来,有人通过Gecko
内核的浏览器 (尤其是Mozilla
和Firefox
),Opera
和Chrome
和超文本网络应用技术工作组建议为下一代的网络技术使用该元素。
Canvas
是由HTML
代码配合高度和宽度属性而定义出的可绘制区域。JavaScript
代码可以访问该区域,类似于其他通用的二维API
,通过一套完整的绘图函数来动态生成图形。二、使用步骤
1.引入库
<canvas> 你的浏览器不支持 canvas标签 </canvas>
什么也不用引入, 只要是支持H5标准的浏览器内核都可以直接使用。
咱们直接使用<canvas></canvas>标签即可。
2.canvas元素
<canvas>
看起来和<img>
标签一样,只是<canvas>
只有两个可选的属性width、heigth
属性,而没有src、alt
属性。如果不给
<canvas>
设置widht、height
属性时,则默认width
为300、height
为 150,单位都是px
。也可以使用css
属性来设置宽高,但是如宽高属性和初始比例不一致,他会出现扭曲。所以,建议永远不要使用css
属性来设置<canvas>
的宽高。<canvas id="canvas_learning" width="300" height="300"></canvas>
当然也有不兼容不支持的情况,虽然现在应该在很少的情况下会碰到吧,但还是提一嘴,提示信息只需要直接写在canvas标签里面就可以了,当浏览器支持canvas时会只渲染canvas的“内容”而忽略其中的替代信息,反之亦然。
例如:
用文本替换:
<canvas> 你的浏览器不支持 canvas标签 </canvas>
也可以使用一张图片来替换,这更符合我们理解的“当代做法”吧:
<canvas> <img src="[你的图片url]" alt=""> </canvas>
特别要注意的是,canvas标签必须要闭合
也就是说必须要有</canvas> 否则文件的其余(想想就知道这是一个很大的量)会被视为canvas标签的替代内容从而在一般情况下不可见。
3.canvas初次使用
canvas顾名思义就是一张画布,那我们要让它显示出来一些东西,那么就需要一支“画笔”,这个“画笔”在这里被我们称为“渲染上下文”(RC,rendering context)。
想必这很容易让人联想到js中的“执行上下文”的相关概念,简单地说就是一支笔它得对应一张画布,不能乱画到别的画布上去。
所以我们先得通过一个叫getContext()的方法获取对“渲染上下文”(红宝书里称呼它为绘图上下文)
let canvas = document.getElementById('canvas_learning'); //获得 2d 上下文对象 let ctx = canvas.getContext('2d');
这里我们用了一支画笔 它的类型是一支"2d"的笔,显然它还可以有别的选择,比如说webGL。这里我摘取MDN对这个参数的解释:
上下文类型(contextType)
是一个指示使用何种上下文的 DOMString 。可能的值是:
"2d
", 建立一个 CanvasRenderingContext2D 二维渲染上下文。"webgl"
(或"experimental-webgl"
) 这将创建一个 WebGLRenderingContext 三维渲染上下文对象。只在实现WebGL 版本1(OpenGL ES 2.0)的浏览器上可用。- "
webgl2
" (或 "experimental-webgl2
") 这将创建一个 WebGL2RenderingContext 三维渲染上下文对象。只在实现 WebGL 版本2 (OpenGL ES 3.0)的浏览器上可用。 "bitmaprenderer"
这将创建一个只提供将canvas内容替换为指定ImageBitmap功能的ImageBitmapRenderingContext 。
好了,我们添加js脚本以及css样式如下,进行一次测试:
canvas{ border:1px solid black; }
<script> console.log("我已经画了这幅画,你能看到嘛!"); function draw() { let canvas=document.getElementById('learning_try'); if(!canvas.getContext) return; let ctx=canvas.getContext('2d'); } draw(); </script>
显示结果:
可以看到canvas已经显示出来了,我们可以对它的width或height进行修改,来改变画布的大小。
下一节,我们一起来绘制一些几何图形丰富一下我们的画作!
更多相关内容 -
HTML5 Canvas游戏开发实战.pdf
2018-06-20 11:31:34《HTML5 Canvas游戏开发实战》主要讲解使用HTML5 Canvas来开发和设计各类常见游戏的思路和技巧,在介绍HTML5 Canvas相关特性的同时,还通过游戏开发实例深入剖析了其内在原理,让读者不仅知其然,而且知其所以然。... -
HTML5 CANVAS游戏开发实战(PDF和源代码)
2018-05-07 10:49:571.2 canvas简介 / 5 1.2.1 canvas标签的历史 / 5 1.2.2 canvas的定义和用法 / 6 1.2.3 如何使用canvas来绘图 / 6 1.2.4 canvas的限制 / 7 1.3 开发与运行环境的准备 / 7 1.3.1 浏览器的支持 / 7 1.3.2 准备... -
HTML5 Canvas游戏开发实战
2017-10-30 10:22:30《HTML5 Canvas游戏开发实战》主要讲解使用HTML5 Canvas来开发和设计各类常见游戏的思路和技巧,在介绍HTML5 Canvas相关特性的同时,还通过游戏开发实例深入剖析了其内在原理,让读者不仅知其然,而且知其所以然。... -
HTML5+CANVAS游戏开发实战
2018-10-26 18:18:36HTML5+CANVAS游戏开发实战,很值得学习,就算不是做游戏,但是对js的进阶也很有好处。 -
HTML 5 CANVAS游戏开发实战
2017-12-28 14:48:07HTML 5 CANVAS游戏开发实战HTML 5 CANVAS游戏开发实战HTML 5 CANVAS游戏开发实战 -
HTML 5 CANVAS游戏开发实战+源代码
2016-10-16 10:49:01HTML 5 CANVAS游戏开发实战pdf电子书 随书源代码 -
canvas小游戏开发
2021-12-30 15:59:40利用canvas画布,进行撞击,消除操作的小游戏 -
canvas游戏FlappyBi
2020-12-10 16:46:17利用中介者模式进行业务,Game是游戏中介者类,它的作用就是中介者的作用 Bird小鸟类,作用是对小鸟的业务进行封装 Land大地类,封装地面的样式 Background背景类,作用是封装背景图 PiPe管子类,作用是随机出现管子 -
html5_canvas_games:HTML5 Canvas游戏
2021-05-10 01:22:50html5_canvas_games HTML5 Canvas游戏 -
2048canvas游戏
2018-05-28 19:04:52canvas版的2048小游戏,canvas版的2048小游戏,canvas版的2048小游戏,canvas版的2048小游戏,canvas版的2048小游戏 -
HTML 5 CANVAS游戏开发实战.zip
2019-06-09 18:51:23HTML 5 CANVAS游戏开发实战 -
Play-Canvas-Electron-Editor:基于离线电子版的Play Canvas游戏引擎编辑器
2021-05-25 08:37:58PlayCanvas离线电子编辑器 这只是PlayCanvas引擎的离线编辑器的样板代码。 它使用打字稿进行设置,并进行一些装饰以与playcanvas集成。 它还具有用于调试电子应用程序的Visual Studio Code设置。... -
HTML 5 CANVAS游戏开发实战_高清完整版
2016-12-17 15:37:50HTML 5 CANVAS游戏开发实战_高清完整版 -
《HTML5 Canvas游戏开发实战》.(张路斌).pdf
2018-04-06 13:12:03《HTML5 Canvas游戏开发实战》.(张路斌).pdf电子高清扫描版 -
scalajs-simple-canvas-game:简单HTML5 Canvas游戏移植到Scala.js
2021-05-12 14:51:56简单HTML5 Canvas游戏移植到Scala.js Javascript原始教程: 。 播放。 看看由了不同版本的游戏中,展示了使用几种技术。 运行应用程序 $ sbt > fastOptJS $ open index-dev.html -
gameboard:简单的 HTML5 Canvas 游戏板
2021-07-05 15:56:48HTML5 画布游戏板 认真简单。 只是普通的 ol' 瓷砖 n' 单位。 您必须使用其他模块或构建自己的部件来解决这个问题。 参见示例。 得到它 安装 npm install gameboard 构建示例 运行以下命令将 browserify 示例并为您... -
坦克移动、背景卷动 Javascript + Canvas 游戏案例
2019-05-29 10:36:35坦克移动、背景卷动 Javascript + Canvas 游戏案例,有4个案例,包括:背景移动、背景移动+边缘控制、背景移动+单向 重复绘图、背景移动+双向 重复绘图 -
基于canvas的小游戏一:飞翔的小鸟
2021-04-29 14:28:33canvas画布写的一个小游戏,通过点击鼠标来控制小鸟的高度,通过一个柱子得一分,碰到柱子或者鸟掉出画布游戏结束。 -
JS——手造极简Canvas游戏引擎
2022-03-22 13:52:42一个Canvas,里面有个矩形一直在移动。 点击它,它会暂停or继续。 1,实现画布 先摆一个元素。 <canvas id="app"></canvas> 给点样式。 #app { outline: solid pink .2px; } 新建一个类,然后创建其...最终效果
一个Canvas,里面有个矩形一直在移动。
点击它,它会暂停or继续。
1,实现画布
先摆一个元素。
<canvas id="app"></canvas>
给点样式。
#app { outline: solid pink .2px; }
新建一个类,然后创建其实例。
class Game { constructor(id, width, height, interval) { //参数绑定 this.element = document.getElementById(id); this.element.width = this.width = width; this.element.height = this.height = height; this.interval = interval; } } let app = new Game("app", 400, 400, 40);
参数分别为:
- 容器ID
- 容器的宽,高
- 刷新频率
这个时候,元素已经有了大小。
2,添加元素
初始化以下参数:
pen:canvas的画笔。
items:元素数组。constructor(id, width, height, interval) { //.... this.pen = this.element.getContext("2d"); this.items = []; }
开启定时器,关闭定时器。
start = () => { this.timer = setInterval(() => { //清除上次画的 this.pen.clearRect(0, 0, this.width, this.height); //画这次的 this.items.forEach(obj => { obj.draw(this.pen, this.width, this.height); }) }, this.interval); } end = () => { clearInterval(this.timer); }
定义一个元素。
data:元素的状态。
draw:元素的绘制方法。let rect = { data: { x: 0, y: 0, direction: 1 }, draw(pen, width, height) { pen.fillStyle = "red"; pen.fillRect(this.data.x, this.data.y, 100, 100); if (this.data.x + 100 >= width || this.data.y + 100 >= height) { this.data.direction = -1; } else if (this.data.x <= 0 || this.data.y <= 0) { this.data.direction = 1; } if (this.data.direction === 1) { this.data.x += 10 this.data.y += 10 } else if (this.data.direction === -1) { this.data.x -= 10 this.data.y -= 10 } } }
定义添加方法。
addItem = (obj) => { this.items.push(obj); }
添加,开始游戏。
app.addItem(rect) app.start();
效果:
3,事件处理
在开启定时器之后,添加点击事件。
start = () => { this.timer = setInterval(() => { this.pen.clearRect(0, 0, this.width, this.height); this.items.forEach(obj => { obj.draw(this.pen, this.width, this.height); }) }, this.interval); this.element.addEventListener('click', e => { this.items.forEach(obj => { obj.click(e.offsetX, e.offsetY); }) }) }
定义元素的点击处理。
click(x, y) { if (x >= this.data.x && x <= this.data.x + 100 && y >= this.data.y && y <= this.data.y + 100) { console.log(1); this.data.active = !this.data.active; } }
添加暂停状态,和暂停判断。
data: { x: 0, y: 0, direction: 1, active: true }, draw(pen, width, height) { pen.fillStyle = "red"; pen.fillRect(this.data.x, this.data.y, 100, 100); if (this.data.active) { if (this.data.x + 100 >= width || this.data.y + 100 >= height) { this.data.direction = -1; } else if (this.data.x <= 0 || this.data.y <= 0) { this.data.direction = 1; } if (this.data.direction === 1) { this.data.x += 10 this.data.y += 10 } else if (this.data.direction === -1) { this.data.x -= 10 this.data.y -= 10 } } }
达成效果!
-
CANVAS游戏开发思路
2020-10-10 15:02:33一、游戏截图 DEMO_1: 卷轴跑酷游戏 DEMO_2: 格斗游戏 以下思路仅为我的一些个人观点,读【HTML5 2D游戏编程核心技术】一书获得的一些收获,欢迎指正!! 二、用到的API 三、开发前的准备 开发一款游戏都需要准备...一、游戏截图
DEMO_1: 卷轴跑酷游戏
DEMO_2: 格斗游戏
以下思路仅为我的一些个人观点,读【HTML5 2D游戏编程核心技术】一书获得的一些收获,欢迎指正!!二、用到的API
三、开发前的准备
开发一款游戏都需要准备些什么呢?这里列出了简单的一些东西。
1、图片资源。 一款游戏最主要的表现力之一就是图片,游戏的登陆,过场界面,地图,人物序列帧,怪物,技能特效,都是基于图片的
2、音效。 恰到好处的音效可以让游戏给玩家留的印象很深,比如仙剑3的回梦游仙。
3、一些数学基础 和 对生活定律的理解。
4、一个开发方向。
5、程序的支持。对于我们程序员来说,这点可能是最拿手的一点了。开发游戏也是很考验自己的基本功的,需要设计出合理的数据结构,游戏会出现很多很多不可预知的,甚至有趣的bug。如果代码结构不过关的话,维护起来是及其吃力的。四、部分难点的开发思路
1、本游戏为横版卷轴滚动类的游戏,类似天天酷跑。如何实现背景的无限滚动呢?
针对滚动,这里用到的核心API为 translate(),该方法可以将当前画布的原点平移到指定位置。 canvas画布的初始原点为左上角,x坐标向右增大,y坐标向下增大。
此时我们原点坐标以(0,0)的方式绘制一张图片。在下一帧开始的时候,通过translate(-1, 0) 将原点坐标向左移动一个像素,还以上次的坐标绘制图片,就会出现滚动的效果了。2、一个游戏会有各种的对象,如何去整合管理呢?
一个游戏,会有场景,ui层,主角,敌人,奖励等各种对象。每个对象通常又会有不同的动作,我们该如何统一管理呢?这里我们创建一个sprite对象,分为四步,指定类型,初始化绘制类,添加行为,初始化sprite。
• 指定类型: 指定该sprite对象的类型,是场景还是主角?
• 初始化绘制类:初始化的绘制类用来绘制该sprite,内部会保存当前sprite的动作状态,第几帧等和绘制相关的属性。
• 添加行为:一个sprite可能会跑,会跳,会发射炸弹。 这些都需要将行为单独添加给sprite
• 初始化:通过模版来初始化sprite属性并生成。
通过以上的步骤,可以模版化的创建出一个sprite,这个流程足够通用。
创建好了所有的sprite后,将它添加到一个list中进行整合,方便游戏本身去遍历访问。
3、上个提到的行为是什么?
行为就是每个sprite可以干什么,行为是让一个sprite具有特色最好的方法。
• 行为的分类
• sprite对象的特定行为: 确定只被一个sprite对象使用的特定行为
• 轻量级(无状态)行为: 不维持状态的行为,可以被多个sprite同时使用。 轻量级的行为可以显著的减少内存,尤其是像包含了上千个sprite对象的例子系统。
• 游戏独立行为:三分之一的行为为独立行为,即通用行为。可以和任何精灵一起工作的行为。比如游戏中通过循环显示sprite对象的图像来实现的周期行为。你可以使用周期性为与任何artist对象是一个表单的sprite对象一起工作。而不用管这事哪种游戏。4、如何实现不同sprite的速度差呢?
sprite都会有自己不同的速度,我们会有一个sprite list来存放所有的sprite,在没帧的时候,通过上一帧到这一帧的时候,来计算当前sprite需不需要去做一个移动,这样就实现了速度差。
5、格斗游戏中的各种判定
demo2中比demo1中多了一些判定框。粗略讲解一下为什么。
在此之前,科普一些基本的判定框种类。
• 体积碰撞框
• 基本所有游戏都会有,用来限制角色的位置。进行碰撞检测。
• 攻击判定框
• 举例,当角色进行攻击时,释放的技能不同,攻击生效的地方也不同。这是就需要一个或多个攻击框来判定伤害触发的范围。
• 受伤范围框
• 在2d游戏中,很多都采用矩形框来进行判定,这是普遍会发有角色不会占满矩形框的情况。我们需要实现多个受伤框,来进行受伤判定。如图。
• 防御范围框
• 角色进行防御时候,会有一个防御范围。通常角色都是正面防御,此时从背面攻击就会破防。这里就会有一个正面的防御判定框。
• 当前帧占位框
• 在这次格斗游戏中,由于素材限定,技能和角色整合在了一起,这就不可避免的出现了一些问题,某一帧中技能特效很华丽,占位特别大,所以用到了此框。
•
6、碰撞体积检测
这两个demo中都使用的是矩形碰撞,所以这里只讲一下矩形碰撞检测的方法。
1、canvas提供的原生api
isPointInPath(), 这个方法用来判定一个点在不在当前的路径内。其实我们常用的图标组件,点击某区域显示什么什么数据,就会用到这个api。 这个api可以很方便的判定一个角色与另一个sprite对象碰撞。首先我们需要先给角色标记几个关键点,如角色碰撞框的四个角点, 中心点。 标记的点越多,碰撞检测越精准,性能也越差。 这个方法局限性很大,很容易误判~
2、边界区域判定法
简单的来讲,就是判断两个矩形存不存在交点,如果存在,即为碰撞。
缺点: 当边界区域太小时候,而两个检测对象速度又很快时候,会出现在一帧中直接穿过的情况。
3、光线投射法。
光线投射法在检测面积小,速度快的sprite对象时候更可靠。其通过检测两个sprite的速度矢量是否存在焦点来判断。
4、分离轴定理。
分离轴定理是最可靠,同样也是最复杂的碰撞检测技术之一。 实战中没有用到~以后有机会细看一下。
这个用来检测多边形之间的碰撞很方便。
7、优化碰撞体积算法。
碰撞计算可以说是每个游戏中最耗费性能的地域了,处理不佳可能会造成性能崩塌。所以进行相关的碰撞检测算法优化是非常有必要的。
1、只对当前可视区域的sprite进行碰撞检测。
一个游戏往往不能一屏显示完毕,会出现滚动屏幕的情况。这时未出现在屏幕中的sprite完全不必要进行检测。
2、预测会发生碰撞的sprite进行检测。
比如A,B赛跑,知道A永远追不上B的情况下,就大可不必对这两个人进行碰撞检测。再比如AB背到而行,也不用进行碰撞检测。
3、只对主角周围特定空间内的sprite对象进行碰撞检测。
这个方法可以极大的减少检测次数。
DEMO_1中,我只对红色矩形范围内的sprite进行碰撞检测,会有很好的性能表现。五、总结一下
暂先写这么多吧~!!以后想到的话再补充。
独立开发一款游戏能学到很多东西,也能将平常自己的技能加以强化,综合。
这两款小的demo游戏,就用到了继承,闭包,设计模式,数据结构各种东西。这对于提升编程功力是一个很不错的方法~ -
canvas游戏-见缝插针
2018-12-28 16:26:19一个专门为圣诞节打造的小游戏,见缝插针,整个画面由canvas绘制而成,用的原生js -
CANVAS游戏开发与实战
2019-07-23 07:21:12资源名称:CANVAS游戏开发与实战 资源截图: 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。 -
坦克移动、边界处理Javascript + Canvas 游戏案例.rar
2019-05-29 10:29:35Javascript + Canvas 的游戏案例,坦克移动,有两个案例,1是不能走出边界处理,2是走出去之后,从另外一边回来; -
canvas 游戏
2012-03-27 14:05:44canvas 游戏 demo 鲨鱼吃小鱼 用鼠标控制