经典小游戏开发思路和算法之推箱子(2)

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42855293/article/details/86030578

游戏简介:推箱子是一个超经典的游戏,目的是锻炼玩家的逻辑思考能力。
游戏规则:这个游戏是在一个正方形的棋盘上进行的,每一个方块表示一个地板或一面墙。地板可以通过,墙面不可以通过。地板上放置了箱子,一些地板被标记为储存位置。玩家被限定在棋盘上,可以水平或垂直移动到空的方块上(不会穿过墙或箱子)。箱子不得被推入其他箱子或墙壁,也不能被拉出。箱子的数量等于储存位置的数量。当所有箱子都被安放到储存地点时,游戏胜利。
开发思路:首先是生成地图,用二维数组来储存地图信息,每个元素用不同的数字来标记不同的对象。(例如:0表示空白,1表示墙,2表示角色,3表示箱子,9表示终点(中间空余的值是为了方便添加其他颜色的箱子等))。
地图的生成:通过遍历地图二维数组,读取每个元素的数值,根据数值标记生成不同的地图对象。也可用一维数组表示,其二维数组映射到一维数组的公式为: b[in+j]==a[i][j].其中,设数组有m行n列,i,j分别表示数组内的行数和列数(0<i<m,o<j<n).
角色移动:使角色在9
9的一位数组中移动,其中左上角为原点。
箱子移动:与角色移动相同。
游戏实现
代码如下:

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

public class Done_Build : MonoBehaviour
{
    public static int[] temp_map;
    public int[] final_map;
    public GameObject[] destoryObj;
    public Sprite[] mapSprites;
    public bool playerDestory = false;
    public bool boxDestory = false;


    GameObject g;

    public GameObject mapPrefab;//地图的墙壁
    public GameObject playerPrefab;//角色
    public GameObject boxPrefab;//箱子
    public GameObject finalBoxPrefab;//到终点后的箱子
    public GameObject finalPrefab;//游戏获胜后刷新一张图片,用于提示游戏获胜。

    /// <summary>
    /// 数组初始化
    /// </summary>
    private void Awake()
    {
        
        final_map = new int[9 * 9];//传值数组
        temp_map = new int[]
            {
                1, 1, 1, 1, 1, 0, 0, 0, 0,
                1, 2, 0, 0, 1, 0, 0, 0, 0,
                1, 0, 3, 0, 1, 0, 1, 1, 1,
                1, 0, 3, 0, 1, 0, 1, 9, 1,
                1, 1, 1, 3, 1, 1, 1, 9, 1,
                0, 1, 1, 0, 0, 0, 0, 9, 1,
                0, 1, 0, 0, 0, 1, 0, 0, 1,
                0, 1, 0, 0, 0, 1, 1, 1, 1,
                0, 1, 1, 1, 1, 1, 0, 0, 0

            };

        for (int i = 0; i < 9; i++)
        {
            for (int j = 0; j < 9; j++)
            {
                final_map[j * 9 + i] = temp_map[j * 9 + i];
            }
        }
    }



    // Use this for initialization
    void Start()
    {
        BuildMap();
    }

    /// <summary>
    /// 地图初始化
    /// </summary>
    void BuildMap()
    {

        destoryObj = new GameObject[9 * 9];//用于销毁GameObject

        int i = 0;
        for (int y = 0; y < 9; y++)
        {
            for (int x = 0; x < 9; x++)
            {
                
               
                switch (temp_map[i])
                {
                    
                    case 1: //生成墙壁
                    case 0://无图
                
                    g = Instantiate(mapPrefab) as GameObject;
                    g.transform.position = new Vector3(x, -y, 0);
                    g.name = x.ToString() + y;

                    destoryObj[y * 9 + x] = g;

                    Sprite icon = mapSprites[temp_map[i]];//使贴图与地图数组吻合
                    g.GetComponent<SpriteRenderer>().sprite = icon;
                        break;
                        
                    case 2://生成人物

                    g = Instantiate(playerPrefab) as GameObject;
                    g.transform.position = new Vector3(x, -y, 0);
                    g.name = "Player";

                    destoryObj[y * 9 + x] = g;
                        break;

                    
                    case 3://生成箱子

                    g = Instantiate(boxPrefab) as GameObject;
                    g.transform.position = new Vector3(x, -y, 0);
                    g.name = "Box";

                    destoryObj[y * 9 + x] = g;
                        break;
                        
                }
                if (i < 80)
                {
                    i++;
                }
            }
        }
    }
    
