仿 微信飞机大战项目

    一、 背景的循环播放

        思想:两张(或多张)背景图片循环向下移动,造成背景的动态效果。

 .
 .
public float mov_Speed =2f;  //定义背景图片移动速度
void Update()
{
    this.transform.Translate(Vector3.down * mov_Speed * Time.deltaTime) //图片(背景图片实例)向下移动
    Vector3 position = this.transform.position; //得到背景图片位置信息,为控制移动范围做准备
    if(position.y<=-8.52f)  //向下移动一定距离,循环(一般为图片的一半)
    {
        this.transform.position=new Vector3(position.x,position.y+8.52f * 2,position.z);
    }
    
}

    二、 主角的动态飞行效果

             230302_ldB1_2376190.gif

       思想:sprite 数组存贮 飞机的状态帧,循环播放图片

Private SpriteRenderer spriteRenderer;  //实例化动画精灵组件
public Sprite [] sprites; //创建 sprite 数组 存储动画帧
public int frameCountPersconds = 10; //每秒播放动画的帧数
void Start()
{
    spriteRenderer =  this.GetComponent();} // GetComponent方法得到SpriteRenderer组件
}
void Update()
{
    timer+=Time.deltaTime;  //得到游戏当前时间
    int framIndex = int((timer)/(1f/frameCountPersconds )); //得到当前播放帧
    int fram=framIndex%2; //求余得到 0、1、0、1循环
    spriteRenderer .sprite=sprites[fram]; //切换当前帧
}

    三、 敌机及奖励物品生成器Spawn

        思想:InvokeRepeating()函数

public GameObject Enemy0Prefab; 
public GameObject Enemy1Prefab;     //三种敌机实例
public GameObject Enemy2Prefab; 
public float Enemy0Rate = 8f;
 public float Enemy1Rate = 9f;
 public float Enemy2Rate = 40f;      //生成时间间隔
 public float Award1Rate=30f;
 public float Award2Rate=40f;
void Update()
{
    nvokeRepeating("CreateEnemy0",3,Enemy0Rate);
    InvokeRepeating("CreateEnemy1",5,Enemy1Rate);         
                                                    //InvokeRepeating(),延迟1s后,每EnemyRate时间后,执行CreateEnemy函数一次
    InvokeRepeating("CreateEnemy2",8,Enemy2Rate);
    InvokeRepeating("CreateAward1",30,Award1Rate);
    InvokeRepeating("CreateAward2",40,Award2Rate);}
public CreateEnemy0()
{
    float x= float x = Random.Range(-2.15f,2.15f);  //随机位置生成
    GameObject.Instantiate(Enemy0Prefab,Vector3(x,transform.position.y,0),Quaternion.identity); 
    //Instantiate函数生成物体
}
public void CreateEnemy1()
 {
    float x = Random.Range(-2.04f,2.04f);
    GameObject.Instantiate(Enemy1Prefab,new Vector3(x,transform.position.y,0),Quaternion.identity);
 }
 public void CreateEnemy2()
 {
    float x = Random.Range(-1.57f,1.57f);
    GameObject.Instantiate(Enemy2Prefab,new Vector3(x,transform.position.y,0),Quaternion.identity);
 }
 public void CreateAward1()
 {
    float x = Random.Range(-2.12f,2.12f);
    GameObject.Instantiate(AwardPrefab1,new Vector3(x,transform.position.y,0),Quaternion.identity);
 }
 public void CreateAward2()
 {
    float x = Random.Range(-2.12f,2.12f);
    GameObject.Instantiate(AwardPrefab2,new Vector3(x,transform.position.y,0),Quaternion.identity);
 }

     四、 两种子弹的发射(条件发射)

        思想:Instantiate+InvokeRepeating,构造openFire()控制

