俄罗斯方块 c语言期中作业

直接放代码啦。

#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>


#define ROW 29 //游戏区行数
#define COL 20 //游戏区列数

#define DOWN 80 //方向键:下
#define LEFT 75 //方向键:左
#define RIGHT 77 //方向键:右

#define SPACE 32 //空格键
#define ESC 27 //Esc键

struct Face
{
    int data[ROW][COL + 10]; //用于标记指定位置是否有方块(1为有,0为无)
    int color[ROW][COL + 10]; //用于记录指定位置的方块颜色编码
}face;

struct Block
{
    int space[5][5];
}block[12][4]; //用于存储7种基本形状和自定义的5种形态方块的各自的4种形态的信息,共48种 


//游戏主体逻辑函数
void StartGame();
//选择界面
void AdminView(); 

//隐藏光标
void HideCursor();
//光标跳转
void CursorJump(int x, int y);
//初始化界面
void InitInterface();
//初始化方块信息
void InitBlockInfo();
//颜色设置
void color(int num);
//画出方块
void DrawBlock(int shape, int form, int x, int y);
//空格覆盖
void DrawSpace(int shape, int form, int x, int y);
//合法性判断
int IsLegal(int shape, int form, int x, int y);
//判断得分与结束
int JudeFunc();

int max, grade,beat,times; //全局变量

int main()
{

    grade = 0; beat = 1,times = 0;//初始化变量
    AdminView(); 
    srand((unsigned int)time(NULL)); //设置随机数生成的起点
    return 0;
}


void Instructions(){

    printf("俄罗斯方块游戏说明:\n");
    printf("玩法说明:\n");
    printf("  计分标准:下落一个块10分,一次消一行100分,两行200分,3行400分,4行800分\n");
    printf("  当分数达到2000分就进入下一关  如果空间被占满就失败!\n");
     
    printf("操作说明:\n");
    printf("左移:←\n");
    printf("右移:→\n");
    printf("加速:↓\n");
    printf("旋转:空格\n");
    printf("暂停: S\n");
    printf("退出: Esc\n");
    printf("重新开始:R\n\n\n");
    
    
}

void AdminView(){
    int n;
    while(1){
        system("cls");
        printf("\t\t俄罗斯方块游戏\n");
        printf("\t\t 1.开始游戏\n");
        printf("\t\t 2.游戏说明\n");
        printf("\t\t 0.退出\n");
        printf("请选择0-2:\n");
        scanf("%d",&n);
        switch(n){
            case 1:
                system("mode con lines=29 cols=60"); //设置cmd窗口的大小
                HideCursor(); //隐藏光标    
                InitInterface(); //初始化界面
                InitBlockInfo(); //初始化方块信息
                StartGame();break;
            case 2:
                Instructions();system("pause"); 
                break;
            case 0:exit(0);break;
        }    
    }    
}


