总汇编语言俄罗斯方块课设

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

课程设计课程名称汇编语言课程设计
题目俄罗斯方块
专业
班级
学号
姓名
指导教师
摘要
近年来,随着游戏产业的突飞猛进,游戏玩家的技术也是与日俱增,当你看见游戏高手完美的表演时,你是否想过我也能达到那种水平,本程序采用全世界最金典的游戏—俄罗斯方块作为背景,程序设置了鼠标和键盘两个选择方式,游戏运行时随着等级的提高而速度加快,这需要玩家快速操作。

因此,本程序主要意义是为高手玩家提训练平台。

其次也可为刚踏入游戏领域的新手们,提供一个很好的锻炼机会。

本次课程设计采用的是汇编语言。

汇编语言,是用英文缩写形式的助记符书写指令。

汇编语言是一种面向CPU指令系统的程序语言,它采用指令系统的助记符来表示操作码和操作数,用符号地址表示操作数地址。

用汇编语言编写程序在输入计算机后,需要将其翻译成目标程序,计算机才能执行相应指令,这个翻译过程成为汇编,完成汇编任务的程序称为汇编程序。

所以我在MASM汇编程序中进行汇编,通过相应的代码来调用相应的指令实现编密码。

本程序要在windows环境下写一个程序,能够提供简单的用户图形界面,启动程序后进入该界面,用户界面由一定数量的小方格组成的方块构成。

用户可以根据相应的提示进行一些功能上的选择,如修改音乐,方块颜色和游戏难度。

当游戏开始时,计算机将随机抽取方块的放到方格上。

此游戏允许玩家旋转方块,左右移动,加速向下。

程序要实现对满行的消除并记录得分以及对游戏的结束判断。

关键词:俄罗斯方块小游戏; 俄罗斯方块游戏的实现; 汇编语言
Abstract
In recent years, along with the game industry make a spurt of progress, but alsogrow with each passing day game player, when you see the game master perfect performance, do you think I can reach that level, the program uses the world's most Golden games - Tetris as background, the program set up the mouse and keyboard two selection, running game with the level of improvement and the speed, which requires the game player fast operation. Therefore, this procedurethe main significance is to provide training platform for the master game player.Secondly, can also be entered the game domain novices, provides a good opportunity to exercise.
The course design is the assembly language. Assembly language is used,English abbreviated form of mnemonic writing instruction. Assembly language is a programming language for the CPU instruction system, it uses the instructionmnemonics to represent the opcode and operand, said operand address with a symbolic address. Assembly language programming is entered into the computer,need to be translated into the target program, a computer can perform thecorresponding instructions, the translation process into assembly, complete theassembly task programs called assembler. So I was compiled in MASMassembler, realization of encryption by the corresponding code to call the corresponding instruction. This procedure is to write a program in Windows environment, can provide a simple graphical user interface, after starting the program into the interface, the user interface is composed of a number of smallsquare box. The user can select some functions according to the correspondingprompts, such as music, the color and the difficulty of the game box. When the game begins, the computer will randomly on the grid box. This game allows thegame player KLAX, move around, and accelerate down. The program to achievethe full line elimination and record the score and the game end.
Keywords: Tetris, Tetris game, the realization of assembly language
目录
摘要 (1)
Abstract (2)
前言 (4)
游戏基本规则 (5)
一、程序需求分析 (5)
1.1游戏需求 (5)
1.2 功能需求 (5)
1.3方块及各种变换需求 (5)
1.4 操作需求 (6)
1.41 向上键 (6)
1.42 向下键 (6)
1.43 向右键 (6)
二、系统分析 (7)
1、问题描述 (7)
2、任务目标 (7)
3、需求规定 (7)
三、系统总体设计 (9)
四、详细设计 (10)
五、系统测试 (33)
5.1测试用例 (33)
5.2测试结果分析 (34)
六、软件使用说明书 (35)
七、设计总结 (36)
八、心得体会 (37)
致谢.............................................................................................................................. 错误!未定义书签。

前言
俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机游戏,它曾造成的轰动与造成的经济价值可言说是游戏史上的一件大事。

这款游戏最初是由苏联的游戏制作人Alex Pajitnov制作的,它看似简单但却变化无穷,令人上瘾。

