Unity2D游戏开发案例-Roguelike拾荒者

来源:互联网 发布:sketch windows 编辑:程序博客网 时间:2024/04/29 01:13

一、创建游戏工程导入游戏素材

二、创建游戏主角及敌人的预制

1、将主角Idle动画的Sprite一起拖入Hierarchy面板,会生成一个主角,同时会生成主角的Player Controller(动画控制器)和PlayerIdle动画,将其他动画分别拖到Player上会生成各自的Animation。

2、敌人创建方法同理,但由于存在多个不同的敌人,它们之间动画相同,只是Sprite不同,所以后面的敌人可以重写第一个创建的敌人时生成的动画控制器,再使用自己的动画。

三、游戏素材中其他素材(如墙、食物、地板、障碍物等)可以直接做成Prefab。

四、游戏地图的生成

这个游戏地图是10*10的大小,围墙和地板两种不同的GameObject,刚好使用两个for循环来生成地图(循环的嵌套)。

五、控制障碍物、食物、敌人的随机生成

1、在围墙边应留一行通路,确保玩家能通过,在剩下中间的位置来生成障碍物。

2、障碍物生成的个数的位置都应该是随机的,因此可以同样用两个for循环遍历所有能生成障碍物的位置,放入一个List列表,然后随机取出一个位置随机放入一个障碍物(注意:取出位置后要把这个位置从List移除)。

3、对于食物和敌人,可以使用同样的方法去实例化,而且在生成障碍物时已经遍历了位置,可以直接使用。

六、完善主角和敌人的动画状态机

1、添加动画切换条件


2、关于状态机的一些参数



如果有切换动画条件Condition,一般不勾选Has Exit Time,由条件控制动画的切换;如果没有Condition,则勾选Has Exit Time表示在什么时候切换动画,下面Settings-->Exit Time值(0到1)来表示切换时间,它是一个百分比的值,1代表动画播放完切换。

2d游戏的动画时帧动画,可以将Transition Duration值设为0。

七、控制主角的移动

1、首先在player上添加Rigidbody2D(不需要重力)和BoxCollider2D组件。

2、使用Rigidbody2D上的MovePosition方法插值Verctor2.Lerp()。

3、由于实在Update方法中移动player的,可能按下方向键时player每帧都会移动,为了避免player移动过快,可以设置一个休息时间。

八、控制主角对墙体的攻击

1、将所有的墙设置一个tag标签,由于围墙不能攻击,只有里面的墙才能攻击,只需给内墙添加被攻击的方法。

2、2D游戏的射线检测:Physical.Linecast()返回一个RaycastHit2D的对象,如果返回的这个对象不为空,通过tag标签判断如果是内墙就可以攻击。

      注意:player在发射射线时,可能检测到自身的collider,因此在检测之前要禁掉自己的collider,检测之后在恢复。

3、通过SendMessage通知碰撞到的墙调用被攻击的方法。

4、在显示内墙被攻击的状态时,可以修改SpriteRenderer组件的sprite。而主角的攻击动画直接用Animator的SetTrigger方法。

九、控制主角吃食物

与攻击墙体的方法差不多,只是食物的collider为触发器,食物在被吃掉后主角的食物量会增加,在Destroy食物时有些信息不能被Destroy,因此可以将吃食物的逻辑放在GameManager中(像这种管理类一般可以使用单例模式)。

十、控制敌人的移动和攻击

1、给敌人添加Rigidbody2D和BoxCollider2D组件,敌人之间、敌人和Player之间碰撞可能会导致旋转,因此将敌人和Player的Rigidbody2D组件的Constraints的旋转锁定。

2、敌人的移动和Player一样使用插值,判断当前位置和目标位置的距离,Vector2中的magnitude返回两个位置的向量的长度。

3、Player移动两步,敌人移动一步,所以敌人移动的方法可以在GameManager中调用,在GameManager中,使用List集合来存放所有的敌人。

4、第2步里判断magnitude小于1.1(1是临界值)时,攻击玩家。

十一、控制食物数量和游戏失败UI的显示

通过一个更新Text的方法在每次食物数量变化时调用来显示食物数量。

十二、游戏关卡胜利的判断和加载

1、当Player的下一个目标位置是终点时,加载下一关SceneManager.LoadScene(0)。

2、系统函数OnLevelWasLoaded()实现关卡数的增加以及地图和UI的初始化。

十三、控制天数UI的显示

Invoke("HideBlack",1)方法等待1秒调用HideBlack方法。

十四、添加音效

随机播放音效,音效播放速度也随机。

单独在一个类中写音效的播放,做成单例模式,带参数数组的方法。

using UnityEngine;public class AudioManager : MonoBehaviour{    private static AudioManager _instance;    public static AudioManager Instance    {        get { return _instance; }    }    public AudioSource audioSource;    public AudioSource BGMusic;    private float minPitch = 0.9f;    private float maxPitch = 1.1f;    void Awake()    {        _instance = this;    }    public void RandPlay(params AudioClip[] audios) //参数数组    {        float pitch=Random.Range(minPitch,maxPitch);        int index=Random.Range(0,audios.Length);        AudioClip clip = audios[index];        audioSource.clip = clip;        audioSource.pitch = pitch;        audioSource.Play();    }    public void StopBGMusic()    {        BGMusic.Stop();    }}

参数数组和数组参数的不同在于函数的调用,调用参数数组的函数时,我们可以传递过来任意多个参数,然后编译器会帮我们自动组拼成一个数组;调用数组参数的时候,那个数组我们要自己手动创建。(参数数组就是帮我们减少了一个数组的创建过程)。


原创粉丝点击