设为首页收藏本站

SKY外语、计算机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

楼主: 回忆搁浅
打印 上一主题 下一主题

[其他] 【JavaScript】js实现俄罗斯方块的游戏, 有代码、、、

[复制链接]

9

主题

0

好友

164

积分

注册会员

Rank: 2

性别
保密
跳转到指定楼层
楼主
发表于 2012-11-8 18:10:26 |只看该作者 |倒序浏览
本帖最后由 sky_yx 于 2015-12-30 14:10 编辑

  你新建一个html, 比如1.html,然后把下面的代码复制进去, 保存, 然后打开这个html。 就是一个简单的俄罗斯方块的小游戏,这个是以前在学校几个玩的好的一起合伙做的。 一些废话就不要说了, 下面就上传我的代码:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>俄罗斯方块</title>
<style>
#board tr td{
width: 20px;
height: 20px;
}
</style>
</head>
<script language="javascript">
/**
* JS俄罗斯方块完美注释版 v 1.01
* 从学c语言那一会儿都想写一个俄罗斯方块,可是每次动起手总觉得难度太大.
* 今天终于用了大约4个小时写出来了. 其中在涉及到方块变型的时候还咨询了
* 同学来帮忙;
*
* 个人觉得难点有这么几个:
* 1: 边界检查, 不多说, 想通了就行
* 2: 旋转, 还是数学上的方法, 一个点相对另外一个点旋转90度的问题.
* 4: 让整个程序在点开始之后, 怎么让它一直自动的运行下去. 我以前一直没有做完,
* 主要是因为没有想清楚到底要用一个什么机制让游戏自动运行下去,
* 这个过程可以这么理解:
* 用户点开始->构造一个活动图形, 设置定时器,
* 每次向下移动后, 都检查是否触底, 如果触底了, 则尝试消行,
* 完了之后再构造一个活动图形, 再设置定时器.
*/
//表示页面中的table, 这个table就是将要显示游戏的主面板
var tbl;
//游戏状态 0: 未开始;1 运行; 2 中止;
var status = 0;
//定时器, 定时器内将做moveDown操作
var timer;
//分数
var score = 0;
//board是一个18*10的数组,也和页面的table对应.
//用来标注那些方格已经被占据. 初始时都为0, 如果被占据则为1
var board = new Array(18);
for (var i = 0; i < 18; i++) {
    board = new Array(10);
}
for (var i = 0; i < 18; i++) {
    for (var j = 0; j < 10; j++) {
        board[j] = 0;
    }
}
//当前活动的方块, 它可以左右下移动, 变型.当它触底后, 将会更新board;
var activeBlock;
//生产方块形状, 有7种基本形状.
function generateBlock() {
    activeBlock = null;
    activeBlock = new Array(4);
    //generate a random int number between 0-6;
    var t = (Math.floor(Math.random() * 20) + 1) % 7;
    switch (t) {
    case 0:
        {
            activeBlock[0] = {
                x: 0,
                y: 4
            };
            activeBlock[1] = {
                x: 1,
                y: 4
            };
            activeBlock[2] = {
                x: 0,
                y: 5
            };
            activeBlock[3] = {
                x: 1,
                y: 5
            };
            break;
        }
    case 1:
        {
            activeBlock[0] = {
                x: 0,
                y: 3
            };
            activeBlock[1] = {
                x: 0,
                y: 4
            };
            activeBlock[2] = {
                x: 0,
                y: 5
            };
            activeBlock[3] = {
                x: 0,
                y: 6
            };
            break;
        }
    case 2:
        {
            activeBlock[0] = {
                x: 0,
                y: 5
            };
            activeBlock[1] = {
                x: 1,
                y: 4
            };
            activeBlock[2] = {
                x: 1,
                y: 5
            };
            activeBlock[3] = {
                x: 2,
                y: 4
            };
            break;
        }
    case 3:
        {
            activeBlock[0] = {
                x: 0,
                y: 4
            };
            activeBlock[1] = {
                x: 1,
                y: 4
            };
            activeBlock[2] = {
                x: 1,
                y: 5
            };
            activeBlock[3] = {
                x: 2,
                y: 5
            };
            break;
        }
    case 4:
        {
            activeBlock[0] = {
                x: 0,
                y: 4
            };
            activeBlock[1] = {
                x: 1,
                y: 4
            };
            activeBlock[2] = {
                x: 1,
                y: 5
            };
            activeBlock[3] = {
                x: 1,
                y: 6
            };
            break;
        }
    case 5:
        {
            activeBlock[0] = {
                x: 0,
                y: 4
            };
            activeBlock[1] = {
                x: 1,
                y: 4
            };
            activeBlock[2] = {
                x: 2,
                y: 4
            };
            activeBlock[3] = {
                x: 2,
                y: 5
            };
            break;
        }
    case 6:
        {
            activeBlock[0] = {
                x: 0,
                y: 5
            };
            activeBlock[1] = {
                x: 1,
                y: 4
            };
            activeBlock[2] = {
                x: 1,
                y: 5
            };
            activeBlock[3] = {
                x: 1,
                y: 6
            };
            break;
        }
    }
    //检查刚生产的四个小方格是否可以放在初始化的位置.
    for (var i = 0; i < 4; i++) {
        if (!isCellValid(activeBlock.x, activeBlock.y)) {
            return false;
        }
    }
    return true;
}
//向下移动
function moveDown() {
    //检查底边界.
    if (checkBottomBorder()) {
        //没有触底, 则擦除当前图形,
        erase();
        //更新当前图形坐标
        for (var i = 0; i < 4; i++) {
            activeBlock.x = activeBlock.x + 1;
        }
        //重画当前图形
        paint();
    }
    //触底,
    else {
        //停止当前的定时器, 也就是停止自动向下移动.
        clearInterval(timer);
        //更新board数组.
        updateBoard();
        //消行
        var lines = deleteLine();
        //如果有消行, 则
        if (lines != 0) {
            //更新分数
            score = score + lines * 10;
            updateScore();
            //擦除整个面板
            eraseBoard();
            //重绘面板
            paintBoard();
        }
        //产生一个新图形并判断是否可以放在最初的位置.
        if (!generateBlock()) {
            alert("Game over!");
            status = 2;
            return;
        }
        paint();
        //定时器, 每隔一秒执行一次moveDown
        timer = setInterval(moveDown, 1000)
    }
}
//左移动
function moveLeft() {
    if (checkLeftBorder()) {
        erase();
        for (var i = 0; i < 4; i++) {
            activeBlock.y = activeBlock.y - 1;
        }
        paint();
    }
}
//右移动
function moveRight() {
    if (checkRightBorder()) {
        erase();
        for (var i = 0; i < 4; i++) {
            activeBlock.y = activeBlock.y + 1;
        }
        paint();
    }
}
//旋转, 因为旋转之后可能会有方格覆盖已有的方格.
//先用一个tmpBlock,把activeBlock的内容都拷贝到tmpBlock,
//对tmpBlock尝试旋转, 如果旋转后检测发现没有方格产生冲突,则
//把旋转后的tmpBlock的值给activeBlock.
function rotate() {
    var tmpBlock = new Array(4);
    for (var i = 0; i < 4; i++) {
        tmpBlock = {
            x: 0,
            y: 0
        };
    }
    for (var i = 0; i < 4; i++) {
        tmpBlock.x = activeBlock.x;
        tmpBlock.y = activeBlock.y;
    }
    //先算四个点的中心点,则这四个点围绕中心旋转90度。
    var cx = Math.round((tmpBlock[0].x + tmpBlock[1].x + tmpBlock[2].x + tmpBlock[3].x) / 4);
    var cy = Math.round((tmpBlock[0].y + tmpBlock[1].y + tmpBlock[2].y + tmpBlock[3].y) / 4);
    //旋转的主要算法. 可以这样分解来理解。
    //先假设围绕源点旋转。然后再加上中心点的坐标。
    for (var i = 0; i < 4; i++) {
        tmpBlock.x = cx + cy - activeBlock.y;
        tmpBlock.y = cy - cx + activeBlock.x;
    }
    //检查旋转后方格是否合法.
    for (var i = 0; i < 4; i++) {
        if (!isCellValid(tmpBlock.x, tmpBlock.y)) {
            return;
        }
    }
    //如果合法, 擦除
    erase();
    //对activeBlock重新赋值.
    for (var i = 0; i < 4; i++) {
        activeBlock.x = tmpBlock.x;
        activeBlock.y = tmpBlock.y;
    }
    //重画.
    paint();
}
//检查左边界,尝试着朝左边移动一个,看是否合法.
function checkLeftBorder() {
    for (var i = 0; i < activeBlock.length; i++) {
        if (activeBlock.y == 0) {
            return false;
        }
        if (!isCellValid(activeBlock.x, activeBlock.y - 1)) {
            return false;
        }
    }
    return true;
}
//检查右边界,尝试着朝右边移动一个,看是否合法.
function checkRightBorder() {
    for (var i = 0; i < activeBlock.length; i++) {
        if (activeBlock.y == 9) {
            return false;
        }
        if (!isCellValid(activeBlock.x, activeBlock.y + 1)) {
            return false;
        }
    }
    return true;
}
//检查底边界,尝试着朝下边移动一个,看是否合法.
function checkBottomBorder() {
    for (var i = 0; i < activeBlock.length; i++) {
        if (activeBlock.x == 17) {
            return false;
        }
        if (!isCellValid(activeBlock.x + 1, activeBlock.y)) {
            return false;
        }
    }
    return true;
}
//检查坐标为(x,y)的是否在board种已经存在, 存在说明这个方格不合法.
function isCellValid(x, y) {
    if (x > 17 || x < 0 || y > 9 || y < 0) {
        return false;
    }
    if (board[x][y] == 1) {
        return false;
    }
    return true;
}
//擦除
function erase() {
    for (var i = 0; i < 4; i++) {
        tbl.rows[activeBlock.x].cells[activeBlock.y].style.backgroundColor = "white";
    }
}
//绘活动图形
function paint() {
    for (var i = 0; i < 4; i++) {
        tbl.rows[activeBlock.x].cells[activeBlock.y].style.backgroundColor = "red";
    }
}
//更新board数组
function updateBoard() {
    for (var i = 0; i < 4; i++) {
        board[activeBlock.x][activeBlock.y] = 1;
    }
}
//消行
function deleteLine() {
    var lines = 0;
    for (var i = 0; i < 18; i++) {
        var j = 0;
        for (; j < 10; j++) {
            if (board[j] == 0) {
                break;
            }
        }
        if (j == 10) {
            lines++;
            if (i != 0) {
                for (var k = i - 1; k >= 0; k--) {
                    board[k + 1] = board[k];
                }
            }
            board[0] = generateBlankLine();
        }
    }
    return lines;
}
//擦除整个面板
function eraseBoard() {
    for (var i = 0; i < 18; i++) {
        for (var j = 0; j < 10; j++) {
            tbl.rows.cells[j].style.backgroundColor = "white";
        }
    }
}
//重绘整个面板
function paintBoard() {
    for (var i = 0; i < 18; i++) {
        for (var j = 0; j < 10; j++) {
            if (board[j] == 1) {
                tbl.rows.cells[j].style.backgroundColor = "red";
            }
        }
    }
}
//产生一个空白行.
function generateBlankLine() {
    var line = new Array(10);
    for (var i = 0; i < 10; i++) {
        line = 0;
    }
    return line;
}
//更新分数
function updateScore() {
    document.getElementById("score").innerText = " " + score;
}
//键盘控制
function keyControl() {
    if (status != 1) {
        return;
    }
    var code = event.keyCode;
    switch (code) {
    case 37:
        {
            moveLeft();
            break;
        }
    case 38:
        {
            rotate();
            break;
        }
    case 39:
        {
            moveRight();
            break;
        }
    case 40:
        {
            moveDown();
            break;
        }
    }
}
//开始
function begin(e) {
    e.disabled = true;
    status = 1;
    tbl = document.getElementById("board");
    if (!generateBlock()) {
        alert("游戏结束!");
        status = 2;
        return;
    }
    paint();
    timer = setInterval(moveDown, 1000);
}
document.onkeydown = keyControl;
</SCRIPT>
<body>
<Input type="button" value="开始" onclick="begin(this);"/>
<span  style="position:absolute; left:150px;"> 分数:</span> <span id="score" style="position:absolute; left:200px;"> 0</span>
<table id="board" cellspacing=0 cellpadding=0 border=1 style="border-collapse:collapse;">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</body>
</html>

分享到: QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
分享淘帖0 收藏收藏0 评分评分
您需要登录后才可以回帖 登录 | 立即注册


手机版|SKY外语计算机学习 ( 粤ICP备12031577 )    

GMT+8, 2024-12-22 16:07 , Processed in 0.096115 second(s), 25 queries .

回顶部