15.蛇长身体

15.游戏场景-蛇长身体


15.1 知识点

创建蛇长身体方法。获得当前蛇尾,new出新长出的身体,新长出的身体初始化位置在在蛇尾。 但是先不画出来,下一帧再画,吃完食物后的下一帧再画。下一帧画之前会执行蛇移动方法,在蛇移动方法中添加长身体逻辑,其实就是从蛇尾开始,不停的让后一个的位置等于前一个的位置。残影不用管,移动方法前面写了擦屁股的逻辑。

#region Lesson7 蛇移动
/// <summary>
/// 蛇的移动方向
/// </summary>
enum E_MoveDir
{
    /// <summary>
    /// 上
    /// </summary>
    Up,
    /// <summary>
    /// 下
    /// </summary>
    Down,
    /// <summary>
    /// 左
    /// </summary>
    Left,
    /// <summary>
    /// 右
    /// </summary>
    Right,
}
#endregion

//蛇类 继承绘制接口
class Snake : IDraw
{
    //蛇的身体数组
    SnakeBody[] bodys;
            
    //当前蛇的长度
    int snakeBodysLength;
    
    //当前移动的方向
    E_MoveDir dir;
    
    //蛇类构造函数
    public Snake(int x, int y)
    {
        //粗暴的 申明200个空间 游戏中 基本不会出现蛇长度达到200个身体
        bodys = new SnakeBody[200];
        
        //声明蛇头
        bodys[0] = new SnakeBody(E_SnakeBody_Type.Head, x, y);
        
        //初始时只有蛇头 初始化为1
        snakeBodysLength = 1;
        
        //初始化默认移动的方向向右
        dir = E_MoveDir.Right;
    }
    
    //蛇类绘制方法
    public void Draw()
    {
        //遍历蛇身体数组 逐个绘制蛇身体
        for (int i = 0; i < snakeBodysLength; i++)
        {
            bodys[i].Draw();
        }
    }
    
    #region Lesson7 蛇的移动
    
    //蛇移动方法
    public void Move()
    {
        //蛇移动前 擦除蛇尾 也就是最后一个位置 否则有残影
        SnakeBody lastBody = bodys[snakeBodysLength - 1];
        Console.SetCursorPosition(lastBody.pos.x, lastBody.pos.y);
        Console.Write("  ");//擦屁股
        
        #region Lesson11 长身体后 蛇身体移动
        
        //在蛇头移动之前 从蛇尾开始 不停的 让后一个的位置 等于前一个的位置
        //遍历蛇身体
        for (int i = snakeBodysLength - 1; i > 0; i--)
        {
            bodys[i].pos = bodys[i - 1].pos;
        }
        
        #endregion
        
        //蛇头移动
        switch (dir)
        {
            case E_MoveDir.Up:
                --bodys[0].pos.y;
                break;
            case E_MoveDir.Down:
                ++bodys[0].pos.y;
                break;
            case E_MoveDir.Left:
                bodys[0].pos.x -= 2;
                break;
            case E_MoveDir.Right:
                bodys[0].pos.x += 2;
                break;
        }
    }
    #endregion
    
    #region Lesson8 改变蛇的方向
    
    //蛇改变移动方向方法
    public void ChangeDir(E_MoveDir dir)
    {
        //蛇只有头部的时候 可以直接左转右 右转左  上转下 下转上
        //蛇有身体时 这种情况就不能直接转
    
    
        if( 
            //假如传进来的方向就等于现在的方向
            dir == this.dir 
            ||
            //或者 蛇长度大于0且想要直接180度转向
            (
                snakeBodysLength > 1 
                && 
                (this.dir == E_MoveDir.Left && dir == E_MoveDir.Right ||
                 this.dir == E_MoveDir.Right && dir == E_MoveDir.Left ||
                 this.dir == E_MoveDir.Up && dir == E_MoveDir.Down ||
                 this.dir == E_MoveDir.Down && dir == E_MoveDir.Up)
                 )
           )
        {
            //直接return
            return;
        }
        
        //只要没有return 就记录外面传入的方向 之后就会按照这个方向去移动
        this.dir = dir;
    }
    #endregion
    
    #region Lesson9 撞墙撞身体结束逻辑
    
    //检测蛇是否撞墙撞身体后 结束游戏
    //在update中每次绘制完检测 要传入地图
    public bool CheckEnd( Map map )
    {
        //是否和墙体位置重合
        for (int i = 0; i < map.walls.Length; i++)
        {
            if( bodys[0].pos == map.walls[i].pos )
            {
                return true;
            }
        }
        
        //是否和自己的身体重合
        for (int i = 1; i < snakeBodysLength; i++)
        {
            if(bodys[0].pos == bodys[i].pos)
            {
                return true;
            }
        }
        
        return false;
    }
    #endregion
    
    #region Lesson10 吃食物相关
    
    //判断是否和蛇重合方法
    //通过传入一个位置 来判断这个位置 是不是和蛇重合
    public bool CheckSamePos(Position p)
    {
        for (int i = 0; i < snakeBodysLength; i++)
        {
            if(bodys[i].pos == p)
            {
                return true;
            }
        }
        return false;
    }
    
    //蛇吃食物方法
    public void CheckEatFood(Food food)
    {
        //判断蛇
        if( bodys[0].pos == food.pos )
        {
            //吃到了 就应该让食物 位置再随机 增加蛇身体的长度
            food.RandomPos(this);
        
            //长身体
            AddBody();
        }
    }
    #endregion
    
    #region Lesson11 长身体
    
    //蛇长身体方法
    private void AddBody()
    {
        //获得当前蛇尾的蛇身子类变量
        SnakeBody frontBody = bodys[snakeBodysLength - 1];
    
        //吃完食物后 先长出身体 但是先不画出来 下一帧再画
        bodys[snakeBodysLength] = new SnakeBody(E_SnakeBody_Type.Body, frontBody.pos.x, frontBody.pos.y);
    
        //增加蛇身体的总长度
        ++snakeBodysLength;
    }
    #endregion
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