当前位置: 首页 > 文档资料 > HTML5 Canvas 实战 >

8.4 创建Level类

优质
小牛编辑
127浏览
2023-12-01

本节,我们将创建Level类,用来渲染关卡,并提供边界地图API。

操作步骤

按照以下步骤,创建Level类:

1. 定义Level构造函数:

 /* Level类应该对Actor或HealthBar类一无所知,
 * 以便它们之间是解耦的
 */
function Level(config){
  this.controller  = config.controller;
  this.x  = config.x;
  this.y  = config.y;
  this.leftBounds  = config.leftBounds;
  this.rightBounds  = config.rightBounds;
  this.boundsData  = null;
  this.GRAVITY  =  3;  // px  / second^2 
  this.MID_RGB_COMPONENT_VALUE  =  128; 
  this.LEVEL_WIDTH  =  6944;
  this.setBoundsData();
}

2. 定义setBoundsData()方法,该方法从边界地图中提取区域数据:

Level.prototype.setBoundsData  = function(){
  var controller  = this.controller;
  var canvas  = controller.view.canvas;
  var context  = controller.view.context;
  canvas.width  =  6944;
  context.drawImage(controller.images.levelBounds,  0,  0); 
  imageData  = context.getImageData(0,  0,  6944,  600);
  this.boundsData  = imageData.data;
  canvas.width  =  900;
};

3. 定义draw()方法,该方法绘制背景图像和关卡图像:

Level.prototype.draw  = function(){
  var context  = this.controller.view.context;
  context.drawImage(this.controller.images.background,  0,  0);
  context.drawImage(this.controller.images.level, this.x, this.y);
};

4. 定义getZoneInfo()方法,该方法返回边界地图上一个点的区域信息:

Level.prototype.getZoneInfo  = function(pos){
  var x  = pos.x;
  var y  = pos.y;
  var red = this.boundsData[((this.LEVEL_WIDTH  * y)  + x)  *  4];
  var green = this.boundsData[((this.LEVEL_WIDTH  * y)  + x)  *  4  + 1];
  var blue = this.boundsData[((this.LEVEL_WIDTH  * y)  + x)  *  4  + 2];
  var inBounds  = false;
  var levitating  = false;
  /*
  * COLOR KEY
  *
  * PINK:  255  0    255
  * CYAN:  0    255  255
  *
  * 颜色标记
  * PINK:玩家在界内,并可以跳跃
  * CYAN:玩家在界内,并悬在空中
  */
  var mid  = this.MID_RGB_COMPONENT_VALUE;
  if  ((red  > mid && green  < mid && blue  > mid) 
   ||  (red  < mid && green  > mid && blue  > mid))  {
    inBounds  = true;
  }
  if  (red  < mid && green  > mid && blue  > mid)  {
    levitating  = true;
  }
  return  {
    inBounds: inBounds,
    levitating: levitating
  };
};

工作原理

Level类的大多数繁重工作都是在setBoundsData()方法和getZoneInfo()方法中完成的。setBoundsData()方法接受边界地图图像,并使用画布上下文对象的getImageData()方法,把它转换为一个像素数据的数组。getZoneInfo()方法方法用来访问边界地图的一个点,并返回相应的区域信息。

对Canvas Hero游戏,区域信息对象包含两个标志:inBounds和levitating。如果边界地图对应的像素颜色是浅绿色,则该点对应的区域在界内,也在悬浮区。如果边界地图对应的像素颜色是洋红色,则该点对应的区域在界内,但不在悬浮区。最后,如果边界地图对应的像素是黑色,则意味着该点既不在界内,也不在悬浮区。

更多参考

  • 第3章 绘制图像
  • 第3章 获取图像数据