第一篇:编写一个以C 语言为基础的DSP程序
实验1.2 : 编写一个以C 语言为基础的DSP程序 一.实验目的
1.学习用标准C语言编制程序;了解常用的C语言程序设计方法和组成部分。2.学习编制连接命令文件,并用来控制代码的连接。
3.学会建立和改变map文件,以及利用它观察DSP内存使用情况的方法。4.熟悉使用软件仿真方式调试程序。
二.实验设备
PC兼容机一台,操作系统为Windows2000(或Windows98,WindowsXP,以下默认为 Windows2000),安装Code Composer Studio 2.0软件。
三.实验原理 1.标准C语言程序
CCS支持使用标准C语言开发DSP应用程序。当使用标准C语言编制的程序时,其CCS在编译标准C语言程序时,首先将其编译成相应汇编语言程序,再进一步编译成源程序文件名的后缀应为.c(如:volume.c)。
目标DSP的可执行代码。最后生成的是coff格式的可下载到DSP中运行的文件,其文件名后缀为.out。由于使用C语言编制程序,其中调用的标准C的库函数由专门的库提供,在编译连接时编译系统还负责构建C运行环境。所以用户工程中需要注明使用C的支持库。2.命令文件的作用 命令文件(文件名后缀为cmd)为链接程序提供程序和数据在具体DSP硬件中的位置分配信息。通过编制命令文件,我们可以将某些特定的数据或程序按照我们的意图放置在DSP 所管理的内存中。命令文件也为链接程序提供了DSP外扩存储器的描述。在程序中使用CMD文件描述硬件存储区,可以只说明使用部分,但只要是说明的,必须和硬件匹配,也就是只要说明的存储区必须是存在的和可用的。3.内存映射(map)文件的作用 一般地,我们设计、开发的DSP程序在调试好后,要固化到系统的ROM中。为了更
精确地使用ROM空间,我们就需要知道程序的大小和位置,通过建立目标程序的map文件可以了解DSP代码的确切信息。当需要更改程序和数据的大小和位置时,就要适当修改cmd文件和源程序,再重新生成map文件来观察结果。另外,通过观察map文件,可以掌握DSP存储器的使用和利用情况,以便进行存储器方面的优化工作。4.程序设计要求 程序框图(图2-1):
四.实验内容与步骤
1.实验准备 设置软件仿真模式。
2.建立新的工程文件(1)双击桌面上图标,启动Code Composer Studio 2.21。(2)进行以下设置(如图2-2):
3.编辑输入源程序(1)C语言程序-先新建源程序窗口:-输入源程序: intx,y,z;main(){ x=1;y=2;while(1){ z=x+y;} }
图2-3 新建源文件
-保存源程序为CProgram.c:(2)连接命令文件
-如同第(1)步操作,建立空的源程序窗口。-输入连接命令文件内容:-l rts2800.lib-stack 400h-heap 100 MEMORY { PAGE 0 : PROG(R): origin = 0x3E8000, length = 0x10000 PAGE 0 : BOOT(R): origin = 0x3FF000, length = 0xFC0 PAGE 0 : RESET(R): origin = 0x3FFFC0, length = 0x2 PAGE 0 : VECTORS(R): origin = 0x3FFFC2, length = 0x3E PAGE 1 : M0RAM(RW): origin = 0x000000, length = 0x400 PAGE 1 : M1RAM(RW): origin = 0x000400, length = 0x400 PAGE 1 : L0L1RAM(RW): origin = 0x008000, length = 0x2000 图2-4 保存为c文件
PAGE 1 : H0RAM(RW): origin = 0x3F8000, length = 0x2000 } SECTIONS { /* 22-bit program sections */.reset : > RESET, PAGE = 0 vectors : > VECTORS, PAGE = 0.pinit : > PROG, PAGE = 0.cinit : > PROG, PAGE = 0.text : > PROG, PAGE = 0 /* 16-Bit data sections */.const : > L0L1RAM, PAGE = 1.bss : > L0L1RAM, PAGE = 1.stack : > M1RAM, PAGE = 1.sysmem : > M0RAM, PAGE = 1 /* 32-bit data sections */.ebss : > H0RAM, PAGE = 1.econst : > H0RAM, PAGE = 1.esysmem : > H0RAM, PAGE = 1 }-l rts2800.lib-如同第(1)步操作,将文件存为:
C:ICETEK-F2812-A-EDUlabDSP281x_examplesLab0102-CProgram CProgram.cmd(3)将上述编译的源程序加入工程CProgram.pjt。4.编译源文件、下载可执行程序(1)单击菜单“Project”、“Rebuild All”。
(2)执行FileàLoad Program,在随后打开的对话框中选择刚刚建立的
C:ICETEK-F2812-EDULabLab0102-CProgramdebugCProgram.out 文件。完成后,系
统自动打开一个反汇编窗口“Disassembly”,并在其中指示程序的入口地址为 “_c_int00”。
5.打开观察窗口
开启CPU寄存器观察窗口:单击菜单View->Registers->Core。6.观察程序运行结果
这时,在“Disassembly”代表程序运行位置的绿色箭头指向程序的入口地址,程序将从 此开始执行。
(1)选择菜单中Debug->Go Main,CCS自动打开CProgram.c,程序会停在用户主程序入
口main上,这从反汇编窗口和CProgram.c窗口中的指示箭头位置可以看出。(2)在内存观察窗口中观察变量的值:
选择“View”菜单中“Memory…”项,在“Memroy Window Options”窗口中的“Adress” 项中输入&x,单击“OK”完成设置;“Memory”窗口中x 的当前取值显示在第1个地 址的后。
(3)将变量x、y、z分别加入观察窗口:
在源程序中双击变量名,再单击鼠标右键,选择“Add to Watch Window”。这时,这3 个变量还未作初始化。
(4)单步运行2次,在观察窗中观察到变量x、y被赋值。变化的值被显示成红色。同时 在“Memory”窗口中也能观察到x和y值的改变。
(5)再单步运行,可观察到z 的值被计算出来。双击观察窗口中变量x、y在“Value”栏 中的取值并修改成其他取值,单步运行后观察结果。
(6)双击观察窗口中变量x、y在“Value”栏中的取值,并修改成0;选择菜单 Debug->Restart,返回程序起点。
(7)重新单步运行程序
7.内存映像文件
(1)选择菜单Project->Build Options…,启动“Build Options”工程设置对话框。(2)单击“Linker”属性页,在“Map Filename”项中观察生成的map文件名和路径。(3)单击“取消”退出。
8.对照观察map文件和cmd文件的内容(1)选择菜单File->Open…,将找到
C:ICETEK-F2812-A-EDUlabDSP281x_examplesLab0102-CProgram Debug目录,将文
件类型改为“Memory Map Files”,选择CProgram.map文件、打开。(2)打开CProgram.cmd 文件。(3)程序的入口地址:map文件中“ENTRY POINT SYMBOL”中说明了程序入口地址(_c_int00)。(4)内存使用情况:
-map文件中“MEMORY CONFIGURATION”标明了程序占用RAM 的使用情况,共占 用aaH个存储单元。
-观察map文件中的“SECTION ALLOCATION MAP”段,可以看出CProgram.obj的入 口地址为0x3e801e,这也是main函数的入口地址。
-用户堆栈段从400H 开始,程序运行到main函数中后,变量x、y、z 均开设在栈中。-还能看出程序运行都需要调用rts2800.lib 中的哪些模块。9.改变内存分配 修改cmd文件中的
PAGE 0 : PROG(R): origin = 0x3E8000, length = 0x10000 改为
PAGE 0 : PROG(R): origin = 0x3E9000, length = 0x10000 重新编译工程,观察map文件中有何变化。
10.退出CCS 五.注意事项
在重新单步运行程序,注意观察在CPU寄存器窗口中,各寄存器使用情况,观察哪个 寄存器参与了运算。
六.实验结果
1.通过实验可以发现,修改cmd文件可以安排程序和数据在DSP内存资源中的分配和位置;map文件中描述了程序和数据所占用的实际尺寸和地址。
2.C语言编制的程序,在经过编译器编译后,需要连接若干C标准程序辅助运行。以下是 运行流程:
(1)程序入口为_c_int00,执行标准C库中的程序,负责初始化C环境、申请堆栈、初始化
有初始值的变量等。
(2)程序最终转到用户编制的主函数运行。(3)程序在主函数中的无限循环中持续运行。
七.心得体会
这次实验的准备工作有两个,分别是仿真和硬件连接,我们组先选择了仿真的方案。在仿真过程中,按步骤一切都还顺利,观察窗中观察到变量x、y被赋值。变化的值被显示成红色。改变了内存分配,观察到map的变化。但是当我们写入冒泡程序时,但是编译后发现了错误。
实验完成的不是很好,但是实验的过程中熟悉了dsp的调试过程,编程环境,以及了解了从编程到烧录的步骤,还是有所收获。
第二篇:5编写一个C语言程序
前面几节介绍了常量和变量、运算符、表达式和语句的概念,对它们的使用有了一个大概的了解。也许刚学程序的人会觉得有些枯燥,下面我们就来编写第一个C语言程序。
#define PI 3.1416 main(){ float Radius,Area;scanf(%f,&Radius);/*输入半径的值*/ Area=PI*Radius*Radius;printf(%fn,Area);/*输出圆的面积*/ }
1.一个C语言程序,通常由带有#号的编译预处理语句开始。关于预处理我们在以后介绍,这里的#define PI 3.1415926相当于PI代表3.1416,下面在程序中遇到PI,我们就用3.1416替代一下。在以后的程序中,在学习预处理之前,我们都将不使用预处理语句。
2.main()任何一个完整的程序都需要main(),这是一个函数,具体什么是函数,以后再讲,这儿你就要记住就行。后面有一对{}把所有的语句都括在里面,表明那些语句都属于main()里面。程序运行时从这个左大括号开始。
3.{}里面的4行语句大家应该都能明白,先定义两个变量,一个代表半径,一个代表面积,然后输入半径的值,然后求面积,最后在屏幕上输出面积。程序到main()的那对{}的右大括号结束。求面积的语句Area=PI*Radius*Radius;相当于Area=3.1416*Radius*Radius;(完全用3.1416替代PI)。
具体程序从编写到运行得到结果的步骤为: 1.双击tc.exe,进入Turbo C 2.0编译界面 2.ALT+E 进入编辑模式 3.书写程序
4.F2 存储程序(也可进入File菜单,选择save),第一次存储需要写上程序名称(*.C),回车
5.ALT+F9 编译,如果有错误和警告,光标停留在错误行,回车进行修改,修改后,回到4;没有错,下一步 6.CTRL+F9 连接和运行程序
7.用ALT+F5查看程序运行结果,任意键返回程序
如何打开一个已有的C文件:
1.双击tc.exe,进入Turbo C 2.0编译界面
2.F3 进入load状态,找到所要打开文件的目录,找到文件,回车;后面都一样。具体的有哪些快捷键及其它们的作用,请查看第一节概述。
说明:
1.必须在程序的最开始部分定义所有用到的变量,例如这里的Area,Radius。2.变量的命名要尽量有意义,如用代表该意思的英文单词、或者是汉语拼音,例如这里的Radius,Area,绝对禁止用毫无干系的字母,如a,b,c。例如下面的程序,虽然意思和上面的一样,但是看上去意思不明朗,时间长了,很可能忘记程序本身的意思。对于仅仅是控制程序运行,不代表实际意思时,可以用一些简单字母。main(){ float a,b;scanf(%f,&a);b=3.1416*a*a;printf(%fn,b);} 3.采用层次书写程序的格式,要有合理的缩进,必要的时候要有空行,一行只书写一个语句。所有语句尽量不分行,除非太长(分行时变量、运算符,格式字符等等不能拆开),例如下面两个程序看起来就不好看了,虽然它们的功能和前面是一样的。main(){float Radius,Area;scanf(%f,&Radius);Area=3.1416*Radius*Radius;printf(%fn,Area);}
main(){ float Radius,Area;scanf(%f, %Radius);Area=3.1416*Radius *Radius;printf(%fn, Area);} 4.程序在适当的地方要用/*……*/注释,它的意思表示在/* */里面的所有字符都不参加编译。因为一个较大的程序,经过一段时间,有些地方可能连编程者都忘记了,增加注释可以帮助恢复记忆,调试程序时,也容易找出错误。注释也可以分行写。5.在书写{}时要对齐。虽然不对应也不影响程序运行,但对齐后方便以后检查程序,也是为了美观,特别是后面学到流程控制时,{}一定要对齐。
程序设计方法:
1.从问题的全局出发,写出一个概括性的抽象的描述。
2.定义变量,选取函数,确定算法。算法这个东西不好说,遇到的问题多了,自然就会形成自己一整套的算法。
3.按照解决问题的顺序把语句和函数在main()里面堆砌起来。一个好的C程序员应该做到: 1.在运行程序之前存盘
2.所有在程序中用到的常量都用预处理语句在程序开头定义 3.所有在程序中用到的函数都在程序开头声明 4.头文件的#ifndef 5.变量名和函数名使用有意思的英文单词或汉语拼音 6.尽量少用全局变量或不用全局变量
7.采用层次的书写程序格式,对for,while,if_else,do_while,switch_case等控制语句或他们的多重嵌套,采用缩格结构 8.所有对应的{}都对齐
9.尽量用for,而不用while做记数循环 10.尽量不用goto语句
11.一个函数不宜处理太多的功能,保持函数的小型化,功能单一化 12.一个函数要保持自己的独立性,如同黑匣子一样,单进单出 13.函数的返回类型不要省略
14.用malloc()分配内存空间时,以后一定要用free()释放 15.打开文件后,记住在退出程序前要关闭 16.出错情况的处理 17.写上必要的注释
这里说的是一些基本的,经常遇到的情况,还有其他很多要注意的地方,在实际编程中都会遇到.
第三篇:用c语言编写一个成绩管理系统
程序说明:有N个学生,每个学生的数据包含学号(不重复)、姓名、三门课的成绩及平均成绩,试设计一学生成绩管理系统,使之能提供以下功能:(1)主菜单 学生成绩管理系统
1、成绩录入
2、成绩查询
3、成绩统计
4、退出(2)各菜单项功能 ① 成绩录入:输入学生的学号、姓名及三门课的成绩; ② 成绩查询:(至少一种查询方式)。v 按学号查询学生记录。v 查询不及格学生的记录。③成绩统计: v 计算学生的平均分; v 根据学生的平均分高低,对学生的数据进行排序后输出; v 对学生单科成绩排序,输出学生姓名与该科成绩; ④退出系统:退出整个系统(即主菜单)。(3)结构体数组: #define N 30 struct student {int num;/* 定义学号*/
char name[20];/* 定义姓名*/
float score[3];/* 定义存贮三门课成绩的数组*/
float average;/* 定义平均成绩*/
};struct student stu[N];/* 定义结构体数组,存贮多个学生的记录*/
.#include
#include
#include
struct student
{ int num;char name[20];
float score[4];
float average;
}
stu[10000];
long t,max;
bool unpass[1000];
FILE *fstu=fopen(“stud.dat”,“at+”);
int init()
{
int no,i;
float s[4],ave;
char nam[20];
while(!feof(fstu))
{
fscanf(fstu,“%d”,&no);
fscanf(fstu,“%s”,nam);
fscanf(fstu,“%f%f%f%f”,&s[1],&s[2],&s[3],&ave);
if(no>max)
max=no;
stu[no].num=no;
strcpy(stu[no].name,nam);
unpass[no]=false;f
or(i=1;i<=3;i++)
{
stu[no].score[i]=s[i];
if(s[i]<60)
unpass[no]=true;
}
stu[no].average=ave;
}
}
int stuinsert()
{
int no,i;
float s[3],sum;
char nam[20],cha;
loop:printf(“请输入学生的学号、姓名及三门课的成绩 n”);
scanf(“%d”,&no);scanf(“%s”,nam);
scanf(“%f%f%f/n”,&s[1],&s[2],&s[3]);
if(no>max)
max=no;
stu[no].num=no;
sum=0.0;
strcpy(stu[no].name,nam);
unpass[no]=false;
for(i=1;i<=3;i++)
{
stu[no].score[i]=s[i];
sum=sum+s[i];
if(s[i]<60)
unpass[no]=true;
}
stu[no].average=sum/3.0;
fprintf(fstu,“n”);
fprintf(fstu,“%d %s %f %f %f %fn”,stu[no].num,stu[no].name,stu[no].score[1],stu[no].score[2],stu[no].score[3],stu[no].average);
}
int find(int x)
{
long i,no;
switch(x)
{
case 1:printf(“请输入学号:”);
scanf(“%d”,&no);
printf(“%d %s %f %f %f %fn”,stu[no].num,stu[no].name,stu[no].score[1], stu[no].score[2],stu[no].score[3],stu[no].average);
break;
case 2:for(i=1;i<=max;i++)if(unpass[i])printf(“%d %s %f %f %f %fn”,stu[i].num,stu[i].name,stu[i].score[1],stu[i].score[2],stu[i].score[3],stu[i].average);
break;
}
}
int sort(int x)
{
extern int headprint(int x);
student so[1000];
int i,j,k,n;
switch(x)
{
case 1:for(i=1;i<=max;i++)if(stu[i].num==i)printf(“%d %s %fn”,i,stu[i].name,stu[i].average);
break;
case 2:n=0;
for(i=1;i<=max;i++)
{
j=1;if(stu[i].num==i)
while((so[j].average>stu[i].average)&&(j<=n))
j++;n++;
for(k=n;k>=j;k--)so[k]=so[k-1];so[j]=stu[i];
}
for(i=1;i<=n;i++)
printf(“%d %s %f %f %f %fn”,so[i].num,so[i].name,so[i].score[1],so[i].score[2],so[i].score[3],so[i].average);break;case 3:headprint(4);
}
}
int othersort(int x)
{
extern int headprint(int x);
student so[1000];
int i,j,k,n,q;q=0;
switch(x)
{
case 1:if(q==0)q=1;
case 2:if(q==0)q=2;
case 3:if(q==0)q=3;
n=0;
for(i=1;i<=max;i++)
{
j=1;
if(stu[i].num==i)
while((so[j].score[q]>stu[i].score[q])&&(j<=n))
j++;
n++;
for(k=n;k>=j;k--)
so[k]=so[k-1];
so[j]=stu[i];
}
for(i=1;i<=n;i++)
printf(“%d %s %fn”,so[i].num,so[i].name,so[i].score[q]);
break;
}
}
int select(int x)
{
extern int headprint(int x);
int p;
switch(x)
{
case 1:scanf(“%d”,&p);
switch(p)
{
case 1:stuinsert();
break;
case 2:headprint(2);
break;
case 3:headprint(3);
break;
case 4:t=0;
break;
}
break;
case 2:scanf(“%d”,&p);
find(p);
break;
case 3:scanf(“%d”,&p);
sort(p);
break;
case 4:scanf(“%d”,&p);
othersort(p);
break;
}
}
int headprint(int x)
{
switch(x)
{ case 1:printf(“学生成绩管理系统n”);
printf(“
1、成绩录入n”);printf(“
2、成绩查询n”);
printf(“
3、成绩统计n”);
printf(“
4、退出n”);
select(x);
break;
case 2:printf(“
1、按学号查询学生记录n”);
printf(“
2、查询不及格学生的记录n”);
select(x);
break;
case 3:printf(“
1、计算学生的平均分n”);
printf(“
2、根据学生的平均分高低,对学生的数据进行排序后输出n”);
5printf(“
3、对学生单科成绩排序,输出学生姓名与该科成绩n”);select(x);
break;
case 4:printf(“
1、第一科n”);printf(“
2、第二科n”);printf(“
3、第三科n”);select(x);break;;
}
}
int main()
{ max=0;t=1;
init();
loop:headprint(1);
if(t!=0)
goto loop;
}
第四篇:如何编写和语言程序解读
如何编写和汇编语言程序
可以用普通文本编辑器编辑汇编语言源程序。常用的有 MS-DOS 下的 EDIT 文本编辑程序,Windows 下的写字板(WORDPAD.EXE)等。用户通过屏幕编辑程序键入源程序,检查无误,可将源程序存到汇编系统盘上,该程序的扩展名为· ASM。软件运行基本环境
运行汇编程序必备的软件环境: DOS 操作系统;汇编系统。汇编系统盘应包含如下文件: MASM 宏汇编程序文件 LISK 连接程序文件
CRFF 索引程序文件(也可不用)汇编源程序编写)源程序的书写格式
当 CPU 访问内存时,是把存储器分成若干个段,通过 4 个段寄存器中存放的地址对内存储器访问,因此在编源程序时必须按段的结构来编制程序。由于每个段的物理空间为≤ 64KB,所以程序中各段可以分别为一个或几个。源程序的书写一般有如下形式:
逻辑堆栈段 堆栈段名 SEGMENT STACK 用变量定义预置的堆栈空间 · ·
堆栈段名 ENDS 逻辑数据段 数据段名 SEGMENT 用变量定义预置的数据空间 · ·
数据段名 ENDS 逻辑代码段 代码段名 SEGMENT ASSUME 定义各段寻址关系 过程名 PROC … 程序 · ·
过程名 ENDP 代码段名 ENDS END 过程名或起始标号
在源程序中最少要有一个代码段,数据段根据需要可有可无,也可以增设附加段。对于堆栈段也可以根据需要可有可无,但在连接(LINK)时计算机将显示警告性的错误: Warning : N STACK segment There was 1 error detected.在程序中如果没有用到堆栈时,该错误提示不影响程序的运行,如果程序中用到堆栈时必须设置堆栈段。其中: SEGMENT、ASSUME、PROC … ENDP 为伪指令,伪指令是发给汇编程序 ASM 的,而不和微处理器打交道,在汇编时不产生目标代码,只是把源程序中各段的设置情况告诉汇编程序。)段寄存器的段地址的装入
Assume 伪指令语句只是建立了当前段与段寄存器的联系,但不能把各段的段地址装入相应的段寄存器中,段寄存器的段地址的装入是在程序中完成的。(1)DS、ES、SS 的装入
由于段寄存器不能用立即数寻址方式直接传送,所以段地址装入可通过通用寄存器传送给段寄存器。MOV AX,逻辑段名 MOV 段寄存器,AX 其中逻辑段名为程序中定义各逻辑段的名字,(不包括代码段),段寄存器是指与各逻辑段相对应的各段寄存器(DS、ES、SS)。(2)CS 的装入
代码段寄存器是装当前执行目标代码的段地址,IP 是提供下一条要执行的目标代码的偏移量,为了保证程序的正确执行,CS 和 IP 装入新值时是一起完成的。对 CS 和 IP 的装入有如下几种情况:
①根据用户程序中的伪指令 END 后的标号为 CS 和 IP 提供代码段的段地址和目标代码的偏移地址。
②在程序运行过程中,当执行某些指令和操作时,CPU 自动修改 CS 和 IP 的值,使它们指向新的代码段。)程序中的数据与变量
在汇编源程序中的数据除了立即数,由指令产生的数和通过键盘输入的数以外,还胡大量的数据是通过伪指令语句进行预置和分配的,也就是在某逻辑段中(除代码段),将所需的数据以某种形式存放起来,在程序中可任意调用。在数据定义的同时还可以定义变量,将变量与数据结合在一起。可以为某个变量分配存储空间以便在程序执行过程中存放中间结果和最终结果,使用起来极为方便。
(1)变量与数据的定义
变量与数据的定义可以通过符号定义伪指令 EQU、=和数据定义伪指令 DB 或 DW 或 DD 来实现。EQU 和=可以出现在程序的逻辑段内也可出现在逻辑段外。
(2)汇编程序中数据的提供方法 ①用数据定义伪指令提供数据
如果程序要求原始数据为一批数据时,用数据定义伪指令 DB、DW 和 DD 来提供较为方便。②用立即数的形式提供数据
当原始数据只有几个时,一般用立即数的方法来提供。当然,用立即数的方法只是将一个数据传送到通用寄存器中,它只是通过通用寄存器传送数据。③用编程的方法提供数据
假如原始数据是一组有规律的数据项,则用编程序的方法形成这一组数据,不用专门为这组数据分配存储单元,节省了存储空间。④用键盘提供数据
当原始数据为任意数据时,一般用键盘输入方法,调用 DOS 21H 中断。
(3)数据的输出方式 ①在显示器上显示一个字符
调用 02H 号功能调用号,发 21H 号中断,将要显示的字符的 ASCII 码送入 DL,就可在显示器上显示该字符。②在打印机上输出一个字符
调用 05H 号功能调用号,发 21H 号中断,将要打印字符的 ASCII 码送入 DL,就可在打印机上打印出 DL 中的字符。
4)返回 DOS 状态的方法
当执行.EXE 文件时,是在 DOS 状态下进行的,如果希望在执行完.EXE 文件后正常返回 DOS 状态,一般用如下两种方法:采用 DOS 4CH 功能调用和采用返回(RET)断点的方法。
汇编处理 — 执行宏汇编程序 MASM.EXE
用汇编语言编写的源程序必须是一个完整的源程序。宏汇编程序对汇编语言源程序的汇编过程包括语法检查和数据代码汇编两部分,生成目标程序和辅助信息文件。为了完成汇编任务,汇编程序一般采用两遍扫描的方法,第一遍扫描源程序产生符号表、处理伪指令等,第二遍扫描产生机器指令代码、确定数据等。源程序用宏汇编程序翻译(汇编)后,可以得到三个文件:一个是扩展名为.OBJ 的目标文件,在该文件中,将源程序的操作码部分变为机器码,但地址操作数是可浮动的相对地址,而不是实际地址,因此需经 LINK 连接文件进行连接才能形成可执行文件。第二个文件是列表文件,扩展名为.LST,它把源程序和目标程序列表,以供检查程序用。第三个文件是交叉索引文件,扩展名为.CRF,它是一个对源程序所用的各种符号进行前后对照的文件。其中目标文件是必须产生的,而其它两个文件在需要时给予命令就可产生,对连接和执行汇编程序无直接的关系。)汇编操作过程
在 DOS 状态下,键入 MASM ↓则调入宏汇编程序,屏幕显示与操作如下: masm ↓ Microsoft(R)Macro Assemble Version 5.00 Copyright(C)Microsoft Corp 1981-1985,1987,All right reserved.Source filename [.ASM ]: MYFILE ↓ Object filename [MYFILE.OBJ ]: MYFILE ↓ Source listing [NUL.LST ]: MYFILE ↓ Cross-reference [NUL.CRF]: MYFILE ↓ 50678 + 410090 Bytes symbol space free 0 Warning Errors 0 Severe Errors 其中划线部分为用户键入部分,MYFILE 为源程序名(MYFILE.ASM),方括号中是机器规定的默认文件名,如果用户认为方括号内的文件名就是要键入的文件名,则可只在划线部分键入回车符。如果不想要列表文件和交叉索引文件,则可在 [NUL.LST ] 和 [NUL.CRF] 后不键入文件名只键入回车符。
当回答完上述四个询问后,汇编程序就对源程序进行汇编。在汇编过程中,如果发现源程序中有语法错误,则提示出错信息,指出是什么性质的错误,错误类型,最后列出错误的总数。之后可重新进入屏幕编辑状态,调入源程序(MYFILE.ASM)进行修改,修改完毕,再进行汇编,直到汇编通过为止。
如果在汇编时不需要产生列表文件(.LST)和交叉索引文件(.CRF),调用汇编程序时可用分号结束。如果需要产生.OBJ 和.LST 文件,不需要.CRF 文件,则在分号前面加两个逗号即可。如果 4 个文件都需要,用简便的操作方法是在分号前用了 3 个逗号。)列表文件(.LST)
列表文件(.LST)是通过汇编程序(MASM)产生的,可以在 DOS 状态下用 TYPE 命令显示或打印该文件,以便分析调试源程序。如显示 D 盘上已存在的列表文件 MYFILE.LST 操作方法如下: D> TYPE MYFILE.LST ;↓ 列表程序由三部分组成:(1)源程序和目标程序清单
列表程序同时列出源程序和对应的机器语言清单。列表程序的第一列给出每条指令所在行号;第二列给出从段的首地址开始的每条指令存放的偏移地址;接着是数字列,给出对应每条语句的机器码和对应于存放在栈段和数据段的值,在机器码加上“ R ”的指令表示:这条指令在连接时可能产生与列出来的偏移地址不同的地址,因为这些偏移地址可能与其它模块有关;最右边就是用汇编语言编写的源程序。(2)段信息汇总表
在段信息汇总表中列出该程序用了哪几个段,如:代码段 CODE、数据段 DATA 和堆栈段 STACK ;每个段所占存储空间的长度(字节数);每个段的定位类型,包括 PAGE(页)、PARA(节)、WORD(字)和 BYTE(字节),它们表示此段的起始边界要求,即起始边界地址应分别可以被 256、16、2 和 1 除尽。该列表清单 中是以 PARA 为 CODE 段、DATA 段和 STACK 段的起始边界地址。最后一列为段的组合类型;段的组合类型是告诉连接程序,本段与其它段的关系,组合类型有 NONE、PUBLIC、COMMOM、AT 表达式、STACK 和 MEMORY。NONE :表示本段与其它段不发生逻辑关系,即每段都有自己的基本地址。是隐含组合类型。
STACK :表明连接程序首先要把本段与同名同类别的其它段相邻地连接在一起,然后为所有定义为栈段的连接在一起的段,定义一个共同的段基地址,即连接成一个物理段。
在列表程序的源程序中只有一个栈段,在栈段定义中给出了组合类型为 STACK,因此在段信息汇总表中列出了该项,在本程序中它没有任何意义,因为没有其它栈段与它连接,只是为了说明这个问题而设置的。(3)符号汇总表
在列表程序中最后部分列出了符号汇总,是指在源程序中用户定义的符号名、类型、值和所在段。
如果在源程序中存在某些语法错误时,列表文件可提示某条语句有哪些错误,出错提示显示在出错指令行的下面,因此用户可借助列表文件很快地找到错误行,以便调试。另外由于列表文件给出了各条指令的偏移地址,对和程序时设置断点很方便。)交叉索引文件(.CRF)
汇编后产生的交叉索引文件,扩展名为.CRF, 它列出了源程序中定义的符号(包括:标号、变量等)和程序中引用这些符号的情况。如果要查看这个符号表,必须使用 CREF.EXE 的文件,它根据.CRF 文件建立一个扩展名为.REF 的文件,而后再用 DOS 的 TYPE 命令显示,就可以看到这个符号使用情况表。具体操作方法如下: D> CREF ↓
cref filename [.CRF] : MYFILE ↓ list filename [MYFILE.REF] : ↓ D> TYPE MYFILE.REF ↓
目标代码链接程序----LINK.EXE
用汇编语言编写的源程序经过汇编程序(MASM)汇编后产生了目标程序(.OBJ),该文件是将源程序操作码部分变成了机器码,但地址是可浮动的相对地址(逻辑地址),因此必须经过连接程序 LINK 连接后才能运行。连接程序 LINK 是把一个或多个独立的目标程序模块装配成一个可重定位的可执行文件,扩展名为.EXE 文件。此外还可以产生一个内存映象文件,扩展名为.MAP。1)连接程序执行过程
在 DOS 状态下,键入 LINK ↓(或 LINK MYFILE ↓)则系统调入 LINK 程序,屏幕显示操作如下: D> LINK ↓
IBM Personal Computer Linker Version 2.00(C)Copyright IBM Corp 1981,1982,1983 Object Modules [.OBJ] : MYFILE ↓ Run File [MYFILE.EXE] : MYFILE ↓ List File [NUL.MAP] : MYFILE ↓ Libraries [.LIB] : ↓
其中划线部分为用户键入部分,MYFILE 为源程序名,方括号内为机器默认文件名,当用户认为方括号中的文件名就是要键入的文件名时,可在冒号后面只键入回车。
其中 MAP 文件是否需要建立,由用户决定,需要则键入文件名,不需要则直接送入一个回车键。
最后一个询问是问是否在连接时用到库文件,对于连接汇编语言源程序的目标文件,通常是不需要的,因此直接键入回车键。
与汇编程序一样,可以在连接时用分号结束后续询问。例如:
D> LINK MYFILE ;↓
IBM Personal Computer Linker Version 2.00(C)Copyright IBM Corp 1981,1982,1983 连接后只产生 MYFILE.EXE 文件。如果除 MYFILE.EXE 文件外还要产生 MYFILE.MAP 文件,则在分号前加两个逗号。D> LINK MYFILE,;↓ IBM Personal Computer Linker Version 2.00(C)Copyright IBM Corp 1981,1982,1983 2)内存映象文件(.MAP)
由连接程序 LINK 产生的扩展名为.MAP 文件,它实际上是连接程序的列表文件,它给出了每个段的地址分配情况及长度。
在 DOS 状态下,用 TYPE 命令显示打印出来。例如: D> TYPE MYFILE.MAP ↓ Start Stop Length Name Class 00000H 0000FH 0010H DATA 00010H 0004FH 0040H STACK 00050H 0005FH 0010H CODE Origin Group Program entry point at 0005:0000 从中可以看到,源程序 MYFILE 中定义了三个段:数据段(DATA)起始地址为 00000H,终止地址为 0000FH,长度为 0010H 个字节;堆栈段(STACK)起始地址为 00010H,终止地址为 0004FH,长度为 0040H 个字节;代码段(CODE)起始地址为 00050H,终止地址为 0005FH,长度为 0010H 个字节。
应用程序执行
当用连接程序 LINK 将目标程序(.OBJ)连接定位后,可产生可执行的应用程序文件(.EXE),可以在 DOS 状态下执行该程序。执行操作如下: D> MYFILE ↓ 或 D> MYFILE.EXE ↓
在源程序 MYFILE 中如果有显示结果的指令,则在执行程序后可以看到执行结果;如需要动态调试应用程序 MYFILE.EXE,则可以借助动态调试程序 DEBUG.COM 来进行调试、运行,DEBUG 是一种支持命令行方式的汇编语言编程调试工具。
动态调试程序 DEBUG.COM 在编写和运行汇编程序的过程中,会遇到一些错误和问题,需要对程序进行分析和调试,调试程序 DEBUG 就是专为汇编语言设计的一种调试工具。它在调试汇编语言程序时有很强的功能,能使程序设计者接触到机器内部,能观察和修改寄存器和存储单元内容,并能监视目标程序的执行情况,使用户真正接触到 CPU 内部,与计算机产生最紧密的工作联系。
动态和程序 DEBUG 的主要特点 DEBUG 的执行 DEBUG 命令格式 主要 DEBUG 命令
动态和程序 DEBUG 的主要特点)能够在最小环境下运行汇编程序
在 DOS 状态下运行汇编程序,必须将程序经过 MASM 汇编程序,而后还要经过 LINK 连接程序产生可执行程序,才能最终运行,比较麻烦。在 DEBUG 状态下,为用户提供了调试、控制测试的环境,可以在此环境下进行编程、调试、监督、执行用户编写的汇编程序。因此调试周期短,为用户提供了极大的方便。2)提供极简单的修改手段
DEBUG 提供了修改命令,可以修改内存单元内容,修改寄存器的内容,为调试程序、修改程序带来了方便。3)提供用户与计算机内部联系的窗口
DEBUG 具有显示命令,它既可以使用户看到某内存单元或某一块单元内容,也可以看到 CPU 内部各寄存器的内容。用单步执行命令实现跟踪执行,每执行一步都使用户看到各寄存器的内容的变化,以便分析和调整程序。4)可装入、修改或显示任何文件
当然在 DEBUG 状态下运行汇编程序也具有一定局限性。在 DEBUG 状态下运行的程序不能使用宏汇编程序中的宏指令,大部分伪指令也不能使用,因此只能把程序分段调试。此外,不能调试太长的程序,只能分块进行中程序设计。在 DEBUG 状态下调试好的程序不能形成可执行文件(.EXE),因此调试好的程序只能记下,到编辑环境下重新键入调试好的程序,通过汇编程序(如 MASM),再通过连接程序(LINK)形成可执行文件(.EXE)。
DEBUG 的执行
在操作系统(DOS 或 WIndows)命令行方式下,直接调入 DEBUG 程序,键入命令的格式如下: D>DEBUG [d:][Path][filename[.ext]][Parm1][Parm2] 其中 [] 的内容为可选项,可以有也可以缺省。
[d:] 为驱动器号,指要调入 DEBUG 状态的可执行文件在哪个驱动器中,如 A:、B:、C: 等。[Path] 为路径,指要调入 DEBUG 状态的可执行文件是在哪个目录下或子目录下。
[filename[.ext]],指要调入 DEBUG 状态下的可执行文件的文件名,该文件可以是通过编辑、汇编、连接后产生的可执行文件,也可以是在 DEBUG 状态下汇编的程序 段,通过写盘命令 W 写入磁盘的文件。[Parm1][Parm2] 为任选参数,是给定文件的说明参数。
在启动 DEBUG 时,如果输入 filename(文件名),则 DEBUG 程序把指定文件装入内存,用户可以通过 DEBUG 的命令对指定文件进行修改、显示或执行。如果没有文件名,则是以当前内存的内容工作,或者用命名命令或装入命令把需要的文件装入内存,然后再通过 DEBUG 命令进行修改、显示或执行。当启动 DEBUG 程序后,屏幕上出现“—”,说明系统已进入 DEBUG 状态。DEBUG 命令格式(1)DEBUG 命令都是一个英文字母,后面跟着一个或多个有关参数。多个操作参数之间用“ , ”或空格隔开。(2)DEBUG 命令必须接着按 ENTER 键,命令才有效。
(3)参数中不论是地址还是数据,均用十六进制数表示,但十六进制数据后面不要用“ H ”。(4)可以用 Ctrl 和 Break 键来停止一个命令的执行,返回到 DEBUG 的提示符“—”下。(5)用 Ctrl - Num Lock 键中止正在上卷的输出行,再通过按任意键继续输出信息。主要 DEBUG 命令
(1)汇编命令 A
格式: a.A [ 段寄存器名 ]:[ 偏移地址 ] b.A [ 段地址 ]:[ 偏移地址 ] c.A [ 偏移地址 ] d.A 功能:用该命令可以将汇编语言程序直接汇编进入内存。
当键入 A 命令后,显示段地址和偏移地址等待用户键入汇编指令,每键入一条汇编指令回车后,自动显示下一条指令的段地址和偏移地址,再键入下一条汇编指令,直到汇编语言程序全部键入,又显示下一地址时可直接键入回车返回到提示符“-”为止。
其中 a 的段地址在段地址寄存器中,因此在使用该命令时必须将段地址寄存器送入段地址,c 的地址在 CS 中,d 的段地址在 CS 中,偏移地址为 100H。
(2)显示内存命令 D 格式: a.D [ 地址 ] b.D [ 地址范围 ] c.D 功能:显示指定内存范围的内容。
显示的内容为两种形式:一种为十六进制内容,一种为与十六进制相对应的 ASCII 码字符,对不可见字符以“·”代替。
对于 a、c 每次显示 128 个字节内容,b 显示的字节数由地址范围来决定。
若命令中有地址,则显示的内容从指定地址开始,若中中无地址(如 c)则从上一个 D 命令所显示的最后一个单元的下一个单元开始。若以前没有使用过 D 命令,则以 DEBUG 初始化的段寄存器的内容为起始段地址,起始偏移地址为 100H,即 CS:100。
对于 a 中的地址为偏移地址,段地址为 CS 的内容,对 b 中的地址范围,可以指定段地址和起始偏移地址和终止偏移地址。
(3)修改存储单元内容命令 E 格式: a · E [ 地址 ] [ 内容表 ] b · E [ 地址 ] 功能: a ·用命令所给定的内容表去代替指定地址范围的内存单元内容。b ·一个单元一个单元地连续修改单元内容。
其中:内容表为一个十六进制数,也可以是用单引号括起的一串字符。
(4)填充内存命令 F
格式: F [ 范围 ][ 单元内容表 ] 功能:将单元内容表中的内容重复装入内存的指定范围内。
(5)内存搬家命令 M
格式: M [ 源地址范围 ][ 目标起始地址 ] 其中源地址范围和目的起始地址为偏移地址,段地址为 DS 的内容。功能:把源地址范围的内容搬至以目标起始地址开始的存储单元中。
(6)比较命令 C
格式: C [ 源地址范围 ],[ 目标地址 ] 其中源地址范围是由起始地址和终止地址指出的一片连续的存储单元,目标地址为与源地址所指单元对比的目标地址起始地址。功能:从源地址范围是由起始的地址单元开始逐个与目标起始地址往后的单元顺序比较每个单元内容,比较到源终止地址为止。比较结果如果一致则不显示任何信息,如果不一致,则以 [ 源地址 ][ 源内容 ][ 目的内容 ][ 目的地址 ] 的形式显示失败单元地址及内容。
(7)搜索指定内容命令 S 格式: S [ 地址范围 ][ 表 ] 功能:在指定地址范围内搜索表中内容,搜索到就显示表中元素所在地址。
(8)检查和修改寄存器内容命令 R 格式: a · R b · R [ 寄存器名 ] 功能: a ·显示 CPU 内部所有寄存器的内容和全部标志位的状态。b ·显示和修改一个指定寄定器的内容和标志位的状态。
其中对状态标志寄存器 FLAG 以位的形式显示,显示时,8 个状态标志的显示次序和符号如表 B - 1 所示。表 B - 1 状态标志显示形式
标 志 位 溢出标志 OF 方向标志 DF 中断标志 IF 符号标志 SF 零标志 ZF 辅助进位 AF 奇偶标志 PF 进位标志 CF
(9)跟踪与显示命令 T
格式: a · T[ =地址 ] 或 T [ 地址 ] b · T[ =地址 ][ 条数 ] 或 T [ 地址 ][ 条数 ] 功能: a ·执行一条指定地址处的指令,停下来,显示 CPU 所有寄存器内容和全部标志位的状态,以及下一条指令的地址和内容。
b ·为多条跟踪命令,从指定地址开始;若命令中用 [ 地址 ] 给定了起始地址,则从起始地址开始,若未给定,则从当前地址(CS:IP)开始,执行命令中的 [ 条数 ] 决定一共跟踪几条指令后返回 DEBUG 状态。
(10)反汇编命令 U 格式: a · U [ 地址 ] b · U [ 地址范围 ] 功能:将指定范围内的代码以汇编 语言形式显示,同时显示该代码位于内存的地址和机器。
若在命令中没有指定地址则以上一个 U 命令的最后一条指令地址的下一个单元作为起始地址;若没有输入过 U 命令,则以 DEBUG 初始化段寄存器的值作为段地址,以 0100H 作为偏移地址。
(11)命名命令 N 格式: N 文件名
功能:在调用 DEBUG 时,没有文件名,则需要用 N 命令将要调用的文件名格式化到 CS:5CH 的文件控制块中,才能用 L 命令把它调入内存进行调试(其它形式参考 DOS 手册)。
(12)读盘命令 L
格式: a · L [ 地址 ][ 驱动器号 ][ 起始扇区号 ][ 所读扇区个数 ] b · L [ 地址 ] c · L 功能: a ·把指定驱动器和指定扇区范围的内容读到内存的指定区域中。其中地址是读入内存的起始地址,当输入时没有给定地址,则隐含地址为 CS:100H。起始扇区号指逻辑扇区号的起始位置。所读扇区个数是指从起始扇区号开始读到内存几个扇区的内容。驱动器号为 0 或 1,0 表示 A 盘,1 表示 B 盘。
b ·读入已在 CS:5CH 中格式化的文件控制块所指定的文件。在使用该命令前用 N 命令命名即可将要读入的文件名格式化到 CS:5CH 的文件控制块中,其中地址为内存地址。
状 态 有 / 无 增 / 减 开 / 关 负 / 正 零 / 非 有 / 无 偶 / 奇 有 / 无
显示形式(置位 / 复位)
OV/NV DN/UP EI/DI NG/PL ZR/NZ AC/NA PE/PO CY/NC c ·同 b ·地址隐含在 CS : 100H 中。
当读入的文件有扩展名.COM 或.EXE,则始终装入 CS:100H 中,命令中指定了地址也没用。其中 BX 和 CX 中存放所读文件的字节数。
(13)写盘命令 W
格式: a · W[ 地址 ][ 驱动器号 ][ 起始扇区号 ][ 所写扇区个数 ] b · W[ 地址 ] c · W 功能: a · 把在 DEBUGU 状态下调试的程序或数据写入指定的驱动器中 , 起始扇区号 , 所写扇区个数为要占盘中几个扇区。
写盘指定扇区的操作应十分小心,如有差错将会破坏盘上的原有内容。如果在命令行中的地址只包含偏移地址,W 命令认为段地址在 CS 中。
b ·当键入不带参数的写盘命令时,(或只键入地址参数的写盘命令),写盘命令把文件写到软盘上。该文件在用 W 命令之前用命名命令 N 将文件格式化在 CS:5CH 的文件控制块中。c ·只有 W 命令以前而没有任何参数时,与 N 配合使用进行写盘操作。在用 W 命令以前在 BX 和 CX 中应写入文件的字节数。
(15)输出命令 O
格式: O[ 端口地址 ] [ 字节值 ] 功能:向指定端口地址输出一个字节。
(16)运行命令 G
格式: G [ =地址 ][ 地址 [ 地址… ]] 功能:执行用户正在调试的程序。
其中地址为执行的起始地址,以 CS 中内容作为段地址,以等号后面的地址为偏移地址。再后面的地址为断点地址。在命令行中只有起始地址,没有断点地址,则程序在执行时不中断。DEBUG 规定最多设置 10 个断点地址。设置多个断点用于调试较大的程序,即程序中有多个模块、多个通路时用,比较方便,在执行时不论走哪条通路,程序都可以在断点处停下来,以便调整程序。
断点地址为程序中断处的偏移地址,段地址在 CS 中。
当执行在 DEBUG 状态下汇编的小段程序时,只用 G 命令即可。
(17)十六进制运算命令 H 格式: H 数据 1 数据 2 其中数据 1 和数据 2 为十六进制数据。
功能:将两个十六进制数进行相加、减,结果显示在屏幕上。(18)结束 DEBUG 返回到 DOS 命令 Q 格式: Q 功能:程序调试完退出 DEBUG 状态,返回到 DOS 状态下。
Q 命令不能把内存的文件存盘,要想存盘必须在退出 DEBUG 之前用 W 命令写盘
读书的好处
1、行万里路,读万卷书。
2、书山有路勤为径,学海无涯苦作舟。
3、读书破万卷,下笔如有神。
4、我所学到的任何有价值的知识都是由自学中得来的。——达尔文
5、少壮不努力,老大徒悲伤。
6、黑发不知勤学早,白首方悔读书迟。——颜真卿
7、宝剑锋从磨砺出,梅花香自苦寒来。
8、读书要三到:心到、眼到、口到
9、玉不琢、不成器,人不学、不知义。
10、一日无书,百事荒废。——陈寿
11、书是人类进步的阶梯。
12、一日不读口生,一日不写手生。
13、我扑在书上,就像饥饿的人扑在面包上。——高尔基
14、书到用时方恨少、事非经过不知难。——陆游
15、读一本好书,就如同和一个高尚的人在交谈——歌德
16、读一切好书,就是和许多高尚的人谈话。——笛卡儿
17、学习永远不晚。——高尔基
18、少而好学,如日出之阳;壮而好学,如日中之光;志而好学,如炳烛之光。——刘向
19、学而不思则惘,思而不学则殆。——孔子
20、读书给人以快乐、给人以光彩、给人以才干。——培根
第五篇:C语言编写俄罗斯方块论文
俄罗斯方块
学 号:
班 级:
姓 名:
指导教师:
完成日期:2012年5月
目
录
1.引言..............................................................................................................................................1
1.1开发工具............................................................................................................................1 1.1.1 C是中级预言......................................................................................................1
1.1.2 C是结构化语言..................................................................................................1 1.1.3 C语言功能齐全..................................................................................................1 1.1.4 C语言可移植性好..............................................................................................1 游戏设计......................................................................................................................................2
2.1游戏设计要求....................................................................................................................2
2.1.1.设计题目:俄罗斯方块游戏.............................................................................2
2.1.2.设计内容:.........................................................................................................2 2.1.3.功能模块划分:.................................................................................................2 2.2 游戏设计思想...................................................................................................................2
2.2.1游戏界面:............................................................................................................2 2.2.2 设计思路.......................................................................................................................2 2.3:游戏功能......................................................................................................................3 2.3.1:开始部分...........................................................................................................3
2.3.2.运行部分...............................................................................................................3
3.实验总结:..................................................................................................................................4
3.1 开发背景与需求分析.......................................................................................................4 3.2 系统功能介绍...................................................................................................................4 4.核心代码:................................................................................................................................8 总结................................................................................................................................................21 参考文献:....................................................................................................................................22
基于C语言的俄罗斯方块游戏
[摘要]:俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机游戏。俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。由于上手简单、老少皆宜,从而家喻户晓,风靡世界。[关键词]:C语言;心得体会;影响
1.引言 随着社会的发展,人们生活的步调日益加快,越来越多的人加入了全球化的世界.人们不在拘泥于一小块天地.加班,出差成了现代人不可避免的公务.而此时一款可以随时随地娱乐的游戏成了必需品.在手机和电脑成为人们日用品的社会,一款能在其上能便捷运行的游戏成为买家的参考点.现在我们所要设计的这一款基于C语言的游戏——贪吃蛇,就是满足以上要求而设计出来的,希望能给玩家带来娱乐.贪吃蛇这一游戏简单易行,操作方便,娱乐性较强,吸引了不少人.这一款游戏紧紧地抓住了人们的心理,虽然简单,却起乐无穷,在人们不断追求更多的欲望下,该游戏给人们带来了追逐的快感,以及成功后的满足感,对于一直处于高压下的现代人是很好的放松工具.1.1开发工具
《C/C++程序设计学习与试验系统》
该系统继承了Turbo C2.0/C++3.0、GCC、Visua C++6.0这四种常见的编译器,可以很好满足目前主流的C语言教材的实验需求。
C语言具有下列特点:
1.1.1 C是中级预言
它把高级语言的基本结构和语句与低级语言的实用性结合起来,C语言可以像汇编语言一样对位、字节和地址进行操作,通常还是称C为高级语言。
1.1.2 C是结构化语言
结构化语言的特点是程序的各个部分除了必要地数据交流外彼此独立。这种结构化方式可使程序层次清晰,便于使用,维护及调试。
1.1.3 C语言功能齐全
C语言具有多种数据类型,并引入了指针概念,可使程序效率更高;C语言也具有强大的图形功能;具有较强的计算功能、逻辑判断功能。
1.1.4 C语言可移植性好
与汇编语言相比,C语言程序适用范围大,可用于各种操作系统和各种型号的计算机。游戏设计
2.1游戏设计要求
2.1.1.设计题目:俄罗斯方块游戏 2.1.2.设计内容:
一组由4个小型正方形组成的规则图形,中文通称为方块共有7种,分别以S、Z、L、J、I、O、T这7个字母的形状来命名。通过设计者预先设置的随机发生器不断地输出单个方块到场地顶部,以一定的规则进行移动、旋转、下落和摆放,锁定并填充到场地中。每次摆放如果将场地的一行或多行完全填满,则组成这些行的所有小正方形将被消除,并且以此来换取一定的积分或者其他形式的奖励。而未被消除的方块会一直累积,并对后来的方块摆放造成各种影响。如果未被消除的方块堆放的高度超过场地所规定的最大高度则游戏结束。
2.1.3.功能模块划分:
系统功能模块
2.2 游戏设计思想
2.2.1游戏界面:
方块堆积。遇整则消。
2.2.2 设计思路
1、一个用于摆放小型正方形的平面虚拟场地,其标准大小:行宽为10,列高为20,以每个小正方形为单位。2.、一组由4个小型正方形组成的规则图形,英文称为Tetromino,中文通称为方块共有7种,分别以S、Z、L、J、I、O、T这7个字母的形状来命名。I:一次最多消除四层
J(左右):最多消除三层,或消除二层
L:最多消除三层,或消除二层
O:消除一至二层
S(左右):最多二层,容易造成孔洞
Z(左右):最多二层,容易造成孔洞
T:最多二层
(1)部分游戏有单格方块,可以穿透固定的方块到达最下层空位。其他的改版中出现更多特别的造型。
方块会从区域上方开始缓慢继续落下。
(2)玩家可以做的操作有:以90度为单位旋转方块,以格子为单位左右移动方块,让方块加速落下。
(3)方块移到区域最下方或是着地到其他方块上无法移动时,就会固定在该处,而新的方块出现在区域上方开始落下。
(4)当区域中某一列横向格子全部由方块填满,则该列会消失并成为玩家的得分。同时删除的列数越多,得分指数上升。
(5)当固定的方块堆到区域最上方而无法消除层数时,则游戏结束。
(6)一般来说,游戏还会提示下一个要落下的方块,熟练的玩家会计算到下一个方块,评估现在要如何进行。由于游戏能不断进行下去对商业用游戏不太理想,所以一般还会随着游戏的进行而加速提高难度。
3、通过设计者预先设置的随机发生器不断地输出单个方块到场地顶部,以一定的规则进行移动、旋转、下落和摆放,锁定并填充到场地中。每次摆放如果将场地的一行或多行完全填满,则组成这些行的所有小正方形将被消除,并且以此来换取一定的积分或者其他形式的奖励。而未被消除的方块会一直累积,并对后来的方块摆放造成各种影响。
4、如果未被消除的方块堆放的高度超过场地所规定的最大高度(并不一定是20或者玩家所能见到的高度),则游戏结束。
具体到每一款不同的游戏,其中的细节规则都可能有千差万别,但是以上的基本规则是相同的。
2.3:游戏功能
2.3.1:开始部分
游戏是运行在图形模式下的,所以第一步一定是初始化图形模式,接着要有开始的界面,就像书有封面一样,我设置了一个游戏的标题画面,除了游戏标题画面我还设置了一个欢迎画面。标题画面以后,还要为游戏的运行部分作初始化,包括绘制游戏运行时的背景,对游戏某些重 要变量的初始化。
2.3.2.运行部分
俄罗斯方块的要求为:不同形状组合的方块从界面上方落下。通过键盘上的四个光标控制方块下落时的形状转换和下落方向。方块堆积在一起,将区域占满时则会消除以增加
游戏分数。
整个游戏过程分为三个步骤:
1、按游戏界面的“开始”按钮或者F2键来开始游戏,自己使用右边的窗口,对手使用左边的窗口
2、键盘操作:系统缺省设置使用右边的窗口,用光标操作,“←”左移一格;“→”右移一格;“↑”旋转方块;↓ 方块丢下(方块下落到底),“End”健可以一格格的下落,用户还可以自定义习惯的按键来操作游戏。
3、计分牌显示的内容:“分数”为双方本局的分数,计分标准为下落一个块10分,一次消一行100分、2行200分、3行400分、4行800分。等级”为双方的游戏设置等级,当分数达到一定的值,等级就会提升、速度加快。“行数”第一行为双方消的行数,第二行是送给对方的行数。“比分”为双方赢的局数。2.3.3:结束部分:
游戏结束时,显示“GAME OVER”
3.实验总结:
3.1 开发背景与需求分析
随着网络技术的发展,人们的生活越来越离不开网络,网络给人们带来了各种各样的信息和更多更新的娱乐。据统计。每天上网的人群中75%的人用来丰富自己的生活。其中游戏最为常见和普遍。所以,这次课程设计我想实现一个小游戏:俄罗斯方块。需求分析
1)游戏面板(画布)GameCanvas类,完成游戏显示; 2)方块绘画drawUnit类,方块下落过程中的各种形态;
3)主界面实现游戏的开始,退出,暂停,提高级数,降低级数功能及图像界面排版;
4)通过键盘按键实现游戏,并且可以调节游戏速度。
3.2 系统功能介绍
俄罗斯方块是一个非常复杂但比较有趣并且耐玩的游戏,相信很多人对俄罗斯方块并不陌生,如下图所示,游戏中共有七种方块,每种方块都有四个方格组成。
这七种方块可以旋转90度、180度、270度,因此每种方块有四种状态,七种方块总有28种状态,这28种状态的方块随机产生,自由下落,落下时可由玩家通过键盘上的上、下、左、右控制键来控制方块的反转、移动和加速下落。如果下落时,方块填满某一行则这一行消失,同时给玩家加分,若由存在空格的方块填满整个窗口,则游戏结束。
图1-1 初始状态
图1-2 开始游戏
图1-3 消除一行
图1-4 消除两行
图1-5 消除四行
图1-6 游戏结束
4.核心代码:
import java.awt.*;import java.awt.event.*;
//俄罗斯方块类
public class computer extends Frame { public static boolean isPlay = false;public static int level = 1, score = 0;public static TextField scoreField, levelField;
public static MyTimer timer;GameCanvas gameScr;//声明一个属于画布类得变量 public static void main(String[] argus){ computer ers = new computer(“俄罗斯方块游戏 V1.0 Author:Vincent”);//运用构造方法为框架名
WindowListener win_listener = new WinListener();//定义一个窗口监听事件对象
ers.addWindowListener(win_listener);//为框架添加该监听器 }
computer(String title)// 俄罗斯方块类的构造方法 { super(title);//调用父类得构造方法
setSize(600, 480);//设置框架的尺寸
setLayout(new GridLayout(1, 2));//设置框架的布局流
gameScr = new GameCanvas();gameScr.addKeyListener(gameScr);//为该对象注册键盘点击监听器
timer = new MyTimer(gameScr);timer.setDaemon(true);timer.start();timer.suspend();
add(gameScr);
Panel rightScr = new Panel();rightScr.setLayout(new GridLayout(2, 1, 0, 30));rightScr.setSize(120, 500);add(rightScr);
// 右边信息窗体的布局
MyPanel infoScr = new MyPanel();infoScr.setLayout(new GridLayout(4, 1, 0, 5));infoScr.setSize(120, 300);rightScr.add(infoScr);
// 定义标签和初始值
Label scorep = new Label(“分数:”, Label.LEFT);Label levelp = new Label(“级数:”, Label.LEFT);scoreField = new TextField(8);levelField = new TextField(8);scoreField.setEditable(false);levelField.setEditable(false);infoScr.add(scorep);
infoScr.add(scoreField);infoScr.add(levelp);infoScr.add(levelField);scorep.setSize(new Dimension(20, 60));scoreField.setSize(new Dimension(20, 60));levelp.setSize(new Dimension(20, 60));levelField.setSize(new Dimension(20, 60));scoreField.setText(“0”);levelField.setText(“1”);
// 右边控制按钮窗体的布局
MyPanel controlScr = new MyPanel();controlScr.setLayout(new GridLayout(5, 1, 0, 5));rightScr.add(controlScr);
// 定义按钮play Button play_b = new Button(“开始游戏”);play_b.setSize(new Dimension(50, 200));play_b.addActionListener(new Command(Command.button_play, gameScr));
// 定义按钮Level UP Button level_up_b = new Button(“提高级数”);level_up_b.setSize(new Dimension(50, 200));level_up_b.addActionListener(new Command(Command.button_levelup, gameScr));
// 定义按钮Level Down Button level_down_b = new Button(“降低级数”);level_down_b.setSize(new Dimension(50, 200));level_down_b.addActionListener(new Command(Command.button_leveldown, gameScr));
// 定义按钮Level Pause Button pause_b = new Button(“游戏暂停”);pause_b.setSize(new Dimension(50, 200));pause_b.addActionListener(new
Command(Command.button_pause,gameScr));
// 定义按钮Quit Button quit_b = new Button(“退出游戏”);quit_b.setSize(new Dimension(50, 200));quit_b.addActionListener(new Command(Command.button_quit, gameScr));
controlScr.add(play_b);controlScr.add(level_up_b);controlScr.add(level_down_b);controlScr.add(pause_b);controlScr.add(quit_b);setVisible(true);gameScr.requestFocus();} }
// 重写MyPanel类,使Panel的四周留空间 class MyPanel extends Panel { public Insets getInsets(){ return new Insets(30, 50, 30, 50);} }
// 游戏画布类
class GameCanvas extends Canvas implements KeyListener { final int unitSize = 30;// 小方块边长 int rowNum;// 正方格的行数 int columnNum;// 正方格的列数
int maxAllowRowNum;// 允许有多少行未削 int blockInitRow;// 新出现块的起始行坐标 int blockInitCol;// 新出现块的起始列坐标 int[][] scrArr;// 屏幕数组 Block b;// 对方快的引用
// 画布类的构造方法 GameCanvas(){ rowNum = 15;columnNum = 10;maxAllowRowNum = rowNum1;blockInitCol = columnNum / 2(row + 1)* unitSize, unitSize, unitSize, true);g.dispose();}
public Block getBlock(){ return b;// 返回block实例的引用 }
// 返回屏幕数组中(row,col)位置的属性值 public int getScrArrXY(int row, int col){ if(row < 0 || row >= rowNum || col < 0 || col >= columnNum)return(-1);else return(scrArr[row][col]);}
// 返回新块的初始行坐标方法 public int getInitRow(){ return(blockInitRow);// 返回新块的初始行坐标 }
// 返回新块的初始列坐标方法 public int getInitCol(){ return(blockInitCol);// 返回新块的初始列坐标 }
// 满行删除方法
void deleteFullLine(){ int full_line_num = 0;int k = 0;
for(int i = 0;i < rowNum;i++){ boolean isfull = true;
L1: for(int j = 0;j < columnNum;j++)if(scrArr[i][j] == 0){ k++;isfull = false;break L1;} if(isfull)full_line_num++;if(k!= 0 && k1, j, 0);else drawUnit(k1][j] = scrArr[i][j];} } for(int i = k1)){
dispBlock(0);col--;dispBlock(1);} }
// 实现块的右移
public void rightMove(){ if(assertValid(blockType, turnState, row, col + 1)){ dispBlock(0);col++;dispBlock(1);} }
// 实现块落下的操作的方法 public boolean fallDown(){ if(blockState == 2)return(false);if(assertValid(blockType, turnState, rowi, col + j);if(temp < 0 || temp == 2)return false;} k = k >> 1;} } return true;}
// 同步显示的方法
public synchronized void dispBlock(int s){ int k = 0x8000;for(int i = 0;i < 4;i++){ for(int j = 0;j < 4;j++){ if(((int)pattern[blockType][turnState] & k)!= 0){ scr.drawUnit(rowcomputer.level + 1)* 100);} catch(InterruptedException e){ } if(!scr.getBlock().fallDown()){ scr.deleteFullLine();if(scr.isGameEnd()){ computer.isPlay = false;suspend();} else scr.getBlock().reset();} } } }
class WinListener extends WindowAdapter { public void windowClosing(WindowEvent l){ System.exit(0);} } 总结
1感悟:当今计算机应用在生活中可以说得是无处不在。因此作为二十一世纪的大学来说掌握程序开发技术是十分重要的,而C语言又是最常见,功能最强大的一种高级语言,因此做好C语言课程设计是十分必要的。回顾起此次课程设计,至今我们仍感慨颇多,的确,自从拿到题目到完成整个编程,从理论到实践,在这么长的时间里,可以学到很多很多的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。通过这次课程设计使我们懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对一些前面学过的知识理解得不够深刻,掌握得不够牢固,比如说结构体,指针,链表……通过这次课程设计之后,我们把前面所学过的知识又重新温故了一遍。
我做的是做俄罗斯方块游戏。简单的一个,但对我来说却是一个很大的困难。更加是第一次做基于C语言的课程设计,所以连续几天翻阅书籍或是参考网上内容却丝毫没有进展,最主要是不知从何开始,这个时候才知道上课老师们不厌其烦的教导是多么的宝贵,这个时候才后悔上课的时候
没有认真的听讲。可是现在一切都晚了,还好时间还算是充裕,只好拿出书本重新复习一下。不过经过几天的努力,大体上把课本上的知识点看了一遍,知识点也都基本是撑握了,所以一下一步就是开始正式的编程序了。不过毕竟水平有限,还是不知如何下手,于是就在网上下了一篇类似的程序,经过仔细的研究,终于读懂了C语言编程的基本过程和方法。经过一波三折,终于开始正式编程。
而且编程是一件高精度、模范化的事情,稍有疏乎都会影响全局,也可能因为某一处的小的错误而导致整个程序的无法运行。所以认真仔细就是非常重要的了。开始的时候真的感觉编程是一件很无聊的事情,所以就在网上下载的程序的基础上开始行动了,不过当一个程序运行成功的时候那种喜悦是无法言语的,那种成就感是无法比拟的。又经过几天的努力,终于把程序完成了,尽管程序还是有很多错误和漏洞,不过还是很高兴的。无论如何是自己的劳动成果,是自己经过努力得到的成绩,同时也是学习C语言的一次实践作业,自己进步的证明。
通过这次课程设计,使我对C语言有了更进一步的认识和了解,要想学好它要重在实践,要通过不断的上机操作才能更好地学习它,我也发现我的好多不足之处,首先是自己在指法上还不行,经常按错字母,通过学习也有所改进;再有对C语言的一些标准库函数不太了解,还有对函数调用的正确使用不够熟悉,还有对C语言中经常出现的错误也不了解,通过实践的学习,我认识到学好计算机要重视实践操作,不仅仅是学习C语言,还是其它的语言,以及其它的计算机方面的知识都要重在实践,所以后在学习过程中,我会更加注视实践操作,使自己便好地学好计算机。
在该游戏设计过程中,收获知识,提高能力的同时,我也学到了很多人生的哲理,懂得怎么样去制定计划,怎么样去实现这个计划,并掌握了在执行过程中怎么样去克服心理上的不良情绪。
2感谢:经过两个星期的苦心钻研,系统终于制作完毕。在本次课程设计中困难遇到不少,也让我学到了很多。在这次系统开发的过程中,我深深地体会到了做一个系统,首先进行需求分析的重要性。了解了一个系统的制作,从功能分析到功能模块分析,与其他系统的关系,这些都有待以后进一步的改进。通过实践对我以后的学习是一笔不小的财富!
在此,感谢班上同学对我的帮助和指点,没有他们所提供的资料,仅凭我个人力量,在短短的两周时间里是很难完成这个设计的。更要感谢的是我的老师,感谢老师孜孜不倦的教诲,一丝不苟的精神和一视同仁的教学风格。我会仅记老师的教诲,一步一个脚印的完成自己的学业!
参考文献:
[1].裘宗燕 著,从问题到程序科学出版社,北京大学出版社,1999年4月。[2].《C程序设计(第二版)》,谭浩强编,清华大学出版社,1999年12月。[3].《C语言编程常见问题解答》,[美]Paul S.R.Chishohm等著,张芳妮 吕波译,清华大学出版社,11996年12月。[4].《The C Programming Language》,by Brian W.Kernighan and Dennis M.Ritchie.,Pubilished by Prentice-Hall in 1988。
[5].朱若愚.数据结构[M].北京: 电子工业出版社, 2006.1
[6].傅清祥,王晓东.数据结构与算法设计[M].北京: 电子工业出版社, 2006.3 [7].李春葆.数据结构(C语言版)习题与解析[M].北京:清华大学出版社, 2006.1 [8].刘大有.数据结构[M].北京: 高等教育出版社, 2006.3 [9].王敬华,陈静.C语言程序设计[M].北京: 清华大学出版社, 2007.10 [10].徐孝凯.数据结构简明教程.[M].北京: 清华大学出版社, 2006.04
课程设计俄罗斯方块游戏源代码
本程序共三个类,建一个包 square。把三个类都封装到一个包里面,三个类分别是
Controller,Main,Square
package square;import javax.swing.JPanel;import java.awt.Color;
// 事倒入java程序所需要的类库文件。如果不倒入相应的文件。java程序是会报错的。import javax.swing.JLabel;public class Controller extends Thread //Controller类从定义从父类继承来来的某些成员变量和成员方法,游戏控制线程
private int x;
//方块左上角的坐标
private int y;
private Square sq;
//方块对象的引用当前
private Square next;
//下一个方块的引用
private JPanel[][] sc;
//显示
private boolean[][] state;
//填充状态
private int sorce;
//分值
private int speed;
//下落速度
private JLabel jl1;
//分数速度提示
private JLabel jl2;
private JPanel jp;
//下一个方块提示
private JPanel[][] sc2;
private int sleepTime;
//等待时间
public Controller(int x, int y, JPanel[][] sc, boolean[][] state,//构造器
传递引用
int sorce, int speed, JLabel jl1, JLabel jl2,JPanel jp, JPanel[][] sc2){
this.x = x;
this.y = y;
this.sc = sc;
this.state = state;
this.sorce = sorce;
this.speed = speed;
this.jl1 = jl1;
this.jl2 = jl2;
this.jp = jp;
this.sc2 = sc2;
this.sleepTime = 200;
sq = new Square((int)(Math.random()* 4)+ 1);
next = new Square((int)(Math.random()* 4)+ 1);
}
public void init(){
for(int i = 0;i < state.length;i++){
for(int j = 0;j < state[i].length;j++){
state[i][j] = false;
}
}
update();
}
@Override
public void run()
//重设run()方法
{
while(true){
try {
if(!isGameOver()){
if(isHit()){
set();
} else {
fall();
}
check();
update();
Thread.sleep(sleepTime);
} else {
break;
}
} catch(InterruptedException e){
e.printStackTrace();
}
}
}
private void set()
//码放方块
{
for(int i = 0;i < 4;i++){
for(int j = 0;j < 4;j++){
if(sq.getState(i, j)== true){
state[i + x][y + j] = true;
}
}
}
x = 0;
y = 0;
sq = next;
next = new Square((int)(Math.random()* 4)+ 1);
sleepTime = 1000 /(speed + 2);
}
private void update()
//更新数据
{
for(int i = 0;i < sc.length;i++){
for(int j = 0;j < sc[i].length;j++){
if(state[i][j] == true){
sc[i][j].setBackground(Color.BLUE);
} else {
sc[i][j].setBackground(Color.WHITE);}
}
}
for(int i = 0;i < 4;i++){
for(int j = 0;j < 4;j++){
if(sq.getState(i, j)){
sc[i + x][j + y].setBackground(Color.BLUE);
}
}
}
for(int i = 0;i < sc2.length;i++){
for(int j = 0;j < sc2[i].length;j++){
if(next.getState(i, j)){
sc2[i][j].setBackground(Color.BLUE);
} else {
sc2[i][j].setBackground(Color.WHITE);
}
}
}
}
private boolean isHit()
//下落碰撞判断
{
for(int i = 0;i < 4;i++){
for(int j = 0;j < 4;j++){
if(sq.getState(i, j)&&(x + i == 19 || state[i + x + 1][j + y])){
return true;
}
}
}
return false;
}
private void fall()
//下落
{
x++;
}
private boolean isLeftHit()
//左移碰撞判断
{
if(y == 0){
return true;
}
for(int i = 0;i < 3;i++){
for(int j = 0;j < 3;j++){
if(sq.getState(i, j)&& state[x + i][y + j1][j];
}
}
sorce += 10;
speed = sorce / 100;
jl1.setText(String.valueOf(sorce));
jl2.setText(String.valueOf(speed));
sleepTime = 1000 /(speed + 2);
} catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
public void moveLeft()
//向左
{
if(!isLeftHit()){
state[x][y] = false;
y--;
}
}
private boolean isRightHit()
//右移碰撞判断
{
for(int i = 0;i < 3;i++){
for(int j = 0;j < 3;j++){
if(sq.getState(i, j)&&(y + j >= 9 || state[x + i][y + j + 1])){
return true;
}
}
}
return false;
}
public void moveRight()//向右
{
if(!isRightHit()){
state[x][y] = false;
y++;
}
}
public void rot()
//旋转
{
sq.rot();
}
public void down()
//加速向下
{
sleepTime = 20;}
}
package square;import javax.swing.*;import java.awt.*;public class Main extends javax.swing.JFrame { private static final long serialVersionUID = 1L;private JPanel sc[][];
private JPanel sc2[][];
private boolean state[][];
Controller t;
/** Creates new form Square */
public Main()
{
initComponents();
sc = new JPanel[20][10];
sc2 = new JPanel[4][4];
state = new boolean[25][15];
jPanel1.setLayout(new GridLayout(20, 10, 2, 2));
jPanel3.setLayout(new GridLayout(4, 4, 2, 2));
jPanel3.setSize(150, 150);
for(int i = 0;i < sc.length;i++){
for(int j = 0;j < sc[i].length;j++){
sc[i][j] = new JPanel();
// sc[i][j].setSize(20, 20);
sc[i][j].setBackground(Color.WHITE);
jPanel1.add(sc[i][j]);
}
}
for(int i = 0;i < sc2.length;i++){
for(int j = 0;j < sc2[i].length;j++){
sc2[i][j] = new JPanel();
// sc2[i][j].setSize(20, 20);
sc2[i][j].setBackground(Color.WHITE);
jPanel3.add(sc2[i][j]);
}
}
jLabel3.setText(“0”);
jLabel4.setText(“0”);
this.setSize(460, 650);
}
/** This method is called from within the constructor to
* initialize the form.* WARNING: Do NOT modify this code.The content of this method is
* always regenerated by the Form Editor.*/
private void initComponents(){
jPanel2 = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jLabel4 = new javax.swing.JLabel();
jButton1 = new javax.swing.JButton();
jPanel1 = new javax.swing.JPanel();
jButton2 = new javax.swing.JButton();
jButton3 = new javax.swing.JButton();
jMenuBar1 = new javax.swing.JMenuBar();
jMenu1 = new javax.swing.JMenu();
jMenuItem1 = new javax.swing.JMenuItem();
jMenu2 = new javax.swing.JMenu();
jMenuBar2 = new javax.swing.JMenuBar();
jMenu3 = new javax.swing.JMenu();
jMenuItem2 = new javax.swing.JMenuItem();
jMenu4 = new javax.swing.JMenu();
jPanel3 = new javax.swing.JPanel();
jButton4 = new javax.swing.JButton();
jMenuBar3 = new javax.swing.JMenuBar();
jMenu5 = new javax.swing.JMenu();
jMenuItem3 = new javax.swing.JMenuItem();
jMenu6 = new javax.swing.JMenu();
jButton5 = new javax.swing.JButton();
jMenuBar4 = new javax.swing.JMenuBar();
jMenu7 = new javax.swing.JMenu();
jMenuItem4 = new javax.swing.JMenuItem();
jMenu8 = new javax.swing.JMenu();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setMinimumSize(new java.awt.Dimension(400, 550));
jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder());
jLabel1.setText(“Score”);
jLabel2.setText(“Speed”);
jLabel3.setText(“jLabel3”);
jLabel4.setText(“jLabel4”);
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addComponent(jLabel1)
.addGap(18, 18, 18)
.addComponent(jLabel3))
.addGroup(jPanel2Layout.createSequentialGroup()
.addComponent(jLabel2)
.addGap(18, 18, 18)
.addComponent(jLabel4)))
.addContainerGap(35, Short.MAX_VALUE)));
jPanel2Layout.setVerticalGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(jLabel3))
.addGap(18, 18, 18)
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel2)
.addComponent(jLabel4))
.addContainerGap(84, Short.MAX_VALUE)));
jButton1.setText(“Start”);
jButton1.addActionListener(new java.awt.event.ActionListener(){
public void actionPerformed(java.awt.event.ActionEvent evt){
jButton1ActionPerformed(evt);
}
});
jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());
jPanel1.setMinimumSize(new java.awt.Dimension(300, 500));
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 291, Short.MAX_VALUE));
jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 504, Short.MAX_VALUE));
jButton2.setText(“L”);
jButton2.addActionListener(new java.awt.event.ActionListener(){
public void actionPerformed(java.awt.event.ActionEvent evt){
jButton2ActionPerformed(evt);
}
});
jButton3.setText(“R”);
jButton3.addActionListener(new java.awt.event.ActionListener(){
public void actionPerformed(java.awt.event.ActionEvent evt){
jButton3ActionPerformed(evt);
}
});
jMenu1.setText(“File”);
jMenuItem1.setText(“Start”);
jMenu1.add(jMenuItem1);
jMenuBar1.add(jMenu1);
jMenu2.setText(“Edit”);
jMenuBar1.add(jMenu2);
jMenu3.setText(“File”);
jMenuItem2.setText(“Start”);
jMenu3.add(jMenuItem2);
jMenuBar2.add(jMenu3);
jMenu4.setText(“Edit”);
jMenuBar2.add(jMenu4);
jPanel3.setBorder(javax.swing.BorderFactory.createEtchedBorder());
jPanel3.setMinimumSize(new java.awt.Dimension(120, 120));
jPanel3.setPreferredSize(new java.awt.Dimension(120, 120));
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
jPanel3.setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 135, Short.MAX_VALUE));
jPanel3Layout.setVerticalGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 116, Short.MAX_VALUE));
jButton4.setText(“Rot”);
jButton4.addActionListener(new java.awt.event.ActionListener(){
public void actionPerformed(java.awt.event.ActionEvent evt){
jButton4ActionPerformed(evt);
}
});
jMenu5.setText(“File”);
jMenuItem3.setText(“Start”);
jMenu5.add(jMenuItem3);
jMenuBar3.add(jMenu5);
jMenu6.setText(“Edit”);
jMenuBar3.add(jMenu6);
jButton5.setText(“D”);
jButton5.addActionListener(new java.awt.event.ActionListener(){
public void actionPerformed(java.awt.event.ActionEvent evt){
jButton5ActionPerformed(evt);
}
});
jMenu7.setText(“File”);
jMenu7.addActionListener(new java.awt.event.ActionListener(){
public void actionPerformed(java.awt.event.ActionEvent evt){
jMenu7ActionPerformed(evt);
}
});
jMenuItem4.setText(“Start”);
jMenu7.add(jMenuItem4);
jMenuBar4.add(jMenu7);
jMenu8.setText(“Edit”);
jMenuBar4.add(jMenu8);
setJMenuBar(jMenuBar4);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(jPanel1,javax.swing.GroupLayout.PREFERRED_SIZE,295, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel2,javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jPanel3, Short.MAX_VALUE)
.addComponent(jButton4,javax.swing.GroupLayout.DEFAULT_SIZE, 139,javax.swing.GroupLayout.PREFERRED_SIZE, 132, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addComponent(jButton2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jButton5)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jButton3)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, Short.MAX_VALUE)))
.addContainerGap()));
layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jPanel2,javax.swing.GroupLayout.PREFERRED_SIZE,10,javax.swing.GroupLayout.Alignment.LEADING,javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jPanel3,javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(44, 44, 44)
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
javax.swing.GroupLayout.PREFERRED_SIZE,33,.addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jButton5, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jButton4, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(63, Short.MAX_VALUE))
.addComponent(jPanel1,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE,38, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE));
pack();
}
//
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt){
// TODO add your handling code here:
t = new Controller(0, 0, sc, state, 0, 0, jLabel3, jLabel4, jPanel3, sc2);
t.init();
t.start();}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt){
// TODO add your handling code here:
t.moveLeft();}
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt){
// TODO add your handling code here:
t.moveRight();}
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt){
// TODO add your handling code here:
t.rot();}
private void jButton5ActionPerformed(java.awt.event.ActionEvent evt){
// TODO add your handling code here:
t.down();
}
private void jMenu7ActionPerformed(java.awt.event.ActionEvent evt){
// TODO add your handling code here:
t.init();}
/**
* @param args the command line arguments
*/
public static void main(String args[]){
java.awt.EventQueue.invokeLater(new Runnable(){
public void run(){
new Main().setVisible(true);
}
});
}
// Variables declaration-do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JButton jButton3;
private javax.swing.JButton jButton4;
private javax.swing.JButton jButton5;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JMenu jMenu1;
private javax.swing.JMenu jMenu2;
private javax.swing.JMenu jMenu3;
private javax.swing.JMenu jMenu4;
private javax.swing.JMenu jMenu5;
private javax.swing.JMenu jMenu6;
private javax.swing.JMenu jMenu7;
private javax.swing.JMenu jMenu8;
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JMenuBar jMenuBar2;
private javax.swing.JMenuBar jMenuBar3;
private javax.swing.JMenuBar jMenuBar4;
private javax.swing.JMenuItem jMenuItem1;
private javax.swing.JMenuItem jMenuItem2;
private javax.swing.JMenuItem jMenuItem3;
private javax.swing.JMenuItem jMenuItem4;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
// End of variables declaration
}
package square;public class Square {
boolean[][][] state;
int condition;
//定义多种情况
public Square(int kind)
//
定义多种类型
{
state = new boolean[4][4][4];
condition = 0;
switch(kind){
case 1:
//方形
每个case之后应该有个break;否则在满足条件之后会继续向后进行会跳出
state[0][0][0] = true;
state[0][0][1] = true;
state[0][1][0] = true;
state[0][1][1] = true;
state[1][0][0] = true;
state[1][0][1] = true;
state[1][1][0] = true;
state[1][1][1] = true;
state[2][0][0] = true;
state[2][0][1] = true;
state[2][1][0] = true;
state[2][1][1] = true;
state[3][0][0] = true;
state[3][0][1] = true;
state[3][1][0] = true;
state[3][1][1] = true;
break;
case 2:
//I型
state[0][0][0] = true;
state[0][1][0] = true;
state[0][2][0] = true;
state[0][3][0] = true;
state[1][0][0] = true;
state[1][0][1] = true;
state[1][0][2] = true;
state[1][0][3] = true;
state[2][0][0] = true;
state[2][1][0] = true;
state[2][2][0] = true;
state[2][3][0] = true;
state[3][0][0] = true;
state[3][0][1] = true;
state[3][0][2] = true;
state[3][0][3] = true;
break;
case 3:
//L型
state[0][0][0] = true;
state[0][1][0] = true;
state[0][2][0] = true;
state[0][2][1] = true;
state[1][0][2] = true;
state[1][1][0] = true;
state[1][1][1] = true;
state[1][1][2] = true;
state[2][0][0] = true;
state[2][0][1] = true;
state[2][1][1] = true;
state[2][2][1] = true;
state[3][0][0] = true;
state[3][0][1] = true;
state[3][0][2] = true;
state[3][1][0] = true;
break;
case 4:
//T型
state[0][0][0] = true;
state[0][0][1] = true;
state[0][0][2] = true;
state[0][1][1] = true;
state[1][0][1] = true;
state[1][1][0] = true;
state[1][1][1] = true;
state[1][2][1] = true;
state[2][0][1] = true;
state[2][1][0] = true;
state[2][1][1] = true;
state[2][1][2] = true;
state[3][0][0] = true;
state[3][1][0] = true;
state[3][1][1] = true;
state[3][2][0] = true;
break;
}
}
public boolean getState(int i, int j)//获得是否为声明的i,j变量的值
{
return state[condition][i][j];
}
public void rot(){
condition =(condition + 1)% 4;
} }