JS 俄罗斯方块(不完美)

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);

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值