当前位置:网站首页>Use typescript to complete simple snake eating function
Use typescript to complete simple snake eating function
2022-06-13 09:06:00 【antRain】
Use typescript Complete the simple snake eating function
Reference material
- TypeScript Chinese net
- Silicon Valley 2021 edition TypeScript course ( Mr. Li Lichao TS new course )
development tool
- vscode
- Recommended plug-ins Live Server Can monitor file changes , And refresh
Interface effect

Interface index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> snake </title>
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<div id="main">
<!-- The main interface of the game -->
<div id="stage">
<!-- Set snake -->
<div id="snake">
<!-- Represents the parts of a snake -->
<div></div>
</div>
<!-- Set food ,4 individual div Represents four corners -->
<div id="food">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<!-- Set the score card of the game -->
<div id="score-panel">
<!-- integral -->
<div>SCORE:<span id="score">0</span></div>
<!-- Grade , Default 10, High level and fast speed -->
<div>LEVEL:<span id="level">1</span></div>
</div>
</div>
<script src="TS/index.js"></script>
</body>
</html>
index.css
- Set the style of the page , It can be used in modular development less
* {
margin: 0;
padding: 0;
box-sizing: border-box;
} /* Clear default style */
body {
font: bold 20px "Courier"
}
#main {
width: 360px;
height: 420px;
background-color: #b7d4a8;
margin: 100px auto;
border: 10px solid black;
border-radius: 40px;
display: flex;
flex-flow: column;
align-items: center;
justify-content: space-around;
}
#stage {
width: 304px;
height: 304px;
border: 2px solid black;
position: relative;
}
#snake>div {
width: 10px;
height: 10px;
background-color: black;
border: 1px solid #b7d4a8;
position: absolute;
}
#food {
width: 10px;
height: 10px;
position: absolute;
left: 40px;
top: 100px;
display: flex;
flex-flow: row wrap; /* Set the main axis to the horizontal axis Wrap the excess part */
/* Set the white space of the main axis and the side axis to be allocated between the elements */
justify-content: space-between;
align-items: center;
}
#food > div {
width: 4px;
height: 4px;
background-color: black;
transform: rotate(45deg);
}
#score-panel {
width: 300px;
display: flex;
justify-content: space-between;
}
index.ts
- In modular development, you can put each class in a separate file
- Here I use a file , have access to The command is convenient for
tsc -t ES6 -w index.tsSaid the use of ES6 Compile , And monitor the files
class Food {
element : HTMLElement
width: number
size: number
constructor (id:string, width = 29, size = 10 ) {
this.element=document.getElementById(id)
this.width = width
this.size = size
}
get X(){
return this.element.offsetLeft
}
get Y() {
return this.element.offsetTop
}
change() {
// Generate random positions The scope is [0,width*10] But it should be an integer And is 10 Multiple
this.element.style.left = Math.round(Math.random()*this.width)*this.size + 'px'
this.element.style.top = Math.round(Math.random()*this.width)*this.size + 'px'
} // Modify the location of the food
}
class ScorePanel {
score = 0
level = 1
scoreEle : HTMLElement
levelEle : HTMLElement
static maxLevel = 10
static upScore = 1 // Set L 1 The grade required
constructor (scoreId:string, levelId:string) {
this.scoreEle = document.getElementById(scoreId)
this.levelEle = document.getElementById(levelId)
this.scoreEle.innerText = this.score + ''
this.levelEle.innerText = this.level + ''
}
addScore (d = 1) {
this.score += 1
this.scoreEle.innerText = this.score + ''
if (this.score % ScorePanel.upScore === 0) this.addLevel()
}
addLevel () {
if (this.level < ScorePanel.maxLevel) {
this.levelEle.innerText = ++this.level + ''
}
}
}
class Snake {
head: HTMLElement // The element representing the snake head
bodies: HTMLCollection // The body of a snake contains its head
element: HTMLElement // Get the container of the snake
range: number // The range of a snake's head
constructor(id, range = 290) {
this.element = document.getElementById(id)
this.element.innerHTML = '<div></div>' // initialization
this.bodies = this.element.getElementsByTagName('div')
this.head = this.bodies[0] as HTMLElement
this.range = range
}
get X() {
return this.head.offsetLeft
} // Get snakehead x coordinate
get Y() {
return this.head.offsetTop
} // Get snakehead y coordinate
set X(value:number) {
if (this.X === value) return
this.judge(value)
this.move()
this.head.style.left = value + 'px'
}
set Y(value:number) {
if (this.Y === value) return
this.judge(value)
this.move()
this.head.style.top = value + 'px'
}
addBody () {
this.element.insertAdjacentHTML("beforeend","<div></div>")
}
move() {
for(let i= this.bodies.length-1;i>0;--i){
let x = (this.bodies[i-1] as HTMLElement).offsetLeft
let y = (this.bodies[i-1] as HTMLElement).offsetTop;
(this.bodies[i] as HTMLElement).style.left = x + 'px';
(this.bodies[i] as HTMLElement).style.top = y + 'px'
}
}
judge(value:number) {
if ( value < 0 || value > this.range) {
throw new Error(' The snake hit the wall ')
}
for(let i= this.bodies.length-1;i>0;--i) {
let x = (this.bodies[i] as HTMLElement).offsetLeft
let y = (this.bodies[i] as HTMLElement).offsetTop;
if (x===this.X && y === this.Y) throw new Error(' Don't eat yourself ')
}
}
}
class GameControl {
snake:Snake
scorePanel: ScorePanel
food: Food
direction:string // Snake head moving direction
isLive = true // Mark that the current snake still exists =
static directionKey = new Set(['w','a','s','d',' ']) // The moving direction of the snake head may take
static speed = 200 // Initial speed setting
constructor() {
this.scorePanel = new ScorePanel('score','level')
this.food = new Food("food")
this.snake = new Snake("snake", this.food.size * this.food.width)
this.direction = ' '
this.init()
}
init() {
this.food.change()
console.log(this.food.X,this.food.Y)
document.addEventListener('keydown',this.keydownHandler.bind(this))
this.run()
}// Game initialization
keydownHandler(event:KeyboardEvent) {
let key = event.key
if (GameControl.directionKey.has(key)){
// Can't move in the opposite direction
if (this.direction === 'w' && key === 's') return
if (this.direction === 'a' && key === 'd') return
if (this.direction === 's' && key === 'w') return
if (this.direction === 'd' && key === 'a') return
this.direction = event.key
}
}// Create a function that responds to a keyboard press
run(){
let x = this.snake.X, y = this.snake.Y
switch(this.direction) {
case 'w':
y -= 10
break // Move up
case 'a':
x -= 10
break // Move to the left
case 's':
y += 10
break // Move down the
case 'd':
x += 10
break // To the right
case ' ':
break // A space indicates pause or resume
}
try {
this.checkEat(x, y)
this.snake.X = x
this.snake.Y = y
}catch (err){
this.isLive = false
if (window.confirm(err.message + ' Whether to continue the game ')) {
game = new GameControl()
}
return
}
this.isLive && setTimeout(this.run.bind(this),GameControl.speed / this.scorePanel.level) // Turn on timed call
}// Method of Snake Movement
checkEat (x:number, y:number) {
if (x === this.food.X && y === this.food.Y) {
this.food.change()
this.scorePanel.addScore()
this.snake.addBody()
}
} // Check whether the snake is late for food
} // Game controller
let game: GameControl = new GameControl()
appendix
- The teacher's webpack.config.js The configuration file , The other part is that I added
const path = require('path')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const {
CleanWebpackPlugin} = require('clean-webpack-plugin')
module.exports = {
context: path.resolve(__dirname, ''), // Base directory , Absolute path , Used to resolve the entry starting point from the configuration (entry point) And loader (loader).
entry: "./src/index.ts", // Specify the entry file
output: {
path: path.resolve(__dirname,'dist') , // Splicing catalog
filename: "bundle.js" ,// Package file name
environment: {
arrowFunction: false
} // Syntax environment of output file
}, // Specify the directory where the package files are located
module: {
rules:[
{
test: /\.tsx?$/, // Specify the file in which the rule takes effect
use: [
{
loader: "babel-loader",
options: {
persets: [
"@babel/preset-env", // Specifies the plug-in for the environment
{
targets: {
"chrome": "88",
"ie": "10"
}, // A compatible browser
"corejs": "3",
"useBuiltIns" : "usage", // Indicates that the required resources are loaded on demand
}
] // Set the predefined environment
} // The configuration item corresponding to the loader , Each loader has its own configuration item
},
"ts-loader"
] ,// Array mode uses multiple loaders
exclude: "/node-modules/" // Folder to exclude
}
] // Specify the rules to load
}, // Appoint webpack Modules to be used when packaging
resolve: {
extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"],
alias: {
'@': resolve('src')
}, // The configuration alias maps the original import path to a new import path
}, // To configure webpack How to find the file corresponding to the module
plugins: [
new CleanWebpackPlugin(),
new HTMLWebpackPlugin({
title : 'ts The project build ', // index.html title
template: "", // Define template location
})
],
devServer: {
} // Provide virtual servers , Let's develop and debug . The corresponding plug-in needs to be installed webpack-dev-server
}
- part package.json Dependencies to be installed
{
"script":{
"build": "webpack",
"start": "webpack serve --open chrome.exe"
},
"devDependencies": {
"clean-webpack-plugin" : "", // webpack Clear plug-ins in , Each build will first clear the directory
"html-webpack-plugin":"", // webpack in html plug-in unit , Used to automatically create html file
"ts-loader":"", // ts loader , Used in webpack Chinese compiler ts file
"typescript":"", // ts compiler
"webpack": "", // Building tools webpack
"webpack-cli": "", // webpack Command line tools for
"webpack-dev-server": "",
"@babel/core": "",
"@babel/preset-enb": "",
"babel-loader":"",
"core-js": ""
}
}
webpack-dev-server: Static resource server with real-time overload capability
边栏推荐
- Object in ES6 Use of entries()
- Cmake Learning Series I
- JS obtain geographic location information according to longitude and latitude and mark it on the map
- Completely uninstall PostgreSQL under Linux
- 20211108 det(AB)=det(A)det(B)
- Pytorch same structure different parameter name model loading weight
- 【安全】零基础如何从0到1逆袭成为安全工程师
- torch. How to calculate addmm (m, mat1, mat2)
- Judgment of single exclamation point and double exclamation point in JS
- JUC Unsafe
猜你喜欢

Library management system based on wechat applet Rar (thesis + source code)

Screenshot of cesium implementation scenario

Top+jstack to analyze the causes of excessive CPU

torch. How to calculate addmm (m, mat1, mat2)

Cesium achieves sunny, rainy, foggy, snowy and other effects

Installation of sonarqube code quality management platform (to be continued)

20220524 如何把CoppeliaSim安装到D盘

20211020 段院士全驱系统

基于微信小程序的图书馆管理系统.rar(论文+源码)

Redis fuzzy query batch deletion
随机推荐
Tutorial (5.0) 01 Product introduction and installation * fortiedr * Fortinet network security expert NSE 5
Pytorch model tuning - only some layers of the pre training model are loaded
Brief description of software testing and software maintenance
20211006 linear transformation
20211108 observable, controllable, stable and measurable
20211018 一些特殊矩阵
20211028 Stabilizability
Knowledge points related to system architecture 2
12. constructor explanation, explicit, initialization list
Vscode plug in
消息中间件
Detailed explanation of C language callback function
Basic use of cesium, including loading images, terrain, models, vector data, etc
20220524 how to install coppeliasim to disk D
教程篇(5.0) 04. Fortint云服务和脚本 * FortiEDR * Fortinet 网络安全专家 NSE 5
【QNX Hypervisor 2.2 用户手册】4.5 构建Guest
Loss outputs Nan for the Nan model
Web page H5 wechat sharing
MySQL startup error: innodb: operating system error number 13 in a file operation
国债逆回购能开户吗,国债逆回购在APP上可以直接开通券商安全吗 ,买股票怎么网上开户