创建菜单与游戏界面(下)

目录

修改地图

画出蛇的头部

实现蛇的移动


修改地图

确保两个蛇的头结点一定不会重合——改为中心对称

如果两条蛇,同时走到相同的格子,会造成平局,这种情况会对优势者不利!
需要把地图变为 偶数 乘 奇数

修改代码:

x = rows - 1 - x;

y = cols - 1 - y;

创建菜单与游戏界面(下)_第1张图片

创建菜单与游戏界面(下)_第2张图片  

画出蛇的头部

如何画蛇 -> 本质上蛇是由一堆格子组成的序列。

新建 Cell.js 存储一堆格子的序列 –> 存储蛇。

创建菜单与游戏界面(下)_第3张图片新建 Snake.js 对象,方便我们进行操作。

 创建菜单与游戏界面(下)_第4张图片

在 GameMap.js 中创建两条蛇的对象。 

创建菜单与游戏界面(下)_第5张图片

 创建菜单与游戏界面(下)_第6张图片

实现蛇的移动

移动应该是连贯的。身体有多个部分,如何让保持连贯?

中间保持不动,头和尾动,在头部创建一个新的节点,朝着目的地移动。尾巴朝着目的地动 ---------加头去尾即可

蛇什么时候可以动?

同时获取到两个人 / 两个机器 的操作才能动。 

基本的移动

在 Snake.js 中添加代码,实现蛇头的向右移动。 

创建菜单与游戏界面(下)_第7张图片

效果

创建菜单与游戏界面(下)_第8张图片

 连贯的移动

由于可能会产生一些问题, 也就是中间某个状态,没有完全移出去,蛇的身子会出现问题。
中间不动,首尾动!创建的虚拟节点朝着目的地移动。只有两个点动。
考虑蛇什么时候动? 回合制游戏,两个人都有输入的时候,才可以移动。

修改 Snake.js创建菜单与游戏界面(下)_第9张图片 

需要有一个裁判来判断两条蛇的移动,我们放在 GameMap.js 中 

 创建菜单与游戏界面(下)_第10张图片

在 Snake.js 中更新一下蛇的状态:

 创建菜单与游戏界面(下)_第11张图片

在 GameMap.js 中更新 创建菜单与游戏界面(下)_第12张图片

 读取键盘的操作:从键盘获取操作 w a s d 和 ↑ ↓ ← → 来控制两条蛇。

在 GameMap.vue中修改 这样才能获取输入

绑定事件: 在 Snake.js 中加入一个辅助函数,用来获取方向。 

//辅助函数
set_direction(d) {
    this.direction = d;
}

 在 GameMap.js 中修改,添加事件。

创建菜单与游戏界面(下)_第13张图片

 在 Snake.js 中更新状态:

创建菜单与游戏界面(下)_第14张图片

实现真正的移动

在 snake.js 中修改 :

import { AcGameObject } from "./AcGameObject";
import { Cell } from "./Cell";

export class Snake extends AcGameObject {
    constructor(info, gamemap) {
        super();

        this.id = info.id;
        this.color = info.color;
        this.gamemap = gamemap;

        this.cells = [new Cell(info.r, info.c)];  // 存放蛇的身体,cells[0]存放蛇头
        this.next_cell = null;  // 下一步的目标位置

        this.speed = 5;  // 蛇每秒走5个格子
        this.direction = -1;  // -1表示没有指令,0、1、2、3表示上右下左
        this.status = "idle";  // idle表示静止,move表示正在移动,die表示死亡

        this.dr = [-1, 0, 1, 0];  // 4个方向行的偏移量
        this.dc = [0, 1, 0, -1];  // 4个方向列的偏移量

        this.step = 0;  // 表示回合数
        this.eps = 1e-2;  // 允许的误差

    }


    start() {

    }

    set_direction(d) {
        this.direction = d;
    }

