百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>html5教程> html5 开发的的俄罗斯方块实例源码
分享文章到:

html5 开发的的俄罗斯方块实例源码

发布时间:01/15 来源: 浏览: 关键词:
这个俄罗斯方块是没事的时候,学习html5做的,可能很多地方都不太理想,大学看了互相学习一下还是可以的。后来还加了一个HTML5 Canvas实现简单的俄罗斯方块实例。

我们先来看看效果图:



上面的数字是得分,游戏没有考虑兼容性,只在chrome上测试过,不过大部分现代浏览器还是可以玩的。


先上HTML代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>俄罗斯方块</title>
    <style type="text/css">
        body {
            padding: 0;
            margin-top: 40px;
            text-align: center;
        }
        .tetris {
            border: 4px solid black;
        }
    </style>
</head>
<body>
    <div id="score"></div>
    <canvas id="tetris" width="240" height="420"></canvas>
    <script type="text/javascript" src="js/tetris2.js"></script>
</body>
</html>


html代码就不解释了哈,重点来说一下js的实现方式。

首先是加载图片的函数:

function dlImg(img) { // 返回一个img对象
    var oimg = new Image();
    oimg.src = 'images/' + img;
    return oimg;
}
/**
 * @param img img对象数组
 * @param sw 屏幕适应的一个比值
 * @param fun 程序入口函数
 */
function loadAllImg(img, sw, fun) {
    var l = img.length,
        i,h = 0;
    for(i = 0; i < l; i ++){
        oimgarr[img[i]] = dlImg(img[i]);
        oimgarr[img[i]].onload = function () { // 加载是异步的
            this.width = this.width  * sw;
            this.height = this.height  * sw;
            h ++;
            h >= l && fun(); // 所有图片加载成功后调用fun函数
        }
    }
}


oimgarr是一个全局变量,暂存着游戏用到的img对象。

然后就是主函数的代码了,包含俄罗斯方块主要的逻辑功能。

主函数内有2个对象,Block对象是形状对象,参数type是形状的类型(上、l、L、田、转形状),Blocks是指整个俄罗斯盘(不知道用什么词形容。。。)的对象

下面是Block对象的实现:

function Block(type) {
    this.type = type;
    this.i = -1;
    this.j = 6;
    this.speed = 100;
    this.defer = 0;
    switch (this.type) {
        case 1: // l字
            this.outline = [{i: this.i, j: this.j},
                {i: this.i - 1, j: this.j},
                {i: this.i - 2, j: this.j},
                {i: this.i - 3, j: this.j}];
            break;
        case 2: // 上字
            this.outline = [{i: this.i, j: this.j - 1},
                {i: this.i - 1, j: this.j},
                {i: this.i, j: this.j},
                {i: this.i, j: this.j + 1}];
            break;
        case 3: // L字
            this.outline = [{i: this.i - 2, j: this.j - 1},
                {i: this.i - 1, j: this.j - 1},
                {i: this.i, j: this.j - 1},
                {i: this.i, j: this.j}];
            break;
        case 4: // 田字
            this.outline = [{i: this.i - 1, j: this.j - 1},
                {i: this.i, j: this.j - 1},
                {i: this.i, j: this.j},
                {i: this.i - 1, j: this.j}];
            break;
        case 5: // 转字
            this.outline = [{i: this.i - 1, j: this.j - 1},
                {i: this.i, j: this.j - 1},
                {i: this.i, j: this.j},
                {i: this.i + 1, j: this.j}];
            break;
    }
    this.dropBlock = function () { // 下落方块
        var that = this;
        if(this.defer == this.speed) {
            this.outline.map(function (o) {
                o.i = o.i + 1;
            });
            this.defer = 0;
        }
        else
            this.defer ++;
    };
    this.setSpeed = function () {
        this.speed = 2;
        this.defer = 0;
    };
    this.isReady = function () {
        return this.speed == this.defer;
    }
}


 下面是Blocks对象的实现方式:

 

