H5游戏开发之抓住小恐龙

  第一次写技术性博文,以前都只是写一些生活感想,记录一些生活发生的事情。

  博主大三学生一枚,目前学习JS一年多,还处于学习阶段,有什么说的不好的希望大牛指点下,由于第一次写博文,排版什么的有待改进,希望大家谅解。

  这是我学习H5 canvas以来写的第一个游戏,第一次接触H5游戏呢,是看了一位大哥码农终结者的博客(http://www.cnblogs.com/chaogex/)(基础要求有点高,等以后一定要研究透彻),正好实验室老师准备喊我写H5的游戏游戏,看了很多canvas的API和大神vajoy(http://www.cnblogs.com/vajoy/)写的canvas教程,打好canvas的基础以后又看了HTML5研究小组第二期技术讲座《手把手制作HTML5游戏》的视频,下了源代码学习了很长一段时间,那段时间一直反反复复的写这个游戏,慢慢领悟很多游戏的概念,然后就有种成竹在胸的感觉(别逗了,我还什么都不懂),当然这种成就感是非常重要的,动力来源于此。这就是我游戏开发到现在将近2个星期的学习经历,分享给大家,希望对大家有用。

        

游戏做出来是这个效果,玩过黑白钢琴的人应该知道,这和那个游戏差不多。

一。图片渲染

  写过游戏的人都知道大多数游戏都是以背景加精灵的方式开展的,这里渲染图片是经常要用的,本人自己封装了一个图片渲染的方法,希望大家给点意见。

  

/**
 * author yh
 * @param imgCount 图片数组 必须有id和src
 * @param callback 回调函数
 * @returns 每个精灵的canvas和context
 */
function getImg(imgCount,callback){
    var total = imgCount.length,
        load = 0,
        img = {},
        w = 0,
        h = 0;

    for(var i = 0;i < total;i++){
        var id = imgCount[i].id;
        var imgs = new Image();
        imgs.src = imgCount[i].src;

        //设置canvas的width和height
        if(imgCount[i].width && imgCount[i].height){
            w = imgCount[i].width;
            h = imgCount[i].height;
        }else{
            w = imgs.width;
            h = imgs.height;
        }

        img["cvs"+id] = document.createElement("canvas");
        img["cvs"+id].width = w;
        img["cvs"+id].height = h;
        img["ct"+id] = img["cvs"+id].getContext("2d");
        img["ct"+id].drawImage(imgs,0,0,imgs.width,imgs.height,0,0,w,h);

        //回收图片资源
        delete imgs;
        imgs = undefined;

        imgs.onload = function(){
            load++;
        };
    };

    if(typeof callback == "function"){
        var me = this;
        function check(){
            if(load >= total)
                callback.call(me,arguments);
            else
                setTimeout(check,300);
        }
        check();
    };
    return img;
}

因为考虑到性能的问题,所以每次加载一个图片都创建一个canvas来画这张图片,当然我们并不需要显示这个canvas,只为以后每次画图的时候可以直接用getImageData和putImageData方法来直接取canvas中的data就可以得到图片,而不用每次都去画图,等下会为大家展示画图的过程,这个方法的调用是这样的:

//callback为回调函数 var global = getImg([
    {id:"bg",src:"img/bg.png",width:400,height:600},
    {id:"di",src:"img/1.png",width:100,height:100},
    {id:"hand",src:"img/hand.png",width:100,height:100},
    {id:"pbg",src:"img/游戏框.png",width:100,height:100}
],callback);

定义一个变量来存取getImg的返回对象,下面是画图的方法:

/**
 * 根据id来获取global中的canvas和context,进行get和put ImageDa
 * target放所有canvas的对象,上面的global * context为目标画布的上下文
 * x y 为初始坐标
 * id 为精灵的id
 */
function draw(target,context,x,y,id){
    var canvas = target["cvs" + id],
        ct = target["ct" + id],
        data = ct.getImageData(0,0,canvas.width,canvas.height);

    context.putImageData(data,x,y);
}

这个方法封装得不是很好,因为很多时候呢我们都需要精灵的动画,就是要随时改变截取图片的x和y,这里封装的只是这个游戏中用到的方法,因为这个游戏中无精灵动画。

二。游戏类

  当图片渲染完以后呢我们需要定义一个game类,在这里写代码,为了提高性能,用的原型方法,这样每次加载JS文件的时候只加载一份,不浪费资源。

因为本人没有github(还没用过这么高端的东西),只能在这里贴代码了。