相信大多数用户都还记得为它痴迷得茶饭不思不想的那个俄罗斯方块时代。

俄罗斯方块最早还是出现在PC 机上,而我国的用户都是通过红白机了解、喜欢上它的。

现在联众又将重新掀起这股让人沉迷的俄罗斯方块风潮。

对于一般用户来说,它的规则简单,容易上手,且游戏过程变化无穷,俄罗斯方块游戏现在基本上是每个手机必备的游戏,种类千变万化,多种多样俄罗斯方块是个老幼皆宜的小游戏,是经久不衰的一款游戏,自从它诞生那天起就一直深受人们的喜爱。

几乎每个人都玩过这个游戏,也是人们接触最多的一款游戏,它实现由四块正方形的色块组成,然后存储在一个数组的四个元素中,计算机随机产生不同七种类型的方块,根据计算机时钟控制它在一定的时间不停得产生,用户根据键盘的四个方向翻转、向左、向右和向下操作,(控制键的实现是由键盘的方向键消息函数实现)。

然后程序根据这七种方块堆叠成各种不停得模型。

以前的俄罗斯方块程序都是采用的是黑白色,颜色单调乏味,在当今色彩斑斓的信息时代不能在在颜色方面吸引更多的玩家,特别是喜欢画面鲜艳的小朋友的注意,这就意味着将失去很多的市场,鉴于此编写一个变换颜色的方块就可以符合广大玩家对色彩的需求。

本程序是可以变换颜色的方块,在下落的过程中颜色变化,可以吸引更多的小玩家,让人觉得更加的有趣,使人的视觉得到冲击,更家的轻松。

游戏基本规则
游戏共有7种不同形状的方块组成,游戏开始后随机产生一个方块由屏幕顶端开始向下落下,降到底端则固定在桌面的底端,并且开始下一个方块。

在游戏窗口左边作为游戏桌面。

游戏桌面右边靠上是下一个要出现方块的形状,游戏桌面靠右下是显示得分。

如果固定到游戏桌面的方块超过了游戏桌面的顶端游戏结束。

方块固定以后如果桌面上固定的方块满一行,则消除一行并将消除一行之上的部分向下移动。

方块落下的过程中可以用左右方向键来控制方块的位置。

上下方向键用来旋转方块,即所谓的变形。

下方键用来加快下落速度。

一、程序需求分析
1.1游戏需求
28种状态的方块随机产生,自由下落,落下时可由玩家用上、下、左、右控制键控制翻转和移动,以便玩家所需要的形态和位置落下。

游戏界面需求:设计良好的游戏界面可以让玩家充分感受到游戏带来的娱乐性。

游戏形状需求:长条形、Z字形、反Z 字形、田字形、7字形、反7字形、T字型显示需求:当不同的方块填满一行时可以消行,剩余方块向下移动并统计分数。

当达到一定分数的时候,会增加相应的分数。

1.2功能需求
随机给出不同的形状下落填充给定的区域,若填满一条便消掉,记分,设计不同的游戏难度,即方块下落的速度不同,若在游戏中各形状填满了给定区域为输者。

1.3方块及各种变换需求
本游戏需要七种方块,而每种方块还可以进行旋转。

每种方块每行每列最多只有4个小方块。

可以将它们放在一个n*m的区域,该区域可以看做是有许多个等面积小方块构成的区域,而这些区域的状态只有两种,被方块占据或空闲。

因此,对于整个游戏区
域的空间是被占据或空闲,可以用一位数来标识。

对于七种方块和它们旋转后的形态我们可以用不同的标识进行标记。

对于旋转,游戏中所有方块都是按照逆时针旋转的规则进行的,而且在旋转过程中它们不会因为旋转而下降,总会保持在同一高度。

任何方块经过一个旋转周期还会变回原型。

1.4 操作需求
1.41 向上键
产生方块旋转操作,方块并非任何情况都能旋转,如果旋转后与小方块矩阵显示的方块有冲突或超出边界是,均不发生旋转。

因此首先要判断是否有足够的空间进行旋转。

然后是旋转是否旋转。

1.42 向下键
产生方块加速下落操作,如果方块已经达到游戏区域底部或者有其他方块遮挡,则方块停止下降。

1.43 向右键
产生下落方块右移操作。

