微信企业微网站,网站前台修改后台对接不上,新主题wordpress,更换网站程序这篇文章将会做弹小球游戏#xff0c;弹小球游戏大家小时候都玩过#xff0c;玩家需要在小球到达游戏区域底部时候控制砖块去承接小球#xff0c;并不断的将小球弹出去。 首先看一下实现的效果。
效果演示 玩家需要通过控制鼠标来实现砖块的移动#xff0c;保证在小球下落… 这篇文章将会做弹小球游戏弹小球游戏大家小时候都玩过玩家需要在小球到达游戏区域底部时候控制砖块去承接小球并不断的将小球弹出去。 首先看一下实现的效果。
效果演示 玩家需要通过控制鼠标来实现砖块的移动保证在小球下落到底部时接到小球。
技术实现
html布局 游戏区域包括小球和砖块2个部分小球在来回移动砖块在底部移动。
import {useEffect, useState} from react;const BounceBall () {// 游戏区域配置const gameArea {width: 500,height: 400}// 小球对象const initBall {width: 20, // 小球宽度height: 20,// 小球高度posX: 240, // 240 ~ 260posY: 190, // 190 ~ 210speedX: 0, // 小球移动速度speedY: 2 // 小球移动速度}const [ball, setBall] useState(initBall)// 砖块对象const initPaddle {width: 80, // 砖块宽度height: 20,// 砖块高度posX: 210, // 210 ~ 290posY: 380 // 380 ~ 400}const [paddle, setPaddle] useState(initPaddle)// 游戏区域样式const gameAreaStyle {position: relative, /*相对定位*/width: ${gameArea.width}px, /*区域宽度*/height: ${gameArea.height}px, /*区域高度*/backgroundColor: #333}// 小球样式const ballStyle {position: absolute,/* 绝对定位 */top: ${ball.posY}px, /*小球位置*/left: ${ball.posX}px, /*小球位置*/width: ${ball.width}px,/* 设置小球的宽度 */height: ${ball.height}px, /* 设置小球的高度 */borderRadius: 50%, /* 设置小球为圆形 */backgroundColor: red /* 设置小球的背景颜色 */}// 砖块样式const paddleStyle {position: absolute, /* 绝对定位 */top: ${paddle.posY}px, /*板块位置*/left: ${paddle.posX}px, /*板块位置*/width: ${paddle.width}px, /* 设置砖块的宽度 */height: ${paddle.height}px, /* 设置砖块的高度 */backgroundColor: blue, /* 设置砖块的背景颜色 */border: 1px solid black /* 设置砖块的边框 */}return (div style{gameAreaStyle}{/*小球*/}div style{ballStyle}/div{/*砖块*/}div style{paddleStyle}/div/div/)
}游戏控制处理
小球移动处理 小球移动通过定时器实现定时器会在小球发生碰撞、游戏失败后清楚。
const [failCnt, setFailCnt] useState(0)
// 定时器控制小球移动
useEffect((){const intervalId setInterval((){// 小球移動ball.posX ball.speedX;ball.posY ball.speedY;setBall({...ball})}, 20)return () {clearInterval(intervalId)} // 返回是一个函数并非结果},[ball.speedX, ball.speedY, failCnt])
砖块移动处理 砖块移动通过控制鼠标移动实现
// 砖块移动
useEffect((){document.addEventListener(mousemove,(ev {const mouseX ev.clientX;let paddlePosX mouseX - paddle.width/2;if (paddlePosX 0){paddlePosX 0;}else if (paddlePosX gameArea.width - paddle.width){paddlePosX gameArea.width - paddle.width;}setPaddle({...paddle,posX: paddlePosX})}))
},[])
小球位置判断 需要考虑边界碰撞、砖块碰撞等场景
// 小球位置判断
useEffect((){// 边界判断if (ball.posX 0 || ball.posX gameArea.width - ball.width) {ball.speedX -1 * ball.speedX;setBall({...ball});return;}if (ball.posY 0) {ball.speedY -1 * ball.speedY;setBall({...ball});return;}// 判断是否碰撞到砖块if (ball.posY gameArea.height - ball.height - paddle.height) {// 未碰撞砖块if (ball.posX ball.width paddle.posX || ball.posX paddle.posX paddle.width) {alert(游戏失败)setBall({...initBall})setPaddle({...initPaddle})setFailCnt(failCnt 1)return;}console.log(ball)// 计算小球x speedconst collisionPoint (ball.posX ball.width/2 ) - (paddle.posX paddle.width/2) ; // 计算碰撞点距离挡板中心点的距离ball.speedX collisionPoint * 0.1ball.speedY -1 * ball.speedYsetBall({...ball})}
}, [ball.posX, ball.posY])
整体代码
import {useEffect, useState} from react;const BounceBall () {// 游戏区域配置const gameArea {width: 500,height: 400}// 小球对象const initBall {width: 20, // 小球宽度height: 20,// 小球高度posX: 240, // 240 ~ 260posY: 190, // 190 ~ 210speedX: 0, // 小球移动速度speedY: 2 // 小球移动速度}const [ball, setBall] useState(initBall)// 砖块对象const initPaddle {width: 80, // 砖块宽度height: 20,// 砖块高度posX: 210, // 210 ~ 290posY: 380 // 380 ~ 400}const [paddle, setPaddle] useState(initPaddle)const [failCnt, setFailCnt] useState(0)// 定时器控制小球移动useEffect((){const intervalId setInterval((){// 小球移動ball.posX ball.speedX;ball.posY ball.speedY;setBall({...ball})}, 20)return () {clearInterval(intervalId)} // 返回是一个函数并非结果},[ball.speedX, ball.speedY, failCnt])// 小球位置判断useEffect((){// 边界判断if (ball.posX 0 || ball.posX gameArea.width - ball.width) {ball.speedX -1 * ball.speedX;setBall({...ball});return;}if (ball.posY 0) {ball.speedY -1 * ball.speedY;setBall({...ball});return;}// 判断是否碰撞到砖块if (ball.posY gameArea.height - ball.height - paddle.height) {// 未碰撞砖块if (ball.posX ball.width paddle.posX || ball.posX paddle.posX paddle.width) {alert(游戏失败)setBall({...initBall})setPaddle({...initPaddle})setFailCnt(failCnt 1)return;}console.log(ball)// 计算小球x speedconst collisionPoint (ball.posX ball.width/2 ) - (paddle.posX paddle.width/2) ; // 计算碰撞点距离挡板中心点的距离ball.speedX collisionPoint * 0.1ball.speedY -1 * ball.speedYsetBall({...ball})}}, [ball.posX, ball.posY])// 砖块移动useEffect((){document.addEventListener(mousemove,(ev {const mouseX ev.clientX;let paddlePosX mouseX - paddle.width/2;if (paddlePosX 0){paddlePosX 0;}else if (paddlePosX gameArea.width - paddle.width){paddlePosX gameArea.width - paddle.width;}setPaddle({...paddle,posX: paddlePosX})}))},[])// 游戏区域样式const gameAreaStyle {position: relative, /*相对定位*/width: ${gameArea.width}px, /*区域宽度*/height: ${gameArea.height}px, /*区域高度*/backgroundColor: #333}// 小球样式const ballStyle {position: absolute,/* 绝对定位 */top: ${ball.posY}px, /*小球位置*/left: ${ball.posX}px, /*小球位置*/width: ${ball.width}px,/* 设置小球的宽度 */height: ${ball.height}px, /* 设置小球的高度 */borderRadius: 50%, /* 设置小球为圆形 */backgroundColor: red /* 设置小球的背景颜色 */}// 砖块样式const paddleStyle {position: absolute, /* 绝对定位 */top: ${paddle.posY}px, /*板块位置*/left: ${paddle.posX}px, /*板块位置*/width: ${paddle.width}px, /* 设置砖块的宽度 */height: ${paddle.height}px, /* 设置砖块的高度 */backgroundColor: blue, /* 设置砖块的背景颜色 */border: 1px solid black /* 设置砖块的边框 */}return (div style{gameAreaStyle}{/*小球*/}div style{ballStyle}/div{/*砖块*/}div style{paddleStyle}/div/div/)
}export default BounceBall