背景的循环播放

功能说明

通过代码控制背景图片进行循环播放。

实现步骤

1、把场景视图设置为2D模式,设置如下:

images-p4_1.png

2、把MainCamera设置为正交相机,设置如下:

images-p4_2.png

3、在层级视图中创建空物体,名字改为BackGround,其Transform组件属性设置如下:

images-p4_3.png

4、把Assets/Images下的background精灵拖拽到BackGround下做为子物体,把background的名字改为bg1,其Transform组件属性设置如下:

images-p4_4.png

5、点击bg1的SpriteRenderer组件中的Sorting Layer按钮,添加排序层如下:

images-p4_5.png

6、bg1的SpriteRenderer组件属性设置如下:

images-p4_6.png

7、把bg1克隆一份,名字改为bg2,其Transform组件属性设置如下:

images-p4_7.png

8、bg2的SpriteRenderer组件属性设置如下:

images-p4_8.png

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);
        }
	}
}

脚本组件属性设置截图

images-p4_10.png

效果展示图

images-p4_11.png

主机子弹预制体创建

功能说明和实现步骤

通过精灵图片创建主机子弹的预制体,在主机发射子弹的时候,可以通过预制体不断实例化子弹,并且子弹可以向上飞行,子弹将和敌机之间进行碰撞检测。

实现步骤

1、把Assets/Images下的bullet1拖到层级视图中,其SpriteRenderer组件的属性设置如下:

images-p4_12.png

2、给bullet1添加Box Collider 2D组件,其属性设置如下:

images-p4_13.png

3、给bullet1添加Rigidboey 2D组件,用于进行碰撞检测,其属性设置如下:

images-p4_14.png

4、给bullet1添加AudioSource组件,用于播放子弹发射时的声音,其属性设置如下:

images-p4_15.png

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);
        }
    }
}

脚本组件属性设置截图

images-p4_17.png

效果展示图

images-p4_18.png

把上述创建好的子弹bullet1拖拽到Assets目录下,即创建了主机子弹的预制体,另外超级子弹的预制体制作过程和上面的一样,只需要把bullet1换成bullet2精灵即可。

主机的移动和发射子弹

功能说明

该功能的主要作用是当按下鼠标左键后,主机会随着鼠标一起移动,主机在移动的过程中,引擎会有动画效果,同时在主机的前端每隔0.1秒发射一颗子弹,当主机碰撞到超级武器后,主机两侧会同时发射子弹,前端不再发射,经过一段时间以后,超级武器的持续时间结束,主机两侧不再发射子弹,改为前端发射子弹。

实现步骤

1、把Assets/Images文件夹中的hero1精灵拖到层级视图中,名字改为Hero,其SpriteRenderer组件的属性设置如下:

images-p4_19.png

2、给Hero添加空子物体,名字改为GunTop,做为主机前端子弹发射点,其Transform组件的属性设置如下:

images-p4_20.png

3、给Hero添加空子物体,名字改为GunRight,做为主机右侧子弹发射点,其Transform组件的属性设置如下:

images-p4_21.png

4、给Hero添加空子物体,名字改为GunLeft,做为主机左侧子弹发射点,其Transform组件的属性设置如下:

images-p4_22.png

5、给Hero添加Box Collider 2D组件,其属性设置如下:

images-p4_23.png

6、给Hero添加Rigidboey 2D组件,用于进行碰撞检测,其属性设置如下:

images-p4_24.png

7、给Hero添加AudioSource组件,用于播放主机碰撞到物品奖励后的声音,其属性设置如下:

images-p4_25.png

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);
        }
    }
}

脚本组件属性设置截图

images-p4_27.png

效果展示图

images-p4_28.png

小飞机预制体创建

功能说明

创建小飞机的预制体,当游戏开始时,会通过小飞机的预制体,不断的实例化出小飞机。

实现步骤

1、把Assets/Images文件夹中的enemy0拖拽到层级视图中,更改其tag值为Enemy,具体设置如下:

images-p4_29.png

2、给enemy0添加SpriteRenderer组件的属性设置如下:

images-p4_30.png

3、给enemy0添加Polygon Collider 2D碰撞器组件,其属性设置如下:

images-p4_31.png

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;
        }
    }
}

脚本组件属性设置截图

images-p4_33.png

效果展示图

images-p4_34.png

最后把enemy0拖拽到Assets目录下做为预制体即可。

中飞机预制体创建

功能说明和实现步骤

创建中飞机的预制体,当游戏开始时,会通过中飞机的预制体,不断的实例化出中飞机,中飞机在碰撞到主机的子弹时,会播放动画。

实现步骤

1、把Assets/Images文件夹中的enemy1拖拽到层级视图中,更改其tag值为Enemy,具体设置如下:

images-p4_35.png

2、给enemy1添加SpriteRenderer组件的属性设置如下:

images-p4_36.png

3、给enemy1添加Polygon Collider 2D碰撞器组件,其属性设置如下:

images-p4_37.png

4、给enemy1添加Enemy脚本组件。

重点代码

代码和小飞机预制体创建代码一样

脚本组件属性设置截图

images-p4_38.png

效果展示图

images-p4_39.png

最后把enemy1拖拽到Assets目录下做为预制体即可。

