贪吃蛇游戏的练习

一、准备工作:

1、新建项目,设置游戏界面分辨率、摄像机

(1) Game 界面,选择16:9 

(2) 设置摄像机背景色:黑色,size:15

2、创建墙:

(1) 2D Object-Sprites-Square,重命名Wall,Position中Y=10,Scale中X=45,选择适当颜色

(2) 选中Wall,Ctrl+D,Position中Y=-10

(3) 复制Wall,Position中Y=0,Rotation中Z=90,Scale中X=20,Position中X=-22

(4) 复制Wall(2),Position中X=22

(5) 选中四面墙,右键,Create Empty Parent

3、创建背景

(1) 2D Object-Sprites-Square,重命名为bp;Scale中X=44,Y=20,选择适当颜色

(2) 选中bp,在Additional Settings中,使Order in Layer的值=-1(设定当前图片需要显示的位置——类似于置于底层)

4、向Hierarchy面板添加游戏对象

(1) 将素材拖放到新建文件夹中,可以按类Create文件夹,如(food,tray等)

(2) 将素材拖放到Hierarchy面板,在新建文件夹中点击素材,调整素材大小(数字越大,图片越小)

(3) 设定Scene界面中各物体的层级(改变Order in Layer的值)

二、移动游戏对象

1、使游戏对象在按下特定键时,持续向某一方向移动,但不能反向移动

(1) 给需要移动的游戏对象添加C#Script,名字自取,如:Snake

(2) 打开Snake.cs,声明一个可以装载3个值的变量,名字自取。如:direction

(3) 输入代码:

(4) 用同样的方法设置其他三个方向,最后添加

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Snake : MonoBehaviour
{
    Vector3 direction;
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            direction = Vector3.up;
        }
        if (Input.GetKeyDown(KeyCode.S) && direction != Vector3.up)
        {
            direction = Vector3.down;
        }
        if (Input.GetKeyDown(KeyCode.A) && direction != Vector3.right)
        {
            direction = Vector3.left;
        }
        if (Input.GetKeyDown(KeyCode.D) && direction != Vector3.left)
        {
            direction = Vector3.right;
        }
        transform.Translate(direction);
    }
}
2、改变游戏运行速度

(1) 使游戏对象一格一格地移动(使用慢动作效果)

(2) 在Unity面板中改变游戏运行速度

A. 声明一个变量,名字自取,如speed,该面板出现在Unity的游戏对象的脚本中

B.改变游戏运行速度,使游戏对象移动减慢

C.回到Unity,设置Speed值

3、本环节代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Snake : MonoBehaviour
{
    public float speed;
    Vector3 direction;
    // Start is called before the first frame update
    void Start()
    {
        Time.timeScale = speed;
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            direction = Vector3.up;
        }
        if (Input.GetKeyDown(KeyCode.S) && direction != Vector3.up)
        {
            direction = Vector3.down;
        }
        if (Input.GetKeyDown(KeyCode.A) && direction != Vector3.right)
        {
            direction = Vector3.left;
        }
        if (Input.GetKeyDown(KeyCode.D) && direction != Vector3.left)
        {
            direction = Vector3.right;
        }
    }
    private void FixedUpdate()
    {
        transform.Translate(direction);
    }
}

三、使FOOD文件夹中的物体随机出现在场景中的随机位置

1、制备做Food的一系列预制体
2、Create Empty

名字自取。如:foodsEmpty

3、Create C#Script

名字自取。如FoodsEmpty,给foodsEmpty添加这个脚本组件

4、声明变量并赋值

(1) 声明数组变量,名字自取。如:foodsEmpties,使这个变量出现在Unity面板中,用以添加Food文件夹中的预制体

(2) 声明变量,名字自取。如:YBound,Xbound

(3) 回到Unity设置坐标

5、随机生成物体

四、打包程序并调用程序

1、打包程序

2、在Start中调用程序:

3、本节代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FoodsEmpty : MonoBehaviour
{
    public GameObject[] foodsEmpties;
    public float YBound = 8f;
    public float XBound = 16f;
    // Start is called before the first frame update
    void Start()
    {
        CreateFood();
    }

    // Update is called once per frame
    void Update()
    {

    }
    public void CreateFood()
    {
        float xrange = Random.Range(-XBound, XBound);
        float yrange = Random.Range(-YBound, YBound);

        int Index = Random.Range(0, foodsEmpties.Length);

        Vector3 pos = new Vector3(xrange, yrange, 0);

        Instantiate(foodsEmpties[Index], pos, Quaternion.identity);
    }
}

五、接触事件——吃掉苹果

1、准备工作:

