使用JavaScript和Canvas开发游戏(四)

标签: Web开发 编程技术 翻译 | 发表时间:2011-08-15 19:56 | 作者:为之漫笔 weslleywang
出处:http://www.cn-cuckoo.com

原文作者:Matthew Casperson • 编辑:Michele McDonough
原文链接: Game Development with JavaScript and the Canvas element

1、认识一下Canvas
2、在Canvas上绘图
3、通过Canvas元素实现高级图像操作
4、写一个游戏框架(一)
5、写一个游戏框架(二)
6、通过Canvas实现视差滚动
7、动画
8、JavaScript键盘输入
9、综合运用
10、定义级别
11、跳跃与坠落
12、添加道具
13、加载资源
14、添加主菜单

4、写一个游戏框架(二)

在这篇文章里,我们继续介绍构成这个基本JavaScript游戏框架的其他必要的类。

前一篇文章介绍了GameObjectManager类,该类负责画布的渲染并允许GameObject类更新和删除它们自己。下面就来看一看GameObject类。

GameObject.js


/**
    游戏中出现的所有元素的基类
    @class
*/
function GameObject()
{
    /** 显示的深度次序。较小的zOrder值表示先渲染,因而会在背景中。
        @type Number
    */
    this.zOrder = 0;
    /**
        x轴的坐标
        @type Number
    */
    this.x = 0;
    /**
        y轴的坐标
        @type Number
    */
    this.y = 0;

    /**
        初始化游戏对象,并将其添加到GameObjectManager维护的对象列表中
        @param x        x轴的坐标
        @param y        y轴的坐标
        @param z        元素的z次序(背景元素的z值较小)
    */
    this.startupGameObject = function(/**Number*/ x, /**Number*/ y, /**Number*/ z)
    {
        this.zOrder = z;
        this.x = x;
        this.y = y;
        g_GameObjectManager.addGameObject(this);
        return this;
    }

    /**
        清理当前对象,将其从GameObjectManager维护的对象列表中删除
    */
    this.shutdownGameObject = function()
    {
        g_GameObjectManager.removeGameObject(this);
    }
}

这个GameObject类(是一个引擎类)的目的,是为游戏中将会出现的所有对象定义一些共有的属性,包括它们的位置(x和y)和深度(z)。需要注意的是,我们不会直接创建GameObject类的实例,而是会再创建一个类来扩展它。

这个类的x和y坐标值没有什么好说的——就是相应对象左上角位置在画布上的坐标。关键是GameObject中的z值,这个值定义的是对象的深度。理解这个值很重要,这个值较小的GameObject会先绘制到画布上。换句话说,z值较大的GameObject将被绘制到z值较小的GameObject上面。

上一篇文章里介绍过,所有类都是通过一个类似startupClassName的函数完成自身初始化的。因此,GameObject类就有一个名为startupGameObject的函数。在这个函数里,除了初始化所有变量外,还会通过addGameObject函数把当前的GameObject添加到由GameObjectManager维护的GameObject列表中。


    /**
        初始化游戏对象,并将其添加到GameObjectManager维护的对象列表中
        @param x        x轴的坐标
        @param y        y轴的坐标
        @param z        元素的z次序(背景元素的z值较小)
    */
    this.startupGameObject = function(/**Number*/ x, /**Number*/ y, /**Number*/ z)
    {
        this.zOrder = z;
        this.x = x;
        this.y = y;
        g_GameObjectManager.addGameObject(this);
        return this;
    }

函数shutdownGameObject用于清除GameObject。这里所谓的清除,是指GameObject通过removeGameObject函数将自身从GameObjectManager中删除。


    /**
        清理当前对象,将其从GameObjectManager维护的对象列表中删除
    */
    this.shutdownGameObject = function()
    {
        g_GameObjectManager.removeGameObject(this);
    }

VisualGameObject.js


/**
    出现在游戏中的所有元素的基类
    @class
*/
function VisualGameObject()
{
    /**
        由当前对象显示的图像
        @type Image
    */
    this.image = null;

    /**
        将当前元素绘制到后台缓冲
        @param dt 自上一帧绘制起经过的秒数
    */
    this.draw = function(/**Number*/ dt, /**CanvasRenderingContext2D*/ context, /**Number*/ xScroll, /**Number*/ yScroll)
    {
        context.drawImage(this.image, this.x - xScroll, this.y - yScroll);
    }

    /**
        初始化当前对象
        @param image 要显示的图像
    */
    this.startupVisualGameObject = function(/**Image*/ image, /**Number*/ x, /**Number*/ y, /**Number*/ z)
    {
        this.startupGameObject(x, y, z);
        this.image = image;
        return this;
    }

    /**
        清理当前对象
    */
    this.shutdownVisualGameObject = function()
    {
        this.shutdownGameObject();
    }
}
VisualGameObject.prototype = new GameObject;