//隐藏光标
void HideCursor()
{
    CONSOLE_CURSOR_INFO curInfo; //定义光标信息的结构体变量
    curInfo.dwSize = 1;  //如果没赋值的话,隐藏光标无效
    curInfo.bVisible = FALSE; //将光标设置为不可见
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄
    SetConsoleCursorInfo(handle, &curInfo); //设置光标信息
}
//光标跳转
void CursorJump(int x, int y)
{
    COORD pos; //定义光标位置的结构体变量
    pos.X = x; //横坐标设置
    pos.Y = y; //纵坐标设置
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄
    SetConsoleCursorPosition(handle, pos); //设置光标位置
}
//初始化界面
void InitInterface()
{
    int i;
    int j;
    color(7); //颜色设置为白色
    for (i = 0; i < ROW; i++)
    {
        for (j = 0; j < COL + 10; j++)
        {
            if (j == 0 || j == COL - 1 || j == COL + 9)
            {
                face.data[i][j] = 1; //标记该位置有方块
                CursorJump(2 * j, i);
                printf("=");
            }
            else if (i == ROW - 1)
            {
                face.data[i][j] = 1; //标记该位置有方块
                
            }
            else
                face.data[i][j] = 0; //标记该位置无方块
        }
    }
    for (i = COL; i < COL + 10; i++)
    {
        face.data[8][i] = 1; //标记该位置有方块
        CursorJump(2 * i, 8);
        printf("=");
    }

    CursorJump(2 * COL, 1);
    printf("下一个方块:");

    CursorJump(2 * COL + 4, ROW - 17);
    printf("当前分数:%d", grade);
    
    CursorJump(2 * COL + 4,ROW - 19); 
    printf("当前关卡:%d 关",beat);
}
//初始化方块信息
void InitBlockInfo()
{
    int i;
    //“T”形
    for (i = 0; i <= 2; i++)
        block[0][0].space[1][i] = 1;
    block[0][0].space[2][1] = 1;

    //“L”形
    for (i = 1; i <= 3; i++)
        block[1][0].space[i][1] = 1;
    block[1][0].space[3][2] = 1;

    //“J”形
    for (i = 1; i <= 3; i++)
        block[2][0].space[i][2] = 1;
    block[2][0].space[3][1] = 1;

    for (i = 0; i <= 1; i++)
    {
        //“Z”形
        block[3][0].space[1][i] = 1;
        block[3][0].space[2][i + 1] = 1;
        //“S”形
        block[4][0].space[1][i + 1] = 1;
        block[4][0].space[2][i] = 1;
        //“O”形
        block[5][0].space[1][i + 1] = 1;
        block[5][0].space[2][i + 1] = 1;
    }

    //“I”形
    for (i = 0; i <= 3; i++)
        block[6][0].space[i][1] = 1;
        
    //自定义形态
        
        //“”形
    for (i = 0; i <= 2; i++)
        block[7][0].space[1][i] = 1;
    block[7][0].space[2][0] = 1;
    block[7][0].space[3][0] = 1;
    block[7][0].space[4][0] = 1;
            //“”形    
    for (i = 0; i <= 3; i++){
        block[8][0].space[i][0] = 1;
    }
    block[8][0].space[0][1] = 1;
    
    for (i = 0; i <= 3; i++){
        block[9][0].space[i][0] = 1;
    }
    block[9][0].space[3][1] = 1;
    
    for (i = 0; i <= 1; i++){
        block[10][0].space[i][0] = 1;
    }
    block[10][0].space[0][1] = 1;
    
    for (i = 0; i <= 2; i++){
        block[11][0].space[0][i] = 1;
    }

    int temp[4][4];
    int shape;
    int form;
    int j;
    for (shape = 0; shape < 12; shape++) //12种形状
    {
        for (form = 0; form < 3; form++) //4种形态(已经有了一种,这里每个还需增加3种)
        {
            //获取第form种形态
            for (i = 0; i < 4; i++)
            {
                for (j = 0; j < 4; j++)
                {
                    temp[i][j] = block[shape][form].space[i][j];
                }
            }
            //将第form种形态顺时针旋转,得到第form+1种形态
            for (i = 0; i < 4; i++)
            {
                for (j = 0; j < 4; j++)
                {
                    block[shape][form + 1].space[i][j] = temp[3 - j][i];
                }
            }
        }
    }
}
//颜色设置
void color(int c)
{    
    
    switch (c)
    {
    case 0:
        c = 13; //“T”形方块设置为紫色
        break;
    case 1:
    case 2:
        c = 12; //“L”形和“J”形方块设置为红色
        break;
    case 3:
    case 4:
        c = 10; //“Z”形和“S”形方块设置为绿色
        break;
    case 5:
        c = 14; //“O”形方块设置为黄色
        break;
    case 6:
        c = 11; //“I”形方块设置为浅蓝色
        break;
    case 7:
        c = 7; //其他默认设置为白色
        break;
    default:
        
        c = 5;break;
    }

        
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //颜色设置
    //注:SetConsoleTextAttribute是一个API(应用程序编程接口)
}
//画出方块
void DrawBlock(int shape, int form, int x, int y)
{
    int i,j;
    for ( i= 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            if (block[shape][form].space[i][j] == 1) //如果该位置有方块
            {
                CursorJump(2 * (x + j), y + i); //光标跳转到指定位置
                printf("田"); //输出方块
            }
        }
    }
}
//空格覆盖
void DrawSpace(int shape, int form, int x, int y)
{
    int i,j;
    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            if (block[shape][form].space[i][j] == 1) //如果该位置有方块
            {
                CursorJump(2 * (x + j), y + i); //光标跳转到指定位置
                printf("  "); //打印空格覆盖(两个空格)
            }
        }
    }
}
//合法性判断
int IsLegal(int shape, int form, int x, int y)
{
    int i,j;
    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            //如果方块落下的位置本来就已经有方块了,则不合法
            if ((block[shape][form].space[i][j] == 1) && (face.data[y + i][x + j] == 1))
                return 0; //不合法
        }
    }
    return 1; //合法
}
//判断得分与结束
int JudeFunc()
{    

    int i,j,m,n;
    //int times = 0; //记录消除了几行方块 一行100分 二行200分 三行400分 4行800分 
    //判断是否得分
    for (i = ROW - 2; i > 4; i--)
    {
        int sum = 0; //记录第i行的方块个数
        for (j = 1; j < COL - 1; j++)
        {
            sum += face.data[i][j]; //统计第i行的方块个数
        }
        if (sum == 0) //该行没有方块,无需再判断其上的层次(无需再继续判断是否得分)
            break; //跳出循环
        if (sum == COL - 2) //该行全是方块,可得分
        {
            times++;
            //PlaySound(TEXT("del.wav"),NULL,SND_FILENAME | SND_ASYNC | NULL);
        
            color(7); //颜色设置为白色

            
            for (j = 1; j < COL - 1; j++) //清除得分行的方块信息
            {
                face.data[i][j] = 0; //该位置得分后被清除,标记为无方块
                CursorJump(2 * j, i); //光标跳转到该位置
                printf("  "); //打印空格覆盖(两个空格)
            }
            //把被清除行上面的行整体向下挪一格
            for (m = i; m >1; m--)
            {
                sum = 0; //记录上一行的方块个数
                for (n = 1; n < COL - 1; n++)
                {
                    sum += face.data[m - 1][n]; //统计上一行的方块个数
                    face.data[m][n] = face.data[m - 1][n]; //将上一行方块的标识移到下一行
                    face.color[m][n] = face.color[m - 1][n]; //将上一行方块的颜色编号移到下一行
                    if (face.data[m][n] == 1) //上一行移下来的是方块,打印方块
                    {
                        CursorJump(2 * n, m); //光标跳转到该位置
                        color(face.color[m][n]); //颜色设置为还方块的颜色
                        printf("田"); //打印方块
                    }
                    else //上一行移下来的是空格,打印空格
                    {
                        CursorJump(2 * n, m); //光标跳转到该位置
                        printf("  "); //打印空格(两个空格)
                    }
                }
                if (sum == 0) //上一行移下来的全是空格,无需再将上层的方块向下移动(移动结束)
                    return 1; //返回1,表示还需调用该函数进行判断(移动下来的可能还有满行)
            }
        }
        
        
        
        
    }
    //判断游戏是否结束
    for (j = 1; j < COL - 1; j++)
    {
        if (face.data[1][j] == 1) //顶层有方块存在(以第1行为顶层,不是第0行)
        {
            Sleep(1000); //留给玩家反应时间
            system("cls"); //清空屏幕
            color(7); //颜色设置为白色
            CursorJump(2 * (COL / 3), ROW / 2 - 3);
            printf("游戏结束!当前得分%d",grade);
            CursorJump(2 * (COL / 3), ROW / 2);
            printf("GAME OVER");
            while (1)
            {
                char ch;
                CursorJump(2 * (COL / 3), ROW / 2 + 3);
                printf("再来一局?(y/n):");
                scanf("%c", &ch);
                if (ch == 'y' || ch == 'Y')
                {
                    system("cls");
                    main();
                }
                else if (ch == 'n' || ch == 'N')
                {
                    CursorJump(2 * (COL / 3), ROW / 2 + 5);
                    exit(0);
                }
                else
                {
                    CursorJump(2 * (COL / 3), ROW / 2 + 4);
                    printf("选择错误,请再次选择");
                }
            }
        }
    }
    return 0; //判断结束,无需再调用该函数进行判断
}
//游戏主体逻辑函数
void StartGame()
{
    int i,j;

    //rand() % 8 
    int shape = rand() % 12, form = rand() % 4; //随机获取方块的形状和形态
    while (1)
    {
        int t = 0;

        //rand() % 8
        int nextShape = rand() % 12, nextForm = rand() % 4; //随机获取下一个方块的形状和形态
        int x = COL / 2 - 2, y = 0; //方块初始下落位置的横纵坐标
    //    color(nextShape); //颜色设置为下一个方块的颜色
        DrawBlock(nextShape, nextForm, COL + 3, 3); //将下一个方块显示在右上角
        while (1)
        {
            color(shape); //颜色设置为当前正在下落的方块
            DrawBlock(shape, form, x, y); //将该方块显示在初始下落位置
            if (t == 0)
            {
                t = 15000; //这里t越小,方块下落越快
            }    
            if(grade >= 2000){
                t -= 300;
                grade = 0;//分数清零 
                beat++;            //关卡加一 
                int zero = 0;
                //显示分数和关卡
                system("cls");
                //清除缓存区
        
                InitInterface(); //初始化界面
                InitBlockInfo(); //初始化方块信息


                
                
                 
            }
            while (--t)
            {
                if (kbhit() != 0) //若键盘被敲击,则退出循环
                    break;
            }
            if (t == 0) //键盘未被敲击
            {
                if (IsLegal(shape, form, x, y + 1) == 0) //方块再下落就不合法了(已经到达底部)
                {
                    //将当前方块的信息录入face当中
                    //face:记录界面的每个位置是否有方块,若有方块还需记录该位置方块的颜色。
                    for (i = 0; i < 4; i++)
                    {
                        for (j = 0; j < 4; j++)
                        {
                            if (block[shape][form].space[i][j] == 1)
                            {
                                face.data[y + i][x + j] = 1; //将该位置标记为有方块
                                face.color[y + i][x + j] = shape; //记录该方块的颜色数值
                            }
                        }
                    }
                    //此次方块下路+10分
                    grade += 10; 
                    while (JudeFunc()); //判断此次方块下落是否得分以及游戏是否结束
                    //显示分数
                    if(times == 0);
                    else if(times == 1) grade += 100;
                    else if(times == 2)    grade += 200;
                    else if(times == 3) grade += 400;
                    else grade += 800;
                    
                    CursorJump(2 * COL + 4, ROW - 17); //光标跳转到显示当前分数的位置
                    printf("当前分数:%d\n", grade); //更新当前分数 
                    
                    times = 0;
                    break; //跳出当前死循环,准备进行下一个方块的下落
                }
                else //未到底部
                {
                    DrawSpace(shape, form, x, y); //用空格覆盖当前方块所在位置
                    y++; //纵坐标自增(下一次显示方块时就相当于下落了一格了)
                }
            }
            else //键盘被敲击
            {
                char ch = getch(); //读取keycode
                switch (ch)
                {
                case DOWN: //方向键:下
                    if (IsLegal(shape, form, x, y + 1) == 1) //判断方块向下移动一位后是否合法
                    {
                        //方块下落后合法才进行以下操作
                        DrawSpace(shape, form, x, y); //用空格覆盖当前方块所在位置
                        y++; //纵坐标自增(下一次显示方块时就相当于下落了一格了)
                    }
                    break;
                case LEFT: //方向键:左
                    if (IsLegal(shape, form, x - 1, y) == 1) //判断方块向左移动一位后是否合法
                    {
                        //方块左移后合法才进行以下操作
                        DrawSpace(shape, form, x, y); //用空格覆盖当前方块所在位置
                        x--; //横坐标自减(下一次显示方块时就相当于左移了一格了)
                    }
                    break;
                case RIGHT: //方向键:右
                    if (IsLegal(shape, form, x + 1, y) == 1) //判断方块向右移动一位后是否合法
                    {
                        //方块右移后合法才进行以下操作
                        DrawSpace(shape, form, x, y); //用空格覆盖当前方块所在位置
                        x++; //横坐标自增(下一次显示方块时就相当于右移了一格了)
                    }
                    break;
                case SPACE: //空格键
                    if (IsLegal(shape, (form + 1) % 4, x, y + 1) == 1) //判断方块旋转后是否合法
                    {
                        //方块旋转后合法才进行以下操作
                        DrawSpace(shape, form, x, y); //用空格覆盖当前方块所在位置
                        y++; //纵坐标自增(总不能原地旋转吧)
                        form = (form + 1) % 4; //方块的形态自增(下一次显示方块时就相当于旋转了)
                    }
                    break;
                case ESC: //Esc键
                    system("cls"); //清空屏幕
                    color(7);
                    CursorJump(COL, ROW / 2);
                    printf("  游戏结束  ");
                    CursorJump(COL, ROW / 2 + 2);
                    exit(0); //结束程序
                case 's':
                case 'S':  //暂停
                    system("pause>nul"); //暂停(按任意键继续)
                    break;
                case 'r':
                case 'R': //重新开始
                    system("cls"); //清空屏幕
                    main(); //重新执行主函数
                }
            }
        }
        shape = nextShape, form = nextForm; //获取下一个方块的信息
        DrawSpace(nextShape, nextForm, COL + 3, 3); //将右上角的方块信息用空格覆盖
    }
}


 

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>俄罗斯方块</title> [removed] var TETRIS_ROWS = 20; var TETRIS_COLS = 14; var CELL_SIZE = 24; // 没方块是0 var NO_BLOCK = 0; var tetris_canvas; var tetris_ctx; // 记录当前积分 var curScore = 0; // 记录当前速度 var curSpeed = 1; // 记录曾经的最高积分 var maxScore = 0; var curScoreEle , curSpeedEle , maxScoreEle; var curTimer; // 记录当前是否游戏的旗标 var isPlaying = true; // 记录正在下掉的四个方块 var currentFall; // 该数组用于记录底下已经固定下来的方块。 var tetris_status = []; for (var i = 0; i < TETRIS_ROWS ; i++ ) { tetris_status[i] = []; for (var j = 0; j < TETRIS_COLS ; j++ ) { tetris_status[i][j] = NO_BLOCK; } } // 定义方块的颜色 colors = ["#fff", "#f00" , "#0f0" , "#00f" , "#c60" , "#f0f" , "#0ff" , "#609"]; // 定义几种可能出现的方块组合 var blockArr = [ // 代表第一种可能出现的方块组合:Z [ {x: TETRIS_COLS / 2 - 1 , y:0 , color:1}, {x: TETRIS_COLS / 2 , y:0 ,color:1}, {x: TETRIS_COLS / 2 , y:1 ,color:1}, {x: TETRIS_COLS / 2 + 1 , y:1 , color:1} ], // 代表第二种可能出现的方块组合:反Z [ {x: TETRIS_COLS / 2 + 1 , y:0 , color:2}, {x: TETRIS_COLS / 2 , y:0 , color:2}, {x: TETRIS_COLS / 2 , y:1 , color:2}, {x: TETRIS_COLS / 2 - 1 , y:1 , color:2} ], // 代表第三种可能出现的方块组合: 田 [ {x: TETRIS_COLS / 2 - 1 , y:0 , color:3}, {x: TETRIS_COLS / 2 , y:0 , color:3}, {x: TETRIS_COLS / 2 - 1 , y:1 , color:3}, {x: TETRIS_COLS / 2 , y:1 , color:3} ], // 代表第四种可能出现的方块组合:L [ {x: TETRIS_COLS / 2 - 1 , y:0 , color:4}, {x: TETRIS_COLS / 2 - 1, y:1 , color:4}, {x: TETRIS_COLS / 2 - 1 , y:2 , color:4}, {x: TETRIS_COLS / 2 , y:2 , color:4} ], // 代表第五种可能出现的方块组合:J [ {x: TETRIS_COLS / 2 , y:0 , color:5}, {x: TETRIS_COLS / 2 , y:1, color:5}, {x: TETRIS_COLS / 2 , y:2, color:5}, {x: TETRIS_COLS / 2 - 1, y:2, color:5} ], // 代表第六种可能出现的方块组合 : 条 [ {x: TETRIS_COLS / 2 , y:0 , color:6}, {x: TETRIS_COLS / 2 , y:1 , color:6}, {x: TETRIS_COLS / 2 , y:2 , color:6}, {x: TETRIS_COLS / 2 , y:3 , color:6} ], // 代表第七种可能出现的方块组合 : ┵ [ {x: TETRIS_COLS / 2 , y:0 , color:7}, {x: TETRIS_COLS / 2 - 1 , y:1 , color:7}, {x: TETRIS_COLS / 2 , y:1 , color:7}, {x: TETRIS_COLS / 2 + 1, y:1 , color:7} ] ]; // 定义初始化正在下掉的方块 var initBlock = function() { var rand = Math.floor(Math.random() * blockArr.length); // 随机生成正在下掉的方块 currentFall = [ {x: blockArr[rand][0].x , y: blockArr[rand][0].y , color: blockArr[rand][0].color}, {x: blockArr[rand][1].x , y: blockArr[rand][1].y , color: blockArr[rand][1].color}, {x: blockArr[rand][2].x , y: blockArr[rand][2].y , color: blockArr[rand][2].color}, {x: blockArr[rand][3].x , y: blockArr[rand][3].y , color: blockArr[rand][3].color} ]; }; // 定义一个创建canvas组件的函数 var createCanvas = function(rows , cols , cellWidth, cellHeight) { tetris_canvas = document.createElement("canvas"); // 设置canvas组件的高度、宽度 tetris_canvas.width = cols * cellWidth; tetris_canvas.height = rows * cellHeight; // 设置canvas组件的边框 tetris_canvas.style.border = "1px solid black"; // 获取canvas上的绘图API tetris_ctx = tetris_canvas.getContext('2d'); // 开始创建路径 tetris_ctx.beginPath(); // 绘制横向网络对应的路径 for (var i = 1 ; i < TETRIS_ROWS ; i++) { tetris_ctx.moveTo(0 , i * CELL_SIZE); tetris_ctx.lineTo(TETRIS_COLS * CELL_SIZE , i * CELL_SIZE); } // 绘制竖向网络对应的路径 for (var i = 1 ; i < TETRIS_COLS ; i++) { tetris_ctx.moveTo(i * CELL_SIZE , 0); tetris_ctx.lineTo(i * CELL_SIZE , TETRIS_ROWS * CELL_SIZE); } tetris_ctx.closePath(); // 设置笔触颜色 tetris_ctx.strokeStyle = "#aaa"; // 设置线条粗细 tetris_ctx.lineWidth = 0.3; // 绘制线条 tetris_ctx.stroke(); } // 绘制俄罗斯方块的状态 var drawBlock = function() { for (var i = 0; i < TETRIS_ROWS ; i++ ) { for (var j = 0; j < TETRIS_COLS ; j++ ) { // 有方块的地方绘制颜色 if(tetris_status[i][j] != NO_BLOCK) { // 设置填充颜色 tetris_ctx.fillStyle = colors[tetris_status[i][j]]; // 绘制矩形 tetris_ctx.fillRect(j * CELL_SIZE + 1 , i * CELL_SIZE + 1, CELL_SIZE - 2 , CELL_SIZE - 2); } // 没有方块的地方绘制白色 else { // 设置填充颜色 tetris_ctx.fillStyle = 'white'; // 绘制矩形 tetris_ctx.fillRect(j * CELL_SIZE + 1 , i * CELL_SIZE + 1 , CELL_SIZE - 2 , CELL_SIZE - 2); } } } } // 当页面加载完成时,执行该函数里的代码。 window. { // 创建canvas组件 createCanvas(TETRIS_ROWS , TETRIS_COLS , CELL_SIZE , CELL_SIZE); document.body.appendChild(tetris_canvas); curScoreEle = document.getElementById("curScoreEle"); curSpeedEle = document.getElementById("curSpeedEle"); maxScoreEle = document.getElementById("maxScoreEle"); // 读取Local Storage里的tetris_status记录 var tmpStatus = localStorage.getItem("tetris_status"); tetris_status = tmpStatus == null ? tetris_status : JSON.parse(tmpStatus); // 把方块状态绘制出来 drawBlock(); // 读取Local Storage里的curScore记录 curScore = localStorage.getItem("curScore"); curScore = curScore == null ? 0 : parseInt(curScore); curScoreEle[removed] = curScore; // 读取Local Storage里的maxScore记录 maxScore = localStorage.getItem("maxScore"); maxScore = maxScore == null ? 0 : parseInt(maxScore); maxScoreEle[removed] = maxScore; // 读取Local Storage里的curSpeed记录 curSpeed = localStorage.getItem("curSpeed"); curSpeed = curSpeed == null ? 1 : parseInt(curSpeed); curSpeedEle[removed] = curSpeed; // 初始化正在下掉的方块 initBlock(); // 控制每隔固定时间执行一次向下”掉“ curTimer = setInterval("moveDown();" , 500 / curSpeed); } // 判断是否有一行已满 var lineFull = function() { // 依次遍历每一行 for (var i = 0; i < TETRIS_ROWS ; i++ ) { var flag = true; // 遍历当前行的每个单元格 for (var j = 0 ; j < TETRIS_COLS ; j++ ) { if(tetris_status[i][j] == NO_BLOCK) { flag = false; break; } } // 如果当前行已全部有方块了 if(flag) { // 将当前积分增加100 curScoreEle[removed] = curScore+= 100; // 记录当前积分 localStorage.setItem("curScore" , curScore); // 如果当前积分达到升级极限。 if( curScore >= curSpeed * curSpeed * 500) { curSpeedEle[removed] = curSpeed += 1; // 使用Local Storage记录curSpeed。 localStorage.setItem("curSpeed" , curSpeed); clearInterval(curTimer); curTimer = setInterval("moveDown();" , 500 / curSpeed); } // 把当前行的所有方块下移一行。 for (var k = i ; k > 0 ; k--) { for (var l = 0; l < TETRIS_COLS ; l++ ) { tetris_status[k][l] =tetris_status[k-1][l]; } } // 消除方块后,重新绘制一遍方块 drawBlock(); //② } } } // 控制方块向下掉。 var moveDown = function() { // 定义能否下掉的旗标 var canDown = true; //① // 遍历每个方块,判断是否能向下掉 for (var i = 0 ; i < currentFall.length ; i++) { // 判断是否已经到“最底下” if(currentFall[i].y >= TETRIS_ROWS - 1) { canDown = false; break; } // 判断下一格是否“有方块”, 如果下一格有方块,不能向下掉 if(tetris_status[currentFall[i].y + 1][currentFall[i].x] != NO_BLOCK) { canDown = false; break; } } // 如果能向下“掉” if(canDown) { // 将下移前的每个方块的背景色涂成白色 for (var i = 0 ; i < currentFall.length ; i++) { var cur = currentFall[i]; // 设置填充颜色 tetris_ctx.fillStyle = 'white'; // 绘制矩形 tetris_ctx.fillRect(cur.x * CELL_SIZE + 1 , cur.y * CELL_SIZE + 1 , CELL_SIZE - 2 , CELL_SIZE - 2); } // 遍历每个方块, 控制每个方块的y坐标加1。 // 也就是控制方块都下掉一格 for (var i = 0 ; i < currentFall.length ; i++) { var cur = currentFall[i]; cur.y ++; } // 将下移后的每个方块的背景色涂成该方块的颜色值 for (var i = 0 ; i < currentFall.length ; i++) { var cur = currentFall[i]; // 设置填充颜色 tetris_ctx.fillStyle = colors[cur.color]; // 绘制矩形 tetris_ctx.fillRect(cur.x * CELL_SIZE + 1 , cur.y * CELL_SIZE + 1 , CELL_SIZE - 2 , CELL_SIZE - 2); } } // 不能向下掉 else { // 遍历每个方块, 把每个方块的值记录到tetris_status数组 for (var i = 0 ; i < currentFall.length ; i++) { var cur = currentFall[i]; // 如果有方块已经到最上面了,表明输了 if(cur.y < 2) { // 清空Local Storage的当前积分值、游戏状态、当前速度 localStorage.removeItem("curScore"); localStorage.removeItem("tetris_status"); localStorage.removeItem("curSpeed"); if(confirm("您已经输了!是否参数排名?")) { // 读取Local Storage里的maxScore记录 maxScore = localStorage.getItem("maxScore"); maxScore = maxScore == null ? 0 : maxScore ; // 如果当前积分大于localStorage记录的最高积分 if(curScore >= maxScore) { // 记录最高积分 localStorage.setItem("maxScore" , curScore); } } // 游戏结束 isPlaying = false; // 清除计时器 clearInterval(curTimer); return; } // 把每个方块当前所在位置赋为当前方块的颜色值 tetris_status[cur.y][cur.x] = cur.color; } // 判断是否有“可消除”的行 lineFull(); // 使用Local Storage记录俄罗斯方块的游戏状态 localStorage.setItem("tetris_status" , JSON.stringify(tetris_status)); // 开始一组新的方块。 initBlock(); } } // 定义左移方块的函数 var moveLeft = function() { // 定义能否左移的旗标 var canLeft = true; for (var i = 0 ; i < currentFall.length ; i++) { // 如果已经到了最左边,不能左移 if(currentFall[i].x <= 0) { canLeft = false; break; } // 或左边的位置已有方块,不能左移 if (tetris_status[currentFall[i].y][currentFall[i].x - 1] != NO_BLOCK) { canLeft = false; break; } } // 如果能左移 if(canLeft) { // 将左移前的每个方块的背景色涂成白色 for (var i = 0 ; i < currentFall.length ; i++) { var cur = currentFall[i]; // 设置填充颜色 tetris_ctx.fillStyle = 'white'; // 绘制矩形 tetris_ctx.fillRect(cur.x * CELL_SIZE +1 , cur.y * CELL_SIZE + 1 , CELL_SIZE - 2, CELL_SIZE - 2); } // 左移所有正在下掉的方块 for (var i = 0 ; i < currentFall.length ; i++) { var cur = currentFall[i]; cur.x --; } // 将左移后的每个方块的背景色涂成方块对应的颜色 for (var i = 0 ; i < currentFall.length ; i++) { var cur = currentFall[i]; // 设置填充颜色 tetris_ctx.fillStyle = colors[cur.color]; // 绘制矩形 tetris_ctx.fillRect(cur.x * CELL_SIZE + 1 , cur.y * CELL_SIZE + 1, CELL_SIZE - 2 , CELL_SIZE - 2); } } } // 定义右移方块的函数 var moveRight = function() { // 定义能否右移的旗标 var canRight = true; for (var i = 0 ; i < currentFall.length ; i++) { // 如果已到了最右边,不能右移 if(currentFall[i].x >= TETRIS_COLS - 1) { canRight = false; break; } // 如果右边的位置已有方块,不能右移 if (tetris_status[currentFall[i].y][currentFall[i].x + 1] != NO_BLOCK) { canRight = false; break; } } // 如果能右移 if(canRight) { // 将右移前的每个方块的背景色涂成白色 for (var i = 0 ; i < currentFall.length ; i++) { var cur = currentFall[i]; // 设置填充颜色 tetris_ctx.fillStyle = 'white'; // 绘制矩形 tetris_ctx.fillRect(cur.x * CELL_SIZE + 1 , cur.y * CELL_SIZE + 1 , CELL_SIZE - 2 , CELL_SIZE - 2); } // 右移所有正在下掉的方块 for (var i = 0 ; i < currentFall.length ; i++) { var cur = currentFall[i]; cur.x ++; } // 将右移后的每个方块的背景色涂成各方块对应的颜色 for (var i = 0 ; i < currentFall.length ; i++) { var cur = currentFall[i]; // 设置填充颜色 tetris_ctx.fillStyle = colors[cur.color]; // 绘制矩形 tetris_ctx.fillRect(cur.x * CELL_SIZE + 1 , cur.y * CELL_SIZE + 1 , CELL_SIZE - 2, CELL_SIZE -2); } } } // 定义旋转方块的函数 var rotate = function() { // 定义记录能否旋转的旗标 var canRotate = true; for (var i = 0 ; i < currentFall.length ; i++) { var preX = currentFall[i].x; var preY = currentFall[i].y; // 始终以第三个方块作为旋转的心, // i == 2时,说明是旋转的心 if(i != 2) { // 计算方块旋转后的x、y坐标 var afterRotateX = currentFall[2].x + preY - currentFall[2].y; var afterRotateY = currentFall[2].y + currentFall[2].x - preX; // 如果旋转后所在位置已有方块,表明不能旋转 if(tetris_status[afterRotateY][afterRotateX + 1] != NO_BLOCK) { canRotate = false; break; } // 如果旋转后的坐标已经超出了最左边边界 if(afterRotateX < 0 || tetris_status[afterRotateY - 1][afterRotateX] != NO_BLOCK) { moveRight(); afterRotateX = currentFall[2].x + preY - currentFall[2].y; afterRotateY = currentFall[2].y + currentFall[2].x - preX; break; } if(afterRotateX < 0 || tetris_status[afterRotateY-1][afterRotateX] != NO_BLOCK) { moveRight(); break; } // 如果旋转后的坐标已经超出了最右边边界 if(afterRotateX >= TETRIS_COLS - 1 || tetris_status[afterRotateY][afterRotateX+1] != NO_BLOCK) { moveLeft(); afterRotateX = currentFall[2].x + preY - currentFall[2].y; afterRotateY = currentFall[2].y + currentFall[2].x - preX; break; } if(afterRotateX >= TETRIS_COLS - 1 || tetris_status[afterRotateY][afterRotateX+1] != NO_BLOCK) { moveLeft(); break; } } } // 如果能旋转 if(canRotate) { // 将旋转移前的每个方块的背景色涂成白色 for (var i = 0 ; i < currentFall.length ; i++) { var cur = currentFall[i]; // 设置填充颜色 tetris_ctx.fillStyle = 'white'; // 绘制矩形 tetris_ctx.fillRect(cur.x * CELL_SIZE + 1 , cur.y * CELL_SIZE + 1 , CELL_SIZE - 2, CELL_SIZE - 2); } for (var i = 0 ; i < currentFall.length ; i++) { var preX = currentFall[i].x; var preY = currentFall[i].y; // 始终以第三个方块作为旋转的心, // i == 2时,说明是旋转的心 if(i != 2) { currentFall[i].x = currentFall[2].x + preY - currentFall[2].y; currentFall[i].y = currentFall[2].y + currentFall[2].x - preX; } } // 将旋转后的每个方块的背景色涂成各方块对应的颜色 for (var i = 0 ; i < currentFall.length ; i++) { var cur = currentFall[i]; // 设置填充颜色 tetris_ctx.fillStyle = colors[cur.color]; // 绘制矩形 tetris_ctx.fillRect(cur.x * CELL_SIZE + 1 , cur.y * CELL_SIZE + 1 , CELL_SIZE - 2, CELL_SIZE - 2); } } } window.focus(); // 为窗口的按键事件绑定事件监听器 window. { switch(evt.keyCode) { // 按下了“向下”箭头 case 40: if(!isPlaying) return; moveDown(); break; // 按下了“向左”箭头 case 37: if(!isPlaying) return; moveLeft(); break; // 按下了“向右”箭头 case 39: if(!isPlaying) return; moveRight(); break; // 按下了“向上”箭头 case 38: if(!isPlaying) return; rotate(); break; } } [removed] <style type="text/css"> body>div { font-size: 13pt; padding-bottom: 8px; } span { font-size: 20pt; color: red; } </style> </head> <body> <h2>俄罗斯方块</h2> <div <div id="curSpeedEle"></span> 当前积分:<span id="curScoreEle"></span></div> <div id="maxScoreEle"></span></div> </div> </body> </html>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值