canvas学习作业,模仿做一个祖玛的小游戏

这个游戏的原理我分为11个步骤,依次如下:

1、布局,

2、画曲线(曲线由两个半径不同的圆构成)

3、画曲线起点起始圆和曲线终点终止圆

4、起始的圆动起来,

5、起始的圆沿曲线走起来

6、起始的圆沿曲线走起来,并在曲线初始位置处产生新圆

7、添加图片,这个图片是为了发射子弹

8、让图片跟随鼠标动起来

9、让动起来的图片跟随鼠标的位置发送子弹,并让子弹的颜色变红

10、图片发射的子弹和轨迹上的小圆碰撞检测

11、碰撞检测后让发射的子弹和轨迹上的小圆消失

这就是该程序步骤的的分解。

第一点:布局

<div id="div1">
    <canvas id="canvas1" width="800px" height="800px"></canvas>
</div>
 *{margin:0;padding:0;}
    #canvas1{background-color: #ccc;}
    #div1{
        width: 800px; margin: 20px auto;}

布局很简单。

第二点:画曲线

//外大圆
                oCG.beginPath();
                oCG.arc(400,400,250,-90*Math.PI/180,180*Math.PI/180,false);
                oCG.stroke();
                //内小圆
                oCG.beginPath();
                oCG.arc(350,400,200,180*Math.PI/180,0,false);
                oCG.stroke();
                //末尾圆
                oCG.beginPath();
                oCG.arc(550,400,30,0,360*Math.PI/180,false);
                oCG.stroke();

外面的大圆圆心坐标为400,400,半径为250,从-90度到180度,顺时针。,内小圆的圆心坐标为350,400,半径为200,从180度到0度,瞬时针。曲线终点有一个小圆,圆心坐标为550,400,半径为30。三个圆都为空心圆。

第三点:画曲线起点起始圆和曲线终点末尾圆

曲线终点的末尾圆,在上面已经绘制了,下来就是曲线的起始点的圆如何绘制

                    oCG.beginPath();
                    oCG.moveTo(400,150);
                    oCG.arc(400,150,30,0,360*Math.PI/180,false);
                    oCG.fill();        

第四点:起始的圆动起来

起始点的坐标为400,150,半径为30,但是要考虑到一点,小圆圆心坐标是变化的,为了方便数据的改变,使用json去存放数据

            var ball=[];
                ball[0]={
                    x:400,  //小圆起始点横坐标
                    y:150,  //小圆起始点纵坐标
                    r:250,   //大圆的半径
                    num:0,   //小圆转过的角度
                    //必须新建一个小圆的横纵坐标,否则小圆会飞出去。
                    X:400,   //小圆起始点横坐标
                    Y:150     //小圆起始点纵坐标
                }

