【React-Redux】自制简易贪吃蛇小游戏,字节跳动最爱考的前端面试题

}

class App extends Component {

state = initState;

render() {

return (

);

}

}

export default App;

把snake-dot的动态生成放到子组件Snake.js中:

import React from ‘react’

export const Snake = ({snakeDots}) => {

return (

<>

{

snakeDots.map((dot, index)=>{

let dotStyle = {

left:${dot[0]}%,

top:${dot[1]}%

}

console.log(dotStyle)

return (

)

})

}

</>

)

}

这样初始化就完成了

贪吃蛇的移动


贪吃蛇的上下左右移动根据键盘输入的上下左右(↑↓←→)键来确定,初始化时默认是向右移动的

先来看看键盘上下左右键的code值

| Key | Code |

| — | — |

| 左箭头 | 37 |

| 右箭头 | 39 |

| 上箭头 | 38 |

| 下箭头 | 40 |

游戏开始时,默认是向右走的,因此,我们增加一个表示方向的state:direction,走的速度是每隔200ms前进一步

const initState = {

snakeDots: [

[0, 0],

[2, 0]

],

direction: “RIGHT”,

speed: 200

}

当检测到上下左右键按下时,更新state中的方向,贪吃蛇沿该方向前进一步;

若没有按键按下,就沿着当前方向一路前进

贪吃蛇的头部(head)是小黑方块的最后一块,不断地删去第一个小黑方块并在direction方向上新增一小黑方块;视觉上,贪吃蛇就有不停向前移动的效果

在这里插入图片描述

componentDidMount() {

// 监听键盘按下事件

document.onkeydown = this.onkeydown;

// 每隔200ms前进一步

setInterval(this.onMove, this.state.speed);

}

onkeydown = (e) => {

// 根据按下的键盘键更新direction

switch (e.keyCode) {

case 37:

this.setState({ direction: “LEFT” });

break;

case 38:

this.setState({ direction: “UP” });

break;

case 39:

this.setState({ direction: “RIGHT” });

break;

case 40:

this.setState({ direction: “DOWN” });

break;

default:

this.setState({ direction: “RIGHT” });

}

}

onMove = () => {

// 根据direction指示的方向前进

let newSnakeDots = […this.state.snakeDots];

let header = newSnakeDots[newSnakeDots.length - 1];

switch (this.state.direction) {

case “UP”:

header = [header[0], header[1] - 2];

break;

case “DOWN”:

header = [header[0], header[1] + 2];

break;

case “LEFT”:

header = [header[0] - 2, header[1]];

break;

case “RIGHT”:

header = [header[0] + 2, header[1]];

break;

default:

header = [header[0] + 2, header[1]];

}

// 删去第一个小黑块,并在direction方向上新增新小黑块,更新snakeDots

newSnakeDots.shift();

newSnakeDots.push(header);

this.setState({ snakeDots: newSnakeDots })

}

效果:

在这里插入图片描述

边界限制与得分计算


当触碰边界或者撞击到自身时,游戏结束,弹窗提示,分数为贪吃蛇的长度-2(初始长度为2,其余均是吃到食物后变长的,吃一个食物长长1格)

componentDidUpdate() {

this.checkIfBordered();

}

checkIfBordered = () => {

let newSnakeDots = […this.state.snakeDots];

let header = newSnakeDots[newSnakeDots.length - 1];

if (header[0] < 0 || header[0] > 98 || header[1] < 0 || header[1] > 98) {

alert(触碰边界,游戏结束,你的得分是:${newSnakeDots.length - 2});

this.setState(initState);

}

}

食物随机出现


由于我们规定,贪吃蛇触碰到边界时算游戏结束,因此,食物不能出现在边界上,否则,一吃到食物就代表触壁结束游戏(可以改进为:贪吃蛇每次前进1%,当食物被触碰比例达50%时可以当作贪吃蛇吃掉该食物,马上掉头避免触壁,以后再改吧~)

因此,食物出现的范围在top:2%~96%,left的范围也是如此

在这里插入图片描述