(1) 给游戏对象添加snake标签;

(2) 添加Collider 2D组件,勾选Istrigger,调整接触范围

(3) 给游戏对象添加Rigidbody 2D组件,选择KInematic

(4) 给food文件夹中的所有预制体添加Collider 2D 组件,勾选Istrigger,(增加标签food)

2、测试接触事件,并使发生接触事件后当前物体消失

(1) 给food文件夹中的所有预制体添加food.cs,打开food.cs

(2) 发生接触事件后,当前物体消失:

(3) 本节代码


    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.CompareTag("snake"))
        {
            Destroy(gameObject);
     
3、物体消失后,生成新的物体

(1) 在Snake.cs中调用FoodEmpty.cs

(2) 在Unity中给Food Empty赋值

(3) 生成新物体(food文件夹中的物体)

    private void OnTriggerEnter2D(Collider2D collision)
    {
                if (collision.CompareTag("food"))
        {
            foodsEmpty.CreateFood();
        }
    }

六、接触事件——蛇的身体出现

1、创建身体

(1) 创建身体图片:Create-2D Object-Sprite-Circle,命名body,重置位置,更改颜色

(2) 把图片变为预制体:

把图片拖放到Project面板中的Asset文件夹中(也可以放入新创建的Prefabs文件夹中)

(3) 删除Hierarchy面板中的预制体

2、通过脚本使body出现(在吃到苹果后)

(1) 打开Snake脚本,声明一个名为bodyPrefab的变量,保存脚本

    public Transform bodyPrefab;

(2) 在Unity中给bodyPrefab赋值

(3) 声明一个数组装载陆续生长的身体

    public List<Transform> bodies = new List<Transform>();

(4) 把当前物体放到List的索引值为0的位置

(5) 生成身体,使之出现在当前物体(Snake)的坐标上

3、使生成的身体随Snake移动

4、本节代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Snake : MonoBehaviour
{
    public Transform bodyPrefab;
    public List<Transform> bodies = new List<Transform>();
    public FoodsEmpty foodsEmpty;
    public float speed;
    Vector3 direction;
    // Start is called before the first frame update
    void Start()
    {
        Time.timeScale = speed;
        bodies.Add(transform);
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            direction = Vector3.up;
        }
        if (Input.GetKeyDown(KeyCode.S) && direction != Vector3.up)
        {
            direction = Vector3.down;
        }
        if (Input.GetKeyDown(KeyCode.A) && direction != Vector3.right)
        {
            direction = Vector3.left;
        }
        if (Input.GetKeyDown(KeyCode.D) && direction != Vector3.left)
        {
            direction = Vector3.right;
        }
    }
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.CompareTag("food"))
        {
            foodsEmpty.CreateFood();

            bodies.Add(Instantiate(bodyPrefab, transform.position, Quaternion.identity));
        }
    }

    private void FixedUpdate()
    {
        transform.Translate(direction);
        for (int i = bodies.Count - 1; i > 0; i--)
        {
            bodies[i].position = bodies[i - 1].position;
        }
    }
}

七、游戏结束,重置场景

1、角色撞到墙,游戏结束

(1) 给四道墙增加box Collider 2D,取消勾选Is Trigger

(2) 添加一个专属标签:自主命名,如:obstacle(障碍物)

(3) 在Snake脚本,新建一个重置场景的方法

void ResetStage()
{
    transform.position = Vector3.zero;
    direction = Vector3.zero;
    for (int i = 1; i < bodies.Count; i++)
    {
        Destroy(bodies[i].gameObject);
    }
    bodies.Clear();
    bodies.Add(transform);
}

(4) 找到OnTriggerEnter2D事件,写入重置场景的方法

        if (collision.CompareTag("obstacle"))
        {
            ResetStage();
        }
2、游戏对象撞到bodyPrefab,游戏结束

给预制体body添加Collider 2D,修改预制体的标签为obstacle

3、每次游戏运行时,游戏对象都在界面中心

