一、 介绍
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