You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

135 lines
3.6 KiB

import "./snake.css";
import SnakeModel from "./core/model";
// view
import SnakeView from "./core/view";
// control
import SnakeControl from "./core/control";
export default class SnakeClass extends SnakeControl {
constructor({ containerId, onLose }) {
const container = document.getElementById(containerId);
const width = container.clientWidth;
const row = 14;
const column = 18;
const height = (width / column) * row;
const bg = document.createElement("div");
bg.className = "snake";
bg.style.paddingTop = `${(240 / 2160) * width}px`;
const buttons = document.createElement("div");
buttons.className = "buttons";
bg.appendChild(buttons);
container.appendChild(bg);
super(new SnakeModel(), new SnakeView(bg, width, height));
Object.assign(this, {
showModal: true,
container: bg,
buttons,
containerWidth: width,
});
const modal = document.createElement("div");
modal.className = "modal show";
modal.addEventListener("click", (e) => {
e.stopPropagation();
e.preventDefault();
if (this.showModal) {
this.showModal = false;
modal.className = "modal";
this.resume();
}
});
bg.appendChild(modal);
this.init({
time: 3000000, // 总时间
width,
height,
row,
column,
// 显示屏的边框
border: 0x414042,
color: 0x414042, // 蛇的节点颜色
food: 0x990000, // 食物的颜色
min: 2, // 初始长度
speed: 0.5, // 速度标量
});
this.event.on("gameover", (res) => {
onLose(res);
});
this.event.on("restart", () => {
this.showModal = true;
modal.className = "modal show";
});
// snakeGame.event.on("eat", (food) => {
// console.log("吃到食物,当前长度: " + snakeGame.length);
// });
this.start();
this.addControl();
}
dispose() {}
addControl() {
let controller = this.buttons;
let curDirection;
const { containerWidth } = this;
let { top, left, width, height } = controller.getBoundingClientRect(),
x = left + width / 2,
y = top + height / 2,
deg45 = Math.PI / 4,
deg90 = Math.PI / 2,
deg135 = Math.PI / 2 + deg45,
deg180 = Math.PI,
deg225 = Math.PI + deg45,
deg270 = Math.PI + deg90,
deg315 = Math.PI * 2 - deg45;
controller.addEventListener(
"touchstart",
({ targetTouches: [{ clientX, clientY }] }) => {
checkDirection(clientX - x, clientY - y);
}
);
controller.addEventListener(
"touchmove",
({ targetTouches: [{ clientX, clientY }] }) => {
checkDirection(clientX - x, clientY - y);
}
);
controller.addEventListener("touchend", () => {
curDirection = undefined;
controller.className = "buttons snake-direction";
});
let checkDirection = (x, y) => {
let radian = Math.asin(y / Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
// 1~2象限
if ((x > 0 && y < 0) || (x > 0 && y > 0)) {
radian += deg90;
}
// 3~4象限
else if ((x < 0 && y > 0) || (x < 0 && y < 0)) {
radian = deg270 - radian;
}
let direction = "up";
if (radian > deg45 && radian < deg135) {
direction = "right";
} else if (radian > deg135 && radian < deg225) {
direction = "down";
} else if (radian > deg225 && radian < deg315) {
direction = "left";
}
direction === curDirection ||
this.turn(
(curDirection = direction),
(controller.className = "buttons snake-direction " + direction)
);
};
}
}