MTK平台俄罗斯方块小游戏

  • 游戏评审
    • 游戏效果的展示
    • 游戏介绍
    • 游戏流程图
    • 游戏的设计
      • 俄罗斯方块的设计
      • 初始方块的随机生成
      • 检查方块的是否可以移动
      • 方块下移
      • 方块左右移
      • 方块旋转
      • 方块消行
    • 定时器
    • 功能模块
    • 新游戏
      • 游戏数据的保存
      • 游戏地图的绘制
      • 菜单高亮函数
      • 游戏逻辑
      • 功能按键的实现
    • 继续游戏
    • 排行榜
    • 帮助菜单
    • 声音
    • 不足

游戏评审

我二月份来到现在这个公司,现在转眼间过去了三个月,今天我也要做游戏评审了,评审通过了,我也就能正式转正了。这三个月好像从头开始学习一样。从MTK平台的搭建、程序的编译、Source Insight编写和浏览代码、vs调试代码(打函数断点、监视、跟踪)、使用SVN从公司服务器拉去代码、Beyond Compare比较代码的修改、C语言宏开关的使用、MTK的资源使用、以及程序和资源的独立。然后用一个月开发了一个小游戏,这个游戏于其说是自己写的,倒不如说是拼凑和修改的。

游戏的代码逻辑主要参考的是这篇文章——C++【EasyX】俄罗斯方块

游戏的MTK菜单框架menu-cui以及菜单处理函数。以及定时器参考的本地电脑中2019年的前辈写的程序写出来的。

游戏的存储,本来是要用nvram写的,但是本人比较内向,也不主动问,然后玩自己移植游戏的时候发现有人写过俄罗斯方块了,而且源码也可以用,也能调试。不过他用的不是nv而是用的是类似于在文件夹中写个txt这种方法来存储文件的。并且游戏声音的播放也是来源于这里

本人的作用就是拆分组装,以及修改一项bug,让程序正常运行。

游戏效果的展示

现在用一张我制作的动图展示我的游戏效果:

上面两个蓝色的方块,左边的是记录游戏分数的方块,右边的是记录游戏时间的方块。游戏得分的规则比较简单,消一行得一分。然后一个是游戏的主屏幕,一个是显示下一个方块的屏幕。 这个屏幕里面的方块显示不是很正。还需要画时间调整。下面两个按键是绘制出来,并且绑定函数来达到按键的效果。

游戏按键,中间键,是控制方块顺时针旋转的,向上的按键是方块硬着陆,向下的按键是加快方块下落速度。

游戏菜单中,有排行榜,继续游戏,新的游戏、声音等

游戏介绍

我制作的游戏主要做的工作是以下六点加上游戏背景的制作(画方格、填充颜色)、游戏按键的绑定。

游戏流程图


游戏初始化的过程大致如下:进入游戏屏幕,初始化全局变量,读取本地游戏文件、根据本地文件得到是否要继续上次的游戏的标志位的情况,绘制分数、绘制时间、绘制左按键、绘制右按键,绑定按键函数,开始游戏和时间两个定时器。

//进入游戏
void enter_my_tetris_screen()
{S32 x1, y1;mmi_frm_scrn_enter(GRP_ID_MY_TETRIS_GROUP, SCR_ID_TETRIS_SCREEN_NEW_GAME, exit_my_tetris_screen, enter_my_tetris_screen, MMI_FRM_FULL_SCRN);clear_screen();Init_Set_Global_Var();tetris_new_or_resume_flag = 1;My_Tetris_ReadLog(&MY_Tetris_Log);MY_Tetris_Log.new_or_resume_flag = tetris_new_or_resume_flag;My_Tetris_WriteLog(&MY_Tetris_Log);tetris_draw_time();tetris_draw_score();tetris_draw_left();SetKeyHandler(tetris_draw_left, KEY_LSK, KEY_EVENT_DOWN);tetris_draw_right();SetKeyHandler(tetris_draw_right, KEY_RSK, KEY_EVENT_DOWN);draw_game_timer();draw_sec_timer();gui_BLT_double_buffer(0, 0, UI_device_width -1, UI_device_height - 1);if(game_status == STATUS_START || game_status == STATUS_PAUSE){Tetris_show_start_popup_text();}tetris_SetKeyHandler();
}

