代码及游戏资料
游戏背景是在火星的上空,主角和敌人是不同的太空飞行器,敌人迎面向主角飞来,主角通过射击消灭敌人来获得分数。如果主角战败,则游戏结束。
屏幕上显示主角生命值以及得分。如果游戏结束,屏幕上显示“游戏结束“,同时显示“再来一次”按钮。按ESC键,游戏会处于暂停状态,显示“继续游戏”,“退出游戏”。
主角有三条性命,被敌人撞击一次性命直接清零,被敌方子弹命中,性命减一,当性命值为0时,游戏结束。
游戏在pc上进行开发,键盘上的上下左右键控制角色在相应位置上移动。空格键和鼠标左键控制发射子弹。
敌人分为两类:初级敌人,装甲较弱,以撞击主角为主;高级敌人,装甲较强,可以发射子弹,也可以撞击主角。
// Palyer.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[AddComponentMenu("MyGame/Player")]
public class Player : MonoBehaviour
{
public float m_life = 3;//主角共3条命
public float m_speed = 3; //控制主角移动速度
float m_rocketRate = 0.3f; //控制子弹发射频率
private float m_rocketspeed = 0;
public Transform m_rocket;
protected Transform m_transform;
public AudioClip m_shootClip; //声音
protected AudioSource m_audio; //声音源
public Transform m_explosionFX; //爆炸特效
public Transform m_explosionFX2; //爆炸特效
// Start is called before the first frame update
void Start()
{
m_transform = this.transform;
m_audio = this.GetComponent<AudioSource>();
}
private void OnTriggerEnter(Collider other)
{
if (other.tag.CompareTo("EnemyRocket") == 0) //碰到敌人的子弹,生命值减一
{
m_life -= 1;
//主角掉血反馈
Instantiate(m_explosionFX2, m_transform.position, Quaternion.identity);
if (m_life <= 0)
{
//主角死亡爆炸特效
Instantiate(m_explosionFX, m_transform.position, Quaternion.identity);
Destroy(this.gameObject);
}
}
if (other.tag.CompareTo("Enemy") == 0) //碰到敌人,生命值清零并销毁
{
m_life = 0;
//主角死亡爆炸特效
Instantiate(m_explosionFX, m_transform.position, Quaternion.identity);
Destroy(this.gameObject);
}
}
// Update is called once per frame
void Update()
{
float moveV = 0; //纵向距离
float moveH = 0; //横向距离
if (Input.GetKey(KeyCode.DownArrow))
{
moveV += m_speed * Time.deltaTime;
}
if (Input.GetKey(KeyCode.UpArrow))
{
moveV -= m_speed * Time.deltaTime;
}
if (Input.GetKey(KeyCode.RightArrow))
{
moveH -= m_speed * Time.deltaTime;
}
if (Input.GetKey(KeyCode.LeftArrow))
{
moveH += m_speed * Time.deltaTime;
}
m_rocketspeed -= Time.deltaTime;
if (m_rocketspeed <= 0)
{
m_rocketspeed = m_rocketRate;
if (Input.GetKey(KeyCode.Space) || Input.GetMouseButton(0))
{
Instantiate(m_rocket, new Vector3(m_transform.position.x,m_transform.position.y,m_transform.position.z + 0.5f), m_transform.rotation);
m_audio.PlayOneShot(m_shootClip);
}
//移动
}
m_transform.Translate(new Vector3(moveH, 0, moveV));
}
}
//Rocket.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[AddComponentMenu("MyGame/Rocket")]
public class Rocket : MonoBehaviour
{
public float m_speed = 10; //设置子弹速度
public float m_liveTime = 1; //设置子弹生存时间
public float m_power = 1; //设置子弹威力
protected Transform m_transform;
// Start is called before the first frame update
void Start()
{
m_transform = this.transform;
}
private void OnTriggerEnter(Collider other)
{
if(other.tag.CompareTo("Enemy") == 0)
{
Destroy(this.gameObject);
}
}
// Update is called once per frame
void Update()
{
m_liveTime -= Time.deltaTime;
if (m_liveTime <= 0)
Destroy(this.gameObject);
m_transform.Translate(new Vector3(0, 0, -m_speed * Time.deltaTime));
}
}
//Explosion.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[AddComponentMenu("MyGame/Explosion")]
public class Explosion : MonoBehaviour
{
public float m_life = 2;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
m_life -= Time.deltaTime;
if(m_life <= 0)
{
m_life = 2;
Destroy(this.gameObject);
}
}
}
// Enemy.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[AddComponentMenu("MyGame/Enemy")]
public class Enemy : MonoBehaviour
{
public float e_life = 20;//敌人的生命值
public float m_speed = 1; //敌人的移动速度
public float m_rotSpeed = 30; //旋转速度
protected float m_timer = 1.5f; //变向间隔时间
public int m_point = 10; //消灭一个敌人获得的分数
public Transform m_explosionFX; //爆炸特效
protected Transform m_transform;
// Start is called before the first frame update
void Start()
{
m_transform = this.transform;
}
// Update is called once per frame
void Update()
{
updataMove();
}
private void OnTriggerEnter(Collider other)
{
if (other.tag.CompareTo("PlayerRocket") == 0) //如果碰到玩家子弹
{
Rocket rocket = other.GetComponent<Rocket>(); //获取Rocket 的脚本Component
if (rocket != null)
{
e_life -= rocket.m_power;
if (e_life <= 0)
{
//敌人死亡时爆炸特效
//Quaternion.identity,该四元数对应于“no rotation”- 对象与世界轴或父轴完全对齐
Instantiate(m_explosionFX, m_transform.position, Quaternion.identity);
Destroy(this.gameObject);
GameManager.instance.AddScore(m_point); //给主角加分
}
}
}
if(other.tag.CompareTo("bound") == 0) //敌人飞出屏幕后自动销毁
{
e_life = 0;
Destroy(this.gameObject);
}
}
virtual protected void updataMove()
{
m_timer -= Time.deltaTime;
if(m_timer <= 0)
{
m_timer = 3; //每间隔3改变一次旋转的方向
m_rotSpeed = -m_rotSpeed;
}
//Rotate()函数会一直旋转,参数一表示轴,参数二表示旋转角度,参数三表示旋转参考系
m_transform.Rotate(Vector3.up, m_rotSpeed * Time.deltaTime, Space.World);//旋转方向
m_transform.Translate(new Vector3(0, 0, -m_speed * Time.deltaTime)); //前进
}
}
//SuperEnemy.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[AddComponentMenu("MyGame/SuperEnemy")]
public class SuperEnemy : Enemy
{
public Transform m_rocket;
protected float m_fireTime = 2;
protected Transform m_player;
void Awake() //在游戏全体实例化时执行一次,并先于stat 方法
{
GameObject obj = GameObject.FindGameObjectWithTag("player");
if (obj != null)
{
m_player = obj.transform;
}
}
// Start is called before the first frame update
protected override void updataMove()
{
m_fireTime -= Time.deltaTime;
if(m_fireTime <= 0)
{
m_fireTime = 2;
if(m_player != null)
{
Vector3 relativePos = m_transform.position - m_player.position;
Instantiate(m_rocket, m_transform.position, Quaternion.LookRotation(relativePos));
}
}
//前进
m_transform.Translate(new Vector3(0, 0, -m_speed * Time.deltaTime));
}
private void OnTriggerEnter(Collider other)
{
if (other.tag.CompareTo("PlayerRocket") == 0) //如果碰到玩家子弹
{
Rocket rocket = other.GetComponent<Rocket>(); //获取Rocket 的脚本Component
if (rocket != null)
{
e_life -= rocket.m_power;
if (e_life <= 0)
{
//敌人死亡时爆炸特效
Instantiate(m_explosionFX, m_transform.position, Quaternion.identity);
Destroy(this.gameObject);
GameManager.instance.AddScore(m_point); //给主角加分
}
}
}
if (other.tag.CompareTo("bound") == 0) //敌人飞出屏幕后自动销毁
{
e_life = 0;
Destroy(this.gameObject);
}
}
}
// EnemySpawn.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[AddComponentMenu("MyGame/EnemySpawn")]
public class EnemySpawn : MonoBehaviour
{
public Transform m_enemy; //敌人的prefab
public float m_timer = 5; //生成敌人的间隔时间
protected Transform m_transform;
// Start is called before the first frame update
void Start()
{
m_transform = this.transform;
}
// Update is called once per frame
void Update()
{
m_timer -= Time.deltaTime;
if (m_timer <= 0)
{
m_timer = 5 + Random.value * 15.0f; //产生5 - 15之间的随机数
// Quaternion.identity就是指Quaternion(0,0,0,0)
Instantiate(m_enemy, m_transform.position, Quaternion.identity);
}
}
//用一幅图填充空对象,在控制台方便知道生成器的位置,游戏中看不到
void OnDrawGizmos()
{
Gizmos.DrawIcon(transform.position, "item.png", true);
}
}
游戏管理器是一个空对象,有且只能有一个,用于控制游戏界面,以及控制游戏开始和退出。
// GameManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[AddComponentMenu("MyGame/GameManager")]
public class GameManager : MonoBehaviour
{
public static GameManager instance;
public float m_score = 0;
public static int m_hiscore = 0;
public AudioClip m_musicClip; //指定音乐片段
protected Player m_player;
protected AudioSource m_audio;
private void Awake()
{
instance = this;
}
// Start is called before the first frame update
void Start()
{
m_audio = this.GetComponent<AudioSource>();
//获取主角
GameObject obj = GameObject.FindGameObjectWithTag("player");
if(obj != null)
{
m_player = obj.GetComponent<Player>();
}
}
// Update is called once per frame
void Update()
{
//循环播放背景音乐
if (!m_audio.isPlaying)
{
m_audio.clip = m_musicClip;
m_audio.Play();
}
//暂停游戏
if(Time.timeScale > 0 && Input.GetKeyDown(KeyCode.Escape))
{
Time.timeScale = 0;
}
}
[System.Obsolete]
private void OnGUI()
{
//暂停游戏
if(Time.timeScale == 0)
{
//继续游戏按钮
if(GUI.Button(new Rect(Screen.width * 0.5f -50,Screen.height * 0.4f, 100, 30), "继续游戏"))
{
Time.timeScale = 1;
}
//退出游戏按钮
if (GUI.Button(new Rect(Screen.width * 0.5f - 50, Screen.height * 0.6f, 100, 30), "退出游戏"))
{
Application.Quit(); //只有当工程打包编译后的程序使用Application.Quit()才奏效
}
}
int life = 0;
if(m_player != null)
{
life = (int)m_player.m_life; //获取主角的生命值
}
else //主角被销毁,即游戏失败
{
//放大字体
GUI.skin.label.fontSize = 50;
//显示游戏失败
GUI.skin.label.alignment = TextAnchor.LowerCenter;
GUI.Label(new Rect(0, Screen.height * 0.2f, Screen.width, 60), "游戏失败");
GUI.skin.label.fontSize = 20;
//显示再来一次按钮
if(GUI.Button(new Rect(Screen.width * 0.5f - 50, Screen.height * 0.5f, 100, 30), "再来一次"))
{
//读取当前关卡
Application.LoadLevel(Application.loadedLevelName);
}
}
GUI.skin.label.fontSize = 15;
//显示主角生命
GUI.Label(new Rect(5, 5, 100, 30), "装甲:" + life);
//显示最高分
GUI.skin.label.alignment = TextAnchor.LowerCenter;
GUI.Label(new Rect(0, 5, Screen.width, 30), "最高分:" + m_hiscore);
//显示当前得分
GUI.Label(new Rect(0, 25, Screen.width, 30), "得分:" + m_score);
}
public void AddScore(int point)
{
m_score += point;
// 更高分记录
if(m_hiscore < m_score)
{
m_hiscore = (int)m_score;
}
}
}
这里游戏基本已经完成,现在需要创建一个开始的标题Scene,然后点击“开始游戏”跳转到当前的level1。
//TitleSceen.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[AddComponentMenu("MyGame/TitleScreen")]
public class TitleSceen : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
[System.Obsolete]
private void OnGUI()
{
GUI.skin.label.fontSize = 48;
GUI.skin.label.alignment = TextAnchor.LowerCenter; //UI中心对齐
GUI.Label(new Rect(0, 30, Screen.width, 100), "太空大战");
//开始游戏按钮
if (GUI.Button(new Rect(Screen.width * 0.5f - 100, Screen.height * 0.7f, 200, 30), "开始游戏"))
{
Application.LoadLevel("level1");
}
}
}
设置游戏图标,以及相应的一些参数。不懂就用默认。
编译时必须把两个Scene全勾上,并调整顺序。
代码及游戏资料