课程/HTML/CSS/前端开发
HTML5小游戏---爱心鱼(上)
-
-
大大米
2020-03-05
4、画大鱼,身子,尾巴,眼睛
使用到的API
translate()
rotate()
Math.atan2(y, x)
-
截图
1赞 · 0采集
-
-
qq_Flyxiang_0
2018-05-02
大鱼绘制使用到的API
translate()
rotate()
Math.atan2(y,x)
-
1赞 · 1采集
-
-
tzhxz
2018-04-10
画大鱼
-
截图
0赞 · 0采集
-
-
ChristineN
2017-01-02
- 因为动画效果是靠gameloop一次一次地循环载入canvas形成的,如果不清除的话,多次载入的画布会重叠在一起,就形成了重影,也就是看上去线条变宽了一样。而cxt2之所以不用清除,是因为canvas2每次重新载入时都是先载入背景图片,直接就把前一次画布上的东西全覆盖了,所以不用清除。这就是两种清除画布的方法,一种直接调用清除方法,一种用背景覆盖。
-
截图
3赞 · 0采集
-
-
java家洼
2016-06-24
- 4问:因为canvas1覆盖在canvas2上,所以就要清空,这是为什么?canvas2跟canvas1本身就不是同一个画布,那是怎么影响的呢?
答:清空的原因不是因为【canvas1覆盖在canvas2上】,教程中从来没这么说。教程中说的是:因为动画一直在循环执行,前一次的图像如果不清除,就会跟后面的图像叠加在一起,使得大鱼小鱼的边线看起来特别粗,所以才要清。打个简单的比方:写满字的黑板如果不擦,继续写上去的字就会跟之前的叠加在一起看不清楚。
5问:请问为什么ctx2每次刷新都不需要ctx2.clearRect(0,0,canWidth, canHeight);?
答:因为它再一次绘制背景的时候,之前画的已经被新的背景覆盖了。。。按照原理来说,肯定要清空ctx2的,加上ctx2.clearRect(0,0,canWidth, canHeight);页面也是正确的,不信你可以注释掉绘制背景图片那个方法,海葵绘制就出问题了。
-
2赞 · 3采集
-
-
java家洼
2016-06-24
- 7,慕课网课后问答摘抄:
1问:translate()就单独使用这个属性来说是什么意思?
答:context.translate(x,y)函数可以使画布的原点坐标变为(x,y),即画笔从这个点开始画。因为我们画完一部分内容之后希望重新定义画笔的属性,所以用context.save()和context.restore()包裹例如context.translate(),context.fillStyle等属性设定。希望能帮助你理解
2问:鱼的坐标问题
ctx1.translate(this.x,this.y); ctx1.drawImage(this.bigBody,-this.bigBody.width*0.5,-this.bigBody.height*0.5); 为什么会是-this.bigBody.width*0.5和-this.bigBody.height*0.5,这个距离是怎么算的
答:如果drawImage方法,没有后面的两个参数,鱼的图片的左上角,就是整个大背景图片的中心位置(即,在translate之后)。加上两个参数的作用可以理解为,使鱼向x轴负方向移动身体的一半,向y轴方向移动身体的一般,把鱼图片的中心点放在当前坐标轴的中心点位置。当然也可以不这么做。
3问:为什么需要清空?没听懂
就是在mom.draw()前那为什么需要?
答:因为动画效果是靠gameloop一次一次地循环载入canvas形成的,如果不清除的话,多次载入的画布会重叠在一起,就形成了重影,也就是看上去线条变宽了一样。而cxt2之所以不用清除,是因为canvas2每次重新载入时都是先载入背景图片,直接就把前一次画布上的东西全覆盖了,所以不用清除。这就是两种清除画布的方法,一种直接调用清除方法,一种用背景覆盖。
-
2赞 · 0采集
-
-
java家洼
2016-06-24
- 6,解释一下translate在画大鱼时的作用:
首先ctx1.translate(this.x,this.y);将canvas1的中心设置为画布的
坐标系原点,即零点(0,0) 因为drawImage方法是从图片本身的左上角开始绘制本图片的,所以要想让大鱼的各部件
的中心都重叠在原点上,那么必须让大鱼各部件图片向西北方向移动到原点,从坐标系上看就是各图片的x坐标向
左(负方向)移动它本身宽度的一半,各图片的y坐标向上(负方向)移动它本身高度的一半。这样子大鱼各部件图片
的中心都在原点上了。
因为老师制作的大鱼的各个部件的图片都是类似圆形的图片,也就是说移动的时候只需要移动图片本身长宽的一半,
如果大鱼身子是长条状的,那么把大鱼眼睛放在大鱼脑袋上,而不是大鱼身子的中心(若大鱼是长条的,大鱼的
眼睛肯定不在大鱼身子的中心位置)这时,大鱼身子往原点移动的距离就是大鱼眼睛向原点移动的距离,因为大鱼眼睛
始终是圆形的。
-
0赞 · 0采集
-
-
java家洼
2016-06-24
- 5,利用translate重新定位大鱼各部件坐标
那么这里的坐标都需要全部改一下了:
this.bigEye它的位置画在,离原点(this.x,this.y),大鱼的x坐标往左移this.bigEye.width*0.5这个距离,
同样的,y坐标往上移this.bigEye.height*0.5这个距离:那么眼睛的中心就在零点处了。
ctx1.drawImage(this.bigEye,-this.bigEye.width*0.5,-this.bigEye.height*0.5);
所以,所有的图片都要绘制在中心点,这里替换一下:
momObj.prototype.draw=function(){
ctx1.save();
ctx1.translate(this.x,this.y);
ctx1.drawImage(this.bigEye,-this.bigEye.width*0.5,-this.bigEye.height*0.5);
ctx1.drawImage(this.bigBody,-this.bigBody.width*0.5,-this.bigBody.height*0.5);
ctx1.drawImage(this.bigTail,-this.bigTail.width*0.5,-this.bigTail.height*0.5);
ctx1.restore();
}
好,我们再刷新一下:好,现在三张图片的中心位置都在这个地方,只是尾巴要往后移一点,我们先把尾巴移出来,
因为眼睛看不到了:绘制尾巴的横坐标再向右移10个px,
ctx1.drawImage(this.bigTail,-this.bigTail.width*0.5+10,-this.bigTail.height*0.5);
好,太少了,好,加30,
ctx1.drawImage(this.bigTail,-this.bigTail.width*0.5+30,-this.bigTail.height*0.5);
好,差不多,大鱼眼睛这个位置看起来挺好的,那眼睛就不改了,好,大鱼就已经绘制好了
接下来,大鱼要动,对不对,它要随着鼠标来动,这个时候我们就需要获取一下鼠标的位置,
然后大鱼的坐标要跟随着鼠标的位置去移动
-
2赞 · 0采集
-
-
java家洼
2016-06-24
- 4,利用translate()方法将大鱼的坐标设置为画布的原点
但是,大鱼的坐标并不是很对,那么这个大鱼的坐标,我们一是为了方便调节这三张图片之间的相对距离,
同时也有利于我们做大鱼的旋转动作,大鱼需要一直跟着我的鼠标,一直指向我的鼠标。也是为了方便做旋转计算
我们使用前面给大家介绍的translate()这个方法(translate方法的作用:重新映射画布上的(0,0)位置),
来给它指定一个相对的原点值,好,这个方法仅适用于大鱼,所以这里需要加一个使用的范围:
momObj.prototype.draw=function(){
ctx1.save();
ctx1.drawImage(this.bigEye,this.x,this.y);
ctx1.drawImage(this.bigBody,this.x,this.y);
ctx1.drawImage(this.bigTail,this.x,this.y);
ctx1.restore();
}
使我们中间定义的属性仅适用于大鱼,
translate到大鱼的坐标位置,
ctx1.translate(this.x,this.y);
好,translate到这个位置之后呢,
这个地方就是原点了。
-
2赞 · 0采集
-
-
java家洼
2016-06-24
- 3,初画大鱼非常粗,加上命令显苗条
那么大鱼应该画在哪一个canvas上面呢?是在第一个canvas下面:
我们先不做调整,先把它都画上去,然后再慢慢调整它的位置:
momObj.prototype.draw=function(){
ctx1.drawImage(this.bigEye,this.x,this.y);
ctx1.drawImage(this.bigBody,this.x,this.y);
ctx1.drawImage(this.bigTail,this.x,this,y);
}
我们来刷新看一下,大鱼已经画出来了。但是它并不像我们的图片那个样子,
原图的线条(src下的大鱼的body的线条是很细的)是很细的,在这里却变得非常的粗
为什么?我们再来看一下,这个canvas1,它是一个透明的,部分透明的,只绘制需要绘制的东西在上面
然后其他地方都是透明的,然后它覆盖在canvas2上,所以我们每一次绘制的时候,都需要把前面一帧的
内容clear一下。把它清空掉,然后再绘制新的,我们需要在gameloop循环里加上这样一个功能:
ctx1.clearRect(0,0,canWidth,canHeight);
从0,0点到canvas的对角线点整个清除掉,然后在干净的画布上面去绘制,
好,这样子绘制出来的东西就是正常的了
-
1赞 · 0采集
-
-
java家洼
2016-06-24
- 2,将大鱼相关的图片作为属性添加到类中,并初始化时加载这些图片
我们再来看一下大鱼的资源都有哪些?大鱼的是big,大鱼会有眼睛,眼睛会有一个动画,同时身体也会有
一个变化的过程,随着吃到果实的数量不同它的颜色会变,同时它的尾巴还会有一个动画,这就是所有有关
大鱼的资源,那么在第一阶段的课程中呢,我们不做大鱼的动画,仅把大鱼的基本东西描绘出来就行了。
我们先不做动画,所有我们把这些图片资源放在类里面吧。我们定义几个图像属性:
var momObj=function(){
this.x;
this.y;
this.bigEye=new Image();
this.bigBody=new Image();
this.bigTail=new Image();
}
那么在初始化的时候,加载一下图片的资源:
momObj.prototype.init=function(){
this.x=0;
this.y=0;
this.bigEye.src="./src/bigEye0.png";
this.bigBody.src="./src/bigSwim0.png";
this.bigTail.src="./src/bigTail0.png";
}
这样初始化的时候,图片就加载进来了。我们先来刷新一下,
现在我们首先来绘制一下大鱼,看这些资源有没有加载进去,
我们把大鱼的坐标放在canvas的中间:
momObj.prototype.init=function(){
this.x=canWidth*0.5;
this.y=canHeight*0.5;
this.bigEye.src="./src/bigEye0.png";
this.bigBody.src="./src/bigSwim0.png";
this.bigTail.src="./src/bigTail0.png";
}
-
2赞 · 1采集
-
-
java家洼
2016-06-24
- 1,绘制大鱼所用API,定义鱼妈妈类,同时在main.js中定义mom对象并初始化
我们将会用到一些API:translate();
rotate();这两个API是html5 canvas的API。还有一个API是Math.atan2(y,x);反正切,这个
API是JavaScript的API。那我们来分别看一下这几个API的含义:
我们先来看一下反正切这个函数:这个函数是计算里面两个参数的反正切值,这两个参数呢
y在前,x在后,同时要注意一点,它的返回值,是一个数字,它的区间是PI到-PI之间,这点要牢记,
因为等会我们要用到这个知识,我们如何来绘制大鱼,我们还是从最基本的开始:首先我们新建一个文件
,Ctrl+N,Ctrl+S,然后保存在js文件夹下mom.js ,首先把这个js文件包含在html里面:
<script type="text/javascript" src="js/mom.js"></script>
我们把鱼妈妈也定义为一个类。因为鱼妈妈也会有各种各样的属性,首先,它会有一个坐标值,同时我们
肯定也要初始化一下,初始化它的位置,初始化完了之后,我们要在画布上画一条大鱼,要用到
drawImage,这个结构就有了,
var momObj=function(){
this.x;
this.y;
}
momObj.prototype.init=function(){
this.x=0;
this.y=0;
}
momObj.prototype.draw=function(){
}
我们把相应的大鱼的对象定义一下:
//大鱼的对象
var mom;
同时在main.js的init方法中把它定义为momObj类型,同时进行初始化,并且把draw方法放到gameloop方法中
//new一个大鱼对象并且初始化
mom=new momObj();
mom.init();
-
2赞 · 1采集
-
-
EyreSS
2016-05-11
- 绘制大鱼
-
截图
0赞 · 0采集
-
-
双双要当大学霸
2016-03-16
- translate()
rotale()
math.atan2(y,x);
-
0赞 · 0采集
-
-
卅白米
2016-01-12
- 仅适用于ctx1.save() - ctx1.restore()之间,在restore之后会将初始值还原
-
截图
0赞 · 0采集
-
-
卅白米
2016-01-12
- ctx1.clearRect(); 清除第一个画布的未画制的部分
-
截图
0赞 · 0采集
-
-
sofa
2015-12-24
- 画大鱼要用到的API
-
截图
0赞 · 0采集
-
-
xuxuyxy
2015-12-01
- 设置画大鱼的使用范围。save,restore。
-
截图
0赞 · 0采集
-
-
xuxuyxy
2015-12-01
- 对前一个画布进行clear.ctx1.clearR...........不然画出来不好看
-
截图
0赞 · 0采集
-
-
狐狸丢丢
2015-10-30
- 4.画大鱼,身子,尾巴,眼睛
-
截图
0赞 · 0采集