Unity实现模拟弹球小游戏过程与收获

目录

一、游戏截图及源码

1.游戏截图与项目对象构成

2.重要脚本代码

二、C#实现过程的收获

1.项目实现阶段遇到Unity崩溃

2.unity协程使用

3.调整游戏运行速度

4.int与string相互转化

5.数据持久化PlayerPrefs

6.随机量获得与数学调用


一、游戏截图及源码

1.游戏截图与项目对象构成

2.重要脚本代码

2.1createBox.cs创建小球,控制射向速度,设置小球移动过程游戏加速

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class creatBox : MonoBehaviour
{
    public Text text_ball_num;
    public int enemy_num;

    public GameObject m_prefab;
    public int ball_number;
    public string create_tag;

    private int num;
    private Vector2 v;
    private Rigidbody2D rb;

    private float Sw, Sh, Swm;
    private int touchCount;
    private LineRenderer aimLine;
    private Touch touch;
    private int key = 1;
    private void Start()
    {
        Sw = Screen.width;
        Sh = Screen.height;
        Swm = Sw / 2f;
        text_ball_num.text = "number:" + ball_number;
        num = ball_number;
        PlayerPrefs.SetInt("Key", 1);
        PlayerPrefs.SetInt("Num", 0);
        aimLine = GetComponent<LineRenderer>();
    }
    private void Update()
    {
        ball_number = (PlayerPrefs.GetInt("Score") / 5) + 10;
        text_ball_num.text = "Ball Number:"+ball_number.ToString();
        if(PlayerPrefs.GetInt("Key")==0)
        {
            if(Input.GetMouseButton(0))
            {
                Time.timeScale = 2;
            }
            else
            {
                Time.timeScale = 1;
            }
        }
        if(PlayerPrefs.GetInt("Key")==1)
        {
            aimandshoot();
        }
        if(PlayerPrefs.GetInt("Key")==2)
        {
            GameObject[] enemy = GameObject.FindGameObjectsWithTag("Enemy");
            for(int i=0;i<enemy.Length;i++)
            {
                enemy[i].transform.position = new Vector3(enemy[i].transform.position.x, enemy[i].transform.position.y - 1, enemy[i].transform.position.z);
            }
            StartCoroutine(this.transform.gameObject.GetComponent<creatEnemy>().createEnemy(enemy_num));
            PlayerPrefs.SetInt("Key", 1);
        }
    }
    private void aimandshoot()
    {
        if(Input.GetMouseButtonDown(0))
        {
            aimLine.SetPosition(0, transform.position);
        }
        if(Input.GetMouseButton(0))
        {
            touch = Input.GetTouch(0);
            if(touch.position.y>=Sh*9f/10f)
            {
                key = 0;
            }
            else
            {
                key = 1;
            }
            float x, y, z, deg;
            x = touch.position.x - Swm;
            y = touch.position.y;
            z = Mathf.Abs(x) / y;
            deg = (int)(Mathf.Atan(z) * 180 / 3.1415);
            v.x = x;
            v.y = y;
            v.Normalize();
            v.x = v.x * 20;
            v.y = v.y * 20;
            if (x < 0)
            {
                transform.rotation = Quaternion.AngleAxis(deg, Vector3.forward);
            }
            else
            {
                transform.rotation = Quaternion.AngleAxis(-deg, Vector3.forward);
            }
            aimLine.SetPosition(1, new Vector3(transform.position.x + (touch.position.x - Swm) / Swm, transform.position.y + touch.position.y / Swm, transform.position.z));
        }
        if(Input.GetMouseButtonUp(0))
        {
            aimLine.SetPosition(1, transform.position);
            if(key==1)
            {
                StartCoroutine(shoot());
                PlayerPrefs.SetInt("Key", 0);
            }
        }
    }
    IEnumerator shoot()
    {
        for(int i=0;i<ball_number;i++)
        {
            rb = GameObject.Instantiate(m_prefab, transform.position, Quaternion.identity).GetComponent<Rigidbody2D>();
            rb.velocity = v;
            PlayerPrefs.SetInt("Num", PlayerPrefs.GetInt("Num") + 1);
            yield return new WaitForSeconds(0.1f);
        }
    }
}

2.2createEnemy.cs创建障碍物,随机生成障碍物元素

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

public class creatEnemy : MonoBehaviour
{
    public Text text_score;

    public GameObject LU;
    public GameObject LD;
    public GameObject RU;
    public GameObject RD;
    public GameObject m_prefab1;
    public GameObject m_prefab2;
    public GameObject m_prefab3;
    public GameObject m_prefab4;
    public GameObject m_prefab5;
    public GameObject m_prefab6;