大飞机预制体创建

功能说明

创建大飞机的预制体,当游戏开始时,会通过大飞机的预制体,不断的实例化出大飞机,大飞机在移动的过程中以及碰撞到主机的子弹时,会播放动画。

实现步骤

1、把Assets/Images文件夹中的enemy2拖拽到层级视图中,更改其tag值为Enemy,具体设置如下:

images-p4_40.png

2、给enemy2添加SpriteRenderer组件的属性设置如下:

images-p4_41.png

3、给enemy2添加Polygon Collider 2D碰撞器组件,其属性设置如下:

images-p4_42.png

4、给enemy2添加Enemy脚本组件。

2.6.2 重点代码

代码和小飞机预制体创建代码一样

2.6.3 脚本组件属性设置截图

images-p4_43.png

2.6.4 效果展示图

images-p4_44.png

最后把enemy2拖拽到Assets目录下做为预制体即可。

超级武器预制体创建

功能说明

超级武器是物品奖励的一种,主机碰撞到超级武器奖励后,主机两侧会发射子弹,当游戏运行后,每隔一定的时间会通过超级武器的预制体实例化出超级武器。

实现步骤

1、把Assets/Images文件夹中的award_type_0拖拽到层级视图中,其tag值改为Award,具体设置如下:

images-p4_45.png

2、award_type_0的SpriteRenderer组件的属性设置如下:

images-p4_46.png

3、给award_type_0添加Polygon Collider 2D碰撞器组件,其属性设置如下:

images-p4_47.png

4、给award_type_0添加AudioSource组件,当超级武器生成后播放声音,其属性设置如下:

images-p4_48.png

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);
        }
	}
}

脚本组件属性设置截图

images-p4_50.png

效果展示图

images-p4_51.png

最后把award_type_0拖拽到Assets下创建预制体即可。

炸弹预制体创建

功能说明

当主机碰撞到所产生的炸弹后,屏幕左下角的炸弹数量会加1,当按下Z键后炸弹的数量会减1,屏幕上的所有敌机均会爆炸。

实现步骤

1、把Assets/Images文件夹中的award_type_1拖拽到层级视图中,其tag值改为Award,具体设置如下:

images-p4_52.png

2、award_type_1的SpriteRenderer组件的属性设置如下:

images-p4_53.png

3、给award_type_1添加Polygon Collider 2D碰撞器组件,其属性设置如下:

images-p4_54.png

4、给award_type_1添加AudioSource组件,当超级武器生成后播放声音,其属性设置如下:

images-p4_55.png

5、给award_type_1添加Award脚本组件。

重点代码

代码和超级武器预制体创建代码一样

脚本组件属性设置截图

images-p4_56.png

效果展示图

images-p4_57.png

最后把award_type_1拖拽到Assets下创建预制体即可。

不同敌机和奖励的生成

功能说明

游戏运行后,通过代码会随机生成不同的敌机和奖励。

实现步骤

1、在层级视图中创建空物体,名字改为Spawn,其Transform组件属性设置如下:

images-p4_58.png

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);
    }
}

脚本组件属性设置截图

images-p4_60.png

效果展示图

images-p4_61.png

游戏管理器

功能说明

主要用来管理游戏的开始和暂停,同时播放背景音乐。

实现步骤

1、在层级视图中创建空物体,名字改为GameManager,添加AudioSource组件,用来播放背景音乐,组件属性设置如下:

images-p4_62.png

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;
    }
}

UI界面的搭建

功能说明

主要用来显示分数,炸弹的图标和个数,显示开始和暂停按钮。

实现步骤

1、在层级视图中创建画布Canvas,给Canvas添加AudioSource组件,用来播放点击按钮时的声音,Audio Source组件属性设置如下:

images-p4_64.png

2、在Canvas下创建Image控件,名字改为Start,Start的Rect Transform组件属性设置如下:

images-p4_65.png

3、Start的Image组件属性设置如下:

images-p4_66.png

4、Start的Button组件属性设置如下:

images-p4_67.png

5、在Canvas下创建Image控件,名字改为Pause,Pause的Rect Transform组件属性设置如下:

images-p4_68.png

6、Pause的Image组件属性设置如下:

images-p4_69.png

7、Pause的Button组件属性设置如下:

images-p4_70.png

8、在Canvas下创建Text控件,用来显示分数,Text的Rect Transform组件属性设置如下:

images-p4_71.png

9、Text的Text组件属性设置如下:

images-p4_72.png

10、在Canvas下创建Text控件,名字改为Score,Score的Rect Transform组件属性设置如下:

images-p4_73.png

11、Score的Text组件属性设置如下:

images-p4_74.png

12、在Canvas下创建Image控件,名字改为Bomb,Bomb的Rect Transform组件属性设置如下:

images-p4_75.png

13、Bomb的Image组件属性设置如下:

images-p4_76.png

14、Bomb的Button组件属性设置如下:

images-p4_77.png

15、在Bomb下创建子控件Text,名字改为BombCount,BombCount的Rect Transform组件属性设置如下:

images-p4_78.png

16、BombCount的Text组件属性设置如下:

images-p4_79.png

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;
        }
    }
}

效果展示图

images-p4_81.png