javascript贪吃蛇案例
作者:互联网
初始化(){
初始化游戏面板和游戏分数显示区
造蛇()
造豆()
监听键盘()
}
造蛇(){
循环蛇初始化长度次{
创造蛇的新关节,每个关节都是一个div
蛇头变红
蛇的新关节推入数组
蛇的新关节的左距离为上一个蛇关节左侧
蛇的新关节展示在面板上
}
}
造豆(){
if(存在旧豆){
从游戏面板上删除旧豆
}
创建新豆,每个豆都是一个span
调用随机坐标(),为新豆生成出生坐标
随机坐标(){
面板宽度1000除以20(豆子宽20px),等分成500份
乘以一个随机数并取整,得出一个0-500的整数
乘以20得到一个0-1000范围内的20的整数倍,即横坐标
纵坐标同理
遍历蛇关节数组{
if(和当前豆的坐标冲突){
随机坐标();
}
}
}
为新豆赋值横纵坐标
将新豆追加到面板中
}
监听键盘(){
按了左键:当方向不为右,方向改为左
按了上键:当方向不为下,方向改为上
按了右键:当方向不为左,方向改为右
按了下键:当方向不为上,方向改为下
按了空格键:暂停和开始游戏效果切换
}
游戏开始(){
清除旧定时器
开启新定时器{
蛇移动()
撞自己():判断本次移动蛇是否撞到自己
吃豆子():判断本次移动蛇是否吃到豆子
}
}
蛇移动(){
获取蛇头左距离和上距离
判断当前蛇的移动方向{
if(对应方向上出界){
游戏结束()
}
蛇身移动()
蛇头移动
}
蛇身移动(){
循环所有蛇身{
后面的关节横向顶替前面的关节
后面的关节纵向顶替前面的关节
}
}
}
撞自己(){
遍历所有蛇身{
if(蛇头坐标与某个蛇身关节坐标冲突){
结束游戏()
}
}
}
吃豆子(){
if(蛇头坐标和当前豆的坐标一致){
分数++
创建一个新的蛇关节
新蛇关节的出生坐标就是被吃掉豆子的坐标
新蛇关节加入到蛇的数组中
新蛇关节展示在游戏面板中
造豆()
}
}
游戏结束(){
清空定时器
刷新页面
展示分数
提示游戏结束
}
游戏暂停(){
清空定时器
}
游戏重置(){
刷新页面
}
复制代码
布局: snake.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>贪食蛇</title>
<link rel="stylesheet" type="text/css" href="snake.css">
<script type="text/javascript" src="snake.js"></script>
</head>
<body>
<header>
<article id="head_left">贪食蛇v1.0</article>
<article id="head_right">您当前的分数为 <span id="score">0</span> 分</article>
</header>
<section id="board"></section>
<footer>
<button class="buttons" onclick="start();">开始 [ start ]</button>
<button class="buttons" onclick="pause();">暂停 [ pause ]</button>
<button class="buttons" onclick="reset();">重置 [ reset ]</button>
</footer>
</body>
</html>
复制代码
样式: snake.css
/*整体:居中*/
body {width: 1000px; margin: 0 auto;}
/*计分板:调整行高、外边距*/
header {
height: 30px; background-color: black; color: white;
line-height: 30px; margin: 10px auto;
}
/*游戏标题:调整左边距、忽略内边距和边框、左漂浮、文字倾斜、字间距*/
#head_left {
width: 700px; padding-left: 20px; box-sizing: border-box;
float: left; font-style: italic; letter-spacing: 10px;
}
/*计分提示:调整右内边距、忽略内边距和边框、右浮动、文字居右*/
#head_right {
width: 300px; padding-right: 20px; box-sizing: border-box;
float: right; text-align: right;
}
/*分数数字:文字加粗,下划线*/
#score {
color: yellow; font-weight: bold; text-decoration: underline;
}
/*游戏面板:居中、父元素设置成相对点*/
#board {
height: 500px; background-color: black;
margin: 0 auto; position: relative;
}
/*豆子:显示为区块、圆角、z轴、绝对定位*/
#board span {
width: 20px; height: 20px; background-color: yellow;
display: block; border-radius: 50%;
z-index: 0; position: absolute;
}
/*蛇:圆角、绝对定位、z轴*/
#board div {
width: 20px; height: 20px; background-color: skyblue;
border-radius: 50%; position: absolute; z-index: 1;
}
/*功能按钮区:内容居中*/
footer { text-align: center; }
/*功能按钮:文字颜色、外边距*/
footer .buttons{
width: 150px; height: 30px;background-color: black;
color: yellow; margin: 10px;
}
复制代码
脚本: snake.js
let snakeArray = []; /*初始化蛇关节的数组*/
let isPause = false; /*游戏是否暂停:未暂停*/
let snakeSize = 5; /*蛇的初始长度*/
let direct = "right"; /*蛇初始方向:向右*/
let speed = 80; /*蛇移动初始速度:80*/
let score, timer, board, bean; /*游戏初始分数显示区,定时器,面板,豆*/
// 初始化(){
onload = () => {
// 初始化游戏面板和游戏分数显示区
board = document.querySelector("#board");
score = document.querySelector("#score");
// 造蛇()
createSnake();
// 造豆()
createBean();
// 监听键盘()
keyListener();
};
// 造蛇(){
function createSnake() {
// 循环蛇初始化长度次{
for (let i = 0; i < snakeSize; i++) {
// 创造蛇的新关节,每个关节都是一个div
let snake = document.createElement("div");
// 蛇头变红
if (i === 0) {
snake["style"]["backgroundColor"] = "red";
}
// 蛇的新关节推入数组
snakeArray.push(snake);
// 蛇的新关节的左距离为上一个蛇关节左侧
snake["style"]["left"] = (snakeSize - i - 1) * 20 + "px";
// 蛇的新关节展示在面板上
board.appendChild(snake);
}
}
// 造豆(){
function createBean() {
// if(存在旧豆){
if (bean) {
// 从游戏面板上删除旧豆
board.removeChild(bean);
}
// 创建新豆,每个豆都是一个span
bean = document.createElement("span");
let x = null, y = null;
// 调用随机坐标(),为新豆生成出生坐标
randomXY();
// 随机坐标(){
function randomXY() {
// 面板宽度1000除以20(豆子宽20px),等分成500份
// 乘以一个随机数并取整,得出一个0-500的整数
// 乘以20得到一个0-1000范围内的20的整数倍,即横坐标
// 纵坐标同理
x = parseInt("" + (Math.random() * (1000 / 20))) * 20;
y = parseInt("" + (Math.random() * (500 / 20))) * 20;
// 遍历蛇关节数组{
for (let i = 0; i < snakeArray.length; i++) {
// if(和当前豆的坐标冲突){
if (snakeArray[i]["offsetLeft"] === x) {
if (snakeArray[i]["offsetTop"] === y) {
// 随机坐标();
randomXY();
break;
}
}
}
}
// 为新豆赋值横纵坐标
bean["style"]["left"] = x + "px";
bean["style"]["top"] = y + "px";
// 将新豆追加到面板中
board.appendChild(bean);
}
//监听键盘
function keyListener() {
document.onkeydown = event => {
let oEvent = event || window.event;
switch (oEvent.keyCode) {
case 37 :
// 按了左键:当方向不为右,方向改为左
if (direct !== "right") {
direct = "left";
}
break;
case 38 :
// 按了上键:当方向不为下,方向改为上
if (direct !== "down") {
direct = "up";
}
break;
case 39 :
// 按了右键:当方向不为左,方向改为右
if (direct !== "left") {
direct = "right";
}
break;
case 40 :
// 按了下键:当方向不为上,方向改为下
if (direct !== "up") {
direct = "down";
}
break;
case 32 :
// 按了空格键:暂停和开始游戏效果切换
if (!isPause) {
pause();
} else {
start();
}
isPause = !isPause;
break;
}
}
}
// 游戏开始(){
function start() {
// 清除旧定时器
clearInterval(timer);
// 开启新定时器{
timer = setInterval(() => {
// 蛇移动()
move();
// 撞自己():判断本次移动蛇是否撞到自己
isHit();
// 吃豆子():判断本次移动蛇是否吃到豆子
isEat();
}, speed);
}
// 蛇移动(){
function move() {
// 获取蛇头左距离和上距离
let hLeft = snakeArray[0].offsetLeft;
let hTop = snakeArray[0].offsetTop;
// 判断当前蛇的移动方向{
switch (direct) {
case "left":
// if(对应方向上出界){
if (hLeft <= 0) {
// 游戏结束()
gameover();
return;
}
// 蛇身移动()
snakeBodyMove();
// 蛇头移动
snakeArray[0]["style"]["left"] = hLeft - 20 + "px";
break;
case "up":
if (hTop <= 0) {
gameover();
return;
}
snakeBodyMove();
snakeArray[0]["style"]["top"] = hTop - 20 + "px";
break;
case "right":
if (hLeft >= 1000 - 20) {
gameover();
return;
}
snakeBodyMove();
snakeArray[0]["style"]["left"] = hLeft + 20 + "px";
break;
case "down":
if (hTop >= 500 - 20) {
gameover();
return;
}
snakeBodyMove();
snakeArray[0]["style"]["top"] = hTop + 20 + "px";
break;
}
// 蛇身移动(){
function snakeBodyMove() {
// 循环所有蛇身{
for (let i = snakeArray.length - 1; i > 0; i--) {
// 后面的关节横向顶替前面的关节
snakeArray[i]["style"]["left"] = snakeArray[i - 1]["style"]["left"];
// 后面的关节纵向顶替前面的关节
snakeArray[i]["style"]["top"] = snakeArray[i - 1]["style"]["top"];
}
}
}
/*判断本次移动是否撞到自己*/
function isHit() {
// 遍历所有蛇身{
for (let i = 1, j = snakeArray.length; i < j; i++) {
// if(蛇头坐标与某个蛇身关节坐标冲突){
if (snakeArray[0].offsetLeft === snakeArray[i].offsetLeft) {
if (snakeArray[0].offsetTop === snakeArray[i].offsetTop) {
// 结束游戏()
gameover();
break;
}
}
}
}
// 吃豆子(){
function isEat() {
// if(蛇头坐标和当前豆的坐标一致){
if (snakeArray[0].offsetLeft === bean.offsetLeft) {
if (snakeArray[0].offsetTop === bean.offsetTop) {
// 分数++
score.innerText = parseInt(score.innerText) + 1;
// 创建一个新的蛇关节
let snake = document.createElement("div");
// 新蛇关节的出生坐标就是被吃掉豆子的坐标
snake["style"]["left"] = bean["style"]["left"];
snake["style"]["top"] = bean["style"]["top"];
// 新蛇关节加入到蛇的数组中
snakeArray.push(snake);
// 新蛇关节展示在游戏面板中
board.appendChild(snake);
// 造豆()
createBean();
}
}
}
// 游戏结束(){
function gameover() {
// 清空定时器
clearInterval(timer);
// 刷新页面
location.reload();
// 提示游戏结束
alert("game over!");
}
// 游戏暂停(){
function pause() {
// 清空定时器
clearInterval(timer)
}
// 游戏重置(){
function reset() {
// 刷新页面
location.reload();
}
标签:style,游戏,javascript,案例,贪吃蛇,let,坐标,关节,snakeArray 来源: https://www.cnblogs.com/wjlynew/p/13929816.html