2d游戏制作原理

来源:互联网 发布:ubuntu安装tomcat8 编辑:程序博客网 时间:2024/05/15 18:50

本篇文章我们将探讨一下Unity3D中如何来制作2D游戏。目前市面上已经有非常成熟的2D游戏引擎,比如cocos2d cocos2d-x等,并且都是免费的开发者可以直接用来制作2D游戏。然而使用3D引擎来制作2D游戏会让游戏画面更加附有立体感,因为2D游戏中Z轴永远是0,而3D游戏中Z轴是可变化的。

        接着说说在Unity3D中制作2D游戏的原理。在Unity3D中绘制贴图的方式大致可分为两种,第一种是在GUI中绘制贴图,

第二种是在网格面上绘制贴图。

先说说第一种,GUI主要用来制作简单的游戏2D界面,比如游戏主界面中绘制的游戏名称开始游戏保存游戏退出游戏一些按钮或界面中一切其它的高级控件,文本框,输入框等等、GUI只能制作简单的图形化界面,因为它的渲染效率非常低,它与3D世界中网格模型的渲染机制完全不一样。

第二种的属于将图片绘制在3D中网格平面中,它的渲染效率远远高于GUI中,在制作2D游戏时都是将所有贴图绘制在平面模型对象之上,最后用摄像机以90度垂直的角度照射这这些平面。

  下面我们开始学习在Unity3D中制作2D游戏的原理。2D游戏又可以分为两种,区别是物体碰撞时带物理引擎或不带物理引擎。带物理引擎就好比《奋斗的小鸟》一样,大家应该都玩过,小鸟发射后下落击落其它物体将发生物理的碰撞。(我没有细看这款游戏,但是我知道2D 3D引擎都都可制作),不带物理引擎的就好比《捕鱼达人》这种游戏,游戏中碰撞都是由代码自己来完成的,经典的2D碰撞监测包括:矩形与矩形的碰撞、点与矩形的碰撞、圆与圆的碰撞等。今天这篇文章我们主要讨论第二种不带物理引擎的2D游戏。

如下图所示,我们盘点一下2D游戏中必备的几个元素。

摄像机:无论是3D游戏还是2D游戏摄像机都是非常重要的属性,移动摄像机即可更改屏幕中显示的内容,游戏地图的坐标永远都不会发生改变。

地图:2D游戏中的地图一般是由tile拼接而成,它可由地图编辑器生成然后将每一块tile绘制在整个贴图中,最后将贴图贴在平面网格面之上即可。还有一种作法是将两个或两个以上屏幕大小平面以队列的形式排在屏幕后面,当摄像机移动超出第一块面显示范围时,将它的坐标移动在第二块面后面,此时地图就形成了一个排序的队列。为了让地图的效果更加完美,一般地图可以由好几层来组成,比如背景层、与主角的遮挡曾、物理层等等。

地图拼接:地图的排序队列中两张图应当是可以无缝拼接,这个应当是由美术来提供资源,这里我就不那么细致了将远离说明白即可。

主角:它的范围就比较广的,敌人、物品等等出现在地图之上的都可以使用它。如果控制主角移动,摄像机移动的同时主角也当跟随移动,并且保持屏幕中的移动比例,除非摄像机无法移动,这时将直接移动主角在屏幕中的坐标。 说的有点绕了呵呵,大家仔细想想哈哈。。

然而上面的一切面是由Plane面来完成。

Unity层次视图中选择摄像机对象,右侧监测面板视图中我们看看摄像机组件的一些属性,如下图所示。需要注意的就是Projection 投影类型。

          首先我们应当修改摄像机的属性,默认摄像机投影的类型是Perspective,它保持摄像机以扩散的的形式照射着不利于2D平面的展示。这里我们应当选择Orthographic,这样摄像机将直直的照射在显示的区域。

从侧面观察摄像机,通过这两张图我相信大家应当能看懂为什么2D游戏要用Orthographic了吧,摄像机的投影类型是可以在代码中动态的修改的。

1

//得到游戏中摄像机对象