4、本节代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Snake : MonoBehaviour
{
    public Transform bodyPrefab;
    public List<Transform> bodies = new List<Transform>();
    public FoodsEmpty foodsEmpty;
    public float speed;
    Vector3 direction;
    // Start is called before the first frame update
    void Start()
    {
        Time.timeScale = speed;
        ResetStage();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.W))
        {
            direction = Vector3.up;
        }
        if (Input.GetKeyDown(KeyCode.S) && direction != Vector3.up)
        {
            direction = Vector3.down;
        }
        if (Input.GetKeyDown(KeyCode.A) && direction != Vector3.right)
        {
            direction = Vector3.left;
        }
        if (Input.GetKeyDown(KeyCode.D) && direction != Vector3.left)
        {
            direction = Vector3.right;
        }
    }
    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.CompareTag("food"))
        {
            foodsEmpty.CreateFood();

            bodies.Add(Instantiate(bodyPrefab, transform.position, Quaternion.identity));
        }
        if (collision.CompareTag("obstacle"))
        {
            ResetStage();
        }
    }

    private void FixedUpdate()
    {
        transform.Translate(direction);
        for (int i = bodies.Count - 1; i > 0; i--)
        {
            bodies[i].position = bodies[i - 1].position;
        }
    }
    void ResetStage()
    {
        transform.position = Vector3.zero;
        direction = Vector3.zero;
        for (int i = 1; i < bodies.Count; i++)
        {
            Destroy(bodies[i].gameObject);
        }
        bodies.Clear();
        bodies.Add(transform);
    }

}

八、添加障碍物

1、准备工作

(1) 在Prefabs文件夹中新建文件夹,名字自取。如Trays。

(2) 调整Sprites文件夹中素材图片的大小:选中Assets/Sprites文件夹中的图片,调整大小(数字越大,图片越小)

(3) 制作障碍物预制体

(4) 给Trays文件夹中的所有障碍物预制体添加Collider2D,取消勾选Istrigger,(增加标签tray)

(5) 在Hierarchy面板,CreateEmpty,名字自取,如:traysEmpty

(6) 给traysEmpty添加脚本组件,名字自取,如:TraysEmpty

(7)

2、声明变量

(1) 打开TraysEmpty.cs,声明数组类变量,以便在Unity的traysEmpty中添加障碍物预制体

    public GameObject[] traysEmpties;

(2) 声明变量表示范围信息

(3) 回到Unity,设置

    public float XboundTray = 16f;
    public float YboundTray = 8f;
