介绍
俄罗斯方块的实现
有问题 或者 有建议 评论区见
代码没有很好优化,可能存在冗余;
代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>俄罗斯方块</title>
<!--修改成你自己jquery的地址-->
<script src="js/jquery-3.6.0.js"></script>
<!--
一个方块是20px
每个方块间距2px
宽 20*12+2*11 = 262
20--20--20--20
高 20*20+2*19 = 438
20
|
20
|
20
-->
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
margin: 0 auto;
height: 40px;
text-align: center;
line-height: 40px;
list-style: none;
}
.score {
color: #ec6565;
}
.background {
position: relative;
left: 50%;
transform: translateX(-50%);
margin-top: 10px;
width: 262px;
height: 438px;
border: 2px solid #2a2a2a;
background-color: #828282;
}
.atom {
position: absolute;
width: 20px;
height: 20px;
background-color: #d6d6d6;
}
</style>
</head>
<body>
<div>
<li class=" score">0</li>
<li class=""><a id="start" href="#">开始</a></li>
<li class=""><a href="">重新开始</a></li>
<li>A:逆时针旋转 上键:顺时针旋转 空格:暂停 方向键左右移动 下键加速</li>
</div>
<div class="background">
</div>
</body>
<script>
var elements = ['I', 'o', 'Z', 'z', 'L', 'l', 'T']
var gameOver = true;
var gamePause = false;
var grid = new Map();
reGrid();
//刷新grid
function reGrid() {
for (var i = 0; i <= 418; i += 22) {
grid.set(i, new Array());
}
}
//将方块存入grid中
function addGrid(atom) {
var top = parseInt($(atom).css('top'));
var left = parseInt($(atom).css('left'));
//已存在的方块存入grid
grid.get(top).push(left);
}
//移动
function move(speed) {
var atoms = $('.atom:lt(4)')
moveDown = setInterval(function () {
var flag = true;
//判断是否移动
$(atoms).each(function () {
var top = parseInt($(this).css('top'));
var left = parseInt($(this).css('left'));
//判断是否到底 到底结束移动
if (top != 418) {
//判断是否有方块
if (grid.get(top + 22).includes(left)) {
flag = false;
}
} else {
flag = false;
}
})
//true可以移动
if (flag) {
$(atoms).each(function () {
var top = parseInt($(this).css('top'));
top += 22;
$(this).css('top', top + 'px');
})
} else {
//结束移动 存入grid中
$('.atom:lt(4)').each(function () {
addGrid($(this));
});
clearInterval(moveDown);
//判断是否得分
score();
}
}, speed)
}
//随机数
function random() {
return Math.floor(Math.random() * 7);
}
//随机创建元素
function create() {
if (!gameOver) {
return;
}
var element = elements[random()];
$('.background').prepend("<div class=\"atom\"></div>\n" +
" <div class=\"atom\"></div>\n" +
" <div class=\"atom\"></div>\n" +
" <div class=\"atom\"></div>")
//创建元素
switch (element) {
case 'I':
I();
break;
case 'o':
o();
break;
case 'Z':
Z();
break;
case 'z':
z();
break;
case 'L':
L();
break;
case 'l':
l();
break;
case 'T':
T();
break;
}
move(300);
}
//判断是否得分
function score() {
var flag = false;
//遍历grid若其中一个value的长度为12 得分
grid.forEach(function (value, key) {
if (value.length === 12) {
console.log(value);
$('.score').text(parseInt($('.score').text()) + 10)
deleteRow(key)
flag = true;
}
})
create();
}
//删除得分行
function deleteRow(row) {
//遍历所有.atom 将得分行的div删除
$('.atom').each(function () {
var top = parseInt($(this).css('top'));
if (top === row) {
$(this).remove();
}
})
//遍历所有.atom 小于row的行数下移一格
$('.atom').each(function () {
var top = parseInt($(this).css('top'));
if (top < row) {
$(this).css('top', top + 22);
}
})
//刷新grid
reGrid();
$('.atom').each(function () {
addGrid($(this));
});
}
//判断生成的是否已经顶到顶部
function judge(atoms) {
$(atoms).each(function () {
var top = parseInt($(this).css('top'));
var left = parseInt($(this).css('left'));
if (grid.get(top).includes(left)) {
over();
}
})
}
//游戏结束
function over() {
gameOver = false;
alert("游戏结束!得分:" + $('.score').text())
}
//键盘监听
//左右移动
$(window).keydown(function (event) {
//判断是否已经游戏结束
if (!gameOver) {
return;
}
//游戏暂停
if (event.which === 32) {
if (gamePause) {
move(200);
gamePause = false;
} else {
clearInterval(moveDown);
gamePause = true;
}
} else if (gamePause) {
return;
}
//左移动
if (event.which === 37) {
var flag = false
$('.atom:lt(4)').each(function () {
var left = parseInt($(this).css('left'));
var top = parseInt($(this).css('top'));
//判断左边是否有方块
if (grid.get(top).includes(left - 22)) {
flag = true;
}
if (left <= 0) {
flag = true;
}
})
if (flag) {
return;
}
$('.atom:lt(4)').each(function () {
var left = parseInt($(this).css('left'));
left -= 22;
$(this).css('left', left + 'px');
})
}
//右移动
if (event.which === 39) {
var flag = false
$('.atom:lt(4)').each(function () {
var left = parseInt($(this).css('left'));
var top = parseInt($(this).css('top'));
//判断左边是否有方块
if (grid.get(top).includes(left + 22)) {
flag = true;
}
if (left >= 242) {
flag = true;
}
})
if (flag) {
return;
}
$('.atom:lt(4)').each(function () {
var left = parseInt($(this).css('left'));
left += 22;
$(this).css('left', left + 'px');
})
}
//变换
//a:65 b:68
var ccw = 65;
var cw = 38;
if (event.which === ccw || event.which === cw) {
var sumT = 0;
var sumL = 0;
var top = parseInt($('.atom:eq(0)').css('top'));
var left = parseInt($('.atom:eq(0)').css('left'));
var atoms = $('.atom:lt(4)');
//判断如果是o直接退出 无需变换
if ($('.atom:eq(0)').attr('id') === 'o') {
return;
}
//计算top left的和
$('.atom:lt(4)').each(function () {
sumT += parseInt($(this).css("top"));
sumL += parseInt($(this).css("left"));
})
//I 变换
if (top * 4 === sumT && $('.atom:eq(0)').attr('id') === 'I') {
if (top < 396) {
if(grid.get(top-22).includes(left)){
return;
}else if(grid.get(top+22).includes(left)){
return;
}else if(grid.get(top+44).includes(left)){
return;
}
$(atoms[1]).css({'top': top - 22, 'left': left});
$(atoms[2]).css({'top': top + 22, 'left': left});
$(atoms[3]).css({'top': top + 44, 'left': left});
}
return;
} else if (left * 4 === sumL && $('.atom:eq(0)').attr('id') === 'I') {
//如果是贴墙变换 向墙的反向移动一格
if (left === 0) {
left += 22;
} else if (left === 242) {
left -= 44;
}
if(grid.get(top).includes(left-22)){
return;
}else if(grid.get(top).includes(left+22)){
return;
}else if(grid.get(top).includes(left+44)){
return
}
$(atoms[0]).css({'top': top, 'left': left});
$(atoms[1]).css({'top': top, 'left': left - 22});
$(atoms[2]).css({'top': top, 'left': left + 22});
$(atoms[3]).css({'top': top, 'left': left + 44});
return;
}
//变换前九宫数组
var a = [
[top - 22, left - 22], [top - 22, left], [top - 22, left + 22],
[top, left - 22], [top, left], [top, left + 22],
[top + 22, left - 22], [top + 22, left], [top + 22, left + 22],
];
//判断是否可以变换
for (var i = 0; i < 9; i++) {
var key = a[i][0];
var value = a[i][1];
var gridValue = grid.get(key);
if (gridValue.includes(value)) {
return;
}
}
//各atom在a中的位置
var c = new Array();
//记录atom在a中的位置 并记录索引 index:atom索引 i:a中位置索引
$('.atom:lt(4)').each(function (index, element) {
var top = parseInt($(element).css('top'));
var left = parseInt($(element).css('left'));
for (var i = 0; i < 9; i++) {
if (top === a[i][0] && left === a[i][1]) {
c.push([index, i]);
}
}
})
var b = new Array();
//判断逆时针 还是顺时针旋转
if (event.which === ccw) {
b = [
6, 3, 0,
7, 4, 1,
8, 5, 2
];
} else {
//顺时针旋转九宫数组所对应的索引
b = [
2, 5, 8,
1, 4, 7,
0, 3, 6
];
}
//变换后的九宫数组
var d = new Array();
for (var i = 0; i < 9; i++) {
d[i] = a[b[i]]
}
//判断是否挨墙
if (left === 0) {
for (var i = 0; i < 4; i++) {
var index = c[i][0];
//var atoms = $('.atom:lt(4)');
$(atoms[index]).css({'top': d[c[i][1]][0], 'left': d[c[i][1]][1] + 22})
}
} else if (left === 242) {
for (var i = 0; i < 4; i++) {
var index = c[i][0];
$(atoms[index]).css({'top': d[c[i][1]][0], 'left': d[c[i][1]][1] - 22})
}
} else {
for (var i = 0; i < 4; i++) {
var index = c[i][0];
$(atoms[index]).css({'top': d[c[i][1]][0] + 'px', 'left': d[c[i][1]][1]})
}
}
}
//加速
if (event.which === 40) {
clearInterval(moveDown)
move(1);
}
})
//监听开始 开始后隐藏
$('#start').click(function () {
create();
$(this).hide();
})
//创建元素
function I() {
let atoms = $('.atom:lt(4)');
$(atoms[1]).css({top: '0px', 'left': "88px"});
$(atoms[0]).css({top: '0px', 'left': "110px"});
$(atoms[2]).css({top: '0px', 'left': "132px"});
$(atoms[3]).css({top: '0px', 'left': "154px"});
$('.atom:lt(4)').each(function () {
$(this).attr('id', 'I');
})
judge(atoms);
}
function o() {
let atoms = $('.atom:lt(4)');
$(atoms[0]).css({top: '0px', 'left': "88px"});
$(atoms[1]).css({top: '0px', 'left': "110px"});
$(atoms[2]).css({top: '22px', 'left': "88px"});
$(atoms[3]).css({top: '22px', 'left': "110px"});
$('.atom:lt(4)').each(function () {
$(this).attr('id', 'o');
})
judge(atoms);
}
function Z() {
let atoms = $('.atom:lt(4)');
$(atoms[2]).css({top: '0px', 'left': "88px"});
$(atoms[1]).css({top: '0px', 'left': "110px"});
$(atoms[0]).css({top: '22px', 'left': "110px"});
$(atoms[3]).css({top: '22px', 'left': "132px"});
judge(atoms);
}
function z() {
let atoms = $('.atom:lt(4)');
$(atoms[0]).css({top: '0px', 'left': "110px"});
$(atoms[1]).css({top: '0px', 'left': "132px"});
$(atoms[2]).css({top: '22px', 'left': "88px"});
$(atoms[3]).css({top: '22px', 'left': "110px"});
judge(atoms);
}
function L() {
let atoms = $('.atom:lt(4)');
$(atoms[2]).css({top: '0px', 'left': "132px"});
$(atoms[1]).css({top: '22px', 'left': "88px"});
$(atoms[0]).css({top: '22px', 'left': "110px"});
$(atoms[3]).css({top: '22px', 'left': "132px"});
judge(atoms);
}
function l() {
let atoms = $('.atom:lt(4)');
$(atoms[2]).css({top: '0px', 'left': "88px"});
$(atoms[1]).css({top: '22px', 'left': "88px"});
$(atoms[0]).css({top: '22px', 'left': "110px"});
$(atoms[3]).css({top: '22px', 'left': "132px"});
judge(atoms);
}
function T() {
let atoms = $('.atom:lt(4)');
$(atoms[2]).css({top: '0px', 'left': "110px"});
$(atoms[1]).css({top: '22px', 'left': "88px"});
$(atoms[0]).css({top: '22px', 'left': "110px"});
$(atoms[3]).css({top: '22px', 'left': "132px"});
judge(atoms);
}
</script>
</html>