游戏的设计

接下来讲解的是我的游戏的设计思路,基本生都来源于C++【EasyX】俄罗斯方块。他的主要问题是俄罗斯边界控制不好,就是刚开始左右移动方块会发生卡块的现象。我改善了一下。

俄罗斯方块的设计

俄罗斯方块类型 实际形状个数
山型 4
L型 4
反L型 4
Z型 2
反Z型 2
I型 2
田型 1

从右到左

//记录作图形状的偏移量,总共有7种形状,每种形状有四个方向,每个形状用两位数记录基准坐标
struct Square squares[7] = { { 0, -2, 0, -1, 0, 0, 1, 0, 0, -1, 1, -1, 2, -1, 0, 0, 0, -2, 1, -2, 1, -1, 1, 0, 0, 0, 1, 0, 2, 0, 2, -1 },       //  L 型{ 0, 0, 1, 0, 1, -1, 1, -2, 0, -1, 0, 0, 1, 0, 2, 0, 0, -2, 0, -1, 0, 0, 1, -2, 0, -1, 1, -1, 2, -1, 2, 0 },       //  L 型(反){ 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, 0 },        // 田 型{ 0, 0, 1, -1, 1, 0, 2, 0, 1, -2, 1, -1, 1, 0, 2, -1, 0, -1, 1, -1, 1, 0, 2, -1, 0, -1, 1, -2, 1, -1, 1, 0 },      // 山 型{ 0, -3, 0, -2, 0, -1, 0, 0, 0, -3, 1, -3, 2, -3, 3, -3, 0, -3, 0, -2, 0, -1, 0, 0, 0, -3, 1, -3, 2, -3, 3, -3 },  //  | 型{ 0, -1, 1, -1, 1, 0, 2, 0, 0, -1, 0, 0, 1, -2, 1, -1, 0, -1, 1, -1, 1, 0, 2, 0, 0, -1, 0, 0, 1, -2, 1, -1 },      //  Z 型{ 0, 0, 1, -1, 1, 0, 2, -1, 1, -2, 1, -1, 2, -1, 2, 0, 0, 0, 1, -1, 1, 0, 2, -1, 1, -2, 1, -1, 2, -1, 2, 0 }       //  Z 型(反)
};

7种类型的俄罗斯方块,每种方块有上下左右四种方向,一个俄罗斯方块有四个基本
方块组成每个方向只要知道基准方块的位置(x坐标和y坐标)即可绘制,所以数组元素
单位有:4 × 4 × 2 =32个元素

俄罗斯方块设计的最终结果:

初始方块的随机生成

在如上所述的设计中,一个俄罗斯方块的全部属性仅仅由以下三者共同唯一决定:

  • 俄罗斯方块类型索引s_idx
  • 俄罗斯方块形状索引d_idx
  • 俄罗斯方块颜色索引c_idx

因此,如果要随机生成一个方块,只需要令其

要确定当前俄罗斯方块和下一个俄罗斯方块,我们需要下面6个变量

当需要切换到下一个俄罗斯方块时,将下一个俄罗斯方块的全部索引赋值给当前俄罗斯方块,然后重新随机生成下一个俄罗斯方块。

now_c_idx = next_c_idx;
now_s_idx = next_s_idx;
now_d_idx = next_d_idx;
next_c_idx = rand() % 7;
next_s_idx = rand() % 7;
next_d_idx = rand() % 4;

游戏中的具体实现