    /// <summary>
    /// 角色移动
    /// </summary>
    void PlayerMove()
    {//获取各项数值

        int x, y;
        int x_num = 0;
        int y_num = 0;

        //获取Player坐标
        Transform playerPos = GameObject.Find("Player").GetComponent<Transform>();
        x = (int)playerPos.position.x;
        y = (int)playerPos.position.y;

        //获取界面移动坐标数值
        x_num = FindObjectOfType<Done_GameController>().x_num;
        y_num = FindObjectOfType<Done_GameController>().y_num;

        //获取动画 一定要放在销毁Player前
        string animator_name = FindObjectOfType<Done_GameController>().animator_name;

        //销毁原有Player
        Destroy(destoryObj[-y*9+x]);

       
        g = Instantiate(playerPrefab) as GameObject;

        g.GetComponent<Animator>().Play(animator_name);
        g.transform.position = new Vector3(x + x_num, y + y_num, 0);
        g.name = "Player";

        //将新的Player存入销毁数组
        destoryObj[-((y + y_num) * 9) + x + x_num] = g;
        playerDestory = false;
    }
    /// <summary>
    /// 箱子移动
    /// </summary>
    void BoxMove()
    {//获取各项数值

        int x, y;
        int x_num = 0;
        int y_num = 0;


        //获取界面移动坐标数值及Box界面编号
        x_num = FindObjectOfType<Done_GameController>().x_num;
        y_num = FindObjectOfType<Done_GameController>().y_num;


        //获取相应Box坐标
        Transform playerPos = GameObject.Find("Player").GetComponent<Transform>();
        x = (int)playerPos.position.x + x_num;//Player的X坐标+x_num为下一个目标点的X坐标,即为相应Box的X坐标,Y同理
        y = (int)playerPos.position.y + y_num;

        //销毁原有Box
        Destroy(destoryObj[-y * 9 + x]);
        
        if (final_map[-((y + y_num) * 9) + x + x_num]== 0 || final_map[-((y + y_num) * 9) + x + x_num] == 3)
        {
            g = Instantiate(boxPrefab) as GameObject;
            g.transform.position = new Vector3(x + x_num, y + y_num, 0);
            g.name = "Box";
        }

        else if (final_map[-((y + y_num) * 9) + x + x_num] == 9)
        {
            g = Instantiate(finalBoxPrefab) as GameObject;
            g.transform.position = new Vector3(x + x_num, y + y_num, 0);
            g.name = "FinalBox";
        }
        //将新的Box存入销毁数组
        destoryObj[-((y + y_num) * 9) + x + x_num] = g;
        playerDestory = false;
        boxDestory = false;
    }

    private void Update()
    {
        if (playerDestory)//如果Player移动并且原有Player需要销毁
        {
            if (boxDestory)//如果Box移动并且原有Box需要销毁
            {
                BoxMove();
            }
            PlayerMove();
        }
        //游戏结束判定
        if (GameObject.Find("Box") == null&&GameObject.Find("Final")==null)
        {
            g = Instantiate(finalPrefab) as GameObject;
            g.transform.position = new Vector3(4, -4, 0);
            g.name = "Final";
        }
    }
}

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

public class Done_GameController : MonoBehaviour {
    
    
    public int x_num = 0;
    public int y_num = 0;
    public bool IsChange = false;
    public int box_num;
    public string animator_name;
 


  
    
  

    // Use this for initialization
    void Start()
    {
      
    }

    public bool IsMove()
    {
        int x, y;
        
        //获取Player坐标
        Transform playerPos = GameObject.Find("Player").GetComponent<Transform>();
        x = (int)playerPos.position.x;
        y = (int)playerPos.position.y;

        GameObject g;



        // 如果人物下一个运动目标点为空
        
        if ((Done_Build.temp_map[-y * 9 + x + (int)dir] == 0 || Done_Build.temp_map[-y * 9 + x + (int)dir] == 9) && IsChange == true)
        {
            //改变数组内人物位置
            Done_Build.temp_map[-y * 9 + x] = 0;
            Done_Build.temp_map[-y * 9 + x + (int)dir] = 2;

            // 回传数据
            //FindObjectOfType<Done_Build>().temp_map = temp_map;
            IsChange = false;
            FindObjectOfType<Done_Build>().playerDestory = true;
            return true;
        }

        //如果人物下一个运动目标点为墙壁
        else if (Done_Build.temp_map[-y * 9 + x + (int)dir] == 1 && IsChange == true)
        {
            IsChange = false;
            return false;
        }
        //   如果人物下一个运动目标点为箱子
        else if (Done_Build.temp_map[-y * 9 + x + (int)dir] == 3 && (Done_Build.temp_map[-y * 9 + x + (int)dir*2] == 0 || Done_Build.temp_map[-y * 9 + x + (int)dir*2] == 9) && IsChange == true)         //temp_map[-y * 9 + x + array_num]:下一个运动目标点的数组位置
        {


            //改变数组内人物及箱子位置
            Done_Build.temp_map[-y * 9 + x] = 0;
            Done_Build.temp_map[-y * 9 + x + (int)dir] = 2;
            Done_Build.temp_map[-y * 9 + x + (int)dir*2] = 3;

            //回传数据
            //FindObjectOfType<Done_Build>().temp_map = temp_map;
            IsChange = false;
            FindObjectOfType<Done_Build>().playerDestory = true;
            FindObjectOfType<Done_Build>().boxDestory = true;
            return true;

        }

        return false;
    }

    public enum Direction { Up = -9,Down = 9,Left = -1,Right = 1}
    public Direction dir;
    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.UpArrow)) { dir = Direction.Up; }
        if (Input.GetKeyDown(KeyCode.DownArrow)) { dir = Direction.Down; }
        if (Input.GetKeyDown(KeyCode.LeftArrow)) { dir = Direction.Left; }
        if (Input.GetKeyDown(KeyCode.RightArrow)) { dir = Direction.Right; }

        switch (dir)
        {
            case Direction.Up:
                IsChange = true;
                x_num = 0;                  //生成新Gameboject时的实际位置坐标
                y_num = 1;
                animator_name = "Up";       //动画控制
                break;

            case Direction.Down:
                IsChange = true;
                x_num = 0;
                y_num = -1;
                animator_name = "Down";
                break;

            case Direction.Left:
                IsChange = true;
                x_num = -1;
                y_num = 0;
                animator_name = "Left";
                break;
            case Direction.Right:
                IsChange = true;
                x_num = 1;
                y_num = 0;
                animator_name = "Right";
                break;

        }
            IsMove();
    }
}

展开阅读全文

没有更多推荐了,返回首页