1.创建工程RoguelikeProjeck,导入素材,创建主角
双击Animator里面的controller可以打开动画编辑器状态机,可以修改速度
将主角放入预设中,同样的操作将Anima2放入预设中
Anima1和Anima2状态机一样,共用一套状态机,鼠标右击,点击Create>Animator Overrite Controller>属性中指定Anima1,Anima2的动画拖动到Anima1上,在状态机中将Anima2的动画删除掉,将Anima1的名字改为Anima2在Anima2的Controller属性中指定Anima2,
选中Anima2的状态机,在属性中指定Anima2的动画,再将默认的sprite改为Anima2的第一帧,最后将Anima2也做成预设放入Prafab文件夹中,
依次将每个场景拖入预设中
2.障碍物生成了但没有显示出来,选中某一物体,Sorting Layers属性中Add,点加号设置bgGround,item,role三层,在各个sprite的Sorting Layers属性选择各个层级
- 创建食物,食物的个数,获取食物的位置,随机取得食物
private Vector2 RandomPosition()
{
int positionIndex = Random.Range(0, positionList.Count);
Vector2 pos = positionList[positionIndex];
positionList.RemoveAt(positionIndex);
return pos;
}
private void InstantiateItems(int count, GameObject[] prefabs)
{
for (int i = 0; i < count; i++)
{
Vector2 pos = RandomPosition();
GameObject enemyPrefab = RandomPrefab(prefabs);
GameObject go = Instantiate(enemyPrefab, pos, Quaternion.identity) as GameObject;
go.transform.SetParent(mapHolder);
}
}
- 动画状态机>Make Transtion>添加参数指定状态切换条件(使用Trigger触发器)>选择一条状态切换线>点击condition下的加号选择条件参数>取消Has Exit Time的勾选(马上切换)>Transition Duratio的改为0(瞬时切换);
Damage>idle条件箭头的属性中勾选HasExitTime,ExitTime选为1;Transiton Duration改为0;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
public class GameManager : MonoBehaviour {
private static GameManager _instance;
public static GameManager Instance {
get {
return _instance;
}
}
public int level = 1;//当前关卡
public int food = 100;
public AudioClip dieClip;
[HideInInspector]public List<Enemy> enemyList = new List<Enemy>();
[HideInInspector]public bool isEnd = false;//是否得到终点
private bool sleepStep = true;
private Text foodText;
private Text failText;
private Image dayImage;
private Text dayText;
private Player player;
private MapManager mapManager;
void Awake() {
_instance = this;
DontDestroyOnLoad(gameObject);
InitGame();
}
void InitGame() {
//初始化地图
mapManager = GetComponent<MapManager>();
mapManager.InitMap();
//初始化UI
foodText = GameObject.Find("FoodText").GetComponent<Text>();
UpdateFoodText(0);
failText = GameObject.Find("FailText").GetComponent<Text>();
failText.enabled = false;
player = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>();
dayImage = GameObject.Find("DayImage").GetComponent<Image>();
dayText = GameObject.Find("DayText").GetComponent<Text>();
dayText.text = "Day " + level;
Invoke("HideBlack",1);
//初始化参数
isEnd = false;
enemyList.Clear();
}
void UpdateFoodText(int foodChange) {
if (foodChange == 0) {
foodText.text = "Food:" + food;
}
else {
string str = "";
if (foodChange < 0) {
str = foodChange.ToString();
}
else {
str = "+" + foodChange;
}
foodText.text = str + " Food:" + food;
}
}
public void ReduceFood(int count) {
food -= count;
UpdateFoodText(-count);
if (food <= 0) {
failText.enabled = true;
AudioManager.Instance.StopBgMusic();
AudioManager.Instance.RandomPlay(dieClip);
}
}
public void AddFood(int count) {
food += count;
UpdateFoodText(count);
}
public void OnPlayerMove() {
if (sleepStep==true) {
sleepStep = false;
}
else {
foreach (var enemy in enemyList) {
enemy.Move();
}
sleepStep = true;
}
//检测有没有到达终点
if (player.targetPos.x == mapManager.cols - 2 && player.targetPos.y == mapManager.rows - 2) {
isEnd = true;
//加载下一个关卡
Application.LoadLevel( Application.loadedLevel );//重新加载本关卡
}
}
void OnLevelWasLoaded(int sceneLevel) {
level++;
InitGame();//初始化游戏
}
void HideBlack() {
dayImage.gameObject.SetActive(false);
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MapManager : MonoBehaviour {
public GameObject[] outWallArray;
public GameObject[] floorArray;
public GameObject[] wallArray;
public GameObject[] foodArray;
public GameObject[] enemyArray;
public GameObject exitPrefab;
public int rows=10;
public int cols=10;
public int minCountWall = 2;
public int maxCountWall = 8;
private Transform mapHolder;
private List<Vector2> positionList = new List<Vector2>();
private GameManager gameManager;
// Update is called once per frame
void Update () {
}
//初始化地图
public void InitMap()
{
gameManager = this.GetComponent<GameManager>();
mapHolder = new GameObject("Map").transform;
//下面是创建围墙和地板
for (int x = 0; x < cols; x++) {
for (int y = 0; y < rows; y++) {
if (x == 0 || y == 0 || x == cols - 1 || y == rows - 1) {
int index = Random.Range(0, outWallArray.Length);
GameObject go = GameObject.Instantiate(outWallArray[index], new Vector3(x, y, 0), Quaternion.identity) as GameObject;
go.transform.SetParent(mapHolder);
}
else
{
int index = Random.Range(0, floorArray.Length);
GameObject go = GameObject.Instantiate(floorArray[index], new Vector3(x, y, 0), Quaternion.identity) as GameObject;
go.transform.SetParent(mapHolder);
}
}
}
positionList.Clear();
for (int x = 2; x < cols-2; x++) {
for (int y = 2; y < rows-2; y++) {
positionList.Add(new Vector2(x,y));
}
}
//创建障碍物 食物 敌人
//创建障碍物
int wallCount = Random.Range(minCountWall, maxCountWall + 1);//障碍物的个数
InstantiateItems(wallCount,wallArray);
//创建食物 2 - level*2
int foodCount = Random.Range(2, gameManager.level*2 + 1);
InstantiateItems(foodCount,foodArray);
//创建敌人 // level/2
int enemyCount = gameManager.level/2;
InstantiateItems(enemyCount,enemyArray);
//创建出口
GameObject go4 = Instantiate(exitPrefab, new Vector2(cols - 2, rows - 2), Quaternion.identity) as GameObject;
go4.transform.SetParent(mapHolder);
}
private void InstantiateItems(int count, GameObject[] prefabs) {
for (int i = 0; i < count; i++)
{
Vector2 pos = RandomPosition();
GameObject enemyPrefab = RandomPrefab(prefabs);
GameObject go = Instantiate(enemyPrefab, pos, Quaternion.identity) as GameObject;
go.transform.SetParent(mapHolder);
}
}
private Vector2 RandomPosition() {
int positionIndex = Random.Range(0, positionList.Count);
Vector2 pos = positionList[positionIndex];
positionList.RemoveAt(positionIndex);
return pos;
}
private GameObject RandomPrefab(GameObject[] prefabs) {
int index = Random.Range(0, prefabs.Length);
return prefabs[index];
}
}
using UnityEngine;
using System.Collections;
public class AudioManager : MonoBehaviour {
private static AudioManager _instance;
public static AudioManager Instance {
get { return _instance; }
}
public float minPitch = 0.9f;
public float maxPitch = 1.1f;
public AudioSource efxSource;
public AudioSource bgSource;
void Awake() {
_instance = this;
}
public void RandomPlay(params AudioClip[] clips) {
float pitch = Random.Range(minPitch, maxPitch);
int index = Random.Range(0, clips.Length);
AudioClip clip = clips[index];
efxSource.clip = clip;
efxSource.pitch = pitch;
efxSource.Play();
}
public void StopBgMusic() {
bgSource.Stop();
}
}
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
public float smoothing = 1;
public float restTime = 1;
public AudioClip chop1Audio;
public AudioClip chop2Audio;
public AudioClip step1Audio;
public AudioClip step2Audio;
public AudioClip soda1Audio;
public AudioClip soda2Audio;
public AudioClip fruit1Audio;
public AudioClip fruit2Audio;
private float restTimer = 0;
[HideInInspector]public Vector2 targetPos = new Vector2(1,1);
private Rigidbody2D rigidbody;
private BoxCollider2D collider;
private Animator animator;
// Use this for initialization
void Start () {
rigidbody = GetComponent < Rigidbody2D>();
collider = GetComponent<BoxCollider2D>();
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
rigidbody.MovePosition(Vector2.Lerp(transform.position, targetPos, smoothing * Time.deltaTime));
if (GameManager.Instance.food <= 0 ||GameManager.Instance.isEnd==true ) return;
restTimer += Time.deltaTime;
if (restTimer < restTime) return;
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
if (h > 0) {
v = 0;
}
if (h != 0 || v != 0) {
GameManager.Instance.ReduceFood(1);
//检测
collider.enabled = false;
RaycastHit2D hit = Physics2D.Linecast(targetPos, targetPos + new Vector2(h, v));
collider.enabled = true;
if (hit.transform == null) {
targetPos += new Vector2(h, v);
AudioManager.Instance.RandomPlay(step1Audio,step2Audio);
}
else {
switch (hit.collider.tag) {
case "OutWall":
break;
case "Wall":
animator.SetTrigger("Attack");
AudioManager.Instance.RandomPlay(chop1Audio,chop2Audio);
hit.collider.SendMessage("TakeDamage");
break;
case "Food":
GameManager.Instance.AddFood(10);
targetPos += new Vector2(h, v);
AudioManager.Instance.RandomPlay(step1Audio, step2Audio);
Destroy(hit.transform.gameObject);
AudioManager.Instance.RandomPlay(fruit1Audio,fruit2Audio);
break;
case "Soda":
GameManager.Instance.AddFood(20);
targetPos += new Vector2(h, v);
AudioManager.Instance.RandomPlay(step1Audio, step2Audio);
Destroy(hit.transform.gameObject);
AudioManager.Instance.RandomPlay(soda1Audio,soda2Audio);
break;
case "Enemy":
break;
}
}
GameManager.Instance.OnPlayerMove();
restTimer = 0;//不管是攻击还是移动 都需要休息
}
}
public void TakeDamage(int lossFood) {
GameManager.Instance.ReduceFood(lossFood);
animator.SetTrigger("Damage");
}
}
using UnityEngine;
using System.Collections;
public class Enemy : MonoBehaviour {
private Vector2 targetPosition;
private Transform player;
private Rigidbody2D rigidbody;
public float smoothing = 3;
public int lossFood = 10;
public AudioClip attackAudio;
private BoxCollider2D collider;
private Animator animator;
void Start() {
player = GameObject.FindGameObjectWithTag("Player").transform;
rigidbody = GetComponent<Rigidbody2D>();
collider = GetComponent<BoxCollider2D>();
animator = GetComponent<Animator>();
targetPosition = transform.position;
GameManager.Instance.enemyList.Add(this);
}
void Update() {
rigidbody.MovePosition( Vector2.Lerp(transform.position, targetPosition, smoothing*Time.deltaTime));
}
public void Move() {
Vector2 offset = player.position - transform.position;
if (offset.magnitude < 1.1f) {
//攻击
animator.SetTrigger("Attack");
AudioManager.Instance.RandomPlay(attackAudio);
player.SendMessage("TakeDamage",lossFood);
}
else {
float x = 0, y = 0;
if (Mathf.Abs(offset.y) > Mathf.Abs(offset.x)) {
//按照y轴移动
if (offset.y < 0) {
y = -1;
}
else {
y = 1;
}
}
else {
//按照x轴移动
if (offset.x > 0) {
x = 1;
}
else {
x = -1;
}
}
//设置目标位置之前 先做检测
collider.enabled = false;
RaycastHit2D hit = Physics2D.Linecast(targetPosition, targetPosition + new Vector2(x, y));
collider.enabled = true;
if (hit.transform == null) {
targetPosition += new Vector2(x, y);
}
else {
if (hit.collider.tag == "Food" || hit.collider.tag == "Soda")
{
targetPosition += new Vector2(x, y);
}
}
}
}
}
using UnityEngine;
using System.Collections;
public class Wall : MonoBehaviour {
public int hp = 2;
public Sprite damageSprite;//受到攻击的图片
//自身受到攻击的时候
public void TakeDamage() {
hp -= 1;
GetComponent<SpriteRenderer>().sprite = damageSprite;
if (hp <= 0) {
Destroy(this.gameObject);
}
}
}
using UnityEngine;
using System.Collections;
public class Loader : MonoBehaviour
{
public GameObject gameManager;
void Awake() {
if(GameManager.Instance==null)
GameObject.Instantiate(gameManager);
}
}