by addy 原创文章,欢迎转载,但希望全文转载,注明本文地址。

本文地址:https://www.iamaddy.net/2018/03/xiaoyouxi/

下图是Laya官方的一张介绍图片,游戏引擎涵盖的东西比较多,掌握游戏开发必须要掌握这些东西,这次讲讲一些游戏中的基本概念。

一、游戏引擎

市面上的H5游戏引擎好多,国内外比较知名的有Egret、Cocos、Laya、Phaser、Three.js等等,各引擎实现上有区别,但游戏里面的一些基本概念都差不多。触类旁通,切换引擎的成本就只在于对引擎API的熟悉。

二、基本概念

1、舞台

舞台是显示游戏元素的平台,在游戏视觉编程里,一切游戏的元素必须添加到舞台才能被显示。因此,舞台也是放置显示对象的最终容器。

舞台也是一种可以显示的对象,从编程的角度讲,任何对象都具有属性和行为。如舞台对象具有宽、高、帧频等属性,具有添加显示对象的方法。
有的引擎还会有场景的概念,也是一种显示容器,是一种抽象的封装。场景本身会提供场景切换的逻辑和特效,当然如果引擎没有场景模块,自己实现一个也不难。

2、精灵 Sprite

Sprite 是2D 游戏中最常见的显示图像的方式。可以有宽高,也可以接受鼠标事件,支持旋转,缩放,位移等操作。Sprite同时也是容器类,可用来添加多个子节点。Sprite可以层层嵌套,最后被添加的节点被显示在最上层。以Laya引擎为例子

var sp = new Laya.Sprite();
sp.graphics.drawRect(0, 0, 100, 100, 'red');

var sp1 = new Laya.Sprite();
sp1.graphics.drawRect(0, 0, 150, 150, 'blue');

var sp2 = new Laya.Sprite();
sp2.graphics.drawRect(0, 0, 200, 200, 'green');

Laya.stage.addChild(sp2);
Laya.stage.addChild(sp1);
Laya.stage.addChild(sp);

如下图。越是后面添加的精灵,展示的越靠前。

3、层级

最后被添加的精灵总是被显示在最上面,精灵可以被隐藏或者移除。
zOrder可以调整精灵的顺序,会按照值的大小对同一容器的所有对象重新排序。

4、文本Text

Text类用于创建显示对象以显示文本。文字是游戏元素中常见的一部分,开发者可以自定义字体,如果运行时系统找不到设定字体,则用系统默认字体渲染文字。

var label1 = new Laya.Text();
label1.text = 'hello game';
label1.fontBold = true;
label1.fontSize = 18;
label1.color = '#f8fdff';
label1.x = (config.GameWidth - label1.width) / 2;
label1.y = 220;
this.addChild(label1);

添加一段文本,可以设置文本颜色、大小、位置、透明度等属性。

5、Graphics

Graphics用于创建绘图显示对象,通过 graphics 可以绘制图片或者矢量图,对原生绘制接口的一次封装。

绘制圆、线条、曲线、矩形、图片等等功能。

graphics.drawCircle(
  0,
  0,
  circle.radius,
  'rgba(255,255,255,0)',
  circle.color,
  circle.border
);

6、坐标系

众所周知,我们可以把游戏世界看成是现实的一个映射,那么就需要坐标来管理游戏世界中物体的位置。
Laya中2D坐标系是以左上角的屏幕第一点为坐标原点(0, 0)。横轴是x轴,往右是正方向。纵轴是y方向,往下是正方向。

但不同引擎的坐标实现可能不一样,像cocos正好和Laya相反,所以如果你将一个cocos编写的游戏用Laya再写一次会有些不方便。

7、相对坐标

与上面的世界坐标系对应。相对坐标指的是,容器的子元素总是相对于父容器的起始点(0, 0)来计算,并不是屏幕的原点。和缩放、旋转、位移等操作强相关。

var parent = new Laya.Sprite();
parent.x = 100;
parent.y = 100;
var child = new Laya.Sprite();
parent.addChild(child);
child.x = 100;
child.y = 100;

child精灵的世界坐标就是200,200,这样的好处是如果一旦元素发生位置、形状的变化,他们将作为一个整体变化。假如设计师说要将parent挪动10像素,那么就不用将child的位置也设置一遍,因此设计的时候将相关性强的精灵组合在一起。

8、帧

游戏最重要的是动画,这是游戏的灵魂。动画中不得不提的一个概念就是帧。
帧——影像动画中最小单位的单幅影像画面,相当于电影胶片上的每一格镜头。 一帧就是一副静止的画面,连续的帧就形成动画。

我们通常说帧数,就是图形处理器每秒钟能够处理图片的帧数,通常用fps(Frames Per Second)表示。fps越大则越流畅,所以当游戏画面出现卡顿时,我们就有必要关注fps。

window.requestAnimFrame = (function(){
  return window.requestAnimationFrame || 
     window.webkitRequestAnimationFrame || 
     window.mozRequestAnimationFrame || 
     window.oRequestAnimationFrame || 
     window.msRequestAnimationFrame || 
     function( callback ){
       window.setTimeout(callback, 1000 / 60);
     };
})();

function repeat() {
  // draw
  requestAnimationFrame(repeat);
}

requestAnimationFrame(repeat);

requestAnimationFrame会充分利用显示器的刷新机制,显示器有固定的刷新频率(60Hz或75Hz),每秒能重绘60次或75次,这样可以到达高fps的要求,游戏会很流畅。引擎做了更加好的封装,方便开发者灵活控制帧率。

Laya.timer.frameLoop(1, this, this.animation);
animation() {
    this.x += 1;
}

上面代码能让精灵沿着X轴运动起来。除了位置动画,还可以改变精灵的图片、颜色。如果提供一组精灵的动画图如下,循环改变单个精灵的图片,看起来鸟就在飞。

9、动画

帧是动画的核心概念,游戏引擎会封装一些动画类,简化开发的复杂度。

9.1、Animation类

绘制IDE制作好的动画资源。

var ani = new Animation();
ani.loadAtlas(AniConfPath); // 加载图集动画
ani.interval = 30; // 设置播放间隔(单位:毫秒)
ani.index = 1; // 当前播放索引
ani.play(); // 播放图集动画
9.2、Tween缓动

使用此类能够实现对目标对象属性的渐变,这里不做过多介绍。

Tween.to(sp,
{
   x: 1000
}, 1000);
9.3、骨骼动画

顾名思义,就是模拟骨骼运动的机制而制作的动画,走、跑、跳是由骨骼带动躯干和四肢完成的。

骨骼动画设计软件
​dragonbones.github.io

引擎绘制骨骼动画有专门的接口

var mAniPath = "res/spine/spineRes1/dragon.sk";
var mFactory = new Templet();
mFactory.loadAni(mAniPath);

结语

这篇文章主要讲游戏中的绘制,下期在介绍其他的,附上一个DEMO,绘制一个游戏动画背景。
上传图片有点麻烦,详细图文版本,请查阅知乎

本文为原创文章,可能会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,谢谢合作

本文地址:https://www.iamaddy.net/2018/03/xiaoyouxi/

个人知乎,欢迎关注:https://www.zhihu.com/people/iamaddy

欢迎关注公众号【入门游戏开发】 入门游戏开发