2

Camera camera = Camera.mainCamera;

3

//设置摄像机投影类型OrthoGraphic

4

camera.isOrthoGraphic = true;

5

//设置摄像机投影类型Perspective

6

camera.isOrthoGraphic = false;

          在代码中取得摄像机投影的区域大小,它也可以动态的修改,这样就可是实现摄像机拉近与拉远的效果。根据投影区域的大小配合着整个地图的宽高来写判断条件,避免移动摄像机时超过地图的范围

1

Camera camera = Camera.mainCamera;

2

Debug.Log(camera.orthographicSize);

   接着我们使用代码来得到地图面的宽高,这段代码写的就比较精细,因为网格面是可以缩放的,首先得到网格面的宽与高,然后分别乘以缩放系数就可以得到真实面的宽与高,然而Unity中的坐标是以为单位。下面代码中用到了中文,如果要想在编辑器中显示中文C#语言需要修改编码格式为UTF-16JavaScript修改编码格式UTF-8UTF-16即可。

01

using UnityEngine;

02

using System.Collections;

03

 

04

public class Test : MonoBehaviour

05

{

06

 

07

    void Start ()

08

    {

09

 

10

        GameObject plane = GameObject.Find("Plane0");

11

        //得到面默认宽度

12

        float size_x = plane.GetComponent<MeshFilter>().mesh.bounds.size.x;

13

        //得到面宽度的缩放比例

14

        float scal_x = plane.transform.localScale.x;

15

        //得到面默认高度

16

        float size_z = plane.GetComponent<MeshFilter>().mesh.bounds.size.z;

17

        //得到面高度缩放比例

18

        float scal_z = plane.transform.localScale.z;

19

 

20

        //原始宽度乘以缩放比例计算出真实宽度

21

        float mapWidth = size_x * scal_x;

22

        float mapHeight = size_z * scal_z;

23

 

24

        Debug.Log("得到面的位置:"+plane.transform.position);

25

        Debug.Log("得到面的宽度:"+ mapWidth);

26

        Debug.Log("得到面的高度:"+ mapHeight);

27

    }

28

 

29

}

有了摄像机照射的区域以及背景地图的宽高尺寸那么就可以在代码中编写逻辑判断条件啦。下面我们来使用简单的代码控制摄像机移动以及主角移动。

01

using UnityEngine;

02

using System.Collections;

03

 

04

public class Controller : MonoBehaviour

05

