首页 > 其他 > 详细

Canvas俄罗斯方块

时间:2014-02-10 19:47:33      阅读:573      评论:0      收藏:0      [点我收藏+]

写在前面

潜水博客园多年,从未写过博客。最近才注册博客,遂将很久前写的俄罗斯方块分享出来。第一次写博客,不喜勿喷。。。

游戏说明

  1. 游戏操作:J向左,L向右,I旋转,K快速下降
  2. 游戏基于HTML canvas开发,请在支持HTML5的浏览器中运行(IE9+, Chrome, Firefox...)
  3. 目前通过CodePen嵌入到页面中存在一个小BUG,请在页面加载完成后5秒左右在开始游戏。

数据结构

  1. 将整个游戏区域视为一个n*m的二维数组,数组中的每一个元素对应游戏区域中长为h的小正方形。如arr[3][4]对应左上角顶点坐标为(3*h,4*h)边长为h的正方形。数组中元素的值由0或1构成,0表示对应游戏区域没有方块1表示对应游戏区域已有方块。
  2. 游戏中的图形由若干个小方块构成,每一种图形有4种状态,可通过改变构成图形的小方块的坐标切换图形的状态。每一种图形有一个基点坐标,根据该基点坐标设置对应状态个小方块的坐标。代码如下所示:

   

bubuko.com,布布扣
var Shape = function () { };

    Shape.prototype.Init = function () {
        this.blocks = [];
        var random = parseInt(Math.random() * 100);
        this.status = random % 4;
        eval("this.st" + this.status + "()");//random status
        this.fillStyle = _config.blockColors[random % _config.blockColors.length];//random color
    }

    Shape.prototype.Down = function () {
        this.x += 1;
        for (var i = 0; i < this.blocks.length; i++) {
            this.blocks[i].x += 1;
        }
    }

    Shape.prototype.Left = function () {
        this.y -= 1;
        for (var i = 0; i < this.blocks.length; i++) {
            this.blocks[i].y -= 1;
        }
    }

    Shape.prototype.Right = function () {
        this.y += 1
        for (var i = 0; i < this.blocks.length; i++) {
            this.blocks[i].y += 1;
        }
    }

    Shape.prototype.st0 = function () { };//abstract method
    Shape.prototype.st1 = function () { };
    Shape.prototype.st2 = function () { };
    Shape.prototype.st3 = function () { };
    Shape.prototype.Rotate = function (i) {//rotate to target status
        var st = (this.status + i) % 4;
        this.status = st;
        switch (st) {
            case 0:
                this.st0();
                break;
            case 1:
                this.st1();
                break;
            case 2:
                this.st2();
                break;
            case 3:
                this.st3();
                break;
            default:
                this.st0();
                break;
        }

    }
图形抽象类
bubuko.com,布布扣
var Triangle = function (x, y) {
        this.x = x;
        this.y = y;
        this.Init();
    };
    Triangle.InheritFrom(Shape, null, null);
    ShapeFactory.AddShape(Triangle);

    Triangle.prototype.st0 = function () {
        this.blocks[0] = new Block(this.x - 1, this.y, 1);
        this.blocks[1] = new Block(this.x, this.y - 1, 1);
        this.blocks[2] = new Block(this.x, this.y, 1);
        this.blocks[3] = new Block(this.x, this.y + 1, 1);
    }

    Triangle.prototype.st1 = function () {
        this.blocks[0] = new Block(this.x, this.y + 1, 1);
        this.blocks[1] = new Block(this.x - 1, this.y, 1);
        this.blocks[2] = new Block(this.x, this.y, 1);
        this.blocks[3] = new Block(this.x + 1, this.y, 1);
    }

    Triangle.prototype.st2 = function () {
        this.blocks[0] = new Block(this.x + 1, this.y, 1);
        this.blocks[1] = new Block(this.x, this.y + 1, 1);
        this.blocks[2] = new Block(this.x, this.y, 1);
        this.blocks[3] = new Block(this.x, this.y - 1, 1);
    }

    Triangle.prototype.st3 = function () {
        this.blocks[0] = new Block(this.x, this.y - 1, 1);
        this.blocks[1] = new Block(this.x + 1, this.y, 1);
        this.blocks[2] = new Block(this.x, this.y, 1);
        this.blocks[3] = new Block(this.x - 1, this.y, 1);
    }
图形子类(L)

类关系图

bubuko.com,布布扣

游戏中的设计模式

发布订阅模式

用于实现游戏中的事件通知,如得分、游戏结束等。

bubuko.com,布布扣
_events = (function () {//Pub&Sub 
        var topics = {},
         uuid = 0,
         event = function () {
             this.listen = function (topic, callback) {
                 if (typeof topic !== "string" || typeof callback !== "function")
                     return this;
                 if (!topics[topic]) {
                     topics[topic] = [];
                 }
                 callback.uuid = uuid++;
                 topics[topic].push(callback);
                 return this;
             };
             this.trigger = function (src, topic, data) {
                 if (!topics[topic] || topics[topic].length === 0)
                     return this;
                 var callbacks = topics[topic],
                     i = 0,
                     length = callbacks.length;
                 for (; i < length; i++) {
                     callbacks[i].call(src, data);
                 }
                 return this;
             };
             this.remove = function (topic, callback) {
                 if (!topics[topic] || topics[topic].length === 0)
                     return this;
                 var callbacks = topics[topic],
                     i = 0,
                     length = callbacks.length;
                 for (; i < length; i++) {
                     if (callback.uuid === callbacks[i].uuid)
                         callbacks.splice(i, 1);
                 }
                 return this;
             };
         };
        return event;
    })();
事件对象
bubuko.com,布布扣
BlockGame.prototype.ListenNewShapeEvents = function (fn) {
        this.events.listen(_eventEnum.newShape, fn);
        return this;
    }
事件对象应用

工厂模式

用于随机的创建下一个图形。

bubuko.com,布布扣
var ShapeFactory = (function () {//absolute factory
        var ShapeArr = [];
        return {
            CreateShape: function (x, y) {//create a random shape
                var random = Math.floor(Math.random() * 100);
                return new ShapeArr[random % ShapeArr.length](x, y);
            },
            AddShape: function (shape) {
                ShapeArr.push(shape);
            }
        };
    })();
工厂模式

游戏效果

Canvas俄罗斯方块

原文:http://www.cnblogs.com/viczha/p/3542951.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!