当前位置:网站首页>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.ts
Said 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
边栏推荐
- Some websites of QT (software download, help documents, etc.)
- 20211028 adjustment and tracking
- Neo4j environment construction
- ""? "& in URL Role of "" sign
- 20211104 why are the traces of similar matrices the same
- 20211006 线性变换
- redis 模糊查询 批量删除
- 20211108 observable, controllable, stable and measurable
- Map 23 summary
- Top+jstack to analyze the causes of excessive CPU
猜你喜欢
【网络安全】SQL注入新思维之webshell提权
Drill down to protobuf - Introduction
Library management system based on wechat applet Rar (thesis + source code)
Mttr/mttf/mtbf diagram
教程篇(5.0) 02. 管理 * FortiEDR * Fortinet 网络安全专家 NSE 5
Simulink如何添加模块到Library Browser
Tutorial (5.0) 04 Fortint cloud services and scripts * fortiedr * Fortinet network security expert NSE 5
How many TCP connections can a machine create at most?
Use of grep
20211020 academician all drive system
随机推荐
Jfinal and swagger integration
Screenshot of cesium implementation scenario
Loss outputs Nan for the Nan model
Detailed explanation of C language callback function
Some websites of QT (software download, help documents, etc.)
Installation of sonarqube code quality management platform (to be continued)
图数据库Neo4j介绍
20211006 integral, differential and projection belong to linear transformation
Neo4j Environment Building
Use of grep
JS obtain geographic location information according to longitude and latitude and mark it on the map
Library management system based on wechat applet Rar (thesis + source code)
20211104 why are the traces of similar matrices the same
QML compilation specification
Cesium common events, including click events, mouse events, and camera movement events
Cmake Learning Series I
20211005 Hermite矩阵及几个性质
消息中间件
JUC原子数组
Margin:0 reason why auto does not take effect