VisualGameObject也是一个引擎类,它扩展了GameObject类,为将在屏幕上绘制的对象定义了更具体的属性和函数。顾名思义,可见对象显然是需要绘制的对象,因此VisualGameObject定义了一个image属性,当把当前对象绘制到后台缓冲时,将以这个属性作为图形的来源。


    /**
        由当前对象显示的图像
        @type Image
    */
    this.image = null;

此外,还需要写几行代码,以便把这个对象实际地绘制到后台缓冲——这就是draw函数了,它接受图像并基于GameObject类中定义的x和y值将其复制到后台缓冲。


    /**
        将当前元素绘制到后台缓冲
        @param dt 自上一帧绘制起经过的秒数
    */
    this.draw = function(/**Number*/ dt, /**CanvasRenderingContext2D*/ context, /**Number*/ xScroll, /**Number*/ yScroll)
    {
        context.drawImage(this.image, this.x - xScroll, this.y - yScroll);
    }

ApplicationManager.js


/**
    ApplicationManager用于管理应用
    @class
*/
function ApplicationManager()
{
    /**
        初始化对象
        @return 对初始化对象的引用
    */
    this.startupApplicationManager = function()
    {
        this.bounce = new Bounce().startupBounce(g_image);
        return this;
    }
}

ApplicationManager是第一个应用类,之所以将其归为应用类,是因为它用来定义应用的运行方式,而不是定义与浏览器的底层交互。这个类非常简单,只用来创建并初始化Bounce类的一个新实例。表面上看,创建一个类仅仅是为了创建一个对象有点多此一举。但在更复杂的应用中,把创建和管理游戏对象的逻辑放到一起是很有必要的。

Bounce.js


/**
    测试类,用于演示VisualGameObject类的用法
    @class
*/
function Bounce()
{
	/** x轴的运动方向
        @type Number
    */
	this.xDirection = 1;
	/** y轴的运动方向
        @type Number
    */
	this.yDirection = 1;
	/** 运动速度
        @type Number
    */
	this.speed = 10;

	/**
        初始化对象
        @return 对初始化对象的引用
    */
	this.startupBounce = function(image)
	{
		this.startupVisualGameObject(image, 0, 0, 0);
		return this;
	}

	/**
       更新对象
        @param dt 自上一帧绘制起经过的秒数
        @param context 绘制上下文
        @param xScroll x轴的全局滚动值
        @param yScroll y轴的全局滚动值
    */
	this.update = function (/**Number*/ dt, /**CanvasRenderingContext2D*/context, /**Number*/ xScroll, /**Number*/ yScroll)
	{
		this.x += dt * this.speed * this.xDirection;
		this.y += dt * this.speed * this.yDirection;

		if (this.x >= 450)
		{
			this.x = 450;
			this.xDirection = -1;
		}
		else if (this.x <= 0)
		{
			this.x = 0;
			this.xDirection = 1;
		}

		if (this.y >= 250)
		{
			this.y = 250;
			this.yDirection = -1;
		}
		else if (this.y <= 0)
		{
			this.y = 0;
			this.yDirection = 1;
		}
	}
}
Bounce.prototype = new VisualGameObject;

Bounce是第二个应用类,它扩展了VisualGameObject类,并将把自己绘制到屏幕上。Bounce类会显示一幅在屏幕上反弹的图像,效果非常类似第一篇文章中举的例子。这个类是在前面所有类的基础上实现最终动画的关键。

startupBounce函数接受一幅图像,通过调用startupVisualGameObject来初始化这个基本的类。


	/**
        初始化对象
        @return 对初始化对象的引用
    */
	this.startupBounce = function(image)
	{
		this.startupVisualGameObject(image, 0, 0, 0);
		return this;
	}

而update函数(将被GameObjectManager在渲染期间调用)会更新图像的位置,在图像到达画布边缘时反转方向。


	/**
       更新对象
        @param dt 自上一帧绘制起经过的秒数
        @param context 绘制上下文
        @param xScroll x轴的全局滚动值
        @param yScroll y轴的全局滚动值
    */
	this.update = function (/**Number*/ dt, /**CanvasRenderingContext2D*/context, /**Number*/ xScroll, /**Number*/ yScroll)
	{
		this.x += dt * this.speed * this.xDirection;
		this.y += dt * this.speed * this.yDirection;

		if (this.x >= 450)
		{
			this.x = 450;
			this.xDirection = -1;
		}
		else if (this.x <= 0)
		{
			this.x = 0;
			this.xDirection = 1;
		}

		if (this.y >= 250)
		{
			this.y = 250;
			this.yDirection = -1;
		}
		else if (this.y <= 0)
		{
			this.y = 0;
			this.yDirection = 1;
		}
	}
}