function Game(option){
    //对象扩展
    for(var attr in option)
        this[attr]  = option[attr];
}
Game.prototype = {
    canvas:null,
    ct:null,  //默认canvas的高和宽
    width:999,
    height:999,  //初始化位置
    x:0,
    y:0,
    n:4,
    m:6,  //定义帧
    FPS:30,
    sleep:0,  //定义数组存放每个手掌的位置
    arr:[],
    click:0,
    init : function(){
        this.canvas = document.createElement("canvas");
        this.canvas.width = this.width;
        this.canvas.height = this.height;
        document.body.appendChild(this.canvas);

        this.ct = this.canvas.getContext("2d");
        this.sleep = (1000/this.FPS)|0;
        this.time = Date.now();
        this.moused = false;
    },
    update:function(){
        this.initDraw();
        this.move();
    },   //初始化
    initDraw : function(){
        this.drawImg(global,this.ct,0,0,"bg");
        var y = 10;
        for(var i = 0;i<this.m;i++){
             var x = 15;
             var ran = ((Math.random()*4)|0);

            for(var j = 0;j<this.n;j++){
                this.drawImg(global,this.ct,x,y,"pbg");
                if(j == ran && i != this.m-1){            //每次画一个手掌在数组中存储他的位置
                    this.drawImg(global,this.ct,x+5,y+3,"hand");
                    this.arr.push(j);

                }else if(j == ran && i == this.m-1)
                    this.drawImg(global,this.ct,x+5,y+3,"di");

                x += 95;
            }
            y += 98;
        }
        this.listener(this.arr);
    },

    drawImg : function(target,context,x,y,id){
        var canvas = target["cvs" + id];
        var    ctx = target["ct" + id];
        var data = ctx.getImageData(0,0,canvas.width,canvas.height);

        context.putImageData(data,x,y);
    },

};

上面这些代码呢完成了初始化,我们先把每个效果实现以后再进行动画,下面我们会设置鼠标事件,还有主循环,这是个很重要的东西,一般一个游戏只有一个主循环。

 listener : function(arr){
        this.arr = arr;
        //获取边界
        var me = this,
            index = this.arr.pop();
        this.y = 402 + 50;
        this.x = 15+index*95 + 50;
        //添加鼠标事件,判断范围
        this.canvas.onmouseup = function(event){
            var cx = event.clientX - me.canvas.offsetLeft - me.x,
                cy = event.clientY - me.canvas.offsetTop - me.y;
            if(-50<=cx&& cx <= 50 && -50<= cy && cy<= 50){
                me.moused = true;
            }
        };
    },
    move : function(){
        var me = this;
        this.mainLoop = setInterval(function(){
            me.loop();
        },this.sleep);
    },
    loop : function(){
        var time = document.getElementById("time");
        Time = (Date.now() - this.time)/1000;
        time.innerHTML = Time;
        if(this.moused){
            this.moused = false;
            this.click++;
            this.reload();
        }
        if(Time >= 5){
            this.drawImg(global,this.ct,0,0,"over");
            clearInterval();
            alert("你一共走了"+this.click+"步");
        }
    },
    reload:function(){
        var data = this.ct.getImageData(0,0,this.width,this.height);
        this.ct.clearRect(0,0,this.width,this.height);
        this.reDraw();
        this.ct.putImageData(data,0,98);
    },
    reDraw:function(){
        this.drawImg(global,this.ct,0,0,"bg");
        var y = 10;
        this.j = 0;
        var x = 15;
        var ran = ((Math.random()*4)|0);

        for(var j = 0;j<this.n;j++){
            this.drawImg(global,this.ct,x,y,"pbg");
            if(j == ran){
                this.drawImg(global,this.ct,x+5,y+3,"hand");
                this.arr.unshift(j);
            }
            x += 95;
        }

        this.listener(this.arr);
    }

每次点击以后我们会得到一份当前context的getImageData,然后设置为putImageData(data,0,100),然后在第一行重新渲染一次,再把数组中的值更新,这样就可以看起来是个动画。比较水平有限,大牛看看就当玩玩,如果水平和我差不多的话可以学习下,以后我们也能成为大牛,也会分享更多更好的东西。

  最近呢还在研究司徒正美的《JS框架设计》,这本书给我第一感觉就是思想高度太高,第一次看就把我看郁闷了,看了第一章什么都没看懂,然后我又从头到尾依次把不懂得新概念百度了一遍,历经2天终于把第一章搞完,慢慢的越来越喜欢这本书,写了一个自己框架的种子模块,打算等自己的框架出来以后再去找工作,到时候应该会更轻松一些。

时间: 2024-10-14 10:45:32

H5游戏开发之抓住小恐龙的相关文章

最近这两天看了关于H5游戏开发的一个教程,实践很短暂,看了很多理论的东西,现在呢也只是想回忆回忆关于EUI的部分知识吧

首先我了解了什么是Egret: Egret中文就是白鹭的意思,Egret是一套H5游戏开发的软件.(纯粹属于个人理解) 其次我对以下几款软件的相关知识做了些了解: Egret Engine(引擎),Egret Wing(编辑器),Texture Merger(可将零散纹理拼合为整图,同时也可以解析SWF.GIF动画,导出可供Egret使用的配置文件),Egret Feather(是一款粒子效果编辑器)ResDepot(是针对资源配置文件的创建,编辑和管理工具)等.......ps:现在我只看了这

今天我看了一个H5游戏EUI的例子,我都快分不清我到底是在用什么语言编译了代码了,作为刚刚学习H5游戏开发的菜鸟只能默默的收集知识

