var NUM_ROWS = 20;
var NUM_COLS = 10;
var BLOCK_WIDTH = 30;
var BLOCK_HEIGHT = 30;
var TICK_MS = 400;
var KEY_LEFT = 37;
var KEY_RIGHT = 39;
var KEY_DOWN = 40;
var KEY_R = 82;
var KEY_ENTER = 13;
var KEY_SPACE = 32;
var GAME_TICK = null;
var blockPiece = [
[0, 0, 0, 0],
[0, 1, 1, 0],
[0, 1, 1, 0],
[0, 0, 0, 0]
];
var longPiece = [
[0, 0, 1, 0],
[0, 0, 1, 0],
[0, 0, 1, 0],
[0, 0, 1, 0]
];
var tPiece = [
[0, 0, 1, 0],
[0, 1, 1, 0],
[0, 0, 1, 0],
[0, 0, 0, 0]
];
var zlPiece = [
[0, 0, 0, 0],
[0, 0, 1, 1],
[0, 1, 1, 0],
[0, 0, 0, 0]
];
var zrPiece = [
[0, 0, 0, 0],
[0, 1, 1, 0],
[0, 0, 1, 1],
[0, 0, 0, 0]
];
var llPiece = [
[0, 0, 1, 0],
[0, 0, 1, 0],
[0, 1, 1, 0],
[0, 0, 0, 0]
];
var lrPiece = [
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 1, 0],
[0, 0, 0, 0]
];
function rotateRight(piece) {
return [
[piece[3][0], piece[2][0], piece[1][0], piece[0][0]],
[piece[3][1], piece[2][1], piece[1][1], piece[0][1]],
[piece[3][2], piece[2][2], piece[1][2], piece[0][2]],
[piece[3][3], piece[2][3], piece[1][3], piece[0][3]]
];
}
//随机生成 pieces
function randomPiece() {
var pieces = [blockPiece, longPiece, tPiece, zlPiece, zrPiece, llPiece, lrPiece];
var i = Math.floor(Math.random() * pieces.length);
var color = Math.floor(Math.random()*7 + 1)
for(y=0;y<4;y++)
for(x=0;x<4;x++)
if(pieces[i][y][x])
pieces[i][y][x]=color;
return pieces[i];
}
//生成主框架
function create_main_board(game){
main_board = document.createElement('div');
main_board.classList.add('main_board');
left_pannel = create_left_pannel(game);
right_pannel = create_right_pannel(game);
main_board.appendChild(left_pannel);
main_board.appendChild(right_pannel);
return main_board;
}
//生成左面板
function create_left_pannel(game){
left_pannel = document.createElement('div');
left_pannel.classList.add('left_pannel');
pre_piece_board = create_pre_piece_board(game);
info_board = create_info_board(game);
left_pannel.appendChild(pre_piece_board);
left_pannel.appendChild(info_board);
return left_pannel;
}
//生成预显示的 方块板
function create_pre_piece_board(game){
pre_piece_board = document.createElement('div');
pre_piece_board.classList.add('pre_piece_board');
piece = game.get_next_piece();
for(i=0;i<4;i++){
for(j=0;j<4;j++){
block = document.createElement('div');
block.style.top = i*30 + 'px';
block.style.left = j*30 +'px';
pre_piece_board.appendChild(block);
if(piece[i][j]==1){
block.classList.add('full1_block')
}else if(piece[i][j]==2){
block.classList.add('full2_block')
}else if(piece[i][j]==3){
block.classList.add('full3_block')
}else if(piece[i][j]==4){
block.classList.add('full4_block')
}else if(piece[i][j]==5){
block.classList.add('full5_block')
}else if(piece[i][j]==6){
block.classList.add('full6_block')
}else if(piece[i][j]==7){
block.classList.add('full7_block')
}else{
block.classList.add('spare_block')
}
}
}
return pre_piece_board;
}
//生成提示信息
function create_info_board(game){
info_board = document.createElement('div');
info_board.classList.add('info_board');
var status = 'Running...'
if(game.pause)
status = 'Stoping...';
if(game.game_over)
status ='Game Over';
info_board.innerHTML=
"<h1>Score: "+ game.score +"</h1>" +
"<h2>Status: "+status+"</h2>"
return info_board;
}
//生成右面板
function create_right_pannel(game){
right_pannel = document.createElement('div');
right_pannel.classList.add('right_pannel');
game_board = create_game_board(game);
right_pannel.appendChild(game_board);
return right_pannel
}
//生成右面板游戏板
function create_game_board(game){
game_board = document.createElement('div');
game_board.classList.add('game_board');
game_block_div = create_game_block_div(game.get_rows());
game_board.appendChild(game_block_div)
return game_board
}
//生成方块
function create_game_block_div(rows){
block_div = document.createElement('div');
for(var i=0; i< NUM_ROWS;i++){
for(var j=0; j<NUM_COLS ; j++){
block = document.createElement('div');
block_div.appendChild(block);
//这里修改属性如果不加 px 无法正确定位,但是他*的在页面上看到是有个别div 成功添加定位为0px的
block.style.left = j*30 +'px';
block.style.top = i*30 +'px';
if(rows[i][j]==1){
block.classList.add('full1_block')
}else if(rows[i][j]==2){
block.classList.add('full2_block')
}else if(rows[i][j]==3){
block.classList.add('full3_block')
}else if(rows[i][j]==4){
block.classList.add('full4_block')
}else if(rows[i][j]==5){
block.classList.add('full5_block')
}else if(rows[i][j]==6){
block.classList.add('full6_block')
}else if(rows[i][j]==7){
block.classList.add('full7_block')
}else{
block.classList.add('spare_block')
}
}
}
return block_div
}
//判断是否会撞到边界
function reach_border(rows,piece,x,y) {
for(var i=0; i<4;i++) {
for(var j=0;j<4;j++) {
if(piece[i][j]){
if( y+i >= NUM_ROWS || j+x<0 || j+x >= NUM_COLS || rows[i+y][j+x]) {//这里匹配下左右边界
return true;
}
}
}
}
return false;
}
function show(rows){
s=''
for(i=0;i<NUM_ROWS;i++){
for(j=0;j<NUM_COLS;j++){
s+=rows[i][j] + ' ';
}
s+='\n';
}
alert(s);
}
//将移动后的方块画到rows中
function move_block(rows,piece,x,y) {
new_rows=[];
for(var i=0;i<NUM_ROWS;i++)
new_rows[i]=rows[i].slice();
for (var i = 0; i < 4; i++)
for (var j = 0; j < 4; j++)
if (piece[i][j]){
new_rows[i + y][j + x]=piece[i][j];
}
return new_rows;
}
//接收当前rows,并消除完整行,返回新的rows
function kill_rows(game){
var row = [];
rows = game.rows;
var killed = 0;
for(var col=0;col<NUM_COLS;col++) //先创建一个空行
row[col]=0;
for(var y=0;y<NUM_ROWS;y++){
for(var x=0;x<NUM_COLS;x++){
if(!rows[y][x]) {
break;
}
if(x == NUM_COLS - 1){//如果满一行,则清空,并将空行移至最上方
rows[y]=row.slice()
killed++;
for(var i=y;i>0;)
rows[i]=rows[--i].slice();
}
}
}
if(killed)
game.score +=Math.pow(3,(killed-1)) ;
}
//游戏的各种属性,以及游戏运行时的数据操作
function mygame(){
this.game_over=false;
this.pause = false;
this.rows=[];
this.current_piece = randomPiece();
this.next_piece = randomPiece();
this.piece_x=NUM_COLS/2-2;
this.piece_y=0;
this.score = 0;
for(i=0; i< NUM_ROWS;i++) {
this.rows[i] = [];
for (j = 0; j < NUM_COLS; j++) {
this.rows[i][j] = 0;
}
}
}
//当然是给画板画block的拉
mygame.prototype.get_rows = function(){
if(this.game_over)
return this.rows;
return move_block(this.rows,this.current_piece,this.piece_x,this.piece_y);
}
//给左边的pre_piece
mygame.prototype.get_next_piece = function () {
return this.next_piece;
}
mygame.prototype.get_game_over = function(){
return this.game_over;
}
mygame.prototype.toggle_pause = function(){
this.pause = !this.pause;
}
mygame.prototype.make_score = function(lines){
this.score += Math.pow((lines-1),2);
}
//更新rows,并重新生成piece
mygame.prototype.update = function(){
this.piece_y = 0;
this.piece_x = NUM_COLS/2 -2;
this.current_piece = this.next_piece;
this.next_piece = randomPiece();
}
//左右下方向移动
mygame.prototype.steer_left = function(){
if(!reach_border(this.rows,this.current_piece,this.piece_x-1,this.piece_y))
this.piece_x-=1;
}
mygame.prototype.steer_right = function(){
if(!reach_border(this.rows,this.current_piece,this.piece_x+1,this.piece_y))
this.piece_x+=1;
}
mygame.prototype.steer_down = function(){
if(!reach_border(this.rows,this.current_piece,this.piece_x,this.piece_y+1))
this.piece_y+=1;
}
//转方块
mygame.prototype.steer_turn_right = function(){
var piece = rotateRight(this.current_piece);
if(!reach_border(this.rows,piece,this.piece_x,this.piece_y))
this.current_piece = piece;
}
//游戏运行
mygame.prototype.running = function () {
running_rows=this.rows;
if(this.game_over || this.pause)
return false;
if(reach_border(running_rows,this.current_piece,this.piece_x,this.piece_y+1)){
this.rows = move_block(this.rows,this.current_piece,this.piece_x,this.piece_y) //更新新图层
this.update();
kill_rows(this);
//这个地方必须先更新图层,在做gameover的判断
//这里不能使用running_rows做判断,因为视图已经更新了
if(reach_border(this.rows,this.current_piece,NUM_COLS/2-2,0)) {
this.game_over = true;
return false;
}
//判断是否已经输了
}else{
this.piece_y++;
}
return true;
}
//游戏画面
function redraw(containE,game){
containE.innerHTML = '';
main_board = create_main_board(game);
containE.appendChild(main_board);
}
function game_start(containE,game) {
GAME_TICK = setInterval(function () {
if (game.running()) {
redraw(containE, game);
}
if(game.game_over){
redraw(containE,game);
clearInterval(GAME_TICK);
}
}, TICK_MS);
}
function game_stop(){
clearInterval(game_tick);
GAME_TICK = null;
}
function load_control_board(containE,game){
containE.addEventListener('keydown',function(key){
var consumed = true;
if (key.keyCode === KEY_LEFT) {
game.steer_left();
} else if (key.keyCode === KEY_RIGHT) {
game.steer_right();
} else if (key.keyCode === KEY_DOWN) {
game.steer_down();
}else if(key.keyCode == KEY_R){
game.steer_turn_right();
}else if(key.keyCode == KEY_ENTER) {
game.toggle_pause();
}else {
consumed = false;
}
if (consumed) {
key.preventDefault();
redraw(containE,game);
}
})
}
function run(containE){
game = new mygame;
game_start(containE,game);
load_control_board(containE,game);
}
JS 俄罗斯方块(不完美)
最新推荐文章于 2023-02-21 16:42:16 发布