文章目录
- 一、 介绍
- 二、 制作墙壁、地面
- 三、 制作箱子
- 四、 制作终点
- 五、 制作人物移动
- 六、 推箱子关键触发机制
- 七、 终点设置
- 八、 关卡切换设置
- 九、 协程
- 十、 下载
一、 介绍
2D推箱子游戏是一种益智类游戏,玩家需要控制角色将箱子推到指定的位置,以完成关卡任务。游戏场景通常是二维平面,玩家需要通过移动角色来推动箱子,避免箱子被卡住或推错位置。游戏难度逐渐增加,需要玩家思考和规划每一步操作,提高解决问题的能力和反应速度。该游戏类型经常出现在各种智力竞赛和游戏比赛中。
二、 制作墙壁、地面
墙壁由很多切割后的小方块组成。
这里使用tilemap方法平铺墙面、地面。
墙面挂上图层wall
三、 制作箱子
箱子图片切割后,添加碰撞体,碰撞体长度要设置为原来的50%。
如果不改变,箱子和墙体只是贴着,就也进入碰撞检测了
四、 制作终点
同样的,挂载碰撞体脚本。
五、 制作人物移动
先按上下左右不移动,保存移动状态。
if (Input.GetKeyDown(KeyCode.RightArrow))moveDir = Vector2.right;if (Input.GetKeyDown(KeyCode.LeftArrow))moveDir = Vector2.left;if (Input.GetKeyDown(KeyCode.UpArrow))moveDir = Vector2.up;if (Input.GetKeyDown(KeyCode.DownArrow))moveDir = Vector2.down;
碰撞检测后,然后移动
void Move(Vector2 dir){transform.Translate(dir);}
六、 推箱子关键触发机制
使用射线检测的方式,检测物体所在的层级
RaycastHit2D hit = Physics2D.Raycast(transform.position, dir, 1.5f, detectLayer);
要移动的方向发射射线后。
1.射线检测不到任何层级,玩家就可以移动一个单位。
2.射线检测到箱子,以箱子为新的发射点,继续检测有没有墙体,有墙体就不能移动,没有墙体就移动一个单位。
bool CanMoveToDir(Vector2 dir){RaycastHit2D hit = Physics2D.Raycast(transform.position, dir, 1.5f, detectLayer);if (!hit)return true;else{if (hit.collider.GetComponent<Box>() != null)return hit.collider.GetComponent<Box>().CanMoveToDir(dir);}return false;}
public bool CanMoveToDir(Vector2 dir){RaycastHit2D hit = Physics2D.Raycast(transform.position + (Vector3)dir * 0.5f, dir, 0.3f);if (!hit){transform.Translate(dir);return true;}return false;}
七、 终点设置
箱子推到终点,触发器监测,箱子颜色变红。
箱子也可以从终点退出来,箱子颜色复原。
private void OnTriggerEnter2D(Collider2D collision){if(collision.CompareTag("Target")){FindObjectOfType<GameManager>().finishedBoxs++;FindObjectOfType<GameManager>().CheckFinish();GetComponent<SpriteRenderer>().color = finishColor;}}private void OnTriggerExit2D(Collider2D collision){if (collision.CompareTag("Target")){FindObjectOfType<GameManager>().finishedBoxs--;GetComponent<SpriteRenderer>().color = originColor;}}
八、 关卡切换设置
全局管理一个计数器,箱子总数totle,初始化为0,每个箱子挂“box”脚本,箱子totle数量+1。
已经达到终点的数量finish,初始化为0,一个箱子达到终点,finish。
当totle==finish,启动协程,等待片刻后,进入下个场景
public void CheckFinish(){if(finishedBoxs == totalBoxs){print("YOU WIN!");StartCoroutine(LoadNextStage());}}
中途失败,可以点击“R”重载游戏
void ResetStage(){SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);}
九、 协程
IEnumerator LoadNextStage(){yield return new WaitForSeconds(2);SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);}
等待两秒,当前关卡场景索引值+1
十、 下载
https://pan.baidu.com/s/1MutUXAxLDGXXUq5RpSSFjw
提取码: 4rf7