首先要判断此方块是否能够发生右移,当越界或被其他显示方块阻挡时,则不能右移。

二、系统分析
1、问题描述
启动程序后进入该界面,用户界面由一定数量的小方格组成的方块构成。

用户可以根据相应的提示进行一些功能上的选择,如修改音乐,方块颜色和游戏难度。

当游戏开始时,计算机将随机抽取方块的放到方格上。

此游戏允许玩家旋转方块,左右移动,加速向下。

程序要实现对满行的消除并记录得分以及对游戏的结束判断。

2、任务目标
(1)在windows环境下建立一个简单的用户界面,用户可以进行功能性的菜单选择,如开始、暂停、结束等。

(2)游戏开始后,通过指定的功能键控制方块,方块可以左右移动、落下、旋转。

(3)界面上要显示分数和游戏已经开始的时间和游戏的难度,还要预先显示下一个方块。

(4)能进行简单的参数设置:修改音乐,改变方块颜色和难度等。

(5)可以进行一些文件操作:读文件、写文件等。

3、需求规定
表1 用户界面需求表
表2 用户界面需求表
表3 软硬件环境需求表
三、系统总体设计
对此次汇编语言与微机原理课程设计,通过在图书馆、网络上收集资料,小组成员得到一致结论用Windows平台下32位汇编为最佳选择。

对俄罗斯方块游戏项目计划划分为四个模块,分别为初始化设置和窗口函数相关模块、绘制表格模块、方块左右移动旋转模块、方块下落模块。

其中绘制表格模块、方块左右移动旋转模块、方块下落模块是先决条件。

在该模块完成的基础上,初始化设置和窗口函数相关模块才能得以实现。

各模块分配如下:
初始化设置和窗口函数相关模块:东起
绘制表格模块:龚彤艳
方块左右移动旋转模块:马萧
方块下落模块:唐银科
对初始化设置和窗口函数相关模块:
该模块实现对全局变量的初始化,对窗口中菜单进行设置。

窗口函数则实现对窗口类的注册,生成窗口,以及对窗口事件的处理。

其具体功能的实现是要用的其他功能模块的子程序。

该模块还需要实现背景音乐、游戏等级、方块背景色更改等附加功能。

四、详细设计
由于我负责的模块是初始化以及窗口的搭建。

对初始化是进行一些简单的赋值操作,序列比较简单,不再进行流程图的复制。

又,窗口函数层次清晰,也不再进行流程图的绘制。