计算运动后下一个圆心的坐标

 setInterval(function(){
                for(var i=0;i<ball.length;i++){
                    ball[i].num++;         // 圆角度由0-360
                    ball[i].x=Math.sin(ball[i].num*Math.PI/180)*ball[i].r+ball[i].X;  //小圆横坐标
                    ball[i].y=ball[i].r-Math.cos(ball[i].num*Math.PI/180)*ball[i].r+ball[i].Y;//小圆的纵坐标
                }{,1000/60)

第五点:起始的圆沿曲线走起来

然后 ball[i].x ball[i].y 附给新画的圆,因为在定时器内,所以就能形成1000/60ms变化一次圆心的效果,进而让圆运动,但是这个运动仅仅是围绕大圆运动的。要想再围绕内小圆运动,就应该再加一个if判断

  setInterval(function(){
                for(var i=0;i<ball.length;i++){
                    ball[i].num++;         // 圆角度由0-360
                    if(ball[i].num==270){// 如果角度变为270度,改变ball的起始点坐标,就是改变它的轨迹。
                        ball[i].r=200;
                        ball[i].X=350;
                        ball[i].Y=200;
                    }
                    else if(ball[i].num==360+45+45
                    ){
                        confirm(‘你失败了!点击确定重来!‘);
                        window.location.reload()
                    }
                              ball[i].x=Math.sin(ball[i].num*Math.PI/180)*ball[i].r+ball[i].X;  //小圆横坐标
                              ball[i].y=ball[i].r-Math.cos(ball[i].num*Math.PI/180)*ball[i].r+ball[i].Y;//小圆的纵坐标
                }
},1000/60)

当小圆走到270度时,把ball的起始点坐标改变,就能改变ball 的轨迹。当ball[i].num=450度时,也就是走到末尾圆,代表游戏结束。

第六点:起始的圆沿曲线走起来,并在曲线初始位置处产生新圆。

为了产生新的圆,只是开一个定时器,让每隔一段时间产生一个新的json

            var ball=[];
            setInterval(function(){
                ball.push({
                    x:400,  //小圆起始点横坐标
                    y:150,  //小圆起始点纵坐标
                    r:250,   //大圆的半径
                    num:0,   //小圆转过的角度
                    //必须新建一个小圆的横纵坐标,否则小圆会飞出去。
                    X:400,   //小圆起始点横坐标
                    Y:150     //小圆起始点纵坐标
                })
            },400);

第七点:添加图片,这个图片是为了发射子弹

var oimg= new Image();
        oimg.src=‘1.jpg‘ ;
        oimg.onload=function(){
     //让图片顺在中心转起来
               var picX=(oC.width-oimg.offsetWidth)/2;
                var picY=(oC.height-oimg.offsetHeight)/2;
                oCG.save(); //为了不受定时器影响,sava起来
                oCG.translate(picX,picY);
                oCG.rotate(-iRotate);//里面的参数是为了控制让图片跟着鼠标旋转
                oCG.translate(-30,-30);  //为了让图片沿着图片中心转动
                oCG.drawImage(oimg,0,0);
//                oCG.drawImage(oimg,(oC.width-oimg.offsetWidth)/2,(oC.height-oimg.offsetHeight)/2)
                oCG.restore();
},1000/60);

8、让图片跟随鼠标动起来

//让图片跟着鼠标转,原理就是求图片纵坐标与鼠标与图片中心的距离的夹角。把这个夹角附给
            //图片旋转的角度
            var iRotate=0;
            oC.onmousemove=function(ev){
                oEvent=ev||event;
                var a=oEvent.clientX-oC.offsetLeft-(oC.width-oimg.offsetWidth)/2;
                var b=oEvent.clientY-oC.offsetTop-(oC.height-oimg.offsetHeight)/2;
                iRotate=Math.atan(a/b);
            };

四角星代表鼠标,角度为a与b的夹角,红色方块代表图片,把获取到角度赋给  ”oCG.rotate(-iRotate);//里面的参数是为了控制让图片跟着鼠标旋转”

第九点:让动起来的图片跟随鼠标的位置发送子弹,并让子弹的颜色变红

 

            //让图片吐子弹
            var Buttle=[];
            oC.onmousedown=function(ev){
                oEvent=ev||event;
                var a=oEvent.clientX-oC.offsetLeft-(oC.width-oimg.offsetWidth)/2;
                var b=oEvent.clientY-oC.offsetTop-(oC.height-oimg.offsetHeight)/2;
                var iSpeed=5;
                var c=Math.sqrt(a*a+b*b); //鼠标距离图片中心的距离
                var iSpeedX=iSpeed*a/c;  //横轴分得到的速度
                var iSpeedY=iSpeed*b/c;  //纵轴分得到的速度
                Buttle.push({
                    x:(oC.width-oimg.offsetWidth)/2,
                    y:(oC.height-oimg.offsetHeight)/2,
                    iSpeedX:iSpeedX,
                    iSpeedY:iSpeedY
                })
            }
 //图片吐子弹的路径,获得吐到子弹终点的坐标
                for(var i=0;i<Buttle.length;i++){
                    Buttle[i].x=Buttle[i].x+Buttle[i].iSpeedX; //子弹终点横坐标
                    Buttle[i].y=Buttle[i].y+Buttle[i].iSpeedY;  //子弹终点纵坐标
                }
  for(var i=0;i<Buttle.length;i++){
                    oCG.save();
                    oCG.beginPath();
                    oCG.fillStyle=‘red‘;
                    oCG.moveTo(Buttle[i].x,Buttle[i].y);
                    oCG.arc(Buttle[i].x,Buttle[i].y,30,0,360*Math.PI/180,false);
                    oCG.fill();
                    oCG.restore();
                }

利用新的坐标Buttle[i].x和Buttle[i].y绘制一个圆。

第10点:图片发射的子弹和轨迹上的小圆碰撞检测

 //构建碰撞检测函数
        function pz(x1,y1,x2,y2){
            var a=x1-x2;
            var b=y1-y2;
            var c=Math.sqrt(a*a+b*b);
            if(c<60){ //如果两圆心的距离小于60
                return true
            }
            else{
                return false
            }

        }

第11点:碰撞检测后让发射的子弹和轨迹上的小圆消失

 for(var i=0;i<Buttle.length;i++){
                    for(var j=0;j<ball.length;j++){
                        if(pz(Buttle[i].x,Buttle[i].y,ball[j].x,ball[j].y)){
                            Buttle.splice(i,1);
                            ball.splice(j,1);
                            break;
                        }
                    }
                }

让子弹和轨迹上的小圆消失,让构建的两个json splice即可。

注意,每次绘画的时候,要clearRect,设置在一个1000/60ms定时器内,静态的图形clear后再绘制依旧是静态的,但是动态生成的图形,在经过定时器后,绘制的是1000/60ms后的图形。图片的dragImage必须是在 onload事件下的,为了不影响图片加载,程序也是在onload事件下的。

以上就是我对这道题的理解。因为时间仓促,里面难免有些语句有错误,恳请大家斧正。

下面是程序的源代码。

    window.onload=function(){
        var oC=document.getElementById(‘canvas1‘);
        var oCG=oC.getContext(‘2d‘);
        //设置图形
        var oimg= new Image();
        oimg.src=‘1.jpg‘ ;
        oimg.onload=function(){
            //重新绘制实现动画效果,每次先清空上次一次绘画的,过一段时间,然后再画下一次绘画的,静态不变,东西改变,实现了动的效果
            setInterval(function(){
                oCG.clearRect(0,0,oC.width,oC.height);
                //外大圆
                oCG.beginPath();
                oCG.arc(400,400,250,-90*Math.PI/180,180*Math.PI/180,false);
                oCG.stroke();
                //内小圆
                oCG.beginPath();
                oCG.arc(350,400,200,180*Math.PI/180,0,false);
                oCG.stroke();
                //末尾圆
                oCG.beginPath();
                oCG.arc(550,400,30,0,360*Math.PI/180,false);
                oCG.stroke();
                //起始圆围绕曲线做圆周运动,把每一个已经动态变过的小圆的横纵坐标赋给新圆坐标,
                // 达到到新位置1000/60ms,每350ms从原起点生成一个新的ball的效果
                for(var i=0;i<ball.length;i++){
                    oCG.beginPath();
                    oCG.moveTo(400,150);
                    oCG.arc(ball[i].x,ball[i].y,30,0,360*Math.PI/180,false);
                    oCG.fill();
                }
                //设置字体
                oCG.font="100px impact";
                oCG.textBaseline=‘top‘;
                oCG.fillText("hello",280,700);
                //让图片顺在中心转起来
               var picX=(oC.width-oimg.offsetWidth)/2;
                var picY=(oC.height-oimg.offsetHeight)/2;
                oCG.save(); //为了不受定时器影响,sava起来
                oCG.translate(picX,picY);
                oCG.rotate(-iRotate);
                oCG.translate(-30,-30);  //为了让图片沿着图片中心转动
                oCG.drawImage(oimg,0,0);
//                oCG.drawImage(oimg,(oC.width-oimg.offsetWidth)/2,(oC.height-oimg.offsetHeight)/2)
                oCG.restore();
                //子弹
                for(var i=0;i<Buttle.length;i++){
                    oCG.save();
                    oCG.beginPath();
                    oCG.fillStyle=‘red‘;
                    oCG.moveTo(Buttle[i].x,Buttle[i].y);
                    oCG.arc(Buttle[i].x,Buttle[i].y,30,0,360*Math.PI/180,false);
                    oCG.fill();
                    oCG.restore();
                }
            },1000/60);
            //循环每一个ball,动态去改变每一个原心的坐标,
            setInterval(function(){
                for(var i=0;i<ball.length;i++){
                    ball[i].num++;         // 圆角度由0-360
                    if(ball[i].num==270){// 如果角度变为270度,改变ball的起始点坐标,就是改变它的轨迹。
                        ball[i].r=200;
                        ball[i].X=350;
                        ball[i].Y=200;
                    }
                    else if(ball[i].num==360+45+45
                    ){
                        confirm(‘你失败了!点击确定重来!‘);
                        window.location.reload()
                    }
                    ball[i].x=Math.sin(ball[i].num*Math.PI/180)*ball[i].r+ball[i].X;  //小圆横坐标
                    ball[i].y=ball[i].r-Math.cos(ball[i].num*Math.PI/180)*ball[i].r+ball[i].Y;//小圆的纵坐标
                }
                //图片吐子弹的路径,获得吐到子弹终点的坐标
                for(var i=0;i<Buttle.length;i++){
                    Buttle[i].x=Buttle[i].x+Buttle[i].iSpeedX; //子弹终点横坐标
                    Buttle[i].y=Buttle[i].y+Buttle[i].iSpeedY;  //子弹终点纵坐标
                }
                //碰撞检测
                for(var i=0;i<Buttle.length;i++){
                    for(var j=0;j<ball.length;j++){
                        if(pz(Buttle[i].x,Buttle[i].y,ball[j].x,ball[j].y)){
                            Buttle.splice(i,1);
                            ball.splice(j,1);
                            break;
                        }
                    }
                }
            },1000/60);
            //开定时器,每350ms添加一个ball
            var ball=[];
            setInterval(function(){
                ball.push({
                    x:400,  //小圆起始点横坐标
                    y:150,  //小圆起始点纵坐标
                    r:250,   //大圆的半径
                    num:0,   //小圆转过的角度
                    //必须新建一个小圆的横纵坐标,否则小圆会飞出去。
                    X:400,   //小圆起始点横坐标
                    Y:150     //小圆起始点纵坐标
                })
            },400);
            //让图片跟着鼠标转,原理就是求图片纵坐标与鼠标与图片中心的距离的夹角。把这个夹角附给
            //图片旋转的角度
            var iRotate=0;
            oC.onmousemove=function(ev){
                oEvent=ev||event;
                var a=oEvent.clientX-oC.offsetLeft-(oC.width-oimg.offsetWidth)/2;
                var b=oEvent.clientY-oC.offsetTop-(oC.height-oimg.offsetHeight)/2;
                iRotate=Math.atan(a/b);
            };
            //让图片吐子弹
            var Buttle=[];
            oC.onmousedown=function(ev){
                oEvent=ev||event;
                var a=oEvent.clientX-oC.offsetLeft-(oC.width-oimg.offsetWidth)/2;
                var b=oEvent.clientY-oC.offsetTop-(oC.height-oimg.offsetHeight)/2;
                var iSpeed=5;
                var c=Math.sqrt(a*a+b*b); //鼠标距离图片中心的距离
                var iSpeedX=iSpeed*a/c;  //横轴分得到的速度
                var iSpeedY=iSpeed*b/c;  //纵轴分得到的速度
                Buttle.push({
                    x:(oC.width-oimg.offsetWidth)/2,
                    y:(oC.height-oimg.offsetHeight)/2,
                    iSpeedX:iSpeedX,
                    iSpeedY:iSpeedY
                })
            }
    };
        //构建碰撞检测函数
        function pz(x1,y1,x2,y2){
            var a=x1-x2;
            var b=y1-y2;
            var c=Math.sqrt(a*a+b*b);
            if(c<60){ //如果两圆心的距离小于60
                return true
            }
            else{
                return false
            }

        }
 }
时间: 2024-10-24 23:22:49

canvas学习作业,模仿做一个祖玛的小游戏的相关文章

html5面向对象做一个贪吃蛇小游戏

canvas加面向对象方式的贪吃蛇 2016-08-25 这个小游戏可以增加对面向对象的理解,可以加强js逻辑能力,总之认真自己敲一两遍收获还是不少啊!!适合刚学canvas的同学练习!! 废话不多说,直接来讲思路和代码. ----------------------------------------------------------------------------------------------------------------- 开发思路:首先要有蛇吃的食物,就是一个个canv

今天来做一个PHP电影小爬虫。

今天来做一个PHP电影小爬虫.我们来利用simple_html_dom的采集数据实例,这是一个PHP的库,上手很容易.simple_html_dom 可以很好的帮助我们利用php解析html文档.通过这个php封装类可以很方便的解析html文档,对其中的html元素进行操作 (PHP5+以上版本)下载地址:https://github.com/samacs/simple_html_dom下面我们以 http://www.paopaotv.com 上的列表页 http://paopaotv.com

使用Html5+JS做的贪吃蛇小游戏

学习了Html5的Canvas的使用,和JS创建对象,做了一个贪吃蛇小游戏,来巩固JS面向对象编程和Canvas的用法. Node.js 1 /** 2 * 格子类,组成贪吃蛇和舞台 3 */ 4 function Node(x,y){ 5 this.x=x; 6 this.y=y; 7 /** 8 * 比较两个格子是否重合 9 */ 10 this.equals=function(x,y){ 11 return this.x==x&&this.y==y; 12 } 13 } Snake.

【C语言探索之旅】 第一部分第八课:第一个C语言小游戏

? 内容简介 1.课程大纲 2.第一部分第八课:第一个C语言小游戏 3.第一部分第九课预告: 函数 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. C语言编程基础知识 什么是编程? 工欲善其事,必先利其器 你的第一个程序 变量的世界 运算那点事 条件表达式 循环语句 实战:第一个C语言小游戏 函数 练习题 习作:完善第一个C语言小游戏 C语言高级技术 模块化编程 进击的指针,C语言王牌 数组 字符串 预处理 创建你自己的变量类型 文

Cocos2d-X开发一个简单的小游戏

学了这么久Cocos2d-X,今天终于可以做出一个简单的小游戏了,游戏非常简单,通过菜单项控制精灵运动 在做游戏前,先学一个新概念 调度器(scheduler): Cocos2d-x调度器为游戏提供定时事件和定时调用服务.所有Node对象都知道如何调度和取消调度事件,使用调度器有几个好处: 每当Node不再可见或已从场景中移除时,调度器会停止. Cocos2d-x暂停时,调度器也会停止.当Cocos2d-x重新开始时,调度器也会自动继续启动. Cocos2d-x封装了一个供各种不同平台使用的调度

需求:有一个猜数字小游戏,请写一个程序实现在测试类中只能使用5次,超过5次提示:游戏试玩结束,请付费。

package cn.idcast4; import java.io.FileNotFoundException;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.Reader;import java.io.Writer;import java.util.Properties; /* * 需求:有一个猜数字小游戏,请写一个程序实现在测试类中只能使用5次, *

根据之前的博文,我把给同学做的三子棋小游戏的代码发出来,只是界面很丑很丑,AI算法很笨很笨,过几天我传到网盘上,提供大家下载娱乐

1 background_image_filename = 'blackground.png' 2 black_mouse_image_filename = 'black.png' 3 white_mouse_image_filename = 'white.png' 4 restart_icon_filename='restart.png' 5 pingju_icon_filename='pingju.jpg' 6 win_icon_filename='win.jpg' 7 lose_icon_

做一个自己的小Linux

实战操作自制一个小Linux 概述:通过前面的系统启动流程,我们大致知道了Linux系统启动时都需要哪些文件和步骤,知道了这些理论内容,现在我们可以自己动手制作一个自己的小Linux. 实践步骤: 1.在已有的Linux添加新的硬盘 2.对此新的硬盘进行分区,两个分区分别为/boot和/分区( 为自制的Linux下所准备的) 3.将刚刚的分区格式化并挂载至两个目录上(我这里为/mnt/boot和/mnt/sysroot) 4.在此新硬盘上安装grub并且编写grub配置文件 5.将vmlinuz

用python做一个简单的pong游戏

pong游戏就是一个用挡板去控制一个小球不触底的一个小游戏,上个世纪以电视游戏的方式发行,取得巨大的成功. 看了一点书,知道pygame是python里一个强大的模块,做出这个游戏的简易模式也不难. 主要思想:1.创建游戏界面,挡板,小球以及记分牌. 2.小球碰到游戏界面四个边界会反弹,即x方向和y方向上的速度会改变为负,碰到底边生命数会减1. 3.小球与挡板碰撞y方向速度会变负,同时分数加1. 4.游戏结束会显示相关文字. 代码如下: import pygame pygame.init() s