版權聲明:
- 本文原創發布於博客園"優夢創客"的博客空間(網址:
http://www.cnblogs.com/raymondking123/
)以及微信公眾號"優夢創客"(微信號:unitymaker) - 您可以自由轉載,但必須加入完整的版權聲明!
雪人兄弟游戲開發過程:
場景搭建:
1.將Map地圖拖入場景,
2.創建一個ground空對象給這個對象添加一些Collider 2D 組件,把這些Collide2D覆蓋到地圖可以行走的地方,創建以個wall空對象給這個對象添加兩個Collider 2D組件,把這兩個 Collide2D 覆蓋到地圖的兩側。
創建主角:
1.創建hero對象給其一張主角的圖片精靈,給hero對象添加Rigidbody2D和Collider 2D組件使其可以進行物理運動和碰撞行為;
2. 創建動畫控制器,編輯一些主角行為的的動畫,再用動畫控制器進行控制;
3. 添加HeroMove腳本,通過編輯代碼使主角可以移動和跳躍;
//Update時通過射線檢測判斷是否可以跳躍:
RaycastHit2D hit = Physics2D.Linecast(this.transform.position, t.position, 1 << LayerMask.NameToLayer("ground"));
//Debug.DrawLine(this.transform.position, t.position);// t.position
//print((bool)hit);
if (Input.GetButtonDown("Jump") && hit)
{
jump = true;
}
···
//FixedUpdate
bool speed = false; //觸發動畫的布爾變量
float h = Input.GetAxis("Horizontal");
if (h != 0)
{
speed = true;
}
Vector2 force = new Vector2(h * moveForce, 0);
//限制移動速度
if (Mathf.Abs(rb.velocity.x) < maxSpeed)
{
GetComponent<Animator>().SetBool("Speed", speed);
rb.AddForce(force);
}
if (Mathf.Abs(rb.velocity.x) >= maxSpeed)
{
rb.velocity = new Vector2(Mathf.Sign(rb.velocity.x) * maxSpeed, rb.velocity.y);
}
//動畫方向轉變
if (h < 0)
{
var s = this.transform.localScale;
s.x = Mathf.Abs(-s.x);
this.transform.localScale = s;
}
else if (h > 0)
{
var s = this.transform.localScale;
s.x = -Mathf.Abs(-s.x);
this.transform.localScale = s;
}
//跳躍
if (jump)
{
GetComponent<Animator>().SetTrigger("jump");
rb.AddForce(Vector2.up * jumpForce);
jump = false;
}
4.讓主角可以發射子彈:
1. 制作子彈預制體 ,
2.給hero添加一個子節點Gun作為生成子彈的點,並添加腳本控制子彈的發射和行為。
void Update () {
if (Input.GetButtonDown("Fire1"))
{
this.transform.parent.gameObject.GetComponent<Animator>().SetTrigger("Shoot");
var rocket = Instantiate(rocketPrefab);
rocket.transform.position = this.transform.position;
if (this.transform.parent.localScale.x > 0)
{
rocket.transform.rotation = Quaternion.Euler(0, 0, 0);
rocket.GetComponent<Rigidbody2D>().velocity = new Vector2(speed, 0);
}
else
{
rocket.transform.rotation = Quaternion.Euler(0, 0, 180);
rocket.GetComponent<Rigidbody2D>().velocity = new Vector2(-speed, 0);
}
}
}
創建敵人:
1.創建一個monsters空對象為了確定敵人生成的位置:
2. 創建monster對象給其一張敵人的圖片精靈,給monster對象添加Rigidbody2D和Collider2D組件使其可以進行物理運動和碰撞行為,並把它做成預制體。
3. 添加Monster腳本,通過編輯代碼使敵人可以移動和跳躍;
public class Monster : MonoBehaviour
{
// public float speed = 3;
private float MonsterMoveForce = 0.8f; //速度
//private float MonsterMaxSpeed = 0.5f; //限制速度
public float monsterJumpForce = 600f; //= 2.8f;
private bool monsterJump = false;
private Transform topCheck;
private Transform frontCheck;
private Transform downCheck;
int h;
private int hp = 1;
public GameObject snowball;
public void Start()
{
topCheck = transform.Find("topCheck");
frontCheck = transform.Find("frontCheck");
downCheck = transform.Find("DownCheck");
}
public void Update()
{
if (hp <= 0)
{
Vector2 s = this.transform.position;
hp = 0;
Destroy(this.gameObject);
GameObject g = Instantiate(snowball);
g.transform.position = s;
return;
}
}
public void FixedUpdate()
{
// 跳躍
RaycastHit2D hit1 = Physics2D.Linecast(topCheck.position, this.transform.position, 1 << LayerMask.NameToLayer("ground"));
RaycastHit2D hit2 = Physics2D.Linecast(downCheck.position, this.transform.position, 1 << LayerMask.NameToLayer("ground"));
RaycastHit2D hit = Physics2D.Linecast(frontCheck.position, this.transform.position);
h = Random.Range(0, 100);
Rigidbody2D rb = this.transform.gameObject.GetComponent<Rigidbody2D>();
Debug.DrawLine(this.transform.position, topCheck.position);
Debug.DrawLine(this.transform.position, downCheck.position);
Debug.DrawLine(this.transform.position, frontCheck.position);
if (hit && hit.transform.gameObject.tag == "wall" || hit.transform.gameObject.tag == "destroyer")
{
Vector3 s = this.transform.localScale;//
s.x = -s.x;
this.transform.localScale = s;
}
else if (hit2 && hit && hit.transform.gameObject.tag == "ground")
{
monsterJump = true;
}
else
{ //隨機方向
if (h == 2)
{
Vector3 s = this.transform.localScale;
s.x = -s.x;
this.transform.localScale = s;
}
}
//移動
Vector2 x = new Vector2(-this.transform.localScale.x * MonsterMoveForce, rb.velocity.y);
rb.velocity = x;
this.gameObject.GetComponent<Animator>().SetTrigger("move");
//跳躍
if (hit1 && hit2 && h == 3)
{
monsterJump = true;
}
if (monsterJump)
{
rb.AddForce(Vector2.up * monsterJumpForce);
monsterJump = false;
}
}
public void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "ground")
{
this.gameObject.GetComponent<Animator>().SetTrigger("ground");
}
if (collision.gameObject.tag == "bullet")
{
hp--;
}
}
public void OnCollisionExit2D(Collision2D collision)
{
if (collision.gameObject.tag == "ground")
{
this.gameObject.GetComponent<Rigidbody2D>().velocity = new Vector2(0, 0);
this.gameObject.GetComponent<Animator>().SetTrigger("groundl");
}
}
}
創建雪球:
1. 創建snowball對象給其一張默認的圖片精靈,給snowball對象添加Rigidbody2D和lColider2D組件使其可以進行物理運動和碰撞行,並把它做成預制體。
2.給snowball對象添加腳本通過編輯代碼,添加狀態機使雪球狀態可以切換。
public class Snowball : MonoBehaviour
{
StateMachine<Snowball> stateMachine = new StateMachine<Snowball>();
public Sprite snowball1;
public Sprite snowball2;
public Sprite snowball3;
public GameObject monster;
public Transform frontCheck;
public GameObject[] props;
public GameObject balldestory;
// Use this for initialization
//雪球狀態
public class SnowballStateB : State<Snowball>
{
public float explodeTime = 0;
public bool gun = false;
public float gunForce = 3f;
float dir;
public override void Enter(Snowball e)
{
e.gameObject.GetComponent<SpriteRenderer>().sprite = e.snowball1; //獲的圖片
e.gameObject.GetComponent<Animator>().SetTrigger("snowball1");
e.frontCheck = e.transform.Find("frontCheck");
e.gameObject.layer = LayerMask.NameToLayer("snowball");
}
public override void Update(Snowball e)
{
//雪球沒滾時隔 6 個時間點恢復成版雪球
if (gun == false)
{
explodeTime += Time.deltaTime;
if (explodeTime > 6)
{
explodeTime = 0;
e.stateMachine.ChangeState(new SnowballStateA());
return;
}
}
else if (gun)
{
Rigidbody2D rb = e.gameObject.GetComponent<Rigidbody2D>();
rb.freezeRotation = false;
Vector2 v = new Vector2(dir * gunForce, rb.velocity.y);
// rb.AddForce(v);
rb.velocity = v;
Collider2D[] enemies = Physics2D.OverlapCircleAll(e.transform.position, 0.05f, 1 << LayerMask.NameToLayer("monster"));
foreach (Collider2D a in enemies)
{
Vector2 s = a.gameObject.transform.position;
Destroy(a.gameObject);
GameObject prop = Instantiate(e.props[Random.Range(0, e.props.Length)]);
prop.transform.position = s;
}
}
}
public override void OnCollisionStay2D(Snowball e, Collision2D collision)
{
ContactPoint2D[] a = collision.contacts;
if (gun == false)
{
if (collision.gameObject.tag == "player" && collision.gameObject.transform.FindChild("Gun").GetComponent<Gun>().isFire)
{
// dir = -GameObject.Find("hero").transform.localScale.x;
gun = true;
dir = -collision.transform.localScale.x;
}
}
}
public override void OnCollisionEnter2D(Snowball e, Collision2D collision)
{
if (gun == false)
{
if (collision.gameObject.tag == "snowball")
{
gun = true;
dir = -collision.transform.localScale.x;
}
}
if (gun)
{
if (collision.gameObject.tag == "wall" || collision.gameObject.tag == "snowball")
{
dir = -dir;
}
if (collision.gameObject.tag == "player")
{
//TODO
//雪球帶着主角走
//transform.SetParent//設置父節點
//collision.transform.SetParent(e.transform);
//collision.transform.position = e.transform.position;
//torque //旋轉
}
}
if (collision.gameObject.tag == "destroyer")
{
e.gameObject.GetComponent<Animator>().SetTrigger("destrayer");
}
}
public override void Exit(Snowball e)
{
}
}
//半雪球狀態
public class SnowballStateA : State<Snowball>
{
public float explodeTime = 0;
int hp = 0;
public override void Enter(Snowball e)
{
e.gameObject.GetComponent<SpriteRenderer>().sprite = e.snowball2;
e.gameObject.GetComponent<Animator>().SetTrigger("snowball2");
e.gameObject.layer = LayerMask.NameToLayer("monster");
hp = 2;
}
public override void Update(Snowball e)
{
print(hp);
if (hp <= 0)
{
e.stateMachine.ChangeState(new SnowballStateB());
return;
}
explodeTime += Time.deltaTime;
if (explodeTime > 5 && hp > 0)
{
explodeTime = 0;
e.stateMachine.ChangeState(new SnowballState());
return;
}
}
public override void Exit(Snowball e)
{
}
public override void OnCollisionEnter2D(Snowball e, Collision2D collision)
{
if (collision.gameObject.tag == "bullet")
{
hp--;
}
}
}
//monster被攻擊狀態;
public class SnowballState : State<Snowball>
{
public float explodeTime = 0;
Vector3 s;
public int hp = 0;
public override void Enter(Snowball e)
{
//取得圖片精靈
e.gameObject.GetComponent<SpriteRenderer>().sprite = e.snowball3;
e.gameObject.GetComponent<Animator>().SetTrigger("snowball3");
e.gameObject.layer = LayerMask.NameToLayer("monster");
hp = 3;
}
public override void Update(Snowball e)
{
print(hp);
if (hp <= 0)
{
e.stateMachine.ChangeState(new SnowballStateA());
hp = 0;
return;
}
explodeTime += Time.deltaTime;
print(explodeTime);
//經過多少時
if (explodeTime > 4 && hp > 0)
{
explodeTime = 0;
hp = 0;
s = e.gameObject.transform.position;
GameObject g = Instantiate(e.monster);
g.transform.position = s;
Destroy(e.gameObject);
return;
}
}
public override void OnCollisionEnter2D(Snowball e, Collision2D collision)
{
if (collision.gameObject.tag == "bullet")
{
hp--;
}
}
}
void Start()
{
stateMachine.Init(this, new SnowballState());
}
// Update is called once per frame
void Update()
{
}
public void FixedUpdate()
{
stateMachine.Update();
}
public void OnCollisionEnter2D(Collision2D collision)
{
stateMachine.OnCollisionEnter2D(this, collision);
}
public void OnCollisionStay2D(Collision2D collision)
{
stateMachine.OnCollisionStay2D(this, collision);
}
public void Destory()
{
Instantiate(balldestory);
Destroy(this.gameObject);
}
}
創建道具
1.添加道具預制體.
2.雪球撞到敵人時敵人死亡,在敵人死亡的地方隨機生成一種道具。
3.主角吃到道具增加屬性或者加分。
過關判定
- 判斷場景中沒有敵人並且沒有雪球並且沒有道具就過關了。