var Blocks = {
            nullimg: imga['null.png'],
            cellimg: imga['cell.png'],
            pause: false, // 游戏是否处于暂停中
            matrix: new Array(21), // 矩阵,-1表示空,0表示正在移动,1表示已存在
            block: new Block(1), // 默认第一个出现的方块类型为1
            score: 0, // 分数累计
            init: function () {
                var that = this, code = null;
                for(var i = 0; i < 21; i ++) { // 初始化矩阵数组
                    this.matrix[i] = new Array(12);
                    for (var j = 0; j < 12; j ++) {
                        this.matrix[i][j] = -1;
                        ctx.drawImage(this.nullimg, j * cell, i * cell, this.nullimg.width, this.nullimg.height);
                    }
                }
                document.onkeydown = function (e) { // 按键事件
                    code = e.keyCode || e.which;
                    switch (code){
                        case 37: // ←
                            that.setSite(-1);
                            break;
                        case 38: // ↑
                            that.rotateBlock();
                            break;
                        case 39: // →
                            that.setSite(1);
                            break;
                        case 40: // ↓ 长按加速下滑
                            if(that.block.speed == config.SPEED)
                                that.block.speedUp(); // 加速
                            break;
                        case 32: // 暂停
                            !that.pause ? that.suspend() : that.start();
                            break;
                        default :
                            return false;
                    }
                };
                document.onkeyup = function (e) {
                    if(e.keyCode == 40){ // 松开↓恢复速度
                        that.block.speed = config.SPEED;
                    }
                }
            },
            start: function () { // 开始游戏
                var that = this;
                time = setInterval(function () {
                    console.time('all');
                    that.block.dropBlock(); // 下落方块
                    that.refreshMat(); // 刷新矩阵
                    that.reachBottom(); // 检测是否到达底部或者碰到已有方块
                    console.timeEnd('all');
                }, config.TIME);
                this.pause = false;
            },
            suspend: function () { // 暂停
                this.pause = true;
                clearInterval(time);
            },
            refreshMat: function () { // 执行一次矩阵刷新
                var img = null, that = this;
                that.block.outline.forEach(function (o) { // 将移动前的位置都置为-1
                    if(o.i > 0 && that.matrix[o.i - 1][o.j] != 1 )
                        that.matrix[o.i - 1][o.j] = -1;
                });
                that.block.outline.forEach(function (o) { // 刷新移动后的位置
                    if(o.i >= 0)
                        that.matrix[o.i][o.j] = 0;
                });
                this.matrix.forEach(function (l, i) { // 重绘矩阵
                    l.forEach(function (m, j) {
                        img = (m == -1 ? that.nullimg : that.cellimg);
                        ctx.drawImage(img, j * cell, i * cell, img.width, img.height);
                    });
                });
            },
            rotatePoint: function (c, p) { // c点为旋转中心,p为旋转点,一次顺时针旋转90度。返回旋转后的坐标
                return {j: p.i - c.i + c.j, i: -p.j + c.i + c.j};
            },
            rotateBlock: function () {
                var that = this, i, o = null, ctr = that.block.outline[1], l = that.block.outline.length;
                if (that.block.type != 4) { // 田字形无法旋转
                    for (i = 0; i < l; i++) {
                        o = that.rotatePoint(ctr, that.block.outline[i]);
                        if (o.j < 0 || o.j > 11 || o.i > 20) { // 旋转时不可以碰到边界
                            break;
                        }
                        else if (o.i > 0 && o.j >= 0 && o.j <= 20 && Blocks.matrix[o.i][o.j] == 1) { // 旋转时不可以已有方块的点
                            break;
                        }
                    }
                    if (i == 4) {
                        that.block.outline.forEach(function (o, i) {
                            if (o.i >= 0)
                                that.matrix[o.i][o.j] = -1; // 清空变化前的位置
                            that.block.outline[i] = that.rotatePoint(ctr, o);
                        });
                    }
                }
            },
            setSite: function (dir) { // 设置左右移动后的位置
                var i, o, l = this.block.outline.length;
                for(i = 0; i < l; i ++){
                    o = this.block.outline[i];
                    // 是否碰到已存在的方块,是否碰到左右边界
                    if(o.i >= 0 && ((Blocks.matrix[o.i][o.j + dir] == 1) || (o.j + dir == -1 || o.j + dir == 12))){
                        break; // 一旦发生碰撞,就退出循环,并不执行移动操作
                    }
                }
                if(i == l) { // 当count=l时,表明移动操作没有发生碰撞
                    this.block.outline.forEach(function (o) {
                        if (o.i >= 0) {
                            Blocks.matrix[o.i][o.j] = -1; // 将当前位置置为-1
                            o.j = (o.j + dir == -1 || o.j + dir == 12) ? o.j : o.j + dir; // 是否允许移动,允许则将o.j+dir的值赋予o.j
                            Blocks.matrix[o.i][o.j] = 0; // 刷新最新值
                        }
                        else { // 小于0时(在矩阵之外),也需进行左右移动
                            o.j = (o.j + dir == -1 || o.j + dir == 12) ? o.j : o.j + dir;
                        }
                    });
                }
            },
            reachBottom: function () {
                var that = this, i, j, o, l = that.block.outline.length;
                if(that.block.isReady()) { // 当前方块下落帧结束时,然后进行检测是否到达了底部
                    for (j = 0; j < l; j ++) {
                        o = that.block.outline[j];
                        if (o.i >= 0 && (o.i == 20 || that.matrix[o.i + 1][o.j] == 1)) { // 向下移动时发生碰撞
                            break; // 方块到达底部或落在其他方块上,方块停止下落,产生新的方块
                        }
                    }
                    if (j < l) { // 当方块落在底部或其他方块时,进行检测
                        for(i = 0; i < l; i ++) {
                            o = that.block.outline[i];
                            if(o.i >= 0){
                                that.matrix[o.i][o.j] = 1;  // 方块停止后,修改矩阵数据
                            }
                            else {
                                that.gameOver(); // 游戏结束
                                return;
                            }
                        }
                        that.ruinMat(); // 检测是否需要爆破行,如果有则执行爆破操作
                        that.block = new Block(parseInt(Math.random() * 5) + 1);
                    }
                }
            },
            detectMat: function () { // 检测矩阵,判断是否有连续一行,返回一个数组
                var count = 0, s,
                    detecta = []; // 需要爆破的行号
                this.matrix.forEach(function (l, i) {
                    for(s = 0; s < l.length; s ++){
                        if(l[s] == 1) count ++; else break;
                    }
                    count == 12 && detecta.push(i);
                    count = 0;
                });
                return detecta.length == 0 ? false : detecta;
            },
            ruinMat: function () { // 爆破连续的一行
                var dmat = this.detectMat(); // 返回整行都有方块的行号集合
                if(dmat){
                    this.score = this.score + (dmat.length == 1 ? 100 : dmat.length == 2 ? 250 : dmat.length == 3 ? 450 : 700);
                    score.innerHTML = this.score.toString();
                    dmat.forEach(function (d) {
                        Blocks.matrix.splice(d, 1); // 删掉整行都有方块的行
                        Blocks.matrix.unshift([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]); // 弥补被删的行
                    });
                }
                dmat = null;
            },
            gameOver: function () {
                clearInterval(time);
                alert('你挂了');
            }
        };



 Block这个对象可以按照下图的坐标来理解:



