您好,登錄后才能下訂單哦!
一邊練習(xí)一下javascript,一邊搞的稍微有趣一點。
這次的界面就是個table表格。其實所有的操作只要操作tabel的class就可以了。我這里把顏色直接用 cell.style.backgroundColor
來設(shè)置內(nèi)聯(lián)樣式的屬性了。
完整代碼如下,預(yù)先顯示下一個方塊的功能沒做。Game Over也沒有寫。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>俄羅斯方塊</title>
<style>
p.tips {margin-top: 20px; text-align: center;}
table#gameUI {margin: 30px auto;}
td {width: 20px; height: 20px; border: 1px solid red;}
td.wall {background-color: red;}
</style>
</head>
<body>
<p class="tips">按回車開始游戲</p>
<table id="gameUI"></table>
</body>
<script>
// 參數(shù)設(shè)置
var rows = 22, cells = 14; // 界面的高度和寬度
// 獲取元素
var tab = document.getElementById('gameUI');
var tips = document.getElementsByClassName('tips')[0];
// 設(shè)置變量
var control; // 當(dāng)前控制的方塊
var score = 0; // 分數(shù)
var scoreConf = [100, 200, 300, 350]; // 一次小幾行,分數(shù)不同
init();
function init() {
// 為了頁面時的初始化
createTab();
bindKeyEnter();
// gameStart()
}
function bindKeyEnter() {
// 按下回車處理的事件
document.onkeydown = function (ev) {
if (ev.keyCode===13){
tips.innerHTML ='游戲開始';
document.onkeydown = null;
gameStart();
}
}
}
function gameStart() {
// 開始游戲
bindKeysForGame();
tips.innerHTML = '按 Z 或 X 旋轉(zhuǎn)方塊';
control = createSqu();
control.position = [1, 4]; // 添加blocks[0]的位置屬性
map(control);
setInterval("move('down')", 500)
}
function createSqu() {
// 創(chuàng)建一個方塊
var types = [
{'name': "方塊", 'color': 'saddlebrown', 'blocks': [[0, 0], [0, 1], [1, 0], [1, 1]],
'styleIndex': 0, 'styles': [
[[0, 0], [0, 1], [1, 0], [1, 1]]
]},
{'name': "7形", 'color': 'green', 'blocks': [[0, 0], [0, 1], [1, 1], [2, 1]],
'styleIndex': 0, 'styles': [
[[0, 0], [0, 1], [1, 1], [2, 1]],
[[1, 0], [1, 1], [1, 2], [0, 2]],
[[0, 0], [1, 0], [2, 0], [2, 1]],
[[0, 0], [1, 0], [0, 1], [0, 2]]
]},
{'name': "反7", 'color': 'green', 'blocks': [[0, 0], [0, 1], [1, 0], [2, 0]],
'styleIndex': 0, 'styles': [
[[0, 0], [0, 1], [1, 0], [2, 0]],
[[0, 0], [0, 1], [0, 2], [1, 2]],
[[0, 1], [1, 1], [2, 0], [2, 1]],
[[0, 0], [1, 0], [1, 1], [1, 2]]
]},
{'name': "長條", 'color': 'darkorange', 'blocks': [[0, 0], [0, 1], [0, 2], [0, 3]],
'styleIndex': 0, 'styles': [
[[0, 0], [0, 1], [0, 2], [0, 3]],
[[0, 0], [1, 0], [2, 0], [3, 0]]
]},
{'name': "丁字", 'color': 'blue', 'blocks': [[0, 0], [0, 1], [1, 1], [0, 2]],
'styleIndex': 0, 'styles': [
[[0, 0], [0, 1], [1, 1], [0, 2]],
[[1, 0], [0, 1], [1, 1], [2, 1]],
[[1, 0], [1, 1], [0, 1], [1, 2]],
[[0, 0], [1, 0], [1, 1], [2, 0]]
]},
{'name': "Z字", 'color': 'gold', 'blocks': [[0, 0], [0, 1], [1, 1], [1, 2]],
'styleIndex': 0, 'styles': [
[[0, 0], [0, 1], [1, 1], [1, 2]],
[[0, 1], [1, 0], [1, 1], [2, 0]]
]},
{'name': "反Z", 'color': 'gold', 'blocks': [[1, 0], [1, 1], [0, 1], [0, 2]],
'styleIndex': 0, 'styles': [
[[1, 0], [1, 1], [0, 1], [0, 2]],
[[0, 0], [1, 0], [1, 1], [2, 1]]
]}
];
var index = Math.floor(Math.random()*types.length+1);
return types[index-1]
}
function map(square) {
// 把方塊畫在表格里
var rubber = arguments[1] ? arguments[1] : false;
for (var i=0; i<square.blocks.length; i++) {
var cell = tab.rows[square.blocks[i][0]+square.position[0]].cells[square.blocks[i][1]+square.position[1]];
if (rubber){
cell.style.backgroundColor = '';
cell.classList.remove('control')
} else {
cell.style.backgroundColor = square.color;
cell.classList.add('control')
}
}
}
function fixed(square){
// 固定方塊
for (var i=0; i<square.blocks.length; i++) {
var cell = tab.rows[square.blocks[i][0]+square.position[0]].cells[square.blocks[i][1]+square.position[1]];
cell.classList.remove('control');
cell.classList.add('fixed')
}
}
function bindKeysForGame() {
// 游戲時候需要綁定的按鍵
document.onkeydown = function (ev) {
switch (ev.keyCode) {
case 37: // 向左
move('left');
break;
case 38: // 向上
// move('up');
change();
break;
case 39: // 向右
move('right');
break;
case 40: // 向下
move('down');
break;
case 90: // 字母Z
change(true);
break;
case 88: // 字母X
change();
break;
// default:
// tips.innerHTML = ev.keyCode;
}
}
}
function change() {
// 改變形狀
var contrarotate = arguments[0] ? arguments[0] : false;
if (contrarotate) {
control.styleIndex -= 1;
if (control.styleIndex < 0) {
control.styleIndex = control.styles.length-1;
}
} else {
control.styleIndex += 1;
if (control.styleIndex > control.styles.length-1){
control.styleIndex = 0;
}
}
var target = [[0,0],[0,0],[0,0],[0,0]];
for (var i=0; i<control.styles[control.styleIndex].length; i++){
target[i][0] = control.styles[control.styleIndex][i][0]+control.position[0];
target[i][1] = control.styles[control.styleIndex][i][1]+control.position[1];
}
if (canMove(target)){
map(control, true);
for (var j=0; j<control.blocks.length; j++){
control.blocks[j][0] = control.styles[control.styleIndex][j][0];
control.blocks[j][1] = control.styles[control.styleIndex][j][1];
}
map(control)
}
}
function move(mode) {
var row, cell;
switch (mode){
case 'left':
row = 0;
cell = -1;
break;
case 'right':
row = 0;
cell = 1;
break;
case 'up':
row = -1;
cell = 0;
break;
case 'down':
row = 1;
cell = 0;
break;
}
var target = [[0,0],[0,0],[0,0],[0,0]];
for (var i=0; i<control.blocks.length; i++){
target[i][0] = control.blocks[i][0]+control.position[0]+row;
target[i][1] = control.blocks[i][1]+control.position[1]+cell;
}
if (canMove(target)){
map(control, true);
control.position[0] += row;
control.position[1] += cell;
map(control)
} else {
if (mode==='down') {
// 向下移動,并且判定為不可移動,則固定
fixed(control); // 固定住方塊
checkAndClean(control); // 檢查消行
control = createSqu();
control.position = [1, 4]; // 添加blocks[0]的位置屬性
map(control);
}
}
}
function checkAndClean(square) {
// 檢查并消除
var checked = [];
var cleaned = [];
var row;
for (var i=0; i<square.blocks.length; i++){
row = square.blocks[i][0] + square.position[0];
if (checked.indexOf(row) === -1){
checked.push(row);
var needClean = true;
for (var j=1; j<cells-1; j++ ) {
var cell = tab.rows[row].cells[j];
if(cell.className.search(/\b(fixed)\b/) === -1){
needClean = false;
break;
}
}
if (needClean) {
// 消除一行
cleaned.push(row);
for (var k=1; k<cells-1; k++) {
cell = tab.rows[row].cells[k];
cell.classList.remove('fixed');
cell.style.backgroundColor = '';
}
}
}
}
cleaned.length && addScore(cleaned.length) && goDown(cleaned); // 結(jié)算分數(shù),然后下沉
}
function addScore(n) {
n = n<=scoreConf.length ? n : scoreConf[scoreConf.length-1];
score += scoreConf[n-1];
tips.innerHTML = "分數(shù):" + score;
return true
}
function goDown(list) {
// 消行后的沉降
var count = 0;
for (var i=list.length; i--;){
for (var r=list[i]-1; r--;){
tab.rows[r+2+count].innerHTML = tab.rows[r+1+count].innerHTML
}
count += 1;
}
}
function canMove(target) {
// 是否可以移動
for (var j=0; j<target.length; j++){
var cell = tab.rows[target[j][0]].cells[target[j][1]];
if(cell.className.search(/\b(wall|fixed)\b/) > -1){
return false
}
}
return true
}
function createTab() {
// 繪制游戲界面
for (var r=rows; r--;){
var row = tab.insertRow();
for (var c=cells; c--;){
var cell = row.insertCell();
if (r===0 || r===rows-1 || c===0 || c===cells-1){
cell.classList.add('wall');
}
}
}
}
</script>
</html>
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。