3、在特定范围内的随机位置生成随机物体
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TraysEmpty : MonoBehaviour
{
    public GameObject[] traysEmpties;
    public float XboundTray = 16f;
    public float YboundTray = 8f;
    // Start is called before the first frame update
    void Start()
    {
        float xrangeTray = Random.Range(-XboundTray, XboundTray);
        float yrangeTray = Random.Range(-YboundTray, YboundTray);
        int indexTray = Random.Range(0, traysEmpties.Length);
        Vector3 posTray = new Vector3(xrangeTray, yrangeTray, 0);
        Instantiate(traysEmpties[indexTray], posTray, Quaternion.identity);
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}
4、打包程序并在Start 中调用:

5、间隔时间出现陷阱
    private float times;

    void Update()
    {
        {
            times += Time.deltaTime;
            if (times >= 2)
            {
                times = 0;
                CreateTray();
            }
        }
    }
6、本节代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TraysEmpty : MonoBehaviour
{
    private float times;
    public GameObject[] traysEmpties;
    public float XboundTray = 16f;
    public float YboundTray = 8f;
    // Start is called before the first frame update
    void Start()
    {
        CreateTray();
    }

    // Update is called once per frame
    void Update()
    {
        {
            times += Time.deltaTime;
            if (times >= 2)
            {
                times = 0;
                CreateTray();
            }
        }
    }
    public void CreateTray()
    {
        float xrangeTray = Random.Range(-XboundTray, XboundTray);
        float yrangeTray = Random.Range(-YboundTray, YboundTray);
        int indexTray = Random.Range(0, traysEmpties.Length);
        Vector3 posTray = new Vector3(xrangeTray, yrangeTray, 0);
        Instantiate(traysEmpties[indexTray], posTray, Quaternion.identity);
    }
}

九、增加接触事件(接触障碍物后游戏数据重置)

1、打开Snake.cs

        if (collision.CompareTag("tray"))
        {
            ResetStage();
        }

十、增加得分记录

1、准备工作

(1) UI-Text-TextMeshPro名字自取。如:Score。设定字体、字号、颜色;把文本放在合适的位置

(2) Create Empty,名字自取。如:UI

(3) 为UI添加脚本,名字自取。如:GameUI

(4) 打开GameUI.cs

    public TMP_Text ScoreText;

(5) 回到Unity,选中UI,在Game UI下面Score Text右侧 ,选择Score

2、打开GameUI.cs
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class GameUI : MonoBehaviour
{
    public TMP_Text ScoreText;

    int score;//声明变量
    // Start is called before the first frame update
    void Start()
    {
        ScoreText.text = score.ToString();//在ScoreText文本中输入转换为String类型的变量(score)
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    public void ResetScore()//创建并公开Score重置为0的方法(方法名自取,如:ResetScore)
    {
        score = 0;
        ScoreText.text = score.ToString();
    }
    public void AddScore()//统计得分
    {
        score++;
        ScoreText.text = score.ToString();
    }
}
3、在Snake脚本中调用打包好的得分记录

(1) 打开Snake.cs

(2) 添加重置分数

(3) 添加得分情况

(4) 回到Unity,选择Snake.cs所挂载的物体,Game UI上选择UI

十一、游戏开始界面

1、准备工作

(1) 素材图片

(2) 在Canvas上右击,UI-Image,名字自取,如:bgImage

(3) 选中bgImage,在Image面板选择准备好的图片

(4) 在Rect Transform组件,点击stretch,弹出如下图对话框,按住Alt键,选择右下角图标使图片完美覆盖整个场景

2、创建开始界面上的文字

(1) Hierarchy界面右击,UI-Text TextMeshPro,名字自取,如titleText

(2) 安装中文字体,添加需要显示的文字(游戏名称titleText、玩法infoText等)

3、创建开始按钮

(1) UI-Button TextMeshPro,适当位置,在Image组件改变颜色

(2) 选择按钮下的文本,输入"开始游戏"

4、设置按钮

(1) 选中开始界面所有元素,右击,Create Empty Parent,重命名这个空物体如StartMune

(2) 设定按钮,使按钮按下(开始游戏)时,StartMenu不显示(消失)

(3) 选择Hierarchy上的Button,找到On Click()面板,按下面的加号

出现下图

(4) 将StartMenu拖放到None(Object)的位置

(5) 打开No Function,选择GameObject-setActive

说明:取消勾选表示按钮按下时,StartMenu不显示

十二、添加音效:

1、准备工作

(1) 素材音乐:背景音乐、吃、吃错音乐。导入Unity

(2) Create Empty,名字自取,如:Audio

(3) Add component(添加组件)-Audio Source

2、导入音乐

(1) 选中Audio,在AudioClip中选择导入的背景音乐

(2) 取消勾选Play On Awake,勾选Loop,调节音量(Volume)

3、背景音乐在点击开始游戏按钮时才播放

选中Button,On Click(),添加事件

4、游戏结束时,背景音乐重复播放

(1) Create-C#Script,名字自取,如:GameAudio

(2) 在GameAudio.cs中,引用AudioSource组件:

    public AudioSource audioPlayer;

(3) 给Audio添加刚刚创建的脚本(GameAudio.cs)

(4) 将Inspector面板中的Audio Source拖放到AudioPlayer上

(5) 打开GameAudio.cs,创建一个新的方法,用于其他方法调用

    public void RePlayBackGroundMusic()
    {
        audioPlayer.Play();
    }

(6) 打开Snake.cs,声明一个变量,以便调用GameAudio.cs脚本中的内容

    public GameAudio gameAudio;

(7) 找到游戏结束的方法(2个),调用GameAudio中的方法

        if (collision.CompareTag("obstacle"))
        {
            ResetStage();
            gameAudio.RePlayBackGroundMusic();
        }
        if (collision.CompareTag("tray"))
        {
            ResetStage();
            gameAudio.RePlayBackGroundMusic();
        }

(8) 打开Unity,给新建的Game Audio赋值:选择Audio

5、吃掉食物音效

(1) 打开GameAudio.cs,声明一个名字自取的变量,如:eatClip

    public AudioClip eatClip;

(2) 回到Unity,选中Audio物体,在Eat Clip中选择音乐素材

(3) 打开GameAudio.cs,新建一个方法

即:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameAudio : MonoBehaviour
{
    public AudioClip eatClip;
    public AudioSource audioPlayer;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    public void ReplayBackGroundMusic()
    {
        audioPlayer.Play();
    }
    public void PlayEatSound()
    {
        audioPlayer.PlayOneShot(eatClip);
    }

}

(3) 打开Snake.cs,找到吃苹果事件

(4) 添加播放声音事件

.

十三、发布游戏

1、File-Build Settings

2、选择需要发布的场景和添加需要发布的场景

3、选择发布平台

4、点击Player Settings,选择Player,设置相关信息

5、打开Resolution and Presentation,选择窗口模式

十四、更多尝试1——吃掉苹果的同时,生成障碍物,碰撞障碍物掉血

1、

十五、更多尝试 2——成功接触后摆放物体——等

1、准备工作:

(1) 导入素材:在Asetts/Sprite文件夹新建文件夹,名字自取。如:Deoxynucleotides

(2) 制作素材预制体

(3) Create Empty,并摆放在固定位置

2、调用物体

(1) 打开Snake.cs

(2) 回到Unity

3、生成物体

  • 9
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值