用TS从零开始制作贪吃蛇游戏--3

简介: 本教程基于B站李立超老师的教学,使用VSCode、Less、TypeScript和Webpack开发了一个经典的贪吃蛇游戏。项目包括食物、贪吃蛇、游戏控制和分数管理四个主要类的实现,详细展示了类的定义、属性和方法的使用,以及游戏逻辑的处理。适合初学者学习TypeScript面向对象编程。

本内容学习来自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语言的方便和特点,如果大家对此游戏有问题的话,欢迎大家发私信给我,我会给大家一一解答。

目录
相关文章
|
前端开发 JavaScript
[项目篇]vue3+ts 移动端和pc端双端实现瀑布流 - 第六天
[项目篇]vue3+ts 移动端和pc端双端实现瀑布流 - 第六天
|
19天前
|
JavaScript 编译器
用TS从零开始制作贪吃蛇游戏--1
本项目使用VSCode、Less、TypeScript及Webpack构建“贪吃蛇”游戏。首先初始化项目结构,创建Gluttonous snake文件夹并用VSCode打开,通过npm初始化package.json。接着配置Webpack,包括安装相关插件(如html-webpack-plugin、clean-webpack-plugin、webpack-dev-server)、设置TS编译环境及Less编译规则。最终实现自动打包、热更新及样式文件的正确处理。
83 52
|
19天前
|
前端开发 JavaScript
用TS从零开始制作贪吃蛇游戏--2
本教程来自B站李立超老师的课程,使用VSCode、Less和TypeScript开发贪吃蛇游戏。本文详细介绍了如何构建游戏的基本HTML结构和CSS样式,为后续的游戏逻辑开发打下基础。
30 1
|
4月前
|
编译器 vr&ar 图形学
从零开始的unity3d入门教程(五)---- 基于Vuforia的AR项目
这是一篇Unity3D结合Vuforia实现增强现实(AR)项目的入门教程,涵盖了环境配置、Vuforia账户注册、Target数据集创建、Unity项目设置、AR程序配置、Android环境配置以及最终在手机上测试运行的全过程。
从零开始的unity3d入门教程(五)---- 基于Vuforia的AR项目
|
6月前
|
图形学
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇2(附项目源码)
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇2(附项目源码)
77 0
|
6月前
|
定位技术 图形学 开发者
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇1(附项目源码)
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇1(附项目源码)
88 0
|
6月前
|
图形学
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇3(附项目源码)
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇3(附项目源码)
64 0
|
存储 监控 JavaScript
保熟的TS知识,拜托,超快超酷的好吗
这一步对于很多人来说是最简单的一步,也是最难的一步,说简单是因为这确确实实仅是入门的一步,就是一个环境配置,说难则是因为很多人无法跨出这一步,当你跨出这一步之后,你会发现后面的真的学得很快很快,现在,就让我们一起跨出这一步吧~
74 0
|
前端开发 JavaScript
我用Vue3+TS实现了一个新年倒计时组件,适用于各种场景
最近在写一个考试系统,有一个倒计时自动交卷的需求,正好也马上春节,就有了编写一个倒计时组件的想法。 对于这个倒计时组件,它应该具有这样的功能: 字体、颜色等样式可以由使用者自定义;
955 0
我用Vue3+TS实现了一个新年倒计时组件,适用于各种场景
|
JavaScript 网络架构 开发者
TS扫盲大法-基础篇
TS扫盲大法-基础篇
117 0
TS扫盲大法-基础篇