其他分享
首页 > 其他分享> > unity3D做2D小游戏飞机大战

unity3D做2D小游戏飞机大战

作者:互联网

**~~

一.飞机

~~ **
在这里插入图片描述

在Assets下面右键Create新建flot命名为Scenes,在右键Create新建Scene命名为MainScene,选中它,点击Create->UI->Canvas
在这里插入图片描述
设置为2D,16:9的画面大小
在这里插入图片描述
在这里插入图片描述

Canvas下面新建text命名为Jet
在这里插入图片描述
这里是已经完成的项目,已经删除了text组件,添加了Image组件
在Assets下新建Flot文件命名为Script。再右键Create新建C# Script文件命名为JecControlScript。双击打开
在这里插入图片描述
当然,有可能是打不开,需要安装Visaul Studio,还需要在Unity中配置一i下
在这里插入图片描述
Edit->Preference->External Tool打开visul studio的exe文件
在这里插入图片描述
JecControlScript代码如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class JecControlScript : MonoBehaviour {
    //RectTransform引用,
    RectTransform rectTransform;
	// Use this for initialization
	void Start () {
        //当对象被放入内存调用
        rectTransform = GetComponent<RectTransform>();
	}
	
	// Update is called once per frame
	void Update () {
        Move();
	}
    void Move() {
        float x_speed = 0;   //横轴速度
        float y_speed = 0;   //纵轴
        if (Input.GetKey(KeyCode.A) == true
            && Input.GetKey(KeyCode.D) == false) {
            x_speed = -300;
        }
        else if (Input.GetKey(KeyCode.D) == true
            && Input.GetKey(KeyCode.A) == false)
        {
            x_speed = +300;
        }
        if (Input.GetKey(KeyCode.W) == true
            && Input.GetKey(KeyCode.S) == false)
        {
            y_speed = +300;
        }
        else if (Input.GetKey(KeyCode.S) == true
            && Input.GetKey(KeyCode.W) == false)
        {
            y_speed = -300;
        }

        //上下左右斜向的速度一样
        if (Mathf.Abs(x_speed) > 1 && Mathf.Abs(y_speed) > 1) {
            x_speed *= Mathf.Sqrt(2) / 2;
            y_speed *= Mathf.Sqrt(2) / 2;
        }
        //取出飞机的当前位置
        Vector2 position = rectTransform.anchoredPosition;
        //修改x坐标
        position.x += x_speed * Time.deltaTime;
        position.y += y_speed * Time.deltaTime;
        //限制x,y的范围,避免超出屏幕
        position.x = Mathf.Clamp(position.x, -360, 360);
        position.y = Mathf.Clamp(position.y, -500, 500);
        //位置修改后再放回去
        rectTransform.anchoredPosition = position;

        
    } 
}

写完后保存回到unity将JecControlScript拖到Jet上面去
在这里插入图片描述
双击Jet看到JecControlScript组件已经添加到里面了在这里插入图片描述
新建img文件夹放图片和音效
在这里插入图片描述
可以直接将图片从其他文件夹拖入这里面,单击图片设置成如下样式,并Apply
在这里插入图片描述
在Add Component中搜索Image Source,添加,然后点击Source Image最后面的圆圈选择图片,将飞机图片添加进去。
在这里插入图片描述

二.子弹