可以看到,棋盘左上角是坐标(0,0),每个小方格代表一个坐标点,坐标点的值对应状态值,即-1表示位置空闲,0表示位置正在刷新,1表示位置被占用。

当然这里还有一个模块没有实现,这个模块就是提示下一个方块的形状,这个有兴趣的同学可以加下哈。

源码在github地址:https://github.com/zquancai/tetrisc
欢迎下载互相学习



HTML5 Canvas实现简单的俄罗斯方块

最近学习了下HTML5,抽时间利用Canvas写了个俄罗斯方块的小游戏,写的比较简单也比较粗糙,还有点bug,算法方面也没深入考虑,只是为了学习使用Canvas。

主要实现思路:

一、绘制画布

画布宽200px,高400px,小方块宽和高为10px。

二、绘制7种形状的方块 



在画布上,每个形状的4个小方块,用相对于画布左上角的坐标来绘制,HTML5的Canvas的左上角坐标为x=0,y=0.

以第一个形状举例,四个方块的坐标分别为:

 
              

                   4个坐标位置存储在数组中[0,0,1,0,1,1,1,2]

                   每个形状的变形后的相对坐标也存储在数组中,这样做是为了简单实现形状变形的算法。

在画布上绘制的时候,需要以画布上的实际坐标绘制四个正方形,正方形的宽度和高度为10px;

fillRect(0,0,10,10)

fillRect(10,0,10,10)

fillRect(10,10,10,10)

fillRect(10,20,10,10)

三、向下移动