就这些了。你可能会想,怎么没有与绘制这个对象有关的代码呢?相应的代码都在VisualGameObject类的draw函数中了。而且,由于VisualGameObject类扩展了GameObject类,所以我们知道每渲染一帧都会调用一次update和draw函数。Bounce类中的所有代码只跟让图像反弹有关,也就是修改变量x和y。

好啦,我们已经创建了一批类,基于这些类也实现了与第一个示例相同的效果。而有了这个框架,再创建游戏就不必因为绘制画布等底层逻辑以及管理游戏对象等问题而重复编码了。

看看示例Demo吧。http://webdemos.sourceforge.net/jsplatformer3/jsplatformer3.html

为之漫笔 最后编辑于:
2011/08/15 @ 22:25

相关 [javascript canvas 开发] 推荐:

使用JavaScript和Canvas开发游戏(一)

- iVane - 为之漫笔
原文作者:Matthew Casperson • 编辑:Michele McDonough. 原文链接: Game Development with JavaScript and the Canvas element. 3、通过Canvas元素实现高级图像操作. 4、通过Canvas实现视差滚动. 8、JavaScript键盘输入.

使用JavaScript和Canvas开发游戏(三)

- weslleywang - 为之漫笔
原文作者:Matthew Casperson • 编辑:Michele McDonough. 原文链接: Game Development with JavaScript and the Canvas element. 3、通过Canvas元素实现高级图像操作. 6、通过Canvas实现视差滚动. 8、JavaScript键盘输入.

使用JavaScript和Canvas开发游戏(四)

- weslleywang - 为之漫笔
原文作者:Matthew Casperson • 编辑:Michele McDonough. 原文链接: Game Development with JavaScript and the Canvas element. 3、通过Canvas元素实现高级图像操作. 6、通过Canvas实现视差滚动. 8、JavaScript键盘输入.

使用JavaScript和Canvas开发游戏(一)

- Alex - HTML5研究小组
原文作者:Matthew Casperson • 编辑:Michele McDonough. 原文链接: http://www.brighthub.com/internet/web-development/articles/38364.aspx. 3、基于Canvas的高级图像操作. 4、通过Canvas实现视差滚动.

Fabric.js – 简单而强大的 JavaScript Canvas 库

- - 博客园_梦想天空
  Fabric.js 是一个简单而强大的 JavaScript Canvas 库,在 HTML5 Canvas 元素之上提供了互动的对象模型,同时还包含 Canvas-to-SVG 解析器. 使用 Toolbar.js 实现超酷的 Tooltip 风格工具栏. Textillate.js – 实现 CSS3 文本动画的简单插件.

用JavaScript将Canvas内容转化成图片的方法

- - WebHek
上周我们花了半天时间开发下一个准备放进Mozilla Marketplace的应用. 有一个应用现在非常的火热,那就是Instagram,Facebook花了100万美元收购了它. 我们也想有100万美元装到口袋里,我决定开发一个Instagram风格的应用,这篇文章了我将介绍一下如何将一张图片拷贝到canvas里,以及反过来,如何将画布内容保存成图片格式.

HTML5 Canvas开发框架:CasualJS Framework

- Jimmy - ITeye论坛最新讨论
CasualJS Framework是根据ActionScript3?.0的架构开发的一套适用于HTML5 Canvas的面向对象的开发框架. 虽然Canvas提供了强大的绘图功能,但满足不了高级开发的需要. 利用CasualJS的显示对象架构及渲染机制,你可以轻松的在Canvas中操控各种位图、图形、影片剪辑等显示对象.

JavaScript开发规范要求

- - 博客 - 伯乐在线
来源: webflash 的博客. 作为一名开发人员(WEB前端JavaScript开发),不规范的开发不仅使日后代码维护变的困难,同时也不利于团队的合作,通常还会带来代码安全以及执行效率上的问题. 本人在开发工作中就曾与不按规范来开发的同事合作过,与他合作就不能用“愉快”来形容了. 现在本人撰写此文的目的除了与大家分享一点点经验外,更多的是希望对未来的合作伙伴能够起到一定的借鉴作用.

html5 canvas入门

- - Marshal's Blog
可以把canvas看做div,不过,它的长和宽不能通过css来定义,要使用标签属性:. 或者javascript对象属性设置:. 使用canvas,只有一种操作方式,使用javascript. 获得canvas对象的上下文对象,该对象是操作canvas的主要对象:. 使用canvas画最简单的线, 点击运行示例,结果看起来是这样:.

手机网站开发及手机中图片加速显示img的Canvas方法

- - CSDN博客Web前端推荐文章
    随着手机开发越来越流行,手机开发的很多框架也应运而生,比较好用的手机网站开发框架推荐如下:.     1、zeptojs,里面封装了很多手机特有方法,例如touch.js等等. 和jquery用法差不多,很好上手. API地址:http://zeptojs.com/#$.extend.     2、jquerymobile   演示地址:http://jquerymobile.com/.