|
|
@ -2,128 +2,67 @@ |
|
|
author: leeenx |
|
|
author: leeenx |
|
|
@ 贪吃蛇的 view 类 |
|
|
@ 贪吃蛇的 view 类 |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
|
|
|
// 获取 Graphics 的 content-box
|
|
|
|
|
|
import "../lib/utils/getContentBoxSize"; |
|
|
|
|
|
|
|
|
|
|
|
// 不显示 PIXI 信息
|
|
|
|
|
|
import "../lib/utils/noHello"; |
|
|
|
|
|
|
|
|
|
|
|
// 链表类
|
|
|
// 链表类
|
|
|
import Chain from "../lib/utils/Chain"; |
|
|
import Chain from "../lib/utils/Chain"; |
|
|
|
|
|
|
|
|
|
|
|
import food from "../food.png"; |
|
|
|
|
|
|
|
|
|
|
|
const startColor = 0xfec321; |
|
|
|
|
|
const endColor = 0xe29b01; |
|
|
|
|
|
const rotate = (cx, cy, point, rad) => { |
|
|
|
|
|
const { x, y } = point; |
|
|
|
|
|
let cos = Math.cos(rad), |
|
|
|
|
|
sin = Math.sin(rad), |
|
|
|
|
|
nx = cos * (x - cx) + sin * (y - cy) + cx, |
|
|
|
|
|
ny = cos * (y - cy) - sin * (x - cx) + cy; |
|
|
|
|
|
point.x = nx; |
|
|
|
|
|
point.y = ny; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const getDir = (x1, y1, x2, y2) => { |
|
|
|
|
|
return x2 > x1 ? "right" : x2 < x1 ? "left" : y2 > y1 ? "bottom" : "top"; |
|
|
|
|
|
}; |
|
|
// view 类
|
|
|
// view 类
|
|
|
export default class view { |
|
|
export default class view { |
|
|
// 构造函数
|
|
|
// 构造函数
|
|
|
constructor(dom, width, height) { |
|
|
constructor(dom, width, height) { |
|
|
// 创建一个 app
|
|
|
|
|
|
let app = new PIXI.Application(width, height, { |
|
|
|
|
|
transparent: true, |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// canvas 添加到 page
|
|
|
|
|
|
dom.appendChild(app.view); |
|
|
|
|
|
|
|
|
|
|
|
// 销毁pixijs的ticker
|
|
|
|
|
|
app.ticker.destroy(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const canvas = document.createElement("canvas"); |
|
|
|
|
|
canvas.style.width = width + "px"; |
|
|
|
|
|
canvas.style.height = height + "px"; |
|
|
|
|
|
canvas.width = width * window.devicePixelRatio; |
|
|
|
|
|
canvas.height = height * window.devicePixelRatio; |
|
|
|
|
|
const ctx = canvas.getContext("2d"); |
|
|
|
|
|
ctx.scale(window.devicePixelRatio, window.devicePixelRatio); |
|
|
|
|
|
dom.appendChild(canvas); |
|
|
// 创建 view 的蛇
|
|
|
// 创建 view 的蛇
|
|
|
this.snake = new Chain(); |
|
|
this.snake = new Chain(); |
|
|
|
|
|
|
|
|
// shift & unshift & pop & push & insertAfter 自动关联 addNode & removeNode
|
|
|
|
|
|
let { shift, unshift, pop, push, insertAfter } = this.snake; |
|
|
|
|
|
|
|
|
|
|
|
// 封闭 shift
|
|
|
|
|
|
this.snake.shift = () => { |
|
|
|
|
|
// 回收尾节点
|
|
|
|
|
|
this.collect(shift.call(this.snake).node); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 封装 unshift
|
|
|
|
|
|
this.snake.unshift = (data) => { |
|
|
|
|
|
unshift.call(this.snake, data); |
|
|
|
|
|
let node = (this.snake.first().node = this.calloc()); |
|
|
|
|
|
node.setPostion(...this.getPosition(data)); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 封闭 pop
|
|
|
|
|
|
this.snake.pop = () => { |
|
|
|
|
|
// 回收尾节点
|
|
|
|
|
|
this.collect(pop.call(this.snake).node); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 封装 push
|
|
|
|
|
|
this.snake.push = (data) => { |
|
|
|
|
|
push.call(this.snake, data); |
|
|
|
|
|
let node = (this.snake.last().node = this.calloc()); |
|
|
|
|
|
node.setPostion(...this.getPosition(data)); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 封装 insertAfter
|
|
|
|
|
|
this.snake.insertAfter = (index, data) => { |
|
|
|
|
|
insertAfter.call(this.snake, index, data); |
|
|
|
|
|
let node = (this.snake.at(index + 1).node = this.calloc()); |
|
|
|
|
|
node.setPostion(...this.getPosition(data)); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 回收节点
|
|
|
|
|
|
this.collection = []; |
|
|
|
|
|
|
|
|
|
|
|
// 保证 updateTicker 指针永远指向 view
|
|
|
// 保证 updateTicker 指针永远指向 view
|
|
|
this.updateTicker = this.updateTicker.bind(this); |
|
|
this.updateTicker = this.updateTicker.bind(this); |
|
|
|
|
|
|
|
|
// 挂载到this
|
|
|
// 挂载到this
|
|
|
this.app = app; |
|
|
|
|
|
this.stage = app.stage; |
|
|
|
|
|
|
|
|
|
|
|
// 扩展 PIXI.Graphics
|
|
|
|
|
|
PIXI.Graphics.prototype.setPostion = function (x, y = x) { |
|
|
|
|
|
this.x = x + this.pivot.x; |
|
|
|
|
|
this.y = y + this.pivot.y; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
this.canvas = canvas; |
|
|
|
|
|
this.ctx = ctx; |
|
|
|
|
|
this.foodImg = new Image(120, 120); |
|
|
|
|
|
this.foodImg.src = food; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 初始化
|
|
|
// 初始化
|
|
|
init(config = {}) { |
|
|
init(config = {}) { |
|
|
// pixijs
|
|
|
|
|
|
let { |
|
|
|
|
|
app, |
|
|
|
|
|
app: { stage, renderer }, |
|
|
|
|
|
} = this; |
|
|
|
|
|
|
|
|
|
|
|
// 蛇的尺寸挂载到 config
|
|
|
// 蛇的尺寸挂载到 config
|
|
|
config.size = { |
|
|
config.size = { |
|
|
width: config.width / config.column, |
|
|
width: config.width / config.column, |
|
|
height: config.height / config.row, |
|
|
height: config.height / config.row, |
|
|
}; |
|
|
}; |
|
|
console.log(config.size); |
|
|
|
|
|
// 初化data
|
|
|
// 初化data
|
|
|
this.data = config.data; |
|
|
this.data = config.data; |
|
|
|
|
|
|
|
|
// 全局 config 挂载
|
|
|
// 全局 config 挂载
|
|
|
this.config = config; |
|
|
this.config = config; |
|
|
|
|
|
|
|
|
// 游戏活动区
|
|
|
|
|
|
stage.addChild((this.zone = new PIXI.Container())); |
|
|
|
|
|
|
|
|
|
|
|
// 绘制边界
|
|
|
|
|
|
// this.drawBounds();
|
|
|
|
|
|
|
|
|
|
|
|
// 食物
|
|
|
// 食物
|
|
|
this.food = this.calloc(); |
|
|
|
|
|
|
|
|
this.food = {}; |
|
|
this.food.visible = false; |
|
|
this.food.visible = false; |
|
|
|
|
|
|
|
|
// 食物动画 - blink
|
|
|
|
|
|
let [from, to] = [ |
|
|
|
|
|
{ |
|
|
|
|
|
alpha: 1, |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
alpha: 0, |
|
|
|
|
|
}, |
|
|
|
|
|
]; |
|
|
|
|
|
TweenMax.fromTo(this.food, 0.2, from, to).repeat(-1).yoyo(true); |
|
|
|
|
|
|
|
|
|
|
|
// 通过 model.zone 创建一张快速定位表
|
|
|
// 通过 model.zone 创建一张快速定位表
|
|
|
this.createQuickMap(this.data.zone); |
|
|
this.createQuickMap(this.data.zone); |
|
|
|
|
|
|
|
|
@ -134,43 +73,8 @@ export default class view { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
destroy() { |
|
|
destroy() { |
|
|
let { |
|
|
|
|
|
app, |
|
|
|
|
|
app: { stage }, |
|
|
|
|
|
} = this; |
|
|
|
|
|
// 销毁所有子节点
|
|
|
|
|
|
for (let child of stage.children) { |
|
|
|
|
|
child.destroy(); |
|
|
|
|
|
} |
|
|
|
|
|
stage.removeChildren(); |
|
|
|
|
|
this.collection = []; |
|
|
|
|
|
this.snake.clean(); |
|
|
this.snake.clean(); |
|
|
} |
|
|
} |
|
|
// 绘制四条边界
|
|
|
|
|
|
drawBounds() { |
|
|
|
|
|
let { |
|
|
|
|
|
app, |
|
|
|
|
|
app: { stage }, |
|
|
|
|
|
} = this, |
|
|
|
|
|
{ border, width, height } = this.config, |
|
|
|
|
|
thickness = 8; |
|
|
|
|
|
let bounds = new PIXI.Graphics() |
|
|
|
|
|
.beginFill(0xffffff, 1) |
|
|
|
|
|
.lineStyle(thickness, border, 1) |
|
|
|
|
|
.drawRect(0, 0, width + thickness, height + thickness); |
|
|
|
|
|
|
|
|
|
|
|
bounds.x = bounds.y = (app.view.width - bounds.cwidth) / 2; |
|
|
|
|
|
|
|
|
|
|
|
stage.addChild(bounds); |
|
|
|
|
|
// bounds 的 index
|
|
|
|
|
|
stage.setChildIndex(bounds, 0); |
|
|
|
|
|
|
|
|
|
|
|
// 活动空间定位
|
|
|
|
|
|
[this.zone.x, this.zone.y] = [ |
|
|
|
|
|
bounds.x + thickness / 2, |
|
|
|
|
|
bounds.y + thickness / 2, |
|
|
|
|
|
]; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 快速寻位表
|
|
|
// 快速寻位表
|
|
|
createQuickMap(map) { |
|
|
createQuickMap(map) { |
|
|
@ -187,36 +91,13 @@ export default class view { |
|
|
return this.quickMap[index]; |
|
|
return this.quickMap[index]; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 创建节点
|
|
|
|
|
|
calloc() { |
|
|
|
|
|
let node; |
|
|
|
|
|
if (this.collection.length === 0) { |
|
|
|
|
|
node = new PIXI.Graphics(); |
|
|
|
|
|
let { width, height } = this.config.size; |
|
|
|
|
|
node.beginFill(this.config.color, 1).drawRect(0, 0, width, height); |
|
|
|
|
|
node.pivot.set(width / 2, height / 2); |
|
|
|
|
|
node.setPostion(0); |
|
|
|
|
|
} else { |
|
|
|
|
|
node = this.collection.pop(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 默认显示在容器里
|
|
|
|
|
|
this.zone.addChild(node); |
|
|
|
|
|
return node; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 回收节点
|
|
|
|
|
|
collect(node) { |
|
|
|
|
|
node && this.collection.push(node) & this.zone.removeChild(node); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 随机生成食物
|
|
|
// 随机生成食物
|
|
|
feed(index) { |
|
|
feed(index) { |
|
|
this.food.visible = 1; |
|
|
this.food.visible = 1; |
|
|
this.food.graphicsData[0].fillColor = this.config.food; |
|
|
|
|
|
this.food.dirty++; |
|
|
this.food.dirty++; |
|
|
this.food.clearDirty++; |
|
|
this.food.clearDirty++; |
|
|
this.food.setPostion(...this.getPosition(index)); |
|
|
|
|
|
|
|
|
const [left, top] = this.getPosition(index); |
|
|
|
|
|
Object.assign(this.food, { left, top }); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// ticker update
|
|
|
// ticker update
|
|
|
@ -308,8 +189,226 @@ export default class view { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
renderFood() { |
|
|
|
|
|
let { width, height } = this.config.size; |
|
|
|
|
|
if (this.food && this.food.visible) { |
|
|
|
|
|
this.ctx.drawImage( |
|
|
|
|
|
this.foodImg, |
|
|
|
|
|
this.food.left, |
|
|
|
|
|
this.food.top, |
|
|
|
|
|
width, |
|
|
|
|
|
height |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
drawHeadTail(x, y, dir, index, length) { |
|
|
|
|
|
const { ctx } = this; |
|
|
|
|
|
let { width, height } = this.config.size; |
|
|
|
|
|
const sWidth = (width / 120) * 90; |
|
|
|
|
|
const r = sWidth / 2; |
|
|
|
|
|
const gap = (width - sWidth) / 2; |
|
|
|
|
|
const a = { x, y: y + height }; |
|
|
|
|
|
const b = { x: x + gap, y: a.y }; |
|
|
|
|
|
const c = { x: x + width / 2, y: a.y }; |
|
|
|
|
|
const d = { x: x + gap + sWidth, y: a.y }; |
|
|
|
|
|
const e = { x: x + width, y: a.y }; |
|
|
|
|
|
const f = { x: b.x, y: y + r }; |
|
|
|
|
|
const g = { x: b.x, y }; |
|
|
|
|
|
const h = { x: c.x, y }; |
|
|
|
|
|
const i = { x: d.x, y }; |
|
|
|
|
|
const j = { x: d.x, y: f.y }; |
|
|
|
|
|
const k = { x: x + width / 2, y: y - index * height }; |
|
|
|
|
|
const l = { x: k.x, y: y + (length - index) * height }; |
|
|
|
|
|
let rad = |
|
|
|
|
|
dir === "bottom" |
|
|
|
|
|
? 0 |
|
|
|
|
|
: dir === "top" |
|
|
|
|
|
? Math.PI |
|
|
|
|
|
: dir === "left" |
|
|
|
|
|
? -Math.PI / 2 |
|
|
|
|
|
: Math.PI / 2; |
|
|
|
|
|
if (index) rad += Math.PI; |
|
|
|
|
|
[a, b, c, d, e, f, g, h, i, j, k, l].forEach((point) => |
|
|
|
|
|
rotate(x + width / 2, y + height / 2, point, rad) |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
// k
|
|
|
|
|
|
// |
|
|
|
|
|
|
// |
|
|
|
|
|
|
// |
|
|
|
|
|
|
// g---h---i
|
|
|
|
|
|
// | / \ |
|
|
|
|
|
|
// f j
|
|
|
|
|
|
// | |
|
|
|
|
|
|
// a-b---c---d-e
|
|
|
|
|
|
// |
|
|
|
|
|
|
// |
|
|
|
|
|
|
// |
|
|
|
|
|
|
// l
|
|
|
|
|
|
|
|
|
|
|
|
const gradient = ctx.createLinearGradient(k.x, k.y, l.x, l.y); |
|
|
|
|
|
gradient.addColorStop(0, "#" + startColor.toString(16)); |
|
|
|
|
|
gradient.addColorStop(1, "#" + endColor.toString(16)); |
|
|
|
|
|
ctx.fillStyle = gradient; |
|
|
|
|
|
ctx.strokeStyle = gradient; |
|
|
|
|
|
ctx.beginPath(); |
|
|
|
|
|
ctx.moveTo(b.x, b.y); |
|
|
|
|
|
ctx.lineTo(f.x, f.y); |
|
|
|
|
|
ctx.arcTo(g.x, g.y, h.x, h.y, r); |
|
|
|
|
|
ctx.arcTo(i.x, i.y, j.x, j.y, r); |
|
|
|
|
|
ctx.lineTo(d.x, d.y); |
|
|
|
|
|
ctx.closePath(); |
|
|
|
|
|
ctx.fill(); |
|
|
|
|
|
ctx.stroke(); |
|
|
|
|
|
} |
|
|
|
|
|
drawRec(x, y, dir, i, length) { |
|
|
|
|
|
const { ctx } = this; |
|
|
|
|
|
let { width, height } = this.config.size; |
|
|
|
|
|
const sWidth = (width / 120) * 90; |
|
|
|
|
|
const gap = (width - sWidth) / 2; |
|
|
|
|
|
const a = { x: x + gap, y: y + height }; |
|
|
|
|
|
const b = { x: a.x, y }; |
|
|
|
|
|
const c = { x: x + gap + sWidth, y }; |
|
|
|
|
|
const d = { x: c.x, y: a.y }; |
|
|
|
|
|
const e = { x: x + width / 2, y: y - i * height }; |
|
|
|
|
|
const f = { x: e.x, y: y + (length - i) * height }; |
|
|
|
|
|
let rad = |
|
|
|
|
|
dir === "bottom" |
|
|
|
|
|
? 0 |
|
|
|
|
|
: dir === "top" |
|
|
|
|
|
? Math.PI |
|
|
|
|
|
: dir === "left" |
|
|
|
|
|
? -Math.PI / 2 |
|
|
|
|
|
: Math.PI / 2; |
|
|
|
|
|
[a, b, c, d, e, f].forEach((point) => |
|
|
|
|
|
rotate(x + width / 2, y + height / 2, point, rad) |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
// e
|
|
|
|
|
|
// |
|
|
|
|
|
|
// b---c
|
|
|
|
|
|
// | |
|
|
|
|
|
|
// a---d
|
|
|
|
|
|
// |
|
|
|
|
|
|
// f
|
|
|
|
|
|
|
|
|
|
|
|
const gradient = ctx.createLinearGradient(e.x, e.y, f.x, f.y); |
|
|
|
|
|
gradient.addColorStop(0, "#" + startColor.toString(16)); |
|
|
|
|
|
gradient.addColorStop(1, "#" + endColor.toString(16)); |
|
|
|
|
|
ctx.fillStyle = gradient; |
|
|
|
|
|
ctx.strokeStyle = gradient; |
|
|
|
|
|
ctx.beginPath(); |
|
|
|
|
|
ctx.moveTo(a.x, a.y); |
|
|
|
|
|
ctx.lineTo(b.x, b.y); |
|
|
|
|
|
ctx.lineTo(c.x, c.y); |
|
|
|
|
|
ctx.lineTo(d.x, d.y); |
|
|
|
|
|
ctx.closePath(); |
|
|
|
|
|
ctx.fill(); |
|
|
|
|
|
ctx.stroke(); |
|
|
|
|
|
} |
|
|
|
|
|
drawCorner(x, y, dir, i, length) { |
|
|
|
|
|
const { ctx } = this; |
|
|
|
|
|
let { width, height } = this.config.size; |
|
|
|
|
|
const sWidth = (width / 120) * 90; |
|
|
|
|
|
const gap = (width - sWidth) / 2; |
|
|
|
|
|
const sqrt2 = width / 2 / Math.sqrt(2); |
|
|
|
|
|
const a = { x: x + gap, y: y + height }; |
|
|
|
|
|
const b = { x: x + gap + sWidth, y: a.y }; |
|
|
|
|
|
const c = { x: b.x, y: y + gap + sWidth }; |
|
|
|
|
|
const d = { x: x + width, y: c.y }; |
|
|
|
|
|
const e = { x: d.x, y: y + gap }; |
|
|
|
|
|
const f = { x: a.x, y: e.y }; |
|
|
|
|
|
let g = { |
|
|
|
|
|
x: x + width / 2 + ((length - i) * 2 + 1) * sqrt2, |
|
|
|
|
|
y: y + height / 2 + ((length - i) * 2 + 1) * sqrt2, |
|
|
|
|
|
}; |
|
|
|
|
|
let h = { |
|
|
|
|
|
x: x + width / 2 - (i * 2 + 1) * sqrt2, |
|
|
|
|
|
y: y + height / 2 - (i * 2 + 1) * sqrt2, |
|
|
|
|
|
}; |
|
|
|
|
|
// if (["rightbottom", "lefttop", "topright", "bottomleft"].includes(dir)) {
|
|
|
|
|
|
// let tmp = h;
|
|
|
|
|
|
// h = g;
|
|
|
|
|
|
// g = tmp;
|
|
|
|
|
|
// }
|
|
|
|
|
|
let rad = |
|
|
|
|
|
dir === "bottomright" || dir === "rightbottom" |
|
|
|
|
|
? 0 |
|
|
|
|
|
: dir === "topleft" || dir === "lefttop" |
|
|
|
|
|
? Math.PI |
|
|
|
|
|
: dir === "righttop" || dir === "topright" |
|
|
|
|
|
? Math.PI / 2 |
|
|
|
|
|
: -Math.PI / 2; |
|
|
|
|
|
[a, b, c, d, e, f, g, h].forEach((point) => |
|
|
|
|
|
rotate(x + width / 2, y + height / 2, point, rad) |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
// g
|
|
|
|
|
|
// /
|
|
|
|
|
|
// -------------
|
|
|
|
|
|
// | |
|
|
|
|
|
|
// ----f-------e
|
|
|
|
|
|
// | | |
|
|
|
|
|
|
// | | c---d
|
|
|
|
|
|
// | | | |
|
|
|
|
|
|
// ----a---b----
|
|
|
|
|
|
// /
|
|
|
|
|
|
// h
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
const gradient = ctx.createLinearGradient(h.x, h.y, g.x, g.y); |
|
|
|
|
|
gradient.addColorStop(0, "#" + startColor.toString(16)); |
|
|
|
|
|
gradient.addColorStop(1, "#" + endColor.toString(16)); |
|
|
|
|
|
ctx.fillStyle = gradient; |
|
|
|
|
|
ctx.strokeStyle = gradient; |
|
|
|
|
|
ctx.beginPath(); |
|
|
|
|
|
ctx.moveTo(a.x, a.y); |
|
|
|
|
|
ctx.lineTo(b.x, b.y); |
|
|
|
|
|
ctx.arcTo(c.x, c.y, d.x, d.y, gap); |
|
|
|
|
|
ctx.lineTo(e.x, e.y); |
|
|
|
|
|
ctx.arcTo(f.x, f.y, a.x, a.y, gap + sWidth); |
|
|
|
|
|
ctx.closePath(); |
|
|
|
|
|
ctx.fill(); |
|
|
|
|
|
ctx.stroke(); |
|
|
|
|
|
} |
|
|
|
|
|
renderSnake() { |
|
|
|
|
|
const { length } = this.snake; |
|
|
|
|
|
const list = []; |
|
|
|
|
|
for (let body of this.snake) { |
|
|
|
|
|
list.push(body); |
|
|
|
|
|
} |
|
|
|
|
|
list.forEach(({ data }, i) => { |
|
|
|
|
|
const pre = list[i - 1]; |
|
|
|
|
|
const nxt = list[i + 1]; |
|
|
|
|
|
const [x, y] = this.getPosition(data); |
|
|
|
|
|
if (i === 0) { |
|
|
|
|
|
// head
|
|
|
|
|
|
const [xNxt, yNxt] = this.getPosition(nxt.data); |
|
|
|
|
|
const dir = getDir(x, y, xNxt, yNxt); |
|
|
|
|
|
this.drawHeadTail(x, y, dir, i, list.length); |
|
|
|
|
|
} else if (i === length - 1) { |
|
|
|
|
|
const [xPre, yPre] = this.getPosition(pre.data); |
|
|
|
|
|
const dir = getDir(xPre, yPre, x, y); |
|
|
|
|
|
this.drawHeadTail(x, y, dir, i, list.length); |
|
|
|
|
|
} else { |
|
|
|
|
|
const [xNxt, yNxt] = this.getPosition(nxt.data); |
|
|
|
|
|
const dir1 = getDir(x, y, xNxt, yNxt); |
|
|
|
|
|
const [xPre, yPre] = this.getPosition(pre.data); |
|
|
|
|
|
const dir2 = getDir(xPre, yPre, x, y); |
|
|
|
|
|
if (dir1 === dir2) { |
|
|
|
|
|
this.drawRec(x, y, dir1, i, length); |
|
|
|
|
|
} else { |
|
|
|
|
|
const dir3 = getDir(x, y, xPre, yPre); |
|
|
|
|
|
this.drawCorner(x, y, dir1 + dir3, i, length); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
// 渲染
|
|
|
// 渲染
|
|
|
render() { |
|
|
render() { |
|
|
this.app.renderer.render(this.app.stage); |
|
|
|
|
|
|
|
|
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); |
|
|
|
|
|
this.renderFood(); |
|
|
|
|
|
this.renderSnake(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|