每向下移动一次,Y坐标+1,例如上图的坐标变为:0,1,1,1,1,2,1,3

四、左右移动

移动一次,X坐标+1或-1,例如如果上图向右移动1个坐标后的坐标为:1,0,2,0,2,1,2,2。

需要判断当前坐标是否到了画布的左边距或右边距,即每个形状或形状的变形中的最右边的方块到了画布的右边缘,则不能再向右移动,相反,最左边的方块到了左边缘,不能再向左移动。

 
五、变形

读取当前形状的变形后的初始坐标,加上未变形前的偏移坐标。


六、消除满格行

按【绘制画布】中的描述,画布被分为40*20个区域,即40行、20列,每个区域可以放置一个方块(10*10),画布中的40*20个区域对应一个二维数组,存储每个区域是否有方块,有为1,没有为0

当每个形状下落到最下方的时候,判断该形状所在的行的每个区域是否都有方块,即对应的数组中的值是否都为1,都为1,则表示该行满格,可以消除。

七、操作

  添加按键事件

  上箭头:变形

  下箭头:加速下移

  左箭头:向左移动

  右箭头:向右移动

八、 代码

<!DOCTYPE html>
<!--
    Author:kinglau(liushouqian)
    Date:2012-07-17
    Description:目前有些内容是固定的,例如画布大小。也存在bug
   Blog:http://www.cnblogs.com/kinglau/
         http://weibo.com/u/1712849017
  -->
