俄罗斯方块
这个寒假没事学学前端有关知识,之前在学爬虫的时候是对html的初次认识,后来又去写抢课脚本,大概知道了其实浏览器后面很多页面在通信、传数据这么一回事。最近又想看看了。然后又系统的瞧了瞧html\css\javascript的基本概念,详细的属性在后面作为应用手册去看就可以了。
无意间发现一个“别踩白块”游戏,然后自己实践了一下,很是开心了一段时间。
后来觉得好像挺没意思了?自己仿照着这份教程又写了一个俄罗斯方块,大同小异,里面没什么算法,暴力整就完事了。但是后来想想还是要记录一下,前端的知识个人感觉还是比较零碎,如果没有记录,再加上长时间不用,很容易就着粥喝掉。
构思
主要实现两个部分,页面和js。(css写到html里去了
index.html
<html>
<head>
<meta charset='utf-8'>
<title>俄罗斯方块</title>
</head>
<body>
<div id="score-line" style='text-align: center;'>
<h2 style='display: inline-block;'>lines:</h2>
<div style='display: inline-block;'>
<h2 id='score'>0</h2>
</div>
</div>
<div class='btn'>
<button class='button' id='start' onclick="start()">游戏开始</button>
<button class='button' id='stop' onclick="fail()">游戏结束</button>
</div>
<div id='out'>
<div id='main'>
</div>
</div>
</body>
<style>
* {
padding: 0;
margin: 0;
}
#score-line {
color: #555;
margin: 10px;
}
.btn {
width: 100%;
text-align: center;
}
.button {
width: 100px;
height: 30px;
text-align: center;
color: rgb(46, 7, 119);
background-color: lightblue;
border: none;
}
#out {
width: 100%;
/* background-color: blueviolet; */
text-align: center;
margin-top: 20px;
}
#main {
margin: 0 auto;
width: 440px;
height: 400px;
border: 2px solid black;
background: white;
}
.row {
height: 20px;
overflow: hidden;
/* margin: 2px auto; */
}
.cell {
height: 20px;
width: 20px;
border: solid 1px #eeeeee;
border-collapse: collapse;
float: left;
}
.fill {
background-color: black;
}
</style>
<script src='index.js'>
</script>
</html>
index.js
var main = document.getElementById('main')
const num = 20;
var flag = false;
var cur;
var sele;
var clock;
var shape = [
[[0, -1], [0, 0], [0, 1], [1, 0], 0, 1, 1, 1],
[[1, -1], [1, 0], [0, 0], [0, 1], 0, 1, 1, 1],
[[0, -1], [0, 0], [1, 0], [1, 1], 0, 1, 1, 1],
[[-1, 0], [0, 0], [1, 0], [1, -1], 1, 0, 1, 1],
[[-1, 0], [0, 0], [1, 0], [1, 1], 1, 1, 1, 0],
[[-2, 0], [-1, 0], [0, 0], [1, 0], 2, 0, 1, 0],
[[0, 0], [1, 0], [0, 1], [1, 1], 0, 1, 1, 0]
];
function start() {
if (!flag)
init();
else
alert('游戏已经开始')
}
function stop() {
clearInterval(clock);
}
// var cell;
function init() {
// flag = true;
main.innerHTML = "";
for (var i = 0; i < num; i++) {
createRow();
}
createSquare();
document.onkeydown = function(event) {
// alert(event.keyCode);
if (event.keyCode == 83)
move([1, 0]);
else if (event.keyCode == 65)
move([0, -1]);
else if (event.keyCode == 68)
move([0, 1]);
else if (event.keyCode == 74)
rotate(1);
else if (event.keyCode == 75)
rotate(-1);
}
clock = setInterval("move([1, 0])", 300);
}
function createSquare() {
sele = ~~(Math.random() * 7);
cur = [-1 - shape[sele][6], ~~(Math.random() * (20 - shape[sele][5] - shape[sele][7])) + shape[sele][7]];
console.log('create', sele, cur[0], cur[1]);
}
function get(x, y) {
try {
return main.childNodes[x].childNodes[y];
}
catch {
console.log('error', x, y);
}
}
function move(dir) {
var ok = true;
var tx = -1, ty, t;
for (var i = 0; i < 4; i++) {
var nx = cur[0] + dir[0] + shape[sele][i][0], ny = cur[1] + dir[1] + shape[sele][i][1];
if (ny < 0 || ny >= num || nx >= num || (nx >= 0 && get(nx, ny).className.indexOf('hold') != -1)) {
t = i;
tx = nx;
ty = ny;
ok = false;
break;
}
}
if (ok) {
for (var i = 0; i < 4; i++) {
var nx = cur[0] + shape[sele][i][0], ny = cur[1] + shape[sele][i][1];
if (nx >= 0 && nx < num && ny >= 0 && ny < num) {
get(nx, ny).className = 'cell';
get(nx, ny).style.backgroundColor = 'white';
}
}
cur[0] += dir[0];
cur[1] += dir[1];
repaint();
}
else if (dir[0] == 1 && dir[1] == 0) {
// bottom
for (var i = 0; i < 4; i++) {
var nx = cur[0] + shape[sele][i][0], ny = cur[1] + shape[sele][i][1];
if (nx > 0 && nx < num && ny >= 0 && ny < num) {
get(nx, ny).className = 'cell fill hold';
}
else if ((ty >= 0 && ty < num) && nx <= 0) {
console.log(cur[0], cur[1], sele, t, tx, ty);
fail();
return;
}
}
delRow();
createSquare();
}
}
// dir = 1: 顺时针旋转
// dir = -1: 逆时针旋转
function rotate(dir) {
var ok = true;
for (var i = 0; i < 4; i++) {
var nx = cur[0] + dir * shape[sele][i][1], ny = cur[1] - dir * shape[sele][i][0];
if (nx >= num || ny < 0 || ny >= num || (nx >= 0 && get(nx, ny).className.indexOf('hold') != -1)) {
ok = false;
break;
}
}
if (ok) {
for (var i = 0; i < 4; i++) {
var nx = cur[0] + shape[sele][i][0], ny = cur[1] + shape[sele][i][1];
if (nx >= 0 && nx < num && ny >= 0 && ny < num) {
get(nx, ny).className = 'cell';
get(nx, ny).style.backgroundColor = 'white';
}
}
for (var i = 0; i < 4; i++) {
var nx = dir * shape[sele][i][1], ny = - dir * shape[sele][i][0];
shape[sele][i][0] = nx, shape[sele][i][1] = ny;
}
if (dir == 1) {
var tmp = shape[sele][i][4];
shape[sele][i][4] = shape[sele][i][7];
shape[sele][i][7] = shape[sele][i][6];
shape[sele][i][6] = shape[sele][i][5];
shape[sele][i][5] = tmp;
}
else {
var tmp = shape[sele][i][4];
shape[sele][i][4] = shape[sele][i][5];
shape[sele][i][5] = shape[sele][i][6];
shape[sele][i][6] = shape[sele][i][7];
shape[sele][i][7] = tmp;
}
repaint();
}
}
function repaint() {
for (var i = 0; i < 4; i++) {
var nx = cur[0] + shape[sele][i][0], ny = cur[1] + shape[sele][i][1];
if (nx >= 0 && nx < num && ny >= 0 && ny < num) {
// console.log('repaint', nx, ny);
get(nx, ny).className = 'cell fill';
get(nx, ny).style.backgroundColor = 'black';
}
}
}
function delRow() {
ans = [];
for (var i = 0; i < num; i++) {
var f = true;
for (var j = 0; j < num; j++)
if (get(i, j).className.indexOf('fill') == -1) {
f = false;
break;
}
if (f)
ans.push(main.childNodes[i]);
}
for (var i = 0; i < ans.length; i++) {
main.removeChild(ans[i]);
var newSco = parseInt(document.getElementById('score').innerHTML) + 1;
document.getElementById('score').innerHTML = newSco;
createRow();
}
}
function fail() {
var newSco = parseInt(document.getElementById('score').innerHTML);
alert('祝贺!你消掉了' + newSco + '行');
document.getElementById('score').innerHTML = 0;
main.innerHTML = "";
flag = false;
stop();
}
function createDiv(className) {
div = document.createElement('div');
div.className = className;
return div;
}
function createRow() {
var row = createDiv('row');
for (var i = 0; i < num; i++) {
row.appendChild(createDiv('cell'));
}
if (main.childNodes.length == 0)
main.appendChild(row);
else
main.insertBefore(row, main.firstChild);
}
我也知道,这两份代码写的不漂亮,不过刚学了javascript不久的我已经很开心了。在这份代码里主要实现的(也是相对复杂一点的)是旋转功能,方块旋转后的位置要搞清,否则就解体了。
实践出真知啊!
一个人没有梦想,和咸鱼有什么区别!