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) ); }; } }