zoukankan      html  css  js  c++  java
  • JS练习实例--编写经典小游戏俄罗斯方块

    最近在学习JavaScript,想编一些实例练练手,之前编了个贪吃蛇,但是实现时没有注意使用面向对象的思想,实现起来也比较简单所以就不总结了,今天就总结下俄罗斯方块小游戏的思路和实现吧(需要下载代码也是有的),我会说得很详细很详细的所以要看完需要好多耐心的。。。

    基本思路

    游戏区域:游戏区域是固定的,这里将它设为宽10单位,高16单位的矩形区域,前端显示用表格来实现,并将每个td保存在一个二维数组中,用于渲染游戏过程。
    方块:方块有7种形状,用一个4*4的矩阵来保存方块的形状;按方向上键方块可以旋转,可通过矩阵旋转来实现;方块可以左右移动,需要判断是否出界机左右是否已有方块;还需注意判断方块是否已经触底。按方向下键方块可以速降。
    分数:在每一次方块降落完成后判断能否得分。

    具体实现

    工具变量

    这部分下文有用上在回来看就行,现在看可能有点混乱( ・ㅂ・)و 。

    1. block_now, block_next; 当前,下一方块对象,将block_next赋值给block_now,再创建新方块后赋值给block_next。

    2. beforeBlock:16*10的矩阵 方块上一时刻的位置,用于擦除上一秒

    3. allBlock: 16*10的矩阵 已完成方块

    4. ground:16*10的游戏区域,获取DOM,渲染游戏区域

    方块类

    实现这个游戏的最核心就在于这个方块类了,我们将创建一个方块类型,然后7种形状的方块继承这个方块类。

    方块类的属性

    方块的实例属性有:移动方向,状态,形状,当前位置,颜色。

    function Block() {
        this.dir = 40;//方块当前移动方向
        this.end = 0;//状态,是否下落完成
        this.shape = new Array();//4*4的方块
        for (var i = 0; i < 4; i++) {
            this.shape[i] = new Array();
        }
        this.pos = [0, 3];//所在行,列
        this.color = ["#FFAEC9", "#B5E61D", "#99D9EA", "#C8BFE7", "#B97A57"];
            }

    这里先明确一下方块和形状的关系哈,后面经常用上这个概念。如下,4*4的矩阵我把它叫“方块”然后有颜色(绿色)的部分我叫它形状。

    clipboard.png

    7种方块子类

    function Block_i() {
        Block.call(this);
        this.shape = [
            [1, 1, 1, 1],
            [0, 0, 0, 0],
            [0, 0, 0, 0],
            [0, 0, 0, 0]
        ];
    }  
    Block_i.prototype = new Block();

    其他形状与上面类似:

    s : [[0, 1, 1, 0],[1, 1, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]];
    j : [[0, 1, 0, 0],[0, 1, 0, 0],[1, 1, 0, 0],[0, 0, 0, 0]];
    o : [[1, 1, 0, 0],[1, 1, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]];
    z : [[1, 1, 0, 0],[0, 1, 1, 0],[0, 0, 0, 0],[0, 0, 0, 0]];
    t : [[0, 1, 0, 0],[1, 1, 1, 0],[0, 0, 0, 0],[0, 0, 0, 0]];
    l : [[1, 0, 0, 0],[1, 0, 0, 0],[1, 1, 0, 0],[0, 0, 0, 0]];

    方块类的方法

    方块类的方法有:旋转方块,移动方块,速降方块,打印方块

    clipboard.png

    旋转方块

    1.旋转方块时我们先将矩阵顺时针旋转90度

    for(var i = 0,dst = 3;i < 4;i++, dst--){
        for(var j = 0;j < 4;j++)  
            tmp[j][dst] = this.shape[i][j]; 
        }

    2.再将旋转后的图像移到矩阵左上角,这样可以表现出在原地旋转的效果。

    for(var i = 0;i < 4;i++){
        var flag = 1;
        for(var j = 0;j < 4;j++){//判断第一列是否有图像
            if (tmp[j][0]) {
                flag = 0;
            }
        }
        if (flag) {//第一列没图像,将第一列移除,并在最后添一列空白
            for(var j = 0;j < 4;j++){
                tmp[j].shift();
                tmp[j].push(0);
            }
        }
    } 

    3.最后将旋转后的矩阵保存回原来的矩阵

    速降方块

    用户按方向下键,方块将直接降落完成。这个步骤我纠结了挺久的,最后用了个比较笨的方法吧,这里简单说下原理,具体可以下载源码看看。

    1.先算出方块矩阵中有形状的内容的右边界和下边界(因为我们已经将图案放在左上角了所以不用求左上边界ヾ( ̄▽ ̄)),比如s形的方块右边界是3,下边界是2这样。这个用两个循环就能实现了。

    clipboard.png

    2.判断形状(注意是形状)的正下方有没有方块(检查allBlock)

    下方有方块时:
    (1)计算当前形状下边界的块对应下方的块的距离y,如图
    

    clipboard.png

    (2)计算下方最顶方块距离上方块对应位置距离x,如图
    

    clipboard.png

    (3)取两个距离中较小的距离为方块垂直移动距离,移动方块。并将方块状态修改。
    下方没有方块时,方块降至最低,计算距离时,记得得加上方块底部与形状底部的距离。并将方块状态修改。
    
    移动方块

    用户通过键盘方向键来移动方块:左(37) 上(38) 右(39) 下(40)括号内为键码。
    对键盘事件进行监听:
    用this.dir记录方块当前移动方向。

    1. 当用户按上键时,调用旋转方块函数;

    2. 按左右时,将方块所在列(this.pos[1])加或减1;

    3. 按下键时,调用速降方块函数。
      最后打印方块(判断是否出界等问题在打印方块步骤)

    打印方块
    1. 判断待打印方块是否超出边界

    2. 判断要渲染(给形状上色)的地方是否已经有方块了

    3. 擦除上一时刻方块

    4. 绘制这一时刻方块

    5. 若方块下落完毕(this.end = 1),将方块加入到已下落方块矩阵(allBlock)中

    好啦!完成到这步就胜利在望了,撒花ヾ( ̄▽ ̄)~

    工具函数

    1. 产生方块

    用两个随机数随机产生方块形状和颜色:

    function createBlock(r1, r2) {
        // var r = 0;
        switch (r1) {
            case 0: block_new = new Block_i();break;
            case 1: block_new = new Block_j();break;
            case 2: block_new = new Block_l();break;
            case 3: block_new = new Block_o();break;
            case 4: block_new = new Block_s();break;
            case 5: block_new = new Block_t();break;
            case 6: block_new = new Block_z();break;
        }
        block_new.color = block_new.color[r2];
        return block_new;
    }

    2.生产分数
    在每次打印方块时都判断一下是否可以得分消去。

    若可以得分,就将allBlock中该行删除(splice),并在最开始位置加上一行空白行([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
    然后在ground中,将该行样式变为上一行样式,以此类推。呈现出消去该行的效果。

    3.记录最高分
    我还弄了个用cookie记录最高分的功能,每次得分时判断下是否为最高分,并显示,具体还是看代码啦。

    最后付上代码下载地址
    差不多啦,恩恩去吃饭。

    本文转载于猿2048:JS练习实例--编写经典小游戏俄罗斯方块

  • 相关阅读:
    C语言内存分析
    算法之快速排序
    单链表逆转
    C程序设计语言之一
    vim插件配置(一)
    makefile示例
    cocos2d基础入门
    Makefile
    Makefile
    GCC编译四阶段
  • 原文地址:https://www.cnblogs.com/10manongit/p/12608210.html
Copyright © 2011-2022 走看看