ts项目 --- 贪吃蛇

},

“less-loader”

]

}

]

},

// 配置Webpack插件

plugins: [

new CleanWebpackPlugin(),

new HTMLWebpackPlugin({

// title: “这是一个自定义的title”

template: “./src/index.html”

}),

],

// 用来设置引用模块

resolve: {

extensions: [‘.ts’, ‘.js’]

},

mode:‘development’

};

  1. 新建src文件夹,创建index.tsindex.html

  2. src文件夹内,新增modules文件夹和style文件夹

2.编写结构和样式

在这里插入图片描述

src/index.html

贪吃蛇
SCORE: 0
LEVEL: 1

src/style/index.less

//设置颜色变量

@bg-color:#b7d4a8;

  • {

margin: 0;

padding: 0;

box-sizing: border-box;

}

#main {

display: flex;

flex-flow: column;

align-items: center;

justify-content: space-around;

margin: 0 auto;

width: 360px;

height: 420px;

border: 10px solid #000;

background-color: @bg-color;

border-radius: 30px;

#stage{

position: relative;

width: 304px;

height: 304px;

border: 2px solid #000;

#snake{

&>div{

position: absolute;

width: 10px;

height: 10px;

background-color: #000;

border: 1px solid @bg-color;

}

}

&>#food{

display: flex;

flex-flow: row wrap;

justify-content: space-between;

align-content: space-between;

position: absolute;

top: 10px;

left: 10px;

width: 10px;

height: 10px;

&>div{

width: 4px;

height: 4px;

background: #000;

transform: rotate(45deg);

}

}

}

#score-panel{

width: 300px;

display: flex;

align-items: center;

justify-content: space-between;

}

}

body {

font:bold 20px “Courier”;

}

3.模块化

src/modules/Food.ts

class Food{

element:HTMLElement;

constructor(){

//this.element=document.getElementById(‘food’) as HTMLElement

this.element=document.getElementById(‘food’)!;

}

get X() {

return this.element.offsetLeft

}

get Y() {

return this.element.offsetTop

}

change() {

this.element.style.left=Math.ceil(Math.random()*29)*10+‘px’;

this.element.style.top=Math.ceil(Math.random()*29)*10+‘px’;

}

}

export default Food;

src/modules/ScorePanel.ts

class ScorePanel{

score:number=0;

level:number=1;

scoreEle:HTMLElement;

levelEle:HTMLElement;

maxLevel:number;

upScore:number;

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.score++;

this.scoreEle.innerHTML = this.score + ‘’;

if(this.score % this.upScore === 0){

this.levelUp();

}

}

levelUp(){

if(this.level<this.maxLevel){

this.levelEle.innerHTML = ++this.level + ‘’;

}

}

}

export default ScorePanel;

src/modules/Snake.ts

class Snake{

head:HTMLElement;

bodies:HTMLCollection;

element:HTMLElement;

constructor(){

this.element = document.getElementById(‘snake’)!;

this.head = document.querySelector(‘#snake>div’)!;

this.bodies=this.element.getElementsByTagName(‘div’)!;

}

public get X(){

return this.head.offsetLeft;

}

public get Y(){

return this.head.offsetTop;

}

set X(value:number){

if(this.X === value){

return;

}

if(value<0 || value>290){

throw new Error(‘蛇撞墙了!!’)

}

//是否掉头

if(this.bodies[1]&&(this.bodies[1] as HTMLElement).offsetLeft === value){

if(value>this.X){

//左走向右调头

value -= 20

}else{

value += 20

}

}

//移动身体

this.moveBody();

//移动蛇头

this.head.style.left = value + ‘px’;

this.checkHeadBody();

}

set Y(value:number){

if(this.Y === value){

return

}

if(value<0 || value>290){

throw new Error(‘蛇撞墙了!!’)

}

//是否掉头

if(this.bodies[1]&&(this.bodies[1] as HTMLElement).offsetTop === value){

if(value>this.Y){

//左走向右调头

value -= 20

}else{

value += 20

}

}

this.moveBody();

this.head.style.top = value + ‘px’;

this.checkHeadBody();

}

addBody(){

this.element.insertAdjacentElement(‘beforeend’,document.createElement(‘div’))

}

moveBody(){

//将后面身体的位置改为前面身体的位置,先改后面的位置,

//后面的位置依附前面的位置

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’;

}

}

// 移动后检查

checkHeadBody(){

//获取所有身体坐标

for (let i = 1; i < this.bodies.length; i++) {

if(this.X === (this.bodies[i] as HTMLElement).offsetLeft &&this.Y === (this.bodies[i] as HTMLElement).offsetTop){

throw new Error(‘撞到自己了!’)

}

}

}

}

export default Snake

src/modules/GameControl.ts

import Food from “./Food”;

import ScorePanel from “./ScorePanel”;

import Snake from “./Snake”;

class GameControl{

snake:Snake;

food:Food;

scorePanel:ScorePanel;

//蛇的运动方向

direction:string=’ ';

//游戏是否结束

isLive = true;

constructor(){

this.snake = new Snake();

this.food = new Food();

this.scorePanel = new ScorePanel();

this.init();

this.run();

}

init(){

//绑定键盘事件

document.addEventListener(‘keydown’,this.keydownHandler.bind(this))

}

//键盘响应函数

//key:ArrowUp ArrowDown ArrowLeft ArrowRight

// IE: Up Down Left Right

keydownHandler(event:KeyboardEvent){

const keyhefa = [‘ArrowUp’,‘ArrowDown’,‘ArrowLeft’,‘ArrowRight’,‘Up’,‘Down’,‘Left’,‘Right’,’ ']

if (keyhefa.indexOf(event.key)>-1) {

this.direction = event.key;

}

}

//蛇移动的方法

run(){

//获取蛇现在的坐标

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 ‘ArrowRight’:

case ‘Right’:

X += 10;

break;

case ‘ArrowLeft’:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)


后记


总结一下这三次面试下来我的经验是:

  1. 一定不要死记硬背,要理解原理,否则面试官一深入就会露馅!

  2. 代码能力一定要注重,尤其是很多原理性的代码(之前两次让我写过Node中间件,Promise.all,双向绑定原理,被虐的怀疑人生)!

  3. 尽量从面试官的问题中表现自己知识的深度与广度,让面试官发现你的闪光点!

  4. 多刷面经!

我把所有遇到的面试题都做了一个整理,并且阅读了很多大牛的博客之后写了解析,免费分享给大家,算是一个感恩回馈吧,有需要的朋友【点击我】免费获取。祝大家早日拿到自己心怡的工作!

篇幅有限,仅展示部分内容



来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

[外链图片转存中…(img-4Hgj3RrO-1713561406012)]
后记


总结一下这三次面试下来我的经验是:

  1. 一定不要死记硬背,要理解原理,否则面试官一深入就会露馅!

  2. 代码能力一定要注重,尤其是很多原理性的代码(之前两次让我写过Node中间件,Promise.all,双向绑定原理,被虐的怀疑人生)!

  3. 尽量从面试官的问题中表现自己知识的深度与广度,让面试官发现你的闪光点!

  4. 多刷面经!

我把所有遇到的面试题都做了一个整理,并且阅读了很多大牛的博客之后写了解析,免费分享给大家,算是一个感恩回馈吧,有需要的朋友【点击我】免费获取。祝大家早日拿到自己心怡的工作!

篇幅有限,仅展示部分内容



  • 20
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值