通过代码控制背景图片进行循环播放。
1、把场景视图设置为2D模式,设置如下:
2、把MainCamera设置为正交相机,设置如下:
3、在层级视图中创建空物体,名字改为BackGround,其Transform组件属性设置如下:
4、把Assets/Images下的background精灵拖拽到BackGround下做为子物体,把background的名字改为bg1,其Transform组件属性设置如下:
5、点击bg1的SpriteRenderer组件中的Sorting Layer按钮,添加排序层如下:
6、bg1的SpriteRenderer组件属性设置如下:
7、把bg1克隆一份,名字改为bg2,其Transform组件属性设置如下:
8、bg2的SpriteRenderer组件属性设置如下:
9、创建BGMove脚本组件,分别添加到bg1和bg2上,实现背景图循环播放。
public class BGMove : MonoBehaviour {
public float moveSpeed = 3;
void Update () {
transform.Translate(Vector3.down * moveSpeed * Time.deltaTime);
Vector3 pos = transform.position;
if (transform.position.y<=-8.52)
{
transform.position = new Vector3(pos.x, pos.y + 8.52f * 2, pos.z);
}
}
}
通过精灵图片创建主机子弹的预制体,在主机发射子弹的时候,可以通过预制体不断实例化子弹,并且子弹可以向上飞行,子弹将和敌机之间进行碰撞检测。
1、把Assets/Images下的bullet1拖到层级视图中,其SpriteRenderer组件的属性设置如下:
2、给bullet1添加Box Collider 2D组件,其属性设置如下:
3、给bullet1添加Rigidboey 2D组件,用于进行碰撞检测,其属性设置如下:
4、给bullet1添加AudioSource组件,用于播放子弹发射时的声音,其属性设置如下:
5、给bullet1添加Bullet脚本组件,控制子弹的移动。
public class Bullet : MonoBehaviour {
public float moveSpeed = 3;
void Update () {
transform.Translate(Vector3.up * Time.deltaTime * moveSpeed);
if (transform.position.y>4.5f)
{
Destroy(gameObject);
}
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.tag=="Enemy")
{
other.GetComponent<Enemy>().BeAttacked();
Destroy(gameObject);
}
}
}
把上述创建好的子弹bullet1拖拽到Assets目录下,即创建了主机子弹的预制体,另外超级子弹的预制体制作过程和上面的一样,只需要把bullet1换成bullet2精灵即可。
该功能的主要作用是当按下鼠标左键后,主机会随着鼠标一起移动,主机在移动的过程中,引擎会有动画效果,同时在主机的前端每隔0.1秒发射一颗子弹,当主机碰撞到超级武器后,主机两侧会同时发射子弹,前端不再发射,经过一段时间以后,超级武器的持续时间结束,主机两侧不再发射子弹,改为前端发射子弹。
1、把Assets/Images文件夹中的hero1精灵拖到层级视图中,名字改为Hero,其SpriteRenderer组件的属性设置如下:
2、给Hero添加空子物体,名字改为GunTop,做为主机前端子弹发射点,其Transform组件的属性设置如下:
3、给Hero添加空子物体,名字改为GunRight,做为主机右侧子弹发射点,其Transform组件的属性设置如下:
4、给Hero添加空子物体,名字改为GunLeft,做为主机左侧子弹发射点,其Transform组件的属性设置如下:
5、给Hero添加Box Collider 2D组件,其属性设置如下:
6、给Hero添加Rigidboey 2D组件,用于进行碰撞检测,其属性设置如下:
7、给Hero添加AudioSource组件,用于播放主机碰撞到物品奖励后的声音,其属性设置如下:
8、分别给GunTop、GunRight和GunLeft添加脚本组件Gun。
9、给主机添加Hero脚本组件,控制主机的移动和发射子弹。
public class Gun : MonoBehaviour {
public float rate = 0.2f;
public GameObject bulletPrefab;
void Fire()
{
Instantiate(bulletPrefab, transform.position, Quaternion.identity);
}
public void OpenFire()
{
InvokeRepeating("Fire", 0, rate);
}
public void StopFire()
{
CancelInvoke("Fire");
}
}
public class Hero : MonoBehaviour {
public bool isAnimation = true;
public Sprite[] sprites;
private float timer = 0;
public int frameCountPerSecond = 10;
bool isMouseDown = false;
private Vector3 lastMousePos = Vector3.zero;
public float superGunTime = 10;
private float resetSuperGunTime = 0;
AudioSource aud;
public int gunCount = 1;
public Gun topGun;
public Gun rightGun;
public Gun leftGun;
SpriteRenderer sr;
public AudioClip superGunClip;
public AudioClip bombClip;
void Start () {
resetSuperGunTime = superGunTime;
superGunTime = 0;
topGun.OpenFire();
aud = GetComponent<AudioSource>();
sr = GetComponent<SpriteRenderer>();
}
// Update is called once per frame
void Update () {
if (isAnimation)
{
timer += Time.deltaTime;
int index = (int)(timer * frameCountPerSecond);
index %= sprites.Length;
sr.sprite = sprites[index];
}
if (Input.GetMouseButtonDown(0))
{
isMouseDown = true;
}
if (Input.GetMouseButtonUp(0))
{
isMouseDown = false;
lastMousePos = Vector3.zero;
}
if (isMouseDown)
{
if (lastMousePos!=Vector3.zero)
{
Vector3 offset = Camera.main.ScreenToWorldPoint(Input.mousePosition) - lastMousePos;
transform.position += offset;
CheckPos();
}
lastMousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
superGunTime -= Time.deltaTime;
if (superGunTime > 0)
{
if (gunCount == 1)
{
TransformToSuperGun();
}
}
else {
if (gunCount==2)
{
TransformToNormalGun();
}
}
}
private void CheckPos()
{
Vector3 pos = transform.position;
float x = pos.x;
float y = pos.y;
x = Mathf.Clamp(x, -1.8f, 1.8f);
y = Mathf.Clamp(y, -3.6f, 3.4f);
transform.position = new Vector3(x, y, pos.z);
}
private void TransformToSuperGun()
{
gunCount = 2;
topGun.StopFire();
leftGun.OpenFire();
rightGun.OpenFire();
}
private void TransformToNormalGun()
{
gunCount = 1;
topGun.OpenFire();
leftGun.StopFire();
rightGun.StopFire();
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.tag=="Award")
{
if (other.GetComponent<Award>().type==0)
{
superGunTime = resetSuperGunTime;
aud.clip = superGunClip;
}
if (other.GetComponent<Award>().type==1)
{
aud.clip = bombClip;
Bomb.Instance.BombCount++;
}
aud.Play();
Destroy(other.gameObject,0.1f);
}
}
}
创建小飞机的预制体,当游戏开始时,会通过小飞机的预制体,不断的实例化出小飞机。
1、把Assets/Images文件夹中的enemy0拖拽到层级视图中,更改其tag值为Enemy,具体设置如下:
2、给enemy0添加SpriteRenderer组件的属性设置如下:
3、给enemy0添加Polygon Collider 2D碰撞器组件,其属性设置如下:
4、给enemy0添加Enemy脚本组件。
public enum EnemyType
{
EnemySmall,
EnemyMiddle,
EnemyBig
}
public class Enemy : MonoBehaviour {
SpriteRenderer sr;
public int hp = 1;
public int score = 1;
public float moveSpeed = 2;
public EnemyType type = EnemyType.EnemySmall;
public bool isDeath = false;
public Sprite[] explosionSprite;
public int explosionAnimatorFrame = 30;
public float timer = 0;
public float hitTime = 0.2f;
private float resetHitTime;
public Sprite[] hitSprtes;
void Start () {
sr = GetComponent<SpriteRenderer>();
resetHitTime = hitTime;
hitTime = 0;
}
void Update () {
transform.Translate(Vector3.down * Time.deltaTime * moveSpeed);
if (transform.position.y<-5.6f)
{
Destroy(gameObject);
}
if (isDeath)
{
timer += Time.deltaTime;
int index = (int)(timer * explosionAnimatorFrame);
if (index >= explosionSprite.Length)
{
Destroy(gameObject);
}
else {
sr.sprite = explosionSprite[index];
}
}
else
{
if (type==EnemyType.EnemyMiddle||type== EnemyType.EnemyBig)
{
if (hitTime>=0)
{
hitTime -= Time.deltaTime;
int index = (int)((resetHitTime - hitTime) * explosionAnimatorFrame);
index %= hitSprtes.Length;
sr.sprite = hitSprtes[index];
}
}
}
if (Input.GetMouseButtonDown(1) && Bomb.Instance.BombCount > 0)
{
ToDie();
}
}
void ToDie()
{
if (isDeath==false)
{
isDeath = true;
GameManager.Instance.Count += score;
}
}
public void BeAttacked()
{
hp -= 1;
if (hp<=0)
{
ToDie();
}
else
{
hitTime = resetHitTime;
}
}
}
最后把enemy0拖拽到Assets目录下做为预制体即可。
创建中飞机的预制体,当游戏开始时,会通过中飞机的预制体,不断的实例化出中飞机,中飞机在碰撞到主机的子弹时,会播放动画。
1、把Assets/Images文件夹中的enemy1拖拽到层级视图中,更改其tag值为Enemy,具体设置如下:
2、给enemy1添加SpriteRenderer组件的属性设置如下:
3、给enemy1添加Polygon Collider 2D碰撞器组件,其属性设置如下:
4、给enemy1添加Enemy脚本组件。
代码和小飞机预制体创建代码一样
最后把enemy1拖拽到Assets目录下做为预制体即可。
创建大飞机的预制体,当游戏开始时,会通过大飞机的预制体,不断的实例化出大飞机,大飞机在移动的过程中以及碰撞到主机的子弹时,会播放动画。
1、把Assets/Images文件夹中的enemy2拖拽到层级视图中,更改其tag值为Enemy,具体设置如下:
2、给enemy2添加SpriteRenderer组件的属性设置如下:
3、给enemy2添加Polygon Collider 2D碰撞器组件,其属性设置如下:
4、给enemy2添加Enemy脚本组件。
代码和小飞机预制体创建代码一样
最后把enemy2拖拽到Assets目录下做为预制体即可。
超级武器是物品奖励的一种,主机碰撞到超级武器奖励后,主机两侧会发射子弹,当游戏运行后,每隔一定的时间会通过超级武器的预制体实例化出超级武器。
1、把Assets/Images文件夹中的award_type_0拖拽到层级视图中,其tag值改为Award,具体设置如下:
2、award_type_0的SpriteRenderer组件的属性设置如下:
3、给award_type_0添加Polygon Collider 2D碰撞器组件,其属性设置如下:
4、给award_type_0添加AudioSource组件,当超级武器生成后播放声音,其属性设置如下:
5、给award_type_0添加Award脚本组件。
public class Award : MonoBehaviour {
public int type = 0;
public float moveSpeed = 3;
void Update () {
transform.Translate(Vector3.down * Time.deltaTime * moveSpeed);
if (transform.position.y<-5.6f)
{
Destroy(gameObject);
}
}
}
最后把award_type_0拖拽到Assets下创建预制体即可。
当主机碰撞到所产生的炸弹后,屏幕左下角的炸弹数量会加1,当按下Z键后炸弹的数量会减1,屏幕上的所有敌机均会爆炸。
1、把Assets/Images文件夹中的award_type_1拖拽到层级视图中,其tag值改为Award,具体设置如下:
2、award_type_1的SpriteRenderer组件的属性设置如下:
3、给award_type_1添加Polygon Collider 2D碰撞器组件,其属性设置如下:
4、给award_type_1添加AudioSource组件,当超级武器生成后播放声音,其属性设置如下:
5、给award_type_1添加Award脚本组件。
代码和超级武器预制体创建代码一样
最后把award_type_1拖拽到Assets下创建预制体即可。
游戏运行后,通过代码会随机生成不同的敌机和奖励。
1、在层级视图中创建空物体,名字改为Spawn,其Transform组件属性设置如下:
2、给Spawn添加Spawn脚本组件。
public class Spawn : MonoBehaviour {
public float rate0 = 0.5f;
public float rate1 = 5f;
public float rate2 = 8f;
public GameObject enemy0Prefab;
public GameObject enemy1Prefab;
public GameObject enemy2Prefab;
public GameObject awardType0Prefab;
public GameObject awardType1Prefab;
public float awardType0Rate = 7f;
public float awardType1Rate = 14;
void Start () {
InvokeRepeating("CreateEnemy0", 1, rate0);
InvokeRepeating("CreateEnemy1", 3, rate1);
InvokeRepeating("CreateEnemy2", 6,rate2);
InvokeRepeating("CreateAwardType0", 8,awardType0Rate);
InvokeRepeating("CreateAwardType1", 12,awardType1Rate);
}
void CreateEnemy0()
{
Create(-2.1f, 2.1f, enemy0Prefab);
}
void CreateEnemy1()
{
Create(-1.9f, 1.9f, enemy1Prefab);
}
void CreateEnemy2()
{
Create(-1.4f, 1.4f, enemy2Prefab);
}
void CreateAwardType0()
{
Create(-2.1f, 2.1f, awardType0Prefab);
}
void CreateAwardType1()
{
Create(-2.1f, 2.1f, awardType1Prefab);
}
void Create(float randomMinX,float randomMaxX,GameObject prefab )
{
float x = Random.Range(randomMinX, randomMaxX);
Instantiate(prefab, new Vector3(x, transform.position.y, transform.position.z), Quaternion.identity);
}
}
主要用来管理游戏的开始和暂停,同时播放背景音乐。
1、在层级视图中创建空物体,名字改为GameManager,添加AudioSource组件,用来播放背景音乐,组件属性设置如下:
2、给GameManager添加GameManager脚本组件。
public enum GameStatus
{
Running,
Pause
}
public class GameManager : MonoBehaviour {
public static GameManager Instance;
public GameStatus gameStatus = GameStatus.Running;
private void Awake()
{
Instance = this;
}
public int Count { get; set; }
public void StartGame()
{
gameStatus = GameStatus.Running;
Time.timeScale = 1;
}
public void PauseGame()
{
gameStatus = GameStatus.Pause;
Time.timeScale = 0;
}
}
主要用来显示分数,炸弹的图标和个数,显示开始和暂停按钮。
1、在层级视图中创建画布Canvas,给Canvas添加AudioSource组件,用来播放点击按钮时的声音,Audio Source组件属性设置如下:
2、在Canvas下创建Image控件,名字改为Start,Start的Rect Transform组件属性设置如下:
3、Start的Image组件属性设置如下:
4、Start的Button组件属性设置如下:
5、在Canvas下创建Image控件,名字改为Pause,Pause的Rect Transform组件属性设置如下:
6、Pause的Image组件属性设置如下:
7、Pause的Button组件属性设置如下:
8、在Canvas下创建Text控件,用来显示分数,Text的Rect Transform组件属性设置如下:
9、Text的Text组件属性设置如下:
10、在Canvas下创建Text控件,名字改为Score,Score的Rect Transform组件属性设置如下:
11、Score的Text组件属性设置如下:
12、在Canvas下创建Image控件,名字改为Bomb,Bomb的Rect Transform组件属性设置如下:
13、Bomb的Image组件属性设置如下:
14、Bomb的Button组件属性设置如下:
15、在Bomb下创建子控件Text,名字改为BombCount,BombCount的Rect Transform组件属性设置如下:
16、BombCount的Text组件属性设置如下:
17、给Score添加脚本组件Score,给Bomb添加脚本组件Bomb。
public class Score : MonoBehaviour {
Text text;
void Start () {
text = GetComponent<Text>();
}
void Update () {
text.text = GameManager.Instance.Count.ToString();
}
}
public class Bomb : MonoBehaviour {
public static Bomb Instance;
private void Awake()
{
Instance = this;
}
public int BombCount { get; set; }
Text text;
void Start () {
BombCount = 3;
text = GetComponentInChildren<Text>();
text.text = BombCount.ToString();
}
void Update () {
if (Input.GetMouseButtonDown(1) && BombCount > 0)
{
//使用炸弹
Debug.Log("使用炸弹");
UseBomb();
}
text.text = BombCount.ToString();
}
public void UseBomb()
{
if (BombCount > 0)
{
BombCount--;
}
else
{
BombCount = 0;
}
}
}