    private float size_x;
    private float size_y;
    private int x, y;

    private HashSet<Vector2> enemy_positions = new HashSet<Vector2>();
    void Start()
    {
        GameObject t = GameObject.Instantiate(m_prefab1, transform.position, Quaternion.identity);
        t.transform.position.Set(this.transform.position.x,this.transform.position.y,this.transform.position.z);
        size_x = t.transform.GetComponent<Renderer>().bounds.size.x;
        size_y = t.transform.GetComponent<Renderer>().bounds.size.y;
        GameObject.Destroy(t.transform.gameObject, 0f);
        x = (int)((RU.transform.position.x - LU.transform.position.x) / size_x);
        y = (int)((RU.transform.position.y - RD.transform.position.y) / size_y);
        CreateEnemy(5);
        text_score.text = "0";
        PlayerPrefs.SetInt("Score", 0);
    }
    public void CreateEnemy(int cnt)
    {
        for (int i = 0; i < cnt; i++)
        {
            randomcreate();
        }
    }
    private void Update()
    {
        text_score.text = PlayerPrefs.GetInt("Score").ToString();
    }
    public IEnumerator createEnemy(int cnt)
    {
        for (int i = 0; i < cnt; i++)
        {
            randomcreate();
            yield return null;
        }
    }
    private void randomcreate()
    {
        Vector2 tmp = new Vector2();
        do
        {
            tmp.Set(Random.Range(LU.transform.position.x, RU.transform.position.x), Random.Range((3 * LU.transform.position.y + LD.transform.position.y) / 4, LU.transform.position.y));
        } while (enemy_positions.Contains(tmp));
        enemy_positions.Add(tmp);
        int j = Random.Range(1, 6);
        GameObject m;
        if (j == 1)
        {
            m = GameObject.Instantiate(m_prefab1, transform.position, Quaternion.identity);
        }
        else if (j == 2)
        {
            m = GameObject.Instantiate(m_prefab2, transform.position, Quaternion.identity);
        }
        else if (j == 2)
        {
            m = GameObject.Instantiate(m_prefab3, transform.position, Quaternion.identity);
        }
        else if (j == 2)
        {
            m = GameObject.Instantiate(m_prefab4, transform.position, Quaternion.identity);
        }
        else if (j == 2)
        {
            m = GameObject.Instantiate(m_prefab5, transform.position, Quaternion.identity);
        }
        else
        {
            m = GameObject.Instantiate(m_prefab6, transform.position, Quaternion.identity);
        }
        m.transform.position = new Vector3(tmp.x, tmp.y, this.transform.position.z);
        m.GetComponent<CreateOrDestroy>().setLive(Random.Range(5 * PlayerPrefs.GetInt("Score")+1, 10 * PlayerPrefs.GetInt("Score") + 10));
        m.GetComponent<Renderer>().material.color = new Color(Random.Range(0, 255) / 255f, Random.Range(0, 255) / 255f, Random.Range(0, 255) / 255f);
    }
}

二、C#实现过程的收获

1.项目实现阶段遇到Unity崩溃

根据网络上言论,通过打开Temp/_Backupscenes/0.backup文件修改后缀可以复原原来场景。这个方法未证实,但是确定了一件事:崩溃后重新打开unity后一切就没救了,所以一定要先尝试上面的方法后打开unity

2.unity协程使用

2.1基本函数:StartCoroutine(),以IEnumerator为返回值的函数

2.2代码示例:

//StartCoroutine(shoot());
    IEnumerator shoot()
    {
        for(int i=0;i<ball_number;i++)
        {
            rb = GameObject.Instantiate(m_prefab, transform.position, Quaternion.identity).GetComponent<Rigidbody2D>();
            rb.velocity = v;
            PlayerPrefs.SetInt("Num", PlayerPrefs.GetInt("Num") + 1);
            yield return new WaitForSeconds(0.1f);
        }
    }

2.3知识点:开始协程函数调用以IEnumerator为返回值的函数,此函数中返回值通过yield return来达到返回要求,事实上yield return的含义是每次运行函数前先运行一遍return后面的代码,示例代码中函数作用为延迟0.1s

3.调整游戏运行速度

3.1需要通过控制Time.timeScale的值,0:暂停、1:正常速度运行、2:2倍速运行

4.int与string相互转化

4.1int->string:调用int对象函数tosting()

4.2string->int:调用Int.Parse(string)函数

5.数据持久化PlayerPrefs

5.1通过PlayerPrefs实现不同脚本简单数据共享

5.2方便设计使用状态机


个人博客:布纸刀 (gitee.io)

希望大家一起学习,共同进步,如果有疑问或错误欢迎联系笔者。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

布纸刀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值