今天看了一个EUI的demo,也是接触H5游戏开发的第五天了,我想看看我能不能做点什么出来,哎,自己写果然还是有问题的.在看EUI哪一个demo的时候就遇见了一些摇摆不定的问题,我觉得提出来 1.toast 当时看见它的时候我不确定是不是我以为的那样,所以就百度了一下,果然它就是我印象中android里面的一种显示信息的机制.(ps:真的是一门汇聚大千语言的技术啊)toast是没有焦点的而且toast显示的时间有限,过一会儿就会自动消失.toast主要用于向用户显示提示消息.项目中它用了一个To

关于微信网页/H5游戏开发中二维码无法识别的解决方法

我接触微信H5开发已经有一年多了,做过很多案例也遇到很多的问题.今天我把困扰我半年之久的问题分享出来,也就是关于微信网页/H5游戏开发中二维码无法识别的解决方法. 我在百度搜索了许久,关于微信H5网页/游戏开发问题以及解决方案的相关文章少之又少,在相关前端交流群中问别人,一问三不知,平时这些群就会上班吹牛逼,真正交流问题的人少又少,真是揪心啊,最后还是得靠自己解决了. [这里,我先举个栗子] 上面这个页面,相信从事微信H5开发的人应该很熟悉,就是常见的分享到朋友圈的页面,通常以[引导分享图标]+

DirectX游戏开发——从一个小游戏开始

本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/26364129 写在前面:自己对DirectX挺感兴趣的,加上自己目前在研究3D重建方面的东西,所以利用课余时间学习一下.看了一段时间的书,感觉还是靠动手编写一些小例子来学习,进步的更快体会的更深.所以从我自己写的一个小游戏开始吧,把自己学习心得和自己的一些想法写下来.更是欢迎有兴趣的童鞋来和我交流. 首先:先把我的小例子分享

H5游戏开发技术的发展进程

首先,手机上最常用的两个浏览器Android Chrome和iOS Safari默认支持WebGL.随着这一飞跃式地发展,PC浏览器和手机都支持硬件图形加速,而这是Web成为可行性游戏平台的必要条件.同时,这也使Flash.Silverlight,JavaFX等技术变得落伍. 其次,经过15年的发展,H5标准最终确定.这开启了 "稳步爬升恢复期".这是目前我们所处的H5阶段,也是web游戏真正爆发的前奏阶段.不过,技术的创新和发展并不止于此.自从H5标准确定以来,发生了很多新事物.尤其

H5游戏开发的那些坑(一) 客户端

[客户端] 1.关于游戏引擎 在15年3月开始准备做h5游戏的时候,首先遇到的问题就是引擎选型的问题. 当时市面上的2d引擎主要有3个:白鹭egret,layabox和cocos2d-js. 一方面,是因为我以前用cocos2d-x(c++)做了一年多的手游客户端,所以,很自然就选择了cocos2d-js.另一方面,是因为当时市面上其他两个引擎的成功项目还不多. cocos引擎的每一次版本更新,我们都会第一时间在我们的游戏里面进行测试. 如果发现游戏在android手机上的性能有明显提升,我们就

H5游戏开发之多边形碰撞检测

2D多边形碰撞检测介绍这是一篇论证如何在2D动作游戏中执行碰撞检测的文章(Mario,宇宙入侵者等),为了保证它的高效性和精确性,碰撞检测是以多边形为基础的,而不是以sprite为基础.这是两种不同的设计途径.基于sprite的检测执行的是检测sprites的像素的交叉,以这种方式来检测碰撞.多边形是使用向量数学来精确的计算点,时间和碰撞的方向.当多边形只是一种近似sprite自身的时候,它就超越了sprite系统.表现出了更精确的物理现象,例如弹性,摩擦,在一个随机的形状中来处理斜坡.碰撞检测

Cocos2d-js 贪吃蛇实战项目,H5游戏开发

Cocos2d-js 贪吃蛇实战项目 课程简介: 本课程主要用Cocos2d-js实现了贪吃蛇实战项目,主要介绍了环境搭建和项目的创建,引擎架构的分析,入口类,场景的切换,屏幕触摸,Node与Schedule计划任务,通过贪食蛇游戏案例来对所有的知识进行贯穿和应用,对游戏原型的设计,实现UI流程,对节点进行封装.游戏逻辑和游戏触摸的实现,在游戏中添加音乐和音效,从Mac平台打包发布到web.从中你会学到如何实现屏幕绘图.事件处理.集合使用.场景跳转.节点封装等技术. 课程大纲: 本课程一共7讲,

H5游戏开发之多边形碰撞检测(JAVA代码)

转载至:http://www.cnblogs.com/Kurodo/archive/2012/08/08/2628688.html 对于矩形碰撞,很多人都知道.但面对多边形图形,大多数采用多矩形覆盖的方式. 但是我不是很喜欢这种方式,我所采用的是利用一个经典算法: SAT 一种可以快速检测不规则的凸多边形是否碰撞的算法 给出两个凸多边形体,如果我们能找到一个轴线,使两物体在此轴线上的投影不重叠,则这两个物体之间没有发生碰撞,这个轴线叫做Separating Axis(红色轴线). 对于2D来说,