SpaceShootGame(太空大战)

来源:互联网 发布:java redis maven 编辑:程序博客网 时间:2024/04/27 15:20
 这是一个类似于飞机大战的游戏。


此处关于背景的设置就不说了,只是在一个Quad上面添加图片纹理,平铺在摄像机下面即可成为背景。

关于相机的设置:
     
关于这个相机投影:
orthographic (true) or perspective (false)(是正交投影还是透视投影)
 
  正交投影也就是平行投影,透视投影是从一个点出发到达物体,构成的一个棱锥,我们看到的界面就是在这个棱锥的半截面出显示的画面。
此处因为是2d平面的一个游戏,设置为
orthographic;
具体可以参考:
http://blog.csdn.net/wong_judy/article/details/6283019

 关于游戏Player:
在构建游戏角色——飞船的时候用到了粒子效果,即飞船后面的引擎,已及飞船的子弹。(引擎的粒子效果当然不是我做出来的,只是拿来直接用,里面涉及到很多知识还需待学习)
Player前构建一个空对象,用来设置子弹出现的位置,将子弹制作成Prefab,当我们按下攻击键的时候,将子弹在指定位置显示出来。

子弹的制作:
 建一个空对象,在空对象下创建一个Quad设置纹理为子弹的图片,然后设置粒子效果属性Particles/Additive提取图片中的粒子图像,其他部分就变成了透明的了。

既然是子弹那么必须要有一个触发器,只有这样在碰到物体的时候才能够检测到,进而触发爆炸之类的效果:
我们给子弹添加一个Capsule Collider(胶囊碰撞器),选中Is Trigger,并调整好触发器的大小,使其完全覆盖我们的子弹。 

然后 子弹就要能够飞行,那么如何进行飞行呢?
我们应该给予子弹一个速度,那么子弹便实现了飞行。所以要添加rigidbody,并且添加脚本,给予子弹向前飞行的一个速度:
public float speed = 10;
// Use this for initialization
void Start () {
rigidbody.velocity = transform.forward * speed;
}
这样一个子弹的Prefab就制作完成。

有了子弹,那么我们应该如何实现按键之后发射子弹呢? 
玩家的控制已及玩家受到敌人子弹后的碰撞检测:

首先考虑到是一架飞机所以我们添加一个Mesh Collider(网格碰撞检测器),注意:此处一定要勾选Is Trigger和Convex属性,即添加触发器(可以忽略到撞到低机后出现一个物理碰撞,这样会影响物体的位置),Convex是允许网格触发检测,不勾选的话,是无法检测到别的网格碰撞器的(即敌机)。然后添加刚体Rigidbody,去除掉重力影响,不然会往下掉落。
 

 
using UnityEngine;
using System.Collections;

[System.Serializable]
public class Boundary{//角色可以移动的区域

public float xMin = -6.7f;
public float xMax = 6.7f;
public float zMin = -3.5f;
public float zMax = 13.5f;
}

public class PlayerControl : MonoBehaviour {

public float speed = 10f;

public Boundary bound;

public GameObject bolt; //发射子弹
public Transform spawnPos;

public float spaceTime = 0.25f;//发射子弹的时间间隔
public float nextTime;//下次发射子弹的时间

public AudioClip weaponPlayer;//音效

public GameObject explosion;//*.txt

private GameControl gameController;
void Start(){
GameObject gameControllerObject = GameObject.FindWithTag ("GameController");//根据Tag名称,查找到当前运行的GameController对象
gameController = gameControllerObject.GetComponent<GameControl> ();//获取到GameControl类
}

void Update(){
if (Input.GetButton ("Fire1") && Time.time > nextTime) {//按下鼠标左键开火,开火的时间间隔为spaceTime
nextTime = Time.time + spaceTime;
Instantiate(bolt,spawnPos.position,spawnPos.rotation);
audio.PlayOneShot(weaponPlayer);
}
}

void FixedUpdate(){//玩家的按键控制,x轴方向和z轴方向,获取的值为-1~1
float h = Input.GetAxis ("Horizontal");
float v = Input.GetAxis ("Vertical");

Vector3 move = new Vector3 (h,0f,v);//获取到的速度方向
rigidbody.velocity = speed * move;//

rigidbody.position = new Vector3 (//角色移动区域的控制
Mathf.Clamp(rigidbody.position.x,bound.xMin,bound.xMax),
0,
Mathf.Clamp(rigidbody.position.z,bound.zMin,bound.zMax)
                                 );//Clamp函数功能:给数值一个最大和最小的范围,超出取最大或最小值
}

void OnTriggerEnter(Collider other){//碰到敌军子弹的一个检测处理,播放玩家飞机爆炸效果,玩家销毁,游戏结束
if (other.gameObject.tag == "EnemyBolt") {
Instantiate (explosion, this.transform.position, this.transform.rotation);
gameController.GameOver ();
Destroy (other.gameObject);
Destroy (this.gameObject);
}

}
}

