改绘制错误 bug + 将地图行,列,障碍物数量改为后端获取

This commit is contained in:
2023-03-01 11:13:30 +08:00
parent e6c49ad600
commit 1224f16414
7 changed files with 235 additions and 92 deletions
+11 -12
View File
@@ -15,18 +15,19 @@ export class GameMap extends AcGameObject {
this.ctx = ctx;
this.parent = parent;
this.store = store;
// 存下每个格子的绝对距离
this.L = 0;
/*
// 定义棋盘格的行数和列数(前端生成地图时使用)
/* // 定义棋盘格的行数和列数(前端生成地图时使用)
// 行数和列数不同时设置为偶数或者不同时设置为奇数,可以避免AB两蛇同时进入同一个格子,避免因此对优势者不公平
this.rows = 13;
this.cols = 14;
// 绘制棋盘内部区域的障碍物(墙)的数量(前端生成地图时使用)
this.inner_walls_count = 30;
*/
this.inner_walls_count = 20; */
this.rows = this.store.state.pk.rows;
this.cols = this.store.state.pk.cols;
this.inner_walls_count = this.store.state.pk.inner_walls_count;
// 存储所有的墙
// 上面的 super() 会先将 AcGameObject 先绘制, walls 的绘制在后面执行,因此墙最后会覆盖原棋盘格进行绘制
@@ -40,7 +41,7 @@ export class GameMap extends AcGameObject {
];
}
/*
/*
// 判断函数:判断角色路径是否联通。传入参数:g数组,起点和终点的横纵坐标(前端生成地图时使用)
check_connectivity(g, sx, sy, tx, ty) {
// 当起点坐标和中点坐标一致时,判断联通,直接返回
@@ -64,11 +65,10 @@ export class GameMap extends AcGameObject {
*/
// 创建障碍物(后端生成地图版本)
create_wall() {
create_walls() {
// 取出后端生成后传到前端 store 中的 game_map
const g = this.store.state.pk.game_map;
// 枚举数组,将 g[r][c] == true 的部分绘制出来
// 如果上一步连通性检测失败,则退出 this.create_wall() 函数,本步骤不再执行生成新对象的操作
for (let r = 0; r < this.rows; r++) {
@@ -79,7 +79,6 @@ export class GameMap extends AcGameObject {
}
}
}
// 绘制成功则 return turn
return true;
}
@@ -188,11 +187,11 @@ export class GameMap extends AcGameObject {
start() {
// 开始时调用一次创建墙的函数
// 循环 1000 次,如果成功创建则 break ,否则继续循环创建(前端生成地图时使用这一条)
// for (let i = 0; i < 1000; i++) if (this.create_wall()) break;
// for (let i = 0; i < 1000; i++) if (this.create_walls()) break;
// 使用后端生成地图时,这里只需要调用一次就好
this.create_wall();
this.create_walls();
// 开始时启动监听方法
this.add_listening_events();
}
+121
View File
@@ -0,0 +1,121 @@
import { AcGameObject } from "./AcGameObject";
import { Wall } from "./Wall";
import { Snake } from './Snake';
export class GameMap extends AcGameObject {
constructor(ctx, parent, store) {
super();
this.ctx = ctx;
this.parent = parent;
this.store = store;
this.L = 0;
this.rows = 13;
this.cols = 14;
this.inner_walls_count = 20;
this.walls = [];
this.snakes = [
new Snake({id: 0, color: "#4876EC", r: this.rows - 2, c: 1}, this),
new Snake({id: 1, color: "#F94848", r: 1, c: this.cols - 2}, this),
];
}
create_walls() {
const g = this.store.state.pk.gamemap;
for (let r = 0; r < this.rows; r ++ ) {
for (let c = 0; c < this.cols; c ++ ) {
if (g[r][c]) {
this.walls.push(new Wall(r, c, this));
}
}
}
}
add_listening_events() {
this.ctx.canvas.focus();
const [snake0, snake1] = this.snakes;
this.ctx.canvas.addEventListener("keydown", e => {
if (e.key === 'w') snake0.set_direction(0);
else if (e.key === 'd') snake0.set_direction(1);
else if (e.key === 's') snake0.set_direction(2);
else if (e.key === 'a') snake0.set_direction(3);
else if (e.key === 'ArrowUp') snake1.set_direction(0);
else if (e.key === 'ArrowRight') snake1.set_direction(1);
else if (e.key === 'ArrowDown') snake1.set_direction(2);
else if (e.key === 'ArrowLeft') snake1.set_direction(3);
});
}
start() {
this.create_walls();
this.add_listening_events();
}
update_size() {
this.L = parseInt(Math.min(this.parent.clientWidth / this.cols, this.parent.clientHeight / this.rows));
this.ctx.canvas.width = this.L * this.cols;
this.ctx.canvas.height = this.L * this.rows;
}
check_ready() { // 判断两条蛇是否都准备好下一回合了
for (const snake of this.snakes) {
if (snake.status !== "idle") return false;
if (snake.direction === -1) return false;
}
return true;
}
next_step() { // 让两条蛇进入下一回合
for (const snake of this.snakes) {
snake.next_step();
}
}
check_valid(cell) { // 检测目标位置是否合法:没有撞到两条蛇的身体和障碍物
for (const wall of this.walls) {
if (wall.r === cell.r && wall.c === cell.c)
return false;
}
for (const snake of this.snakes) {
let k = snake.cells.length;
if (!snake.check_tail_increasing()) { // 当蛇尾会前进的时候,蛇尾不要判断
k -- ;
}
for (let i = 0; i < k; i ++ ) {
if (snake.cells[i].r === cell.r && snake.cells[i].c === cell.c)
return false;
}
}
return true;
}
update() {
this.update_size();
if (this.check_ready()) {
this.next_step();
}
this.render();
}
render() {
const color_even = "#AAD751", color_odd = "#A2D149";
for (let r = 0; r < this.rows; r ++ ) {
for (let c = 0; c < this.cols; c ++ ) {
if ((r + c) % 2 == 0) {
this.ctx.fillStyle = color_even;
} else {
this.ctx.fillStyle = color_odd;
}
this.ctx.fillRect(c * this.L, r * this.L, this.L, this.L);
}
}
}
}
+9 -3
View File
@@ -8,6 +8,9 @@ export default {
opponent_username: "",
opponent_photo: "",
game_map: null,
rows: 0,
cols: 0,
inner_walls_count: 0,
},
getters: {},
mutations: {
@@ -25,9 +28,12 @@ export default {
state.status = status;
},
// 更新地图
updateGameMap(state,game_map){
state.game_map = game_map;
}
updateGameMap(state, game_data) {
state.game_map = game_data.game_map;
state.rows = game_data.rows;
state.cols = game_data.cols;
state.inner_walls_count = game_data.inner_walls_count;
},
},
actions: {},
module: {},
+3 -2
View File
@@ -56,9 +56,10 @@ export default {
// ,: matching -> playing
setTimeout(() => {
store.commit("updateStatus", "playing");
}, 2000);
}, 200);
// ,
store.commit("updateGameMap",data.game_map)
store.commit("updateGameMap", data.game_data);
console.log(data.game_data);
}
}