-----Gun( )-----
public GameObject bullet; //子弹实例
public float rate =0.2f //发射间隔
public Fire()
{
    GameObject.Instantiate(bullet,transform.positon,Quaternion.identity); //生成子弹
} 
public openFire()
{
    InvokeRepeating(Fire,1,rate);
}
public stopFire()
{
    CancelInvoke("Fire");
}
public Gun topGun;
public Gun leftGun;
public Gun rightGun;
public float superGunTime =10f;  //持续时间
public int gunCount =1; //触发切换标志位
void Strat()
{    
    resetsuperGunTime = superGunTime;
    superGunTime = 0;
    gunTop.OpenFire();
}
void Update()
{
    superGunTime-=time.deltaTime
    if(superGunTime>0)
    {
       if(gunCount=1)
       {
            transformToSuperGun()
        }
    } else
    {
       if(gunCount=2)
       {
            transformToNormalGun()
        }
    }
}
private void transformToSuperGun()
{
    gunCount=2;
    gunLeft.openFire();
    gunRight.openFire();
    gunTop.sotpFire();
}
private void transformToNormalGun()
{
    gunCount=1;
    gunLeft.stopFire();
    gunRight.stopFire();
    gunTop.openFire();
}
pubic void OnTriggerEnter2D()
{
    if(collider.tag=="Award")
  {
   Award award = collider.GetComponent();                        //(触发条件)碰撞检测
   if(award.type==0)
   {
    superGunTime = resetsuperGunTime;   //发生碰撞则重置标志位
    Destroy(collider.gameObject);
   }
}

         五、 鼠标(触摸)控制飞机的移动,及边界检测

        思想:GetMouseButtonDown()函数检测鼠标是否按下

public bool isMouseDown =false;
private Vector3 lastMousePosition =Vector3.Zero;  //初始位置
void Update()
{
    if(Input.GetMouseButtonDown(0))
    {
        isMouseDown =true;
    }
    if(Input.GetMouseButtonUp(0))
    {
        isMouseDown =false;
        lastMousePosition =Vector3.Zero;
    }
    if(isMouseDown)
    {
        Vector3 offSet =Input.mouseposition - lastMousePosition;   //鼠标位移量
        transform.position+=offSet;  //鼠标当前位置 = 鼠标初始位置 + 鼠标位移量
    }
    lastMousePosition = Input.mouseposition;  //更新鼠标位置
}

         注意:这样写有一个问题,所有的位置信息x、y、z都是像素坐标,而控制主角移动是以屏幕坐标为准,所以要把像素坐标转化为屏幕坐标:用到函数Camera.main.ScreenToWorldPoint()

         lastMousePosition = Input.mouseposition;    -->  lastMousePosition = Camera.main.ScreenToWorldPoint         ( Input.mouseposition);

         Vector3 offSet =Input.mouseposition - lastMousePosition;  -->  Vector3 offSet = Camera.main.ScreenToWorldPoint(Input.mouseposition) - lastMousePosition;

    边界检测:

void checkPositon()
{
    Vector3 pos =transform.position;   //得到当前位置
    float x =pos.x;
    float y =pos.y;
    if(x<-2.2f)
    x=-2.2f;
    if(x>2.2f)
    x=2.2f;
    if(y<-3.9f)
    y=-3.9f;
    if(y>3.4f)
    y=3.4f;
    transform.position = new Vector3(x,y,0);   //重置当前位置 
}

        六、 主角和敌机的死亡动画

    同主角的动画思想一致,只不过先要判断是否发生碰撞,若碰撞则播放动画。

        七、 UI界面部分

        思想:使用单例模式,统一在GameManager 里管理

using UnityEngine;
using System.Collections;
public class GameManager : MonoBehaviour 
{
 public static GameManager  _instance; 
}
void Awake()
{
    _instance=this;
}

    _instance是一个静态的句柄,在Awake()中指向自身实例,这样我们就可以在其它类中使用GameManager。_instance的形式直接取得GameManager实例,但是GameManager只能有一个实例。

转载于:https://my.oschina.net/Magicwu/blog/484804

你可能感兴趣的:(仿 微信飞机大战项目)