This is the fourth day of my participation in Gwen Challenge

1. Prelude to actual combat

Instance properties must be accessed through the instance

Static properties must be accessed through classes

class Person1 {
    // Define instance attributes
    name: string = 'zlm';
    // Use the static keyword in front of an attribute to define a static attribute, which is a class method
    static age: number = 12;
    // The property is read-only and cannot be modified
    readonly sex: boolean = false;

    sayHello() {
        console.log("hello world")}}const person = new Person1()
console.log(person.name)
console.log(Person1.age)
console.log(person.sayHello())
Copy the code

Constructor: When new Person(), constructor executes

In the instance method, this represents the current instance

You can use this to add attributes to a newly created object

class Dog {
    name: string;
    age: number;
    // The constructor is called when the object is created,
    constructor(name:string, age:number) {
        this.name = name;
        this.age = age;
    }
    bark() {
        alert(123)}}const dog = new Dog('river'.4)
Copy the code

Inheritance: With inheritance, a subclass owns all the methods and attributes of its parent class

Override: If a subclass adds the same method as its parent class, the parent class will be overwritten. This is called override

A subclass wants to call its parent’s method: super.sayHello()

If a subclass writes a constructor, it must call super().

Abstract classes: Classes that begin with abstract are abstract classes. Abstract classes are different from other classes: abstract classes cannot be used to create objects. Abstract classes are classes that are specifically designed to be inherited

** Interface: ** is used to define a class structure, which attributes and methods should be included in a class, and can also be used as a type declaration

type myType2 = {
    name: string.age: number
}
interface myInterface {
    name: string;
    age: number
}
const Obj:myType2 = {
    name: 'zlm'.age: 19
}
const Obj2:myInterface = {
    name: 'zlm'.age: 20
}
Copy the code

Type and interface can be used equally

An interface can limit the structure of a class. An interface can only be defined and cannot have an actual value.

** Implement interface ** : All methods in the interface must be implemented

class myInter implements myInterface {
    name: string;
    age: number
    constructor(name: string, age: number) {
        this.name = name
        this.age = age
    }
}
Copy the code

Syntactic sugar:

class myInter implements myInterface {
    constructor(public name: string.public age: number) {
        this.name = name
        this.age = age
    }
}
Copy the code

Generics: Use generics when the type is ambiguous

// Do not use the same method
function fnn(a:any) :any {
   return a;
}

// Define a generic T to implement
function fnnn<T> (a: T) :T {
   return a;
}
function fun<T.K> (a:T, b:K) :T {
   return a;
}
// Control generics
interface Inter {
   length: number;
}
// Indicates that the generic T inherits the interface Inter and implements the class
function fn3<T extends Inter> (a: T) :number {
   return a.length
}
Copy the code

2. Actual project combat

The following is a snake code, not fully implemented, developed over and over again, constantly updated

Style file: index.html

<! DOCTYPEhtml>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <title>snake</title>
</head>
<body>
    <! Create the game's main container -->
    <div id="main">
        <! -- Game stage -->
        <div id="stage">
            <div id="snake">
                 <div></div>
            </div>
            <! -- Set food -->
            <div id="food">
                <div></div>
                <div></div>
                <div></div>
                <div></div>
            </div>
        </div>
        <! -- Game score card -->
        <div id="socre-panel">
            <div>
                SCORE: <span id="score">0</span>
            </div>
            <div>
                LEVEL: <span id="level">1</span>
            </div>

        </div>

    </div>
</body>
</html>
Copy the code

The CSS file