在Canvas下面新建Create Empty命名为BulletsManager在新建text命名为Bullet
在这里插入图片描述
在这里插入图片描述
BulletsManagerScript

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BulletsManagerScript : MonoBehaviour {
    public GameObject originBullet;                 //原始的一发子弹
    public RectTransform rectTransform;             //飞机的位置
    List<GameObject> list = new List<GameObject>(); //装子弹

    AudioSource audioSource;                        //音频组件

    //返回所有子弹
    public List<GameObject> GetList()
    {
        return list;
    }

    // Use this for initialization
    void Start () {
        audioSource = GetComponent<AudioSource>();

        for (int i = 0; i < 50; i++) {
            GameObject bullet = Instantiate(originBullet);
            //将复制的子弹添加到父对象
            bullet.transform.SetParent(this.transform);
            //恢复原始比例
            bullet.transform.localScale = new Vector3(1,2,1);
            list.Add(bullet);
        }
    }
	
	// Update is called once per frame
	void Update () {
        //发射子弹
        if (Input.GetKeyDown(KeyCode.J) == true){
            if (audioSource.isPlaying == true) {
                audioSource.Stop();
            }
            audioSource.Play();

            //找出任意一颗屏幕下方的子弹,拿到屏幕上来
            for (int i = 0; i < list.Count; i++) {
                RectTransform objTrans = list[i].GetComponent<RectTransform>();
                if (objTrans.anchoredPosition.y < -800) {
                    Vector2 position = objTrans.anchoredPosition;
                    position.x = rectTransform.anchoredPosition.x;
                    position.y =rectTransform.anchoredPosition.y+40;
                    objTrans.anchoredPosition = position;
                    break;
                }

            }
        }
        //让屏幕上的子弹飞
        for (int i = 0; i < list.Count; i++) {
            RectTransform objTrans = list[i].GetComponent<RectTransform>();
            if (objTrans.anchoredPosition.y > -600) {
                Vector2 position = objTrans.anchoredPosition;
                position.y += 800 * Time.deltaTime;
                //从屏幕顶端飞出就会回到屏幕下面
                if (position.y > 600) {
                    position.y = -1000;
                }
                objTrans.anchoredPosition = position;
            }

        }
    }
}

三.敌机

在这里插入图片描述
在这里插入图片描述
把该拖得拖进去,这里不赘述了

AlienScript

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AlienScript : MonoBehaviour {
    RectTransform rectTransform;
    public EnemyBulletManagerScript ebs;

	// Use this for initialization
	void Start () {
        rectTransform = GetComponent<RectTransform>();	
	}

    float scaleSpeed = 5f;
	// Update is called once per frame
	void Update () {
        //取出缩放
        Vector3 scale = rectTransform.localScale;
        scale.y += scaleSpeed * Time.deltaTime;
        scale.x -= scaleSpeed * Time.deltaTime;

        rectTransform.localScale = scale;

        if (scaleSpeed > 0 && scale.y > 1
            ||scaleSpeed<0&&scale.y<0.25) {
            scaleSpeed *= -1;
            //缩放时有五分之一几率发射子弹
            if (Random.Range(0, 5) == 0) {
                ebs.Shoot(rectTransform.anchoredPosition);
            }
        }

	}
}

EnemiesManagerScript

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemiesManagerScript : MonoBehaviour {
    //初始敌人
    public GameObject alien;
    List<GameObject> list = new List<GameObject>();

    //返回所有敌人
    public List<GameObject> GetList() {
        return list;
    }

    // Start is called before the first frame update
    void Start()
    {
        //复制敌人
        for (int i = 0; i < 20; i++)
        {
            GameObject a = Instantiate(alien);
            //添加到父对象上
            a.transform.SetParent(this.transform);
            //重设坐标
            a.GetComponent<RectTransform>().anchoredPosition = new Vector2(-2000, 0);
            //调整缩放比例
            a.transform.localScale = new Vector3(1, 0.75f, 1);
            list.Add(a);
        }
    }

    float timeStep = 0;   //计步器
    // Update is called once per frame
    void Update()
    {
        timeStep += Time.deltaTime;
        if (timeStep >= 1f)
        {
            timeStep = 0;
            //生产新的敌人
            for (int i = 0; i < list.Count; i++)
            {
                //获取每个敌人的RectTransform组件
                RectTransform objTrans = list[i].GetComponent<RectTransform>();
                if (objTrans.anchoredPosition.x < -1500)
                {
                    Vector2 position = objTrans.anchoredPosition;
                    position.x = Random.Range(-355, 356);
                    position.y = 600;
                    objTrans.anchoredPosition = position;
                    break;
                }
            }
        }
        //让敌人下落 enemies fall
        for (int i = 0; i < list.Count; i++)
        {
            RectTransform rectTransform = list[i].GetComponent<RectTransform>();
            if (rectTransform.anchoredPosition.x > -1000)
            {
                Vector2 position = rectTransform.anchoredPosition;
                position.y -= 200 * Time.deltaTime;
                if (position.y < -600)
                {
                    position.x = -2000;
                }
                rectTransform.anchoredPosition = position;
            }
        }
    }
}

四.敌人子弹