/*****************************************************************************\
* Funcation: initDatasPerSquare
*
* Purpose  : 初始化每次掉落的俄罗斯方块数据
*
* Explain  : 初始化每次掉落的俄罗斯方块数据
\*****************************************************************************///每次方块的初始化
void initDatasPerSquare()
{My_Tetris_ReadLog(&MY_Tetris_Log);MY_Tetris_Log.now_mp_x = SQUARE_X_START;MY_Tetris_Log.now_mp_y = SQUARE_Y_START;MY_Tetris_Log.flag_next = 0;MY_Tetris_Log.now_c_idx = MY_Tetris_Log.next_c_idx;//俄罗斯方块的颜色索引MY_Tetris_Log.now_s_idx = MY_Tetris_Log.next_s_idx;//现在的俄罗斯方块类型索引 MY_Tetris_Log.now_d_idx = MY_Tetris_Log.next_d_idx;//俄罗斯方块形状索引,记录俄罗斯方块的朝向MY_Tetris_Log.next_c_idx = rand() % 7;MY_Tetris_Log.next_s_idx = rand() % 7;MY_Tetris_Log.next_d_idx = rand() % 4;if(MY_Tetris_Log.now_s_idx == 4 && MY_Tetris_Log.now_d_idx) MY_Tetris_Log.now_mp_y += 2;My_Tetris_WriteLog(&MY_Tetris_Log);speedUp = 0;
}

检查方块的是否可以移动

分别读取四个方块的左边,然后在遍历,看每个坐标是否左右和下面越界。返回一个布尔类型的变量。

/*****************************************************************************\
* Funcation: checkPut
*
* Purpose  : 游戏块是否到达边界
*
* Explain  : 游戏块是否到达边界
\*****************************************************************************/MMI_BOOL checkPut(int mp_x, int mp_y, int dir_idx)
{int i;//存储四个方块坐标的数组int sq_x[4];int sq_y[4];My_Tetris_ReadLog(&MY_Tetris_Log);for (i = 0; i < 4; ++i){sq_x[i] = mp_x + squares[now_s_idx].dir[dir_idx][i][0];  //现在方块坐标的x轴sq_y[i] = mp_y + squares[now_s_idx].dir[dir_idx][i][1];  //现在方块坐标的y轴}// 【左右越界、下方越界、重复占格】for (i = 0; i < 4; ++i){if (sq_x[i] < 0 || sq_x[i] > SQUARE_X_NUM - 1 || sq_y[i] > SQUARE_Y_NUM - 1)return MMI_FALSE;if (sq_y[i] < 0) // 检查坐标合法性continue;if (MY_Tetris_Log.MAP[sq_x[i]][sq_y[i]])return MMI_FALSE;}return MMI_TRUE;
}

方块下移