{

06

 

07

    //动画数组

08

    private Object[] anim;

09

    //主角对象

10

    private GameObject hero;

11

    //限制一秒多少帧

12

    private float fps = 10;

13

    //帧序列

14

    private int nowFram;

15

    //记录当前时间

16

    private float time;

17

 

18

    void Start ()

19

    {

20

         //得到资源名称为down文件夹中的所有对象资源

21

         anim = Resources.LoadAll("down");

22

         //得到主角的对象

23

         hero = GameObject.Find("hero");

24

    }

25

 

26

    void FixedUpdate ()

27

    {

28

        //上、下、左、右平移摄像机

29

        if (Input.GetKey (KeyCode.A))

30

        {

31

            transform.Translate(-0.01f,0,0); 

32

 

33

        }

34

 

35

        if(Input.GetKey (KeyCode.D))

36

        {

37

            transform.Translate(0.01f,0,0);

38

        }

39

 

40

        if (Input.GetKey (KeyCode.W))

41

        {

42

            transform.Translate(0,0.01f,0);

43

        }

44

 

45

        if(Input.GetKey (KeyCode.S))

46

        {

47

            transform.Translate(0,-0.01f,0);

48

        }

49

 

50

        //上、下、左、右平移主角

51

        if (Input.GetKey (KeyCode.J))

52

        {

53

 

54

            hero.transform.Translate(0.001f,0,0);

55

        }

56

 

57

        if(Input.GetKey (KeyCode.L))

58

        {

59

 

60

            hero.transform.Translate(-0.001f,0,0);

61

        }

62

 

63

        if (Input.GetKey (KeyCode.I))

64

        {

65

            hero.transform.Translate(0,0,-0.001f);

66

        } 

67

 

68

        if(Input.GetKey (KeyCode.K))

69

        {

70

            hero.transform.Translate(0,0,0.001f);

71

        }

72

 

73

        DrawAnimation(anim);

74

    }

75

 

76

    void  DrawAnimation(Object[] tex)

77

    {

78

 

79

        //计算限制帧的时间

80

        time += Time.deltaTime;

81

        //超过限制帧切换贴图

82

         if(time >= 1.0 / fps){

83

             //帧序列切换

84

             nowFram++;

85

             //限制帧清空

86

             time = 0;

87

            //超过帧动画总数从第0帧开始

88

             if(nowFram >= tex.Length)

89

             {

90

                nowFram = 0;

91

             }

92

        }

93

        //将对应的贴图赋予主角对象,强制将资源文件转换成贴图

94

        hero.renderer.material.mainTexture = (Texture)tex[nowFram];

95

    }

96

}

 代码中我们使用 Resources.LoadAll(“down”);来加载主角动画资源,这里将主角一组4帧的行走动画放在项目资源视图中 Resources文件夹中的down文件夹内。值得注意的是,使用Resources来加载资源就必须将资源放在Resources文件夹中,否则提示无法找到喔。在书中我以将人物四宫格行走动画加入在其中,因为这里只是一个是示例,所以我只加载了向下行走的4帧动画。我们看看资源在项目资源视图中的保存结构。 还有一个比较重要的地方就是要修改材质的shder类型,因为默认的材质是Diffuse,它是不支持透明的。如果材质不支持透明。主角的背景将会是白色。如下图所示,这里选择Transparent/Diffuse。保存为Transparent家族中的材质都是支持透明的。

最后2D游戏效果图映入我们眼帘了哦。按键WSAD控制摄像机移动,按键JKIL、控制主角移动。

  总结一下这篇文章,本文我们在多个Plane对象身上贴上材质资源,再让摄像机直直的照射着它。实现2D游戏的基本原理,本文没有涉及到Unity3D的物理引擎,不要紧在下章中我将向大家介绍一下Unity3D中的刚体组件与角色控制器组件如何来实现模型的物理效果,包括物理引擎与3D2D游戏的结合。另外大家一定要期待我的新书喔,哇咔咔~嘿嘿。


来源:  http://url.cn/RTBgdY
 
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 水养富贵竹有虫怎么办 水养的富贵竹叶子发黄怎么办 百合花水里的盐放多了怎么办 芦荟叶子发黄干瘪了怎么办 水插百合不开花怎么办 干百合冷水泡了怎么办 牡丹籽油过期了怎么办 ps画布建小了怎么办 腰突然疼的受不了了怎么办 微信里面打不开表格怎么办? 浏览器未正常加载相关控件怎么办 猫的眼睛发炎了怎么办 橡胶手机壳松了怎么办 橡胶手机壳小了怎么办 苹果手机下载不了软件了怎么办 苹果手机浏览器下载不了软件怎么办 小狗吃了硬的棉花怎么办 小狗吃了隔尿垫里的棉花怎么办 眼睫毛掉进眼睛里怎么办 爱掉头发怎么办吃什么 头皮屑多头发干燥脱发怎么办 剪了头发后悔了怎么办 2岁宝宝发际线高怎么办 脱发怎么办吃什么能长发 后面头发睡平了怎么办 鸟羽毛长得不好怎么办 吃激素药头发掉怎么办 吃了药头发掉怎么办 头皮痒头发掉的厉害怎么办 西昌学院被记过了怎么办? 初三了数学太差怎么办 板绘线条不流畅怎么办 嘴被风吹歪了怎么办 被风吹的嘴歪了怎么办 怀孕一个多月见红了怎么办 b本扣了6分怎么办 b牌驾驶证扣6分怎么办 忘记了谁考证的密码怎么办 专升本学校有课怎么办 跨境额度超了怎么办 微商代购被骗了怎么办