详细设计代码实现:
;**** *********俄罗斯方块(模块一:初始化设置和窗口函数相关模块)******** ;窗口生成子程序
WinMain proc
hInst:HINSTANCE,hPreInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD LOCAL wc:WNDCLASSEX ;定义一个窗口类实例变量
LOCAL msg:MSG ;定义一个消息结构
LOCAL hwnd:HWND ;用于存放窗口代号
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,NULL
mov wc.lpszMenuName,0
mov wc.lpszClassName,OFFSET ClassName
Invoke LoadIcon,NULL,ICO_MAIN
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
invoke RegisterClassEx, addr wc ;注册窗口类
invoke LoadMenu,NULL,offset MenuName ;加载Menu
mov hmenu,eax
invoke CreateWindowEx,NULL,\
ADDR ClassName,\
ADDR AppName,\
WS_CAPTION OR WS_SYSMENU or WS_MINIMIZEBOX or WS_DLGFRAME,\ ;
400,\
75,\
;CW_USEDEFAULT,\
500,\
550,\
NULL,\
hmenu,\
hInst,\
NULL
mov hwnd,eax
mov hwnd1,eax
invoke ShowWindow, hwnd,CmdShow
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.endw
mov eax,msg.wParam
ret
WinMain endp
;**** *********俄罗斯方块(模块一:初始化设置和窗口函数相关模块)******** ;窗口回调子程序
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM ;窗口处理函数
LOCAL hdc:HDC ;定义设备描述表代号
LOCAL ps:PAINTSTRUCT ;定义PAINTSTRUCT结构
LOCAL point:POINT
LOCAL hMemDC:HDC ;存位图代号
LOCAL rect:RECT ;定义矩形区域
;定义菜单项信息结构
LOCAL menuiteminfo:MENUITEMINFO
.IF uMsg==WM_DESTROY
invoke DeleteObject,hBitmap
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_CREATE
invoke LoadBitmap,hInstance,IDB_MAIN
mov hBitmap,eax
.ELSEIF uMsg==WM_COMMAND
mov eax,wParam
;对菜单项点击进行处理逻辑
.IF ax==IDM_NEW
;调用初始化子程序
invoke Init
invoke EnableMenuItem,hmenu,IDM_DIJI,MF_GRAYED
invoke EnableMenuItem,hmenu,IDM_ZHONGJI,MF_GRAYED
invoke EnableMenuItem,hmenu,IDM_GAOJI,MF_GRAYED
invoke EnableMenuItem,hmenu,IDM_KAISHI,MF_ENABLED
invoke EnableMenuItem,hmenu,IDM_NEW,MF_GRAYED
invoke EnableMenuItem,hmenu,IDM_BAI,MF_GRAYED
invoke EnableMenuItem,hmenu,IDM_HEI,MF_GRAYED
invoke EnableMenuItem,hmenu,IDM_HONG,MF_GRAYED
invoke EnableMenuItem,hmenu,IDM_HUANG,MF_GRAYED
invoke EnableMenuItem,hmenu,IDM_LV,MF_GRAYED
invoke EnableMenuItem,hmenu,IDM_LAN,MF_GRAYED
invoke EnableMenuItem,hmenu,IDM_ZI,MF_GRAYED
invoke EnableMenuItem,hmenu,IDM_ZONG,MF_GRAYED
.ELSEIF ax==IDM_KAISHI
mov gamestate,1 ;设置游戏状态为1:运行状态
;设置游戏开始时间
invoke GetTickCount
sub eax,gamezantingtime
add gamestarttime,eax
;判断是否开启音乐
**************************************
.if yinyuepanduan==1
invoke PlaySound, addr yinyue, hInstance, SND_ASYNC or SND_LOOP ;开始播放
.endif
;*****************************************************
invoke EnableMenuItem,hmenu,IDM_KAISHI,MF_GRAYED
invoke
EnableMenuItem,hmenu,IDM_ZANTING,MF_ENABLED
;自动下落计时器开始计时,根据等级确定时间
.if jibie==1
invoke SetTimer,NULL,NULL,500,addr DownTimerFunction
mov downTimer,eax
.elseif jibie==2
invoke SetTimer,NULL,NULL,450,addr DownTimerFunction
mov downTimer,eax
.elseif jibie==3
invoke SetTimer,NULL,NULL,400,addr DownTimerFunction
mov downTimer,eax
.elseif jibie==4
invoke SetTimer,NULL,NULL,350,addr DownTimerFunction
mov downTimer,eax
.elseif jibie==5
invoke SetTimer,NULL,NULL,300,addr DownTimerFunction
mov downTimer,eax
.elseif jibie==6
invoke SetTimer,NULL,NULL,250,addr DownTimerFunction
mov downTimer,eax
.elseif jibie==7
invoke SetTimer,NULL,NULL,200,addr DownTimerFunction
mov downTimer,eax
.elseif jibie==8
invoke SetTimer,NULL,NULL,150,addr DownTimerFunction
mov downTimer,eax
.elseif jibie==9
invoke SetTimer,NULL,NULL,100,addr DownTimerFunction
mov downTimer,eax
.elseif jibie==10
invoke SetTimer,NULL,NULL,50,addr DownTimerFunction
mov downTimer,eax
.endif
.ELSEIF ax==IDM_ZANTING
mov gamestate,2 ;将游戏状态设为暂停
;关闭自动下落计时器
invoke KillTimer,NULL,downTimer
;设置游戏暂停时间
invoke GetTickCount
mov gamezantingtime,eax
;停止播放音乐
invoke PlaySound, NULL, hInstance, SND_ASYNC or SND_LOOP
invoke EnableMenuItem,hmenu,IDM_KAISHI,MF_ENABLED
invoke EnableMenuItem,hmenu,IDM_ZANTING,MF_GRAYED .ELSEIF ax==IDM_TUICHU
invoke PostQuitMessage,NULL
.ELSEIF ax==IDM_BEIJINGYINYUE
;根据yinyuepanduan全局变量,实现点击该菜单项时循环播放和取消音乐
;****************************************************************
inc yinyuepanduan
mov eax,yinyuepanduan
mov edx,0
mov ebx,2
div ebx
.if edx==1
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_CHECKED
invoke
SetMenuItemInfo,hmenu,IDM_BEIJINGYINYUE,FALSE,addr menuiteminfo
mov yinyuepanduan,1
.if gamestate==1
invoke PlaySound, addr yinyue, hInstance,
SND_ASYNC or SND_LOOP ;开始播放
.endif
.elseif edx==0
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_UNCHECKED
invoke
SetMenuItemInfo,hmenu,IDM_BEIJINGYINYUE,FALSE,addr menuiteminfo
invoke PlaySound, NULL, hInstance, SND_ASYNC or SND_LOOP ;停止播放
mov yinyuepanduan,0
.endif
;****************************************************************
;对游戏级别进行设置,里面包含大量对游戏级别菜单项操作;****************************************************************
.ELSEIF ax==IDM_DIJI
mov youxidengji,1
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_CHECKED
invoke SetMenuItemInfo,hmenu,IDM_DIJI,FALSE,addr menuiteminfo
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_UNCHECKED
invoke SetMenuItemInfo,hmenu,IDM_ZHONGJI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_GAOJI,FALSE,addr menuiteminfo
.ELSEIF ax==IDM_ZHONGJI
mov youxidengji,2
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_UNCHECKED
invoke SetMenuItemInfo,hmenu,IDM_DIJI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_GAOJI,FALSE,addr menuiteminfo
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_CHECKED
invoke SetMenuItemInfo,hmenu,IDM_ZHONGJI,FALSE,addr menuiteminfo
.ELSEIF ax==IDM_GAOJI
mov youxidengji,3
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_UNCHECKED
invoke SetMenuItemInfo,hmenu,IDM_DIJI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZHONGJI,FALSE,addr menuiteminfo
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_CHECKED
invoke SetMenuItemInfo,hmenu,IDM_GAOJI,FALSE,addr menuiteminfo
;****************************************************************
.ELSEIF ax==IDM_BAI
mov BlockColor,0
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_CHECKED
invoke SetMenuItemInfo,hmenu,IDM_BAI,FALSE,addr menuiteminfo
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_UNCHECKED
invoke SetMenuItemInfo,hmenu,IDM_HEI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HONG,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HUANG,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_LV,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_LAN,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZONG,FALSE,addr menuiteminfo
.ELSEIF ax==IDM_HEI
mov BlockColor,1
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_CHECKED
invoke SetMenuItemInfo,hmenu,IDM_HEI,FALSE,addr menuiteminfo
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_UNCHECKED
invoke SetMenuItemInfo,hmenu,IDM_BAI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HONG,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HUANG,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_LV,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_LAN,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZONG,FALSE,addr menuiteminfo
.ELSEIF ax==IDM_HONG
mov BlockColor,2
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_CHECKED
invoke SetMenuItemInfo,hmenu,IDM_HONG,FALSE,addr menuiteminfo
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_UNCHECKED
invoke SetMenuItemInfo,hmenu,IDM_BAI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HEI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HUANG,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_LV,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_LAN,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZONG,FALSE,addr menuiteminfo
.ELSEIF ax==IDM_HUANG
mov BlockColor,3
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_CHECKED
invoke SetMenuItemInfo,hmenu,IDM_HUANG,FALSE,addr menuiteminfo
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_UNCHECKED
invoke SetMenuItemInfo,hmenu,IDM_BAI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HEI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HONG,FALSE,addr
menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_LV,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_LAN,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZONG,FALSE,addr menuiteminfo
.ELSEIF ax==IDM_LV
mov BlockColor,4
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_CHECKED
invoke SetMenuItemInfo,hmenu,IDM_LV,FALSE,addr menuiteminfo
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_UNCHECKED
invoke SetMenuItemInfo,hmenu,IDM_BAI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HEI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HONG,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HUANG,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_LAN,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZONG,FALSE,addr menuiteminfo
.ELSEIF ax==IDM_LAN
mov BlockColor,5
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_CHECKED
invoke SetMenuItemInfo,hmenu,IDM_LAN,FALSE,addr menuiteminfo
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_UNCHECKED
invoke SetMenuItemInfo,hmenu,IDM_BAI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HEI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HONG,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HUANG,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_LV,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZONG,FALSE,addr menuiteminfo
.ELSEIF ax==IDM_ZI
mov BlockColor,6
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_CHECKED
invoke SetMenuItemInfo,hmenu,IDM_ZI,FALSE,addr menuiteminfo
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_UNCHECKED
invoke SetMenuItemInfo,hmenu,IDM_BAI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HEI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HONG,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HUANG,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_LV,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_LAN,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZONG,FALSE,addr menuiteminfo
.ELSEIF ax==IDM_ZONG ;点击帮助菜单
mov BlockColor,7
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_CHECKED
invoke SetMenuItemInfo,hmenu,IDM_ZONG,FALSE,addr
menuiteminfo
mov menuiteminfo.cbSize,sizeof menuiteminfo
mov menuiteminfo.fMask,MIIM_STATE
mov menuiteminfo.fState,MFS_UNCHECKED
invoke SetMenuItemInfo,hmenu,IDM_BAI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HEI,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HONG,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_HUANG,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_LV,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_LAN,FALSE,addr menuiteminfo
invoke SetMenuItemInfo,hmenu,IDM_ZI,FALSE,addr menuiteminfo
.ELSEIF ax==IDM_HELP
invoke MessageBox ,hWnd,ADDR HelpString,addr HelpTitle,MB_OK
.ENDIF
.ELSEIF uMsg==WM_KEYDOWN
.if wParam==VK_LEFT
.if gamestate==1
;满足条件,执行方框左移子程序
invoke LeftMove
.endif
.elseif wParam==VK_RIGHT
.if gamestate==1
;满足条件,执行方框右移子程序
invoke RightMove
.endif
.elseif wParam==VK_UP
.if gamestate==1
;满足条件,执行方框旋转子程序
invoke Roll
.endif
.elseif wParam==VK_DOWN
.if gamestate==1
;满足条件,执行方框下落子程序
invoke DownTimerFunction
.endif
.endif
.ELSEIF uMsg==WM_PAINT
;实现有待更改,消除闪屏
;****************************************************************
invoke BeginPaint,hWnd, ADDR ps
mov hdc,eax
invoke SetBkMode,hdc,TRANSPARENT
invoke CreateCompatibleDC,hdc
mov hMemDC,eax
invoke SelectObject,hMemDC,hBitmap
invoke GetClientRect,hWnd,addr rect
invoke BitBlt,hdc,0,0,rect.right,rect.bottom,hMemDC,0,0,SRCCOPY
invoke DeleteDC,hMemDC
.if gamestate!=0
.if gamestate==2
invoke GetTickCount
mov ebx,eax
sub eax,gamezantingtime
add gamestarttime,eax
mov gamezantingtime,ebx
.endif
mov point.x,46
mov point.y,25
invoke PrintTable,point,hdc,20
invoke PrintActiveTable,point,hdc,20
mov point.x,330
mov point.y,90
invoke PrintYulanTable,point,hdc,25
;invoke TextOut,hdc,350,200,addr textstring,5
;刷新得分区域
mov point.x,395;
mov point.y,285
invoke PrintNumText,hdc,point,mark
;刷新游戏时间区域
mov point.x,395;
mov point.y,350
invoke PrintGameTime,hdc,point
;刷新级别区域
mov point.x,395;
mov point.y,315
invoke PrintNumText,hdc,point,jibie
.endif
invoke SetBkMode,hdc,OPAQUE
invoke EndPaint,hWnd, ADDR ps
;****************************************************************
.ELSEIF uMsg==WM_CLOSE
invoke PostQuitMessage,NULL
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
;**** *********俄罗斯方块(模块一:初始化设置和窗口函数相关模块)******** ;游戏一局结束,重置布局子程序
;无返回值
;用到gamestate、jibie、gamestarttime、gamezantingtime、youxidengji
;table、mark、dj、yulannum
;调用NextBlock子程序
Init proc
LOCAL frmRect:RECT
mov gamestate,2 ;将游戏设置为暂停状态
;初始化游戏级别为1
mov jibie,1
;设置游戏开始时间,
invoke GetTickCount
mov gamestarttime,eax
mov gamezantingtime,eax
mov mark,0
;根据等级将俄罗斯数组初始化
.if youxidengji==1
mov esi,0
.while esi<200
mov table[esi],0
inc esi
.endw
.elseif youxidengji==2
mov esi,0
.while esi<200
mov al,dj2[esi]
mov table[esi],al
inc esi
.endw
.elseif youxidengji==3
mov esi,0
.while esi<200
mov al,dj3[esi]
mov table[esi],al
inc esi
.endw
.endif
;随即将预览区域初始化为7个模型中的任意一个,并将该模型编号送到yulannum中
invoke GetTickCount
add eax,5
mov edx,0
mov ebx,7
div ebx
mov yulannum,edx
invoke NextBlock
invoke GetClientRect,hwnd1,addr frmRect
invoke InvalidateRect,hwnd1,addr frmRect,TRUE
ret
Init endp
;**** *********俄罗斯方块(模块一:初始化设置和窗口函数相关模块)******** ;用于输出数值子程序,参数说明如下
;hdc:设备描述表代号
;point:输出数据所在的左上方坐标
;printNum:要输出的数据
;没有用到全局数据
;没有调用子程序
PrintNumText proc hdc:HDC,point:POINT,printNum:DWORD
LOCAL weishu:DWORD
LOCAL xiabiao:DWORD
LOCAL ling:DWORD
LOCAL printNumMiddle[15]:byte
;如果输出的数据为0,则直接输出
.if printNum==0
mov dl,30h
mov esi,0
mov byte ptr printNumMiddle[esi],dl
lea eax, printNumMiddle
invoke TextOut,hdc,point.x,point.y,eax,1
ret
.endif
mov weishu,0
mov xiabiao,14
;对输出数组进行初始化
;.while会影响eax的数值
mov eax,printNum
push eax
mov esi,eax
.while esi>0
POP eax
mov edx,0
mov ebx,10
div ebx
;将edx中数值的ASCII码放到数组中
add edx,30H
mov edi,xiabiao
mov byte ptr printNumMiddle[edi],dl
dec xiabiao
inc weishu
push eax
mov esi,eax
.endw
pop eax
inc xiabiao
lea eax,printNumMiddle
add eax,xiabiao
invoke TextOut,hdc,point.x,point.y,eax,weishu
ret
PrintNumText endp
;**** *********俄罗斯方块(模块一:初始化设置和窗口函数相关模块)******** ;输出游戏时间子程序,参数生命如下
;hdc:设备描述表代号
;point:输出数据所在的左上方坐标
;用到gamestarttime全局数据
;调用PrintNumText子程序
PrintGameTime proc hdc:HDC,point:POINT
LOCAL miaopoint:POINT LOCAL fen:DWORD
LOCAL miao:DWORD LOCAL dunhao:DWORD LOCAL dunhaoPoint:POINT mov dunhao,3aH
mov eax,point.x
add eax,20
mov miaopoint.x,eax
mov eax,point.y
mov miaopoint.y,eax
mov eax,point.x
add eax,15
mov dunhaoPoint.x,eax
mov eax,point.y
mov dunhaoPoint.y,eax
;计算游戏开始时间,以毫秒计mov ebx,gamestarttime
invoke GetTickCount
sub eax,ebx
;计算游戏开始时间,以秒计mov edx,0
mov ebx,1000
div ebx
;计算游戏开始时间,以分秒计mov edx,0
mov ebx,60
div ebx
mov fen,eax
mov miao,edx
;输出分
invoke PrintNumText,hdc,point,fen
;输出冒号
lea eax,dunhao
invoke TextOut,hdc,dunhaoPoint.x,dunhaoPoint.y,eax,1 ;输出秒
invoke PrintNumText,hdc,miaopoint,miao
ret
PrintGameTime endp
五、系统测试
游戏基本达到设计要求,由于使用了菜单功能,程序的操作更加直观,一般情况下能正确提示错误信息。