关于陨石:
给陨石添加一个Capsule Collider碰撞器,刚体Rigidbody属性,脚本脚本给予一个速度,设置如上,给以一个随机角速度实现旋转:
rigidbody.angularVelocity = Random.insideUnitSphere * tumb;
最重要的是添加碰撞检测脚本:
1〉碰到子弹
2〉碰到玩家
3〉碰到其他

关于敌机:
设置基本 和玩家一样,关于敌机的控制:
1〉自动发射子弹
2〉制定好运动轨迹 
3〉挂载碰撞检测脚本 


碰撞检测脚本:
using UnityEngine;
using System.Collections;

public class DestroyByContact : MonoBehaviour {

public GameObject explosion;//当前物体的爆炸效果
public GameObject playerExplosion;//玩家的爆炸效果

private GameControl gameController;

void Start(){
GameObject gameControllerObject = GameObject.FindWithTag ("GameController");
gameController = gameControllerObject.GetComponent<GameControl> ();
}

void OnTriggerEnter(Collider other){
if (other.gameObject.tag == "Boundary") {//如果是在场景区域内部的触发,不做处理
return;
}
if (other.gameObject.tag == "Player") {//如果是碰到了游戏玩家,该物体和玩家都销毁,并播放玩家爆炸效果,游戏结束
Instantiate (playerExplosion, this.transform.position, this.transform.rotation);
gameController.GameOver ();
Destroy (other.gameObject);
Destroy (this.gameObject);
}
if (other.gameObject.tag == "Bolt") {//如果碰撞到的是玩家子弹,则物体播放爆炸效果,销毁
Destroy (other.gameObject);
Destroy (this.gameObject);
Instantiate (explosion, this.transform.position, this.transform.rotation);
}

}

}
 
 整个游戏的宏观控制:
1〉生成敌人
2〉游戏结束条件
3〉退出应用设置


 挂载到游戏内的一个对象上即可:
using UnityEngine;
using System.Collections;

public class GameControl : MonoBehaviour
{
public Vector3 spawnPos;//敌人出现的坐标地点
public GameObject[] spawn;//敌人种类
public int numberSpawns = 10;//小行星个数
public float startWait = 2f;//玩家开始等待时间
public float spawnWait = 1f;//小行星出现的时间间隔
public float waveWait = 4f;//每波间隔时间

public bool isEnd = false;

// Use this for initialization
void Start ()
{
StartCoroutine (SpawnWave ());//开始协同程序,可以使用yield,yield的返回值控制何时恢复协同程序向下执行。
}

// Update is called once per frame
void Update ()
{
if (isEnd && Input.GetKey (KeyCode.R)) {//玩家死亡,按R键重新开始游戏
Application.LoadLevel(Application.loadedLevel);
}
if (Input.GetKey (KeyCode.Escape)) {//Esc键退出应用
Application.Quit();
}
}

IEnumerator SpawnWave ()//随机产生一波小行星和敌人
{
yield return new WaitForSeconds (startWait);
while (true) {
for (int i= 0; i<numberSpawns; i++) {
Spawn ();
//wait time
yield return new WaitForSeconds (spawnWait);
}
yield return new WaitForSeconds (waveWait);
if(isEnd) break;
}
}

void Spawn ()//在一个随机坐标产生敌人
{
GameObject o = spawn [Random.Range (0, spawn.Length)];
Vector3 p = new Vector3 (Random.Range (-spawnPos.x, spawnPos.x), spawnPos.y, spawnPos.z);
Quaternion q = o.transform.rotation;
Instantiate (o, p, q);
}

public void GameOver(){
isEnd = true;
}
}


这样子基本上游戏就可以进行了,但是你会发现出现的游戏物体如果没有被击中的话,超出界面后都没有消失,此时我们需要划定一块场景区域,当任何物体出了这块区域后就自动销毁。
我们可以在一个空的游戏对象上添加一个Box Collider(也可以是其他类型的Collider) ,设置为触发器,并且设定好范围即可:
void OnTriggerExit(Collider other){
Destroy (other.gameObject);
}
当物体出了触发器范围后就会调用这个函数,会自动销毁超出范围的物体。
(个人觉得这个方法挺好的,感觉在仇恨范围判定,伤害范围判定之类的都能用这种触发方法,脚本控制范围即可)具体是否如实,等待后面学习的验证

当然最后还需要
对于出现过的爆炸效果进行处理:
        public float lifeTime;

// Use this for initialization
void Start () {
Destroy (this.gameObject,lifeTime);
} 
根据爆炸效果的时间控制销毁的时间即可,出现后等待爆炸效果 播放完毕即可进行销毁。

 (对于积分功能,由于目前还不太会使用UGUI,视频教程说的是以前版本的,自己折腾了下还是没弄太像,需要等待日后的继续学习,敌机部分的创建以及控制,玩家碰到敌机后的检测处理,随机出现敌机均是自己完善的
——爱生活,乐分享
Polaris 

0 0
原创粉丝点击