目录
一、游戏截图及源码
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)
希望大家一起学习,共同进步,如果有疑问或错误欢迎联系笔者。