在这里插入图片描述
在这里插入图片描述
EnemyBulletManagerScript

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyBulletManagerScript : MonoBehaviour {
    public GameObject enemyBullet;
    List<GameObject> list = new List<GameObject>();

    public List<GameObject> GetList() {
        return list;
    }


	// Use this for initialization
	void Start () {
        for (int i = 0; i < 50; i++) {
            GameObject e = Instantiate(enemyBullet);
            e.transform.SetParent(this.transform);
            e.transform.localScale = Vector3.one;
            list.Add(e);
        }
	}
	
	// Update is called once per frame
	void Update () {
        //所有敌人发射了的子弹往下落
        for (int i = 0; i < list.Count; i++) {
            RectTransform ebt = list[i].GetComponent<RectTransform>();
            if (ebt.anchoredPosition.x > -1000) {
                Vector2 position = ebt.anchoredPosition;
                position.y -= 400 * Time.deltaTime;
                if (position.y < -600) {
                    position.x = -2000;
                }
                ebt.anchoredPosition = position;
            }
        }
        
	}
    public void Shoot(Vector2 position) {
        //找一课子弹放到position的位置
        for (int i = 0; i < list.Count; i++) {
            RectTransform ebt = list[i].GetComponent<RectTransform>();
            if (ebt.anchoredPosition.x < -1000) {
                ebt.anchoredPosition = position;
                return;
            }
        }
    }
}

五.爆炸效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
BoomManagerScript

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BoomManagerScript : MonoBehaviour {
    public GameObject boom;     //初始的爆炸效果
    List<BoomScript> list = new List<BoomScript>();

    // Start is called before the first frame update
    void Start()
    {
        //复制爆炸效果
        for (int i = 0; i < 10; i++)
        {
            GameObject b = Instantiate(boom);
            b.transform.SetParent(this.transform);
            b.transform.localScale = Vector3.one * 2;
            list.Add(b.GetComponent<BoomScript>());
        }
    }

    // Update is called once per frame
    void Update()
    {

    }

    //根据位置演示爆炸效果
    public void Boom(Vector2 position)
    {
        
        for (int i = 0; i < list.Count; i++)
        {
            if (list[i].isBoom == false)
            {
                list[i].GetComponent<RectTransform>().anchoredPosition = position;
                list[i].Boom();
                break;
            }
        }
    }
}


BoomScript

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BoomScript : MonoBehaviour {
    public RectTransform[] positions;   //四个爆炸块
    public bool isBoom = false;         //爆炸音效

    //爆炸
    public void Boom() {
        isBoom = true;
        audioSource.Play();
    } 

    AudioSource audioSource;

	// Use this for initialization
	void Start () {
        audioSource = GetComponent<AudioSource>();
	}
	
	// Update is called once per frame
	void Update () {
        if (isBoom == false) {
            return;
        }
        //创建四个速度
        Vector2[] speed ={
            new Vector2(-800,800),
            new Vector2(800,800),
            new Vector2(-800,-800),
            new Vector2(800,-800)
        };
        for (int i = 0; i < positions.Length; i++) {
            Vector2 pos=positions[i].anchoredPosition;
            pos += speed[i] * Time.deltaTime;
            positions[i].anchoredPosition = pos;
        }
        if (positions[0].anchoredPosition.x < -2000) {
            //复位
            positions[0].anchoredPosition = new Vector2(-20, 20);
            positions[1].anchoredPosition = new Vector2(20, 20);
            positions[2].anchoredPosition = new Vector2(-20, -20);
            positions[3].anchoredPosition = new Vector2(20, -20);

            isBoom = false; //非爆炸状态,待命状态
            GetComponent<RectTransform>().anchoredPosition = new Vector2(2000, 0);
        }
	}
}

六.撞击检测