const getRandomFood = ()=>{

// 食物出现的范围是:[2, 96] 推算过程:[0,95)->[2, 97)->[1, 48.5]->[1,48]->[2,96]

let max = 95;

let min = 2;

let x = Math.floor((Math.random() * max + min) / 2) * 2;

let y = Math.floor((Math.random() * max + min) / 2) * 2;

return [x,y]

}

const initState = {

snakeDots: [

[0, 0],

[2, 0]

],

direction: “RIGHT”,

speed: 200,

food:getRandomFood() // 随机生成食物的位置

}

食物的展示:

import { Food } from ‘./components/Food’;

render() {

return (

);

}

import React from ‘react’

export const Food = ({food}) => {

let foodStyle = {

left:${food[0]}%,

top:${food[1]}%

}

return (

)

}

食物的样式:

.food {

height: 2%;

width: 2%;

background-color: red;

border: 1px solid #fff;

position: absolute;

}

判断是否吃到食物


贪吃蛇的头(head)和食物重叠时,代表吃到

贪吃蛇变长,食物的位置变成新的head,重新放置食物

componentDidUpdate() {

// 每次更新都判断一下

this.checkIfBordered();

this.checkIfEated();

}

checkIfEated = ()=>{

let newSnakeDots = […this.state.snakeDots];

let header = newSnakeDots[newSnakeDots.length - 1];

// head与食物重叠时,代表吃到食物

if(header[0]==this.state.food[0] && header[1]==this.state.food[1]){

console.log(“吃到了”)

newSnakeDots.unshift([]);

this.setState({snakeDots:newSnakeDots});

this.setState({food:getRandomFood()});

}

}

效果:

在这里插入图片描述

完整代码:

新建文件夹component存放组件:

在这里插入图片描述

App.js

import React, { Component } from ‘react’

import { Snake } from ‘./components/Snake’;

import { Food } from ‘./components/Food’;

// 随机获取食物位置

const getRandomFood = ()=>{

// [2, 96]: [0,95)->[2, 97)->[1, 48.5]->[1,48]->[2,96]

let max = 95;

let min = 2;

let x = Math.floor((Math.random() * max + min) / 2) * 2;

let y = Math.floor((Math.random() * max + min) / 2) * 2;

console.log(“food-position”,x,y)

return [x,y]

}

// 另存state以便重新初始化

const initState = {

snakeDots: [

[0, 0],

[2, 0]

],

direction: “RIGHT”,

speed: 200,

food:getRandomFood()

}

class App extends Component {

state = initState;

// 监听与计时器

componentDidMount() {

document.onkeydown = this.onkeydown;

setInterval(this.onMove, this.state.speed);

}

// 更新时检测是否出界或吃到食物

componentDidUpdate() {

this.checkIfBordered();

this.checkIfEated();

}

// 判断键盘按键,更新direction

onkeydown = (e) => {

switch (e.keyCode) {

case 37:

this.setState({ direction: “LEFT” });

break;

case 38:

this.setState({ direction: “UP” });

break;

case 39:

this.setState({ direction: “RIGHT” });

break;

case 40:

this.setState({ direction: “DOWN” });

break;

default:

this.setState({ direction: “RIGHT” });

}

}

// 根据direction移动

onMove = () => {

let newSnakeDots = […this.state.snakeDots];

let header = newSnakeDots[newSnakeDots.length - 1];

switch (this.state.direction) {

case “UP”:

header = [header[0], header[1] - 2];

break;

case “DOWN”:

header = [header[0], header[1] + 2];

break;

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

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

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

img

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

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

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

核心竞争力,怎么才能提高呢?

成年人想要改变生活,逆转状态?那就开始学习吧~

万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。

为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。

前端面试题汇总

JavaScript

性能

linux

前端资料汇总

完整版PDF资料免费分享,只需你点赞支持,动动手指点击此处就可免费领取了

前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的小伙伴要注意了,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候无论遇到什么情况,问题都不会大。

48fd0fcb265f3401a21603bda2b.png)

前端面试题汇总

JavaScript

性能

linux

前端资料汇总

完整版PDF资料免费分享,只需你点赞支持,动动手指点击此处就可免费领取了

前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的小伙伴要注意了,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候无论遇到什么情况,问题都不会大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值