本内容学习来自B站李立超老师 原文链接
本项目软件使用vscode,样式文件使用less,面对对象的TS,打包通过webpack进行制作
目录
编写食物类代码
编写贪吃蛇类代码
编写游戏控制类
编写游戏分数类
效果
结语
编写食物类代码
在src文件夹下新建js文件夹,在js文件夹中新建一个food.ts文件,编写如下代码
// 食物类
class Food{
element: HTMLElement
constructor(){
this.element = document.getElementById('food')!
}
// 获取食物X坐标
get X(){
return this.element.offsetLeft
}
// 获取食物Y坐标
get Y(){
return this.element.offsetTop
}
// 改变食物位置
change(){
let top = Math.round(Math.random() 29) 10
let left = Math.round(Math.random() 29) 10
this.element.style.top = top + 'px'
this.element.style.left = left + 'px'
}
}
export default Food
编写贪吃蛇类代码
在js文件夹中新建一个snake.ts文件,编写如下代码
class Snake {
head: HTMLElement
bodies: HTMLCollectionOf
element: HTMLElement
constructor() {
this.element = document.getElementById('snake')!
this.head = document.querySelector('#snake > div') as HTMLElement
this.bodies = this.element.getElementsByTagName('div')
}
get X() {
return this.head.offsetLeft
}
get Y() {
return this.head.offsetTop
}
set X(value: number) {
if (this.X === value) return
if (value < 0 || value >= 290) {
throw new Error('111')
}
// 判断是否发生了调头
if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === value) {
// 如果发生调头 让蛇继续向反方向走
if (value > this.X) {
value = this.X - 10
} else {
value = this.X + 10
}
}
this.moveBody()
this.head.style.left = value + 'px'
this.checkHeadBody()
}
set Y(value: number) {
if (this.Y === value) return
if (this.Y < 0 || this.Y >= 290) {
throw new Error('111')
}
// 判断是否发生了调头
if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value) {
// 如果发生调头 让蛇继续向反方向走
if (value > this.Y) {
value = this.Y - 10
} else {
value = this.Y + 10
}
}
this.moveBody()
this.head.style.top = value + 'px'
this.checkHeadBody()
}
// 增加蛇的身体
addBody() {
this.element.insertAdjacentHTML('beforeend', '
}
// 移动蛇的身体
moveBody() {
for (let i = this.bodies.length - 1; i > 0; i--) {
// 获取前面身体的位置
console.log(111)
let X = this.bodies[i - 1].offsetLeft
let Y = this.bodies[i - 1].offsetTop
// 将这个值设置到当前身体上
this.bodies[i].style.left = X + 'px'
this.bodies[i].style.top = Y + 'px'
}
}
checkHeadBody() {
// 获取所有的身体 检查是否和蛇头位置重叠
for (let i = 1; i < this.bodies.length; i++) {
if (this.X === this.bodies[i].offsetLeft && this.Y === this.bodies[i].offsetTop) {
// 相撞
throw new Error('蛇身体相撞了')
}
}
}
}
export default Snake
编写游戏控制类
在js文件夹中新建一个GameControl.ts文件,编写如下代码
import Snake from './snake'
import Food from './food'
import ScorePanel from './scorePanel'
class GameControl {
snake: Snake
food: Food
scorePanel: ScorePanel
direction: string = ''
// 游戏是否结束
isLive: boolean = true
constructor() {
this.snake = new Snake()
this.food = new Food()
this.scorePanel = new ScorePanel()
this.init()
}
init() {
document.addEventListener<'keydown'>('keydown', this.keydownHandler.bind(this))
this.run()
this.food.change()
}
keydownHandler(event: KeyboardEvent): void {
this.direction = event.key
}
// 蛇移动
run(): void {
let X = this.snake.X
let Y = this.snake.Y
switch (this.direction) {
case 'ArrowUp':
case 'Up':
Y -= 10
break
case 'ArrowDown':
case 'Down':
Y += 10
break
case 'ArrowLeft':
case 'Left':
X -= 10
break
case 'ArrowRight':
case 'Right':
X += 10
break
}
this.checkEat(X, Y)
try {
this.snake.X = X
this.snake.Y = Y
} catch (e: any) {
alert(e.message)
this.isLive = false
}
this.isLive &&
setTimeout(() => {
this.run()
}, 100 - (this.scorePanel.level - 1) * 30)
}
// 检查蛇是否吃到食物
checkEat(x: number, y: number): void {
if (x === 0 && y === 0 && this.food.X === 0 && this.food.Y === 0) {
return
}
if (x === this.food.X && y === this.food.Y) {
this.food.change()
this.scorePanel.addScore()
this.snake.addBody()
}
}
}
export default GameControl
编写游戏分数类
在js文件夹中新建一个ScorePanel.ts文件,编写如下代码
class ScorePanel{
score: number = 0
level:number = 1
private maxLevel:number;
private upScore:number;
scoreEle: HTMLElement;
levelEle: HTMLElement;
constructor(maxLevel:number = 10,upScore:number = 10){
this.scoreEle = document.getElementById('score')!
this.levelEle = document.getElementById('level')!
this.maxLevel = maxLevel
this.upScore = upScore
}
// 设置一个加分的方法
addScore(){
this.scoreEle.innerHTML = ++this.score + ''
if(this.score % this.upScore === 0){
this.levelUp( )
}
}
levelUp(){
if(this.level >this.maxLevel) return
this.levelEle.innerHTML = ++this.level + ''
}
}
export default ScorePanel
效果
结语
这个游戏代码逻辑不难但是能让大家更好的理解ts语言的方便和特点,如果大家对此游戏有问题的话,欢迎大家发私信给我,我会给大家一一解答。