在这里插入图片描述
AttackCheckScript

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AttackCheckScript : MonoBehaviour {
    public BulletsManagerScript bms;    //自己的子弹
    public EnemiesManagerScript ems;    //敌人的碰撞体
    public BoomManagerScript bombms;    //爆炸管理器

    public RectTransform jetTrans;      //自己碰撞体
    public EnemyBulletManagerScript ebms;//敌人子弹管理器

    public GameObject panel;            //菜单
	// Use this for initialization
	void Start () {
        Time.timeScale = 1; //时间恢复
	}
	
	// Update is called once per frame
	void Update () {
        List<GameObject> bullets = bms.GetList();
        List<GameObject> enemies = ems.GetList();

        //判断子弹和敌人是否相交
        for (int i = 0; i < bullets.Count; i++) {
            RectTransform bulletTrans = bullets[i].GetComponent<RectTransform>();
            if (bulletTrans.anchoredPosition.y > 540 
                || bulletTrans.anchoredPosition.y < -540) {
                continue;
            }

            for (int j = 0; j < enemies.Count; j++) {
                RectTransform enemyTrans = enemies[j].GetComponent<RectTransform>();
                if (enemyTrans.anchoredPosition.x < -1500) {
                    continue;
                }
                //判断子弹和敌人是否相交
                if (OnAttack(bulletTrans,enemyTrans,Vector2.one,Vector2.one) == true) {
                    Vector2 position = bulletTrans.anchoredPosition;
                    position.y = -1000;
                    bulletTrans.anchoredPosition = position;

                    position = enemyTrans.anchoredPosition;

                    //插入爆炸动画效果
                    bombms.Boom(position);

                    position.x = -2000;
                    enemyTrans.anchoredPosition = position;
                }
            }
        }
        List<GameObject> ebullets = ebms.GetList();
        for (int i = 0; i < ebullets.Count; i++) {
            if (OnAttack(jetTrans, ebullets[i].GetComponent<RectTransform>(), Vector2.one * 0.8f, Vector2.one)) {
                Time.timeScale = 0; //程序暂停
                //显示菜单
                panel.SetActive(true);
            }
        }

    }
    //判断两个矩形是否相交
    bool OnAttack(RectTransform p1,RectTransform p2,Vector2 offset1,Vector2 offset2) {
        Vector2 position1 = p1.anchoredPosition;
        Vector2 size1 = p1.sizeDelta;
        size1.x *= p1.localScale.x;
        size1.x *= offset1.x;
        size1.y *= p1.localScale.y;
        size1.y *= offset1.y;

        Vector2 position2 = p2.anchoredPosition;
        Vector2 size2 = p2.sizeDelta;
        size2.x *= p2.localScale.x;
        size2.y *= p2.localScale.y;
        size2.x *= offset2.x;
        size2.y *= offset2.y;

        //p1左边界,右,上,下边界
        float x1a = position1.x - size1.x / 2;
        float x1b = position1.x + size1.x / 2;
        float y1a = position1.y + size1.y / 2;
        float y1b = position1.y - size1.y / 2;

        //p2左边界,右,上,下边界
        float x2a = position2.x - size2.x / 2;
        float x2b = position2.x + size2.x / 2;
        float y2a = position2.y + size2.y / 2;
        float y2b = position2.y - size2.y / 2;

        //判断横轴相交
        if (x1a < x2b && x1b > x2a || x2a < x1b && x2b > x1a) {
            if (y1a > y2b && y1b < y2a || y2a > y1b && y2b < y1a) {
                return true;
            }
        }
        return false;
    }
}

七.背景

在这里插入图片描述
BackGroundScript

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BackGroundScript : MonoBehaviour {

    public RectTransform[] bs;

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
        for (int i = 0; i < bs.Length; i++) {
            Vector2 pos = bs[i].anchoredPosition;
            pos.y -= 50 * Time.deltaTime;
            if (pos.y <= -1080) {
                pos.y += 2160;      //从最下面回到最上面
            }
            bs[i].anchoredPosition = pos;
        }	
	}
}

八.音效

AudioScript

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AudioScript : MonoBehaviour {

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
		
	}
}

九.菜单

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里需要说一下在Button下选择Menu Script->Quit
在这里插入图片描述
在这里插入图片描述
这里也要修改一下Menu Script->Restart
在这里插入图片描述
MenuScript

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class MenuScript : MonoBehaviour {
    public void Restart() {
        //载入场景,既可以载入当前场景,又可以切换到其他场景
        //Time.timeScale = 1;
        SceneManager.LoadScene("MainScene");
    }

    public void Quit() {
        //退出程序
        Application.Quit();
    }
}

下面附带自己画的像素图片,想画可以自己画app链接:https://pan.baidu.com/s/1Mju7Qo0s_EuyBfWdWG315g
提取码:kdrj
复制这段内容后打开百度网盘手机App,操作更方便哦
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

最后我把我的项目打包放在百度网盘里,我只是入门,水平不高,继续努力吧。
链接:https://pan.baidu.com/s/1Q2RQ1UN1gu0cfZtfXqA49Q
提取码:aj92
复制这段内容后打开百度网盘手机App,操作更方便哦

标签:unity3D,anchoredPosition,Vector2,list,2D,小游戏,using,position,public
来源: https://blog.csdn.net/weixin_43820992/article/details/89922653