但是在测试中也发现软件的一些不足与缺陷,需要进一步修改和维护时予以纠正。

总的来说,程序通过了测试。

5.1测试用例
运行游戏:选择游戏——新游戏选项:
图5.1 运行游戏图5.2 选择游戏——新游戏选项
图5.3 选择开始图5.4 游戏界面如下
5.2测试结果分析
界面设计相对单一,游戏界面不够完美,代码设计不够完整而系统。

程序的主要缺陷是在进行游戏的时候不是很顺畅,需要改进游戏程序,以方便操作和节约时间,增加趣味性。

六、软件使用说明书
1:此俄罗斯方块游戏是作为汇编语言与微机原理课程设计作品,仅供参考。

2:此作品所用汇编为Windows 32汇编,所用开发工具为RadASM 2.2.1.8,欲打开工程项目需先安装该软件。

3:欲编译后成功运行俄罗斯方块小游戏需在工程项目的music文件夹下放入三个WAV格式音乐文件,分别以如下命名:beijingyinyue.wav、gameover.wav、shengji.wav 4:同样,可执行程序中也将三个音乐文件删除,欲成功玩转该小游戏,需在music 文件夹下放入三个WAV格式音乐文件,分别以如下命名:beijingyinyue.wav 5:只有严格按照上面所要求操作,该游戏才能正确使用。