/*****************************************************************************\
* Funcation: moveDown
*
* Purpose  : 游戏块向下
*
* Explain  : 游戏块向下
\*****************************************************************************/void moveDown()
{   My_Tetris_ReadLog(&MY_Tetris_Log);// 尝试能否下移if (checkPut(MY_Tetris_Log.now_mp_x, MY_Tetris_Log.now_mp_y + 1, MY_Tetris_Log.now_d_idx)){++MY_Tetris_Log.now_mp_y;My_Tetris_WriteLog(&MY_Tetris_Log);return;}// 不能下移则说明这块方块“触礁”了,执行以下操作// 1、提示可以开始下一个方块// 2、将方块记录到map地图中// 3、判断是否可以消行// 4、判断消行后游戏是否结束MY_Tetris_Log.flag_next = 1;My_Tetris_WriteLog(&MY_Tetris_Log);recordSquareNow();execClear();if (checkOver()){flag_over = 1;MY_Tetris_Log.flag_over = flag_over;My_Tetris_WriteLog(&MY_Tetris_Log);if(MY_Tetris_Log.game_status == STATUS_PLAYING)My_Tetris_PlaySound((U8*)Tetris_Lose_Sound,sizeof(Tetris_Lose_Sound),FALSE);     }}

就是每个方块y轴坐标加一个单位。

方块左右移

就是每个方块x轴坐标加加减一个单位。

方块旋转

/*****************************************************************************\
* Funcation: moveRotate
*
* Purpose  : 游戏块旋转
*
* Explain  : 游戏块旋转
\*****************************************************************************/void moveRotate()
{int i;My_Tetris_ReadLog(&MY_Tetris_Log);now_mp_x = MY_Tetris_Log.now_mp_x;now_mp_y = MY_Tetris_Log.now_mp_y;now_d_idx = MY_Tetris_Log.now_d_idx;// 尝试剩余所有形状,可以旋转即调整旋转状态for (i = 1; i <= 3; ++i)if (checkPut(now_mp_x, now_mp_y, (now_d_idx + i) % 4)){now_d_idx = (now_d_idx + i) % 4;MY_Tetris_Log.now_d_idx = now_d_idx;My_Tetris_WriteLog(&MY_Tetris_Log);break;}
}

一个俄罗斯方块由dir的三维数组表示,右边的第一个维度代表方向,我们遍历剩下的三种形态,并判度是否可以旋转,然后进行旋转。

方块消行

/*****************************************************************************\
* Funcation: execClear
*
* Purpose  : 删去成行游戏块并加分
*
* Explain  : 删去成行游戏块并加分
\*****************************************************************************/void execClear()
{int i;int j;int cnt_j = SQUARE_Y_NUM;My_Tetris_ReadLog(&MY_Tetris_Log);memcpy(mp, MY_Tetris_Log.MAP, SQUARE_X_NUM * SQUARE_Y_NUM*sizeof(int));memcpy(mp_c, MY_Tetris_Log.MAP_C, SQUARE_X_NUM * SQUARE_Y_NUM*sizeof(int));memset(mp_tmp, 0, sizeof(mp_tmp));memset(mp_c_tmp, 0, sizeof(mp_c_tmp));//j代表地图中的第几行//game_height/p 代表地图中的函数for (j = SQUARE_Y_NUM; j >= 0; --j){int cnt = 0;//cnt统计一行中的方块个数//i代表地图中的第几列for (i = 0; i < SQUARE_X_NUM; ++i)if (mp[i][j])++cnt;if (cnt != SQUARE_X_NUM)     //行不满时{for (i = 0; i < SQUARE_X_NUM; ++i){mp_tmp[i][cnt_j] = mp[i][j];mp_c_tmp[i][cnt_j] = mp_c[i][j];//疑问:flag_over的值在这里改变了,当mp_tmp[8][14]=0到mp_tmp[9][14]=1时,flag_over的值从0变为1MY_Tetris_Log.flag_over = 0;}--cnt_j;}else{++tetris_player_score_count;  //行满时,增加分数MY_Tetris_Log.tetris_player_score_count = tetris_player_score_count;My_Tetris_PlaySound((U8*)Tetris_Clear_Sound,sizeof(Tetris_Clear_Sound),FALSE);}My_Tetris_WriteLog(&MY_Tetris_Log);}//更新地图for (j = 0; j < SQUARE_Y_NUM ; ++j)for (i = 0; i < SQUARE_X_NUM; ++i){MY_Tetris_Log.MAP[i][j] = mp_tmp[i][j];MY_Tetris_Log.MAP_C[i][j] = mp_c_tmp[i][j];}My_Tetris_WriteLog(&MY_Tetris_Log);
}

从底部第一行开始遍历,累加一行中的方块个数,如果它满行了,进行销行处理。
销行的操作,主要是定义了一个cnt_j变量,和空的地图数组,一行地图循环遍历时,行不满的时候cnt_j上移一行,行满的时候cnt_j,不变,以达到销行的目的。

定时器

功能模块

本游戏主要有六个功能模块组成:


继续菜单隐藏了。

新游戏

游戏运行所涉及到的核心是:

  1. 对T卡中的数据文件进行读写的操作
  2. 游戏地图的绘制
  3. 菜单高亮函数的设置
  4. 游戏逻辑
  5. 功能按键的实现

游戏数据的保存

把游戏中所有要中途保存的数据写入一个结构体中,方便将数据批量写入T卡中。

//写入手机内存的数组,记录游戏数据
typedef struct Grades{char name[20];int score;
}Grades;typedef struct Tetris_RECORD{    int MAP[SQUARE_X_NUM][SQUARE_Y_NUM];color MAP_C[SQUARE_X_NUM][SQUARE_Y_NUM];int level;int time;int new_or_resume_flag;int now_mp_y;int now_mp_x;int now_s_idx;int now_d_idx;int now_c_idx;int next_s_idx;int next_d_idx;int next_c_idx;int flag_over;int flag_next;int CurElapse;int tetris_player_score_count;int game_status;MMI_BOOL sound;Grades Tetris_grades[6];
}Tetris_RECORD;Tetris_RECORD MY_Tetris_Log;

写此结构体写入和读取T卡中的函数如下:

//写入到手机存储器成为log的方法
void My_Tetris_InitLog(){  memset(&MY_Tetris_Log,0,sizeof(MY_Tetris_Log));MY_Tetris_Log.sound = MMI_TRUE;MY_Tetris_Log.new_or_resume_flag = 0;MY_Tetris_Log.level = 1;
}    void My_Tetris_WriteLog(){S32 size;FS_HANDLE fd ;fd= FS_Open(L"D:\\MY_Tetris_Log.txt",FS_CREATE);   if(fd >= 0){FS_Write(fd, (void*)&MY_Tetris_Log, sizeof(MY_Tetris_Log), (UINT*)&size);           FS_Close(fd);}
} void My_Tetris_ReadLog(){S32 size; FS_HANDLE fd ;fd= FS_Open(L"D:\\MY_Tetris_Log.txt",FS_READ_ONLY); if(fd >= 0 ){if(FS_GetFileSize(fd, (UINT *)&size)==FS_NO_ERROR){FS_Read( fd,(void*)&MY_Tetris_Log,sizeof(MY_Tetris_Log),(UINT*)&size );}FS_Close(fd);     }else{My_Tetris_InitLog();My_Tetris_WriteLog();}
}

游戏地图的绘制

游戏中的地图绘制,是将数组中的元素以绘制方块的形式绘制到屏幕上,数组元素便是绘制矩形框的位置。

一个数组储存位置,一个数组储存颜色。

菜单高亮函数

屏幕结构以及相应的处理函数

游戏逻辑

游戏详细的流程图如下:

功能按键的实现


//俄罗斯方块按键注册
void tetris_SetKeyHandler(){SetKeyHandler(Press_key_enter,  KEY_ENTER, KEY_EVENT_DOWN); SetKeyHandler(Press_key_enter,  KEY_5, KEY_EVENT_DOWN);SetKeyHandler(press_moveDown, KEY_8, KEY_EVENT_DOWN);SetKeyHandler(press_moveDown, KEY_DOWN_ARROW, KEY_EVENT_DOWN);    SetKeyHandler(moveLeft, KEY_4, KEY_EVENT_DOWN);SetKeyHandler(moveLeft, KEY_LEFT_ARROW, KEY_EVENT_DOWN);SetKeyHandler(moveRight, KEY_6, KEY_EVENT_DOWN);SetKeyHandler(moveRight, KEY_RIGHT_ARROW, KEY_EVENT_DOWN);//SetKeyHandler(tetris_reset_timer, KEY_2, KEY_EVENT_DOWN);SetKeyHandler(moveDown_Fast, KEY_UP_ARROW, KEY_EVENT_DOWN);SetKeyHandler(moveDown_Fast, KEY_2, KEY_EVENT_DOWN);SetKeyHandler(highlight_tetris_option, KEY_LSK, KEY_EVENT_UP);SetKeyHandler(close_tetris_screen, KEY_RSK, KEY_EVENT_UP);}

多功能按键的注册可以设置一个游戏状态变量,让后用swich语句来调整。

继续游戏

  1. 读取My_Tetris_WriteLog(&MY_Tetris_Log),读取MY_Tetris_Log

  2. 判断MY_Tetris_Log 的new_or_resume_flag是否为真

  3. 如果为真则隐藏Resume菜单,为假则显示Resume菜单


排行榜

排行榜功能主要包括数据的获取和界面的实现。

  1. 数据获取通过My_Tetris_ReadLog这个函数来读取T卡中数据文件中保存的数据
  2. 界面实现是通过ShowCategory153Screen模板来实现


帮助菜单

此菜单主要是对游戏的按键的说明,以及游戏得分的规则,按右键可返回至游戏列表界面。使用模板ShowCategory74Screen实现的。

声音

从其它游戏中移植过来 声音的二进制文件

//一行被清除时播放的音乐
#define  TETRIS_MID_CLEAR_LEN 306 //513const U8 Tetris_Clear_Sound[TETRIS_MID_CLEAR_LEN] = {0x4D,0x54,0x68,0x64,0x00,0x00,0x00,0x06,0x00,0x01,0x00,0x04,0x03,0xC0,0x4D,0x54,0x72,0x6B,0x00,0x00,0x00,0x50,0x00,0xFF,0x03,0x08,0x75,0x6E,0x74,0x69,0x74,0x6C,0x65,0x64,0x00,0xFF,0x02,0x1B,0x43,0x6F,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x3F,0x32,0x30,0x30,0x33,0x20,0x62,0x79,0x20,0x47,0x61,0x6D,0x65,0x6C,0x6F,0x66,0x74,0x00,0xFF,0x01,0x08,0x4D,0x61,0x74,0x68,0x69,0x65,0x75,0x0A,0x00,0xFF,0x58,0x04,0x04,0x02,0x18,0x08,0x00,0xFF,0x59,0x02,0x00,0x00,0x00,0xFF,0x51,0x03,0x07,0xA1,0x20,0x00,0xFF,0x2F,0x00,0x4D,0x54,0x72,0x6B,0x00,0x00,0x00,0x72,0x00,0xFF,0x03,0x07,0x54,0x72,0x61,0x63,0x6B,0x20,0x31,0x00,0xC0,0x11,0x00,0xB0,0x07,0x7F,0x2D,0x65,0x00,0x01,0x64,0x00,0x01,0x06,0x04,0x01,0x26,0x58,0x36,0xE0,0x67,0x06,0x08,0x90,0x38,0x7D,0x00,0x41,0x6B,0x15,0xE0,0x47,0x07,0x10,0x7E,0x08,0x10,0x49,0x0A,0x10,0x6B,0x0B,0x10,0x35,0x0D,0x10,0x35,0x0F,0x10,0x06,0x11,0x10,0x09,0x13,0x10,0x69,0x15,0x10,0x05,0x1A,0x10,0x1C,0x21,0x10,0x0D,0x27,0x10,0x70,0x2D,0x10,0x03,0x36,0x10,0x3E,0x3E,0x10,0x66,0x49,0x10,0x2D,0x55,0x10,0x1F,0x61,0x10,0x0B,0x6D,0x06,0x90,0x41,0x00,0x00,0x38,0x00,0x0A,0xE0,0x2E,0x76,0x00,0xFF,0x2F,0x00,0x4D,0x54,0x72,0x6B,0x00,0x00,0x00,0x2B,0x00,0xFF,0x03,0x07,0x54,0x72,0x61,0x63,0x6B,0x20,0x32,0x00,0xC1,0x76,0x00,0x91,0x3B,0x57,0x1E,0x3B,0x00,0x0F,0x3D,0x63,0x1A,0x3D,0x00,0x02,0x3F,0x69,0x1B,0x3F,0x00,0x04,0x42,0x7B,0x1E,0x42,0x00,0x00,0xFF,0x2F,0x00,0x4D,0x54,0x72,0x6B,0x00,0x00,0x00,0x17,0x00,0xFF,0x03,0x07,0x54,0x72,0x61,0x63,0x6B,0x20,0x33,0x6E,0x99,0x26,0x64,0x82,0x3B,0x26,0x00,0x00,0xFF,0x2F,0x00
};//游戏进行时的背景音乐  //游戏失败音乐

不足

本次制作的游戏还存在很多的不足。

  1. 游戏界面设计的还是比较难看。

    这个是手机中原本存在的俄罗斯方块的设计界面,相比较之下我的游戏界面还比较丑陋。
  2. 游戏不太顺畅,由于定时器设置的不好,控制方块左右移动,有种延迟的感觉。
  3. 读写T卡的频率很高。

MTK平台俄罗斯方块游戏评审相关推荐

  1. 500行代码写一个俄罗斯方块游戏

    导读:本文我们要制作一个俄罗斯方块游戏. 01 俄罗斯方块 Tetris 俄罗斯方块游戏是世界上最流行的游戏之一.是由一名叫Alexey Pajitnov的俄罗斯程序员在1985年制作的,从那时起,这 ...

  2. 500 行代码写一个俄罗斯方块游戏

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 导读:本文我们要制作一个俄罗斯方块游戏. 作者 | 派森 ...

  3. Python 写一个俄罗斯方块游戏

    使用 Python 的 PyGame 库写一个俄罗斯方块游戏的逐步指南 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多已经做案例 ...

  4. python下俄罗斯方块的游戏设计_[源码和文档分享]基于Python的PyGame的俄罗斯方块游戏设计与实现...

    摘 要 近年来,随着游戏产业的突飞猛进,游戏玩家的技术也是与日俱增,当你看见游戏高手完美的表演时,你是否想过我也能达到那种水平,本程序用Python语言编写俄罗斯方块,左侧显示正在运行的游戏,右边显示 ...

  5. C++编写简单的俄罗斯方块游戏

    代码地址如下: http://www.demodashi.com/demo/14593.html C++编写简单的俄罗斯方块游戏 使用C++编写一个简单的俄罗斯方块游戏. 1 环境要求 使用C++图形 ...

  6. 一个简易的游戏代码_500 行代码写一个俄罗斯方块游戏

    01 俄罗斯方块 Tetris 俄罗斯方块游戏是世界上最流行的游戏之一.是由一名叫Alexey Pajitnov的俄罗斯程序员在1985年制作的,从那时起,这个游戏就风靡了各个游戏平台. 俄罗斯方块归 ...

  7. 基于80x86汇编的俄罗斯方块游戏

    一.游戏背景介绍 1.1 背景知识 俄罗斯方块原本是前苏联科学家阿列克谢·帕基特诺夫所开发的教育用软件,之后开始提供授权给各个游戏公司,造成各平台上软件大量发行的现象.Game Boy 版的俄罗斯方块 ...

  8. 基于java的俄罗斯方块游戏系统设计与实现(项目报告+答辩PPT+源代码+数据库+截图+部署视频)

    基于Java的俄罗斯方块游戏的设计与实现 俄罗斯方块是一款风靡全球,从一开始到现在都一直经久不衰的电脑.手机.掌上游戏机产品,是一款游戏规则简单,但又不缺乏乐趣的简单经典小游戏,上手容易,适用范围广泛 ...

  9. 【java毕业设计】基于java+swing+Eclipse的俄罗斯方块游戏GUI设计与实现(毕业论文+程序源码)——俄罗斯方块游戏

    基于java+swing+Eclipse的俄罗斯方块游戏GUI设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+swing+Eclipse的俄罗斯方块游戏GUI设计与实现,文章末尾 ...

最新文章

  1. hadoop集群_Ambari搭建hadoop集群
  2. C++类模板特化全总结
  3. EVA 4400存储数据恢复报告
  4. 送给程序员终身受用的建议
  5. liteos内核驱动和linux,移植RTOS必备基础知识
  6. 小程序 省市区县三级联动选择器(caseCade)
  7. 2020年秋计算机科学导论,南开大学《主干课1-计算机科学导论》2020秋主干课考试...
  8. 柯里化的前生今世(四):编译器与解释器
  9. 2017.10.7 括号序列 思考记录
  10. php mvc登陆注册,Asp.Net MVC 5使用Identity之简单的注册和登陆
  11. java批处理_Java内存模型你应该知道
  12. 用c语言ipv6组播,闲谈IPv6-组播和广播
  13. SilverLight跨域访问及其常用的几种解决方法
  14. 3500份课程课后习题答案与大家分享
  15. 20个值得研究的vue项目
  16. science图表_Science和Nature大部分图表都出自这款绘图软件,了解一下?
  17. ASCLL UTF-8 GBK URL编码
  18. Android Bluetooth源码结构
  19. php liger 表格排序,LigerUI中通过加载服务端数据进行表格的分页显示
  20. 融360赴美IPO:大数据能否助其吸引海外投资者青睐?

热门文章

  1. 【论文阅读】RoadMap: A Light-Weight Semantic Map for Visual Localization towards Autonomous Driving
  2. ISV的想法,用友全都懂
  3. 数字孪生医院的智能化运营平台建设内容
  4. BERT大火却不懂Transformer?读这一篇就够了
  5. mysql vb.net odbc_在VB.net中连接MySql的类库_MySQL
  6. 最强大脑 奇虎360 2017校园招聘笔试题
  7. 黄金周在即,国家勒令禁止大数据杀熟,网友:早就该管管了!
  8. android 数字滚动抽奖_Android滚动的数字更好看
  9. mac 在调度中心关闭软件
  10. 把图片放大后还很清晰的办法