<html>
<head>
    <title></title>
    <meta charset="UTF-8" />
    <style>
        #canvas{
            border: black 1px solid;
        }
    </style>
    <script type="text/javascript">
        //7个基本形状,及变形后的坐标
        var shap1=[[0,0,1,0,1,1,1,2],[0,1,1,1,2,1,2,0],[0,0,0,1,0,2,1,2],[0,0,1,0,2,0,0,1]];
        var shap2=[[0,0,0,1,0,2,1,0],[0,0,1,0,2,0,2,1],[0,2,1,0,1,1,1,2],[0,0,0,1,1,1,2,1]];
        var shap3=[[0,0,1,0,1,1,2,1],[1,0,1,1,0,1,0,2],[0,0,1,0,1,1,2,1],[1,0,1,1,0,1,0,2]]
        var shap4=[[0,1,1,0,1,1,2,0],[0,0,0,1,1,1,1,2],[0,1,1,0,1,1,2,0],[0,0,0,1,1,1,1,2]];
        var shap5=[[0,0,1,0,0,1,1,1],[0,0,1,0,0,1,1,1],[0,0,1,0,0,1,1,1],[0,0,1,0,0,1,1,1]];
        var shap6=[[0,1,1,1,2,1,1,0],[0,0,0,1,0,2,1,1],[0,0,1,0,2,0,1,1],[1,0,1,1,0,1,1,2]];
        var shap7=[[0,0,1,0,2,0,3,0],[0,0,0,1,0,2,0,3],[0,0,1,0,2,0,3,0],[0,0,0,1,0,2,0,3]];
        var shaps=[shap1,shap2,shap3,shap4,shap5,shap6,shap7];
        //单位长度
        var unitLen=10;
        //画布上下文
        var ctx;
        //定时
        var tid;
        //画布区域对应的数组
        var resultArray=new Array(40);
        function init()
        {
            //获取画布上下文
            ctx=document.getElementById("canvas").getContext('2d');
            //增加按键事件
            document.addEventListener('keydown',moveShape,false);
            //初始化画布区域数组
            for(var i=0;i<40;i++)
            {
                var row=new Array();
                for(var j=0;j<20;j++)
                {
                    row[j]=0;
                }
                resultArray[i]=row;
            }
            //
            startRun=true;
            DrawLine();
            topTrue=true;
            tid=setInterval("DrawTetris();",200);
        }
        //每个形状在画布上相对于初始位置的坐标偏移量
        var rectX=0;
        var rectY=0;
        //形状变形
        var rotate=0;
        //当前形状或变形的初始坐标
        var t;
        //当前形状
        var shape;
        var startRun=true;
        var shapeHeight=0;//当前形状的高度,四个方块的Y坐标的最大差
        //用于产生随机形状
        var randmShape=1;
        //当前形状每个方块的坐标
        var shapeXY=new Array(4);
        //根据坐标绘制形状
        function Draw(){
            var i=0;
            var tempY=0;
            shapeXY=new Array(4);
            for(i=0;i<4;i++){
                DrawRect((t[i*2]+rectX) *unitLen,(t[i*2+1]+rectY)*unitLen);
                var row=new Array(2);
                row[0]=(t[i*2+1]+rectY);
                row[1]=t[i*2]+rectX;
                shapeXY[i]=row;
                //shapeXY[i,0]=(t[i*2+1]+rectY);
                //shapeXY[i,1]=t[i*2];
                if(topTrue==true)
                {
                    if(tempY<(t[i*2+1]+rectY))
                    {
                        tempY=t[i*2+1]+rectY;
                        shapeHeight=tempY+1;
                    }
                }
                else
                {
                    //tempY=rectY;
                }
            }
            //rectY=tempY;
            rectY+=1;
        }
        //根据捕获的按键,判断具体的按键
        function getDirection(event){
            var keyCode = event.which || event.keyCode;
            switch(keyCode){
                case 1:
                case 38:
                case 269: //up
                    return 'up';
                    break;
                case 2:
                case 40:
                case 270:
                    return 'down';
                    break;
                case 3:
                case 37:
                case 271:
                    return 'left';
                    break;
                case 4:
                case 39:
                case 272:
                    return 'right';
                    break;
                case 339: //exit
                case 240: //back
                    return 'back';
                    break;
            }
        }
        //根据按键确定执行的操作
        function moveShape(event){
            if(getDirection(event)=='right')
            {
                for(var i=0;i<4;i++){
                    if(t[2*i]+rectX+1>=20 || resultArray[2*i+rectX+1]==1 ){
                        return;
                    }
                }
                rectX+=1;
            }
            if(getDirection(event)=='left')
            {
                for(var i=0;i<4;i++)
                {
                    if(t[2*i]+rectX-1<0 || resultArray[2*i+rectX-1]==1){
                        return;
                    }
                }
                rectX-=1;
            }
            if(getDirection(event)=='up'){
                var mleft=0;
                for(var i=0;i<4;i++){
                    if(t[i*2]+rectX>mleft){
                        mleft=rectX;
                    }
                }
                if(rotate==3){
                    rotate=0;
                }
                else{
                    rotate+=1;
                }
                t=shape[rotate];
                for(var i=0;i<4;i++){
                    //t[2*i]=t[2*i]+mleft;
                    rectX=mleft;
                }
            }
            if(getDirection(event)=='down'){
                clearInterval(tid);
                tid=setInterval("DrawTetris();",50);
            }
        }
        //定时执行的方法
        function DrawTetris(){
            if(CheckBottom()==true) return;
            //t=shape[rotate];
            if(startRun==false){
                ctx.clearRect(shapeXY[0][1]*unitLen-1,shapeXY[0][0]*unitLen-1,unitLen+2,unitLen+2);
                ctx.clearRect(shapeXY[1][1]*unitLen-1,shapeXY[1][0]*unitLen-1,unitLen+2,unitLen+2);
                ctx.clearRect(shapeXY[2][1]*unitLen-1,shapeXY[2][0]*unitLen-1,unitLen+2,unitLen+2);
                ctx.clearRect(shapeXY[3][1]*unitLen-1,shapeXY[3][0]*unitLen-1,unitLen+2,unitLen+2);
            }
            startRun=false;
            //ctx.clearRect(0,0,200,400-(shapeHeight)*10);
            DrawLine();
            var sp=randmShape;
            shape=shaps[sp-1];
            t=shape[rotate];
            Draw();
        }
        var topTrue=false;
        //检查当前形状是否到了画布底部
        function CheckBottom()
        {
            if(topTrue==true){
                startRun=true;
                topTrue=false;
                rectX=9;
                rectY=0;
                randmShape=Math.floor(Math.random()*7+1);
                return true;
            }
            if(rectY+shapeHeight-1>=40 || rectY==0)
            {
                //clearInterval(tid);
                //ctx.clearRect(0,0,200,300);
                if(rectY==0)
                {
                    return false
                }
                CurrentShapeOnBottom();
                return true;
            }
            else
            {
                //形状中的四个方块有一个到了底部,就不能再向下移动
                if(shapeXY[0][0]==39 || shapeXY[1][0]==39 || shapeXY[2][0]==39 || shapeXY[3][0]==39)
                {
                    CurrentShapeOnBottom();
                    return true;
                }
                //形状中的每个方块所在行的下一行,如果已经存在方块,不能再向下移动
                if((resultArray[shapeXY[0][0]+1][shapeXY[0][1]]+resultArray[shapeXY[1][0]+1][shapeXY[1][1]]
                        +resultArray[shapeXY[2][0]+1][shapeXY[2][1]]+resultArray[shapeXY[3][0]+1][shapeXY[3][1]]
                       >=1) )
                {
                    CurrentShapeOnBottom();
                    return true;
                }
                topTrue=false;
                return false;
            }
        }
        //当前形状到达画布底部后进行的操作
        function CurrentShapeOnBottom(){
            resultArray[shapeXY[0][0]][shapeXY[0][1]]=1;
            resultArray[shapeXY[1][0]][shapeXY[1][1]]=1;
            resultArray[shapeXY[2][0]][shapeXY[2][1]]=1;
            resultArray[shapeXY[3][0]][shapeXY[3][1]]=1;
            if(ClearRow()==false){
                return;
            }
            rectY=0;
            rectX=9;
            randmShape=Math.floor(Math.random()*7+1)
            startRun=true;
            topTrue=true;
            clearInterval(tid);
            tid=setInterval("DrawTetris();",200);
        }
        //计分
        var vpoint=0;
        //清除满格行,并计分
        function ClearRow(){
            var row=new Array();
            var spaceRow=new Array();
            var spaceRows=new Array();
            for(var i=0;i<20;i++){
                spaceRow[i]=0;
            }
            row[0]=shapeXY[0][0];
            for(var i=1;i<4;i++){
                for(var j=0;j<row.length;j++){
                    if(row[j]!=shapeXY[i][0]){
                        if(row[j]<shapeXY[i][0]){
                            row.push(shapeXY[i][0]);
                        }
                        else {
                            row.unshift(shapeXY[i][0]);
                        }
                        break;
                    }
                }
            }
            var isNeedRedraw=false;
            for(var i=0;i<row.length;i++){
                var rowState=0;
                for(var j=0;j<20;j++){
                    rowState+=resultArray[row[i]][j];
                }
                if(rowState==20){
                    resultArray.splice(row[i],1);
                    resultArray.unshift(spaceRow);
                    vpoint+=10;
                    document.getElementById("txtPoint").value=vpoint;
                    isNeedRedraw=true;
                }
            }
            if(isNeedRedraw==true){
                ctx.clearRect(0,0,200,400);
                RedrawCanvas();
            }
            else
            {
                if(shapeXY[0][0]==0 || shapeXY[1][0]==0 || shapeXY[2][0]==0 || shapeXY[3][0]==0){
                    document.getElementById("idState").innerText="Game Over";
                    clearInterval(tid);
                    return false;
                }
            }
            return true;
        }
        //清除满格行后,重新绘制画布
        function RedrawCanvas()
        {
            for(var i=0;i<40;i++){
                for(var j=0;j<20;j++){
                    if(resultArray[i][j]==1){
                        DrawRect(j*unitLen,i*unitLen);
                    }
                }
            }
        }
        //绘制形状中的小方格
        function DrawRect(x,y){
            ctx.fillStyle="red";
            ctx.strokeStyle="black";
            ctx.lineWidth=1;
            ctx.fillRect(x,y,10,10);
            ctx.strokeRect(x,y,10,10);
        }
        
        function DrawLine()
        {
            /*
            var i=1;
            for(i=1;i<40;i++)
            {
                ctx.beginPath();
                ctx.strokeStyle="black";
                ctx.lineWidth=1;
                ctx.moveTo(0,i*10);
                ctx.lineTo(200,i*10);
                ctx.stroke();
            }
            */
        }
    </script>
    </head>
<body onload="init()">
    <canvas id="canvas" width="200" height="400">
        浏览器不支持HTML5  Canvas
    </canvas>
    <br>
    <form id="f" name="f" onsubmit="init()">
        <br>
        <input id="btnStart" type="submit" value="开始" />
        <label id="idState"></label>
        </div>
        <br>
        <label>分数:</label>
        <input  id="txtPoint" readonly="true"  value="0" />
    </form>
</body>
</html>


打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有9人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板