七、设计总结
本次课程设计,用Win32汇编实现了一个简易的俄罗斯方块游戏。

了解了汇编语言的强大特性,游戏是在速度上的高效性,是其他编程语言无法企及的。

需求分析,概要设计,详细设计在编程中的重要性是不言而喻的。

正确、高效的分析、设计为后面的编程打下了坚实的基础,后面的工作就顺利成章了。

当然,在需求分析、概要设计、详细设计阶段是需要通过不断的讨论、论证来对项目进行更改的代码实现阶段就是软件的具体实现,通过编码来实现需求中的功能。

在代码实现阶段可能会遇到各种问题,此时有可能就要对需求设计乃至需求分析进行更改。

测试阶段同样重要。

在本次软件设计中,在测试阶段就发现了游戏闪屏的问题。

后来想到了通过修改程序结构来解决这个问题,但是,这样代价是惨重的。

这就意味着以前的工作几乎都白做了。

后来通过查找资料,通过更改背景刷新模式,问题得到基本解决,基本解决闪屏的问题。

但如果能够用到双缓冲机制,此问题可得以全部解决正确的功能模块划分是此次课程设计能够顺利完成的关键,通过小组成员完成各个模块,然后将各个模块合并到系统框架中,然后系统得以实现。

八、心得体会
经过一个星期的不断努力,课程设计容基本上完成了。