    next_step() { //蛇的状态变为走下一步
        const d = this.direction;
        this.next_cell = new Cell(this.cells[0].r + this.dr[d], this.cells[0].c + this.dc[d]);
        this.direction = -1;
        this.status = "move";
        this.step ++ ;   

        // 求长度
        const k = this.cells.length;
        for (let i = k; i > 0; i -- ) { // 初始元素不变 每一个元素往后移动一位
            this.cells[i] = JSON.parse(JSON.stringify(this.cells[i - 1]));
        }

    }

    update_move() {
        const dx = this.next_cell.x - this.cells[0].x;
        const dy = this.next_cell.y - this.cells[0].y;
        const distance = Math.sqrt(dx * dx + dy * dy);



        if (distance < this.eps) {  // 走到目标点了
            this.cells[0] = this.next_cell;  // 添加一个新蛇头
            this.next_cell = null;
            this.status = "idle";  // 走完了,停下来

        } else {
            const move_distance = this.speed * this.timedelta / 1000;
            this.cells[0].x += move_distance * dx / distance;
            this.cells[0].y += move_distance * dy / distance;
        }
    }

    update() {  // 每一帧执行一次
        if (this.status === 'move') {
            this.update_move();
        }

        this.render();
    }


    render() {
        const L = this.gamemap.L;
        const ctx = this.gamemap.ctx;

        ctx.fillStyle = this.color;
        for (const cell of this.cells) {
            ctx.beginPath();
            ctx.arc(cell.x * L, cell.y * L, L / 2, 0, Math.PI * 2);
            ctx.fill();
        }
    }
}

创建菜单与游戏界面(下)_第15张图片蛇尾移动

在 Snake.js 中添加代码,判断蛇尾是否增长

    check_tail_increasing(){
        if(this.step <= 10) return true;//前10步 不增
        if(this.step%3 === 1) return true;// 每3步增一单位
        return false;
    }

修改 Snake.js , 判断蛇尾是否在下一步是否增长

创建菜单与游戏界面(下)_第16张图片

基本效果

创建菜单与游戏界面(下)_第17张图片

 美化蛇

创建菜单与游戏界面(下)_第18张图片

修改 Snake.js ,让蛇变得连贯、缩小一点。添加下列代码: 

   render(){
        //画出基本蛇头
        const L = this.gamemap.L; //单位长度
        const ctx = this.gamemap.ctx;//画笔
        ctx.fillStyle = this.color;
        for(const cell of this.cells){
            ctx.beginPath();
            ctx.arc(cell.x*L ,cell.y*L,L*0.8/2,0,Math.PI*2);
            ctx.fill();
        }
        for(let i = 1;i

基本效果: 

创建菜单与游戏界面(下)_第19张图片

  检测非法逻辑

在GameMap.js中更新创建菜单与游戏界面(下)_第20张图片

在snake.js中更新

创建菜单与游戏界面(下)_第21张图片

 创建菜单与游戏界面(下)_第22张图片

 创建菜单与游戏界面(下)_第23张图片

 实现眼睛

比如说蛇头朝上的时候,让蛇头cell中心点向做偏移一个,向右偏移一个就是蛇的双眼.

给蛇眼睛设置dx,dy偏移量数组,因为两只眼,所以数组设置应是这样的:

this.eye_dx = [ // 蛇眼不同方向x偏移量 (从圆心向左向右的偏移量)
    [-1, 1], //向上,右,左,下
    [1, 1],
    [-1, 1],
    [-1, -1],
]    
this.eye_dy = [ // 蛇眼不同方向y偏移量
    [-1, -1],
    [-1, 1],
    [1, 1],
    [-1, 1],
        ]

创建菜单与游戏界面(下)_第24张图片修改snake.js

 创建菜单与游戏界面(下)_第25张图片创建菜单与游戏界面(下)_第26张图片

效果:创建菜单与游戏界面(下)_第27张图片

至此,我们实现了最基本的地图和两条蛇的移动。

实现点击地图即刷新

实现异步刷新
刷新整个组件就行了
修改 PkIndexView.vue 如下:



创建菜单与游戏界面(下)_第28张图片

 

你可能感兴趣的:(springboot,vue,游戏)