// Set the color variable
@bg-color: #b7d4a8;
// Clear the default styles
* {
    margin: 0;
    padding: 0;
    // Change the calculation of the box model
    box-sizing: border-box;
}
body {
    font: bold 20px "Courier"
}
// Style the main window
#main {
 width: 360px;
 height: 420px;
 background-color: @bg-color;
 margin: 100px auto;
 border: 10px solid black;
 border-radius: 10px;
 // Open the elastic box model
 display: flex;
 // Set the spindle method
 flex-flow: column;
 // Set the alignment of the auxiliary axis
 align-items: center;
 // Set the spindle alignment
 justify-content: space-around;
 #stage {
     width: 304px;
     height: 304px;
     border: 2px solid black;
     margin: 0 auto;
     position: relative;
     // Set the snake style
     #snake {
         &>div {
           width: 10px;
           height: 10px;
           background-color: # 000;
           border: 1px solid @bg-color;
           // Enable absolute positioning
           position: absolute; }}#food {
        width: 10px;
        height: 10px;
        position: absolute;
        left: 40px;
        top: 100px;
        display: flex;
        // Set the horizontal axis to the main axis, wrap means automatic line wrapping
        flex-flow: row wrap;
        justify-content: space-between;
        align-content: space-between;
        &>div {
            width: 4px;
            height: 4px;
            background-color: black;
            transform: rotate(45deg); }}}/ / the scoreboard
 #socre-panel {
     width: 300px;
     display: flex;
     justify-content: space-around; }}Copy the code

TS file

// Introduce CCTV
import './style/index.less'
// Define the food class
class Food {
    // Define a food element
    element: HTMLElement;
    constructor() {
        this.element = document.getElementById('food')! ;/ / add! Indicates that ID cannot be null
    }
    // Get the X coordinates of the food
    get X() {
        return this.element.offsetLeft
    }
    // Get the Y coordinates of the food
    get Y() {
        return this.element.offsetTop
    }
    // Change the location of food
    change() {
        // Generate a random number with a maximum of 290, a minimum of 0, and an integer multiple of 10
        let top = Math.round(Math.random() * 29) * 10
        let left = Math.round(Math.random() * 29) * 10
        this.element.style.left = left + 'px';
        this.element.style.top = top + 'px'; }}// Test the code
const food = new Food()
console.log(food.X, food.Y)
food.change()
console.log(food.X, food.Y)

// Define the scoreboard class
class ScorePanel {
    score = 0;
    level = 1;
    scoreEle: HTMLElement;
    levelEle: HTMLElement;
    constructor() {
        this.scoreEle = document.getElementById('score')! ;this.levelEle = document.getElementById('level')! ; }// set the bonus point method
    addScore() {
        this.score ++;
        this.scoreEle.innerHTML = ++this.score + ' ';
    }
    // The upgrade method
    levelUp() {
        if(this.level < 10) {
            this.levelEle.innerHTML = ++this.level + ' '; }}}Copy the code

Attach the webPack configuration file

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
// All configuration information in webpack should be written in module.exports
module.exports = {
    // Specify the entry file
    entry: './src/index.ts'.// Specify the directory where the package file resides
    output: {
         // The packaged file
         filename: "bundle.js".// Specify the directory to package the files
         path: path.resolve(__dirname, 'dist'),
        // Configure the packaging environment, telling WebPack not to use arrow functions
        // arrowFunction: true, // no arrowFunction
        // const: false
        / /}
    },
    // Specify the module to use when webpack is packaged
    module: {
        // Specify the rules to load
        rules: [{test: /\.ts$/.// test specifies the file in which the rule takes effect
                 // The loader to use
                use: [
                 / / configuration Babel
                   {
                      // specify load to go
                      loader: "babel-loader"./ / set the Babel
                      options: {
                          // Set the predefined environment
                          presets: [[// Specify a plug-in for the environment
                                  "@babel/preset-env".// Configuration information
                                  {   
                                      // Be compatible with the target browser
                                      targets: {
                                          "chrome": "88",},// Specify the version of Corejs
                                      "corejs": "3".// Using the corejs method, "usage" means load on demand
                                      "useBuiltIns": "usage"}]]}},'ts-loader'].exclude: /node_modules/ // Files to be checked
            },
            // Set the processing of less files
            {
                test: /\.less$/,
                use: [
                    "style-loader"."css-loader"./ / introduce postcss
                    {
                       loader: "postcss-loader".options: {
                           postcssOptions: [["postcss-preset-env",
                                   {
                                       browsers: 'last 2 versions'}]]}},"less-loader"]]}},// Configure the WebPack plug-in
    plugins: [
      new CleanWebpackPlugin(),
      new HtmlWebpackPlugin({
          title: 'This is a custom Title'.template: "./src/index.html"})].// Set the import module
    resolve: {
        extensions: ['.ts'.'.js']}}Copy the code

The latter

This is a typeScript field note. The game is still in development and will continue to be updated, with the full Github address attached