首先,在这里七、心得体会经过一个星期的不断努力,课程设计容基本上完成了。

首先,在这里要感谢我班上的同学,他们都在身边督促我,我们也互相鼓励,共同进步。

另外,我还要谢谢我的室友,是她们对我的课题提出了许多富有启发性和建设性的意见和建议。

在做课程设计中碰到了许多的问题,从一开始的代码错误到实现课程设计报告的格式,特别是在代码中的错误,大大小小的问题很多,但是经过自已的反复查阅和同学的帮助,都一一克服了。

以后再大的事,有自己的努力和朋友的帮助,我相信没有什么事情是可以难倒我的要感谢我班上的同学,他们都在身边督促我,我们也互相鼓励,共同进步。

另外,我还要谢谢我的室友,是她们对我的课题提出了许多富有启发性和建设性的意见和建议。

在做课程设计中碰到了许多的问题,从一开始的代码错误到实现课程设计报告的格式,特别是在代码中的错误,大大小小的问题很多,但是经过自已的反复查阅和同学的帮助,都一一克服了。

以后再大的事,有自己的努力和朋友的帮助,我相信没有什么事情是可以难倒我的。

参考文献
[1]王爽.汇编语言[M](第二版).清华大学, 2008.
[2] 美明,温冬婵.IBM-PC汇编语言程序设计(第二版).清华大学, 2001.
[3] [美]Kip R.Irvine著,温玉洁,等译.Intel汇编语言程序设计(第五版).电子工业, 2007.
[4] 钱晓捷.汇编语言程序设计(第二版). 电子工业, 2003.
[5] 罗云彬.Windows环境下32位汇编语言程序设计(第二版).电子工业, 2006.
[6] Windows API函数参考手册.人民邮电, 2002.。

相关文档
最新文档