1、1本科毕业论文(设计)题 目: 基 于 单 片 机 的 推 箱 子 游 戏 设 计 学生姓名: 学号: P30914093 院(系): 电子信息工程 专业: 微电子 入学时间: 2009 年 9 月导师姓名: 职称/学位: 讲师 导师所在单位: 安徽大学 完成时间: 2013 年 5 月2基于 PROTEUS 的推箱子游戏的设计摘 要本论文主要介绍了基于单片机的推箱子游戏的规则、硬件结构、软件代码的编写及工作原理、基于 T6963C 内核的液晶模块 PG160128A 的详细介绍以及指令集。模拟出 Windows系统下的推箱子游戏,具有任意关数选择、难度依次加大、游戏步数记录、游戏时间记录、按
2、键发声、系统低功耗、可实现在线调试等特点。本系统是以单片机为其控制核心,以有源晶振构成的电路作为时钟信号,通过方向键的选择向单片机控制系统发出人物移动控制命令,控制系统接收命令后做出一系列必要的判断后,控制人物及箱子的移动。本设计已通过了实验仿真,运行稳定,基本上没有规则方面的错误。论文主要分为两大块:一块为游戏的硬件电路组成部分,一块为软件程序设计部分。在硬件电路里主要包括有源晶振部分、方向控制部分及液晶显示部分等与单片机的接线设计;软件编程方面主要是子程序和主程序的编写,包括:初始化代码、液晶驱动代码、方向按键代码、过关判断代码、步数记录代码、时间记录代码、按键发声代码、关数选择代码及表格
3、数据代码等等。所有这些在文中都有详细说明。关键词:单片机;推箱子;PG160128A; T6963C 内核;指令集3Design Of PROTEUS Sokoban Game Based On1AbstractThis paper introduces the single-chip based on the rules of the game Sokoban, the structure of hardware, software code writing and working principle, based on the core T6963C LCD module PG160128
4、A, as well as details of the instruction set. Simulate the system under Windows Sokoban game, an arbitrary number of related options, in turn increase the difficulty of the game a few step-by-step record time of the game record, sound button, low-power system can achieve on-line debugging and so on.
5、 The system is based on its single-chip control of the core, consisting of active crystal clock circuit clock signal sent through the arrow keys to select the single-chip control system to control mobile command characters, the control system after receiving an order to make a Series to determine th
6、e necessary, to control the movement of people and boxes. This design has been adopted by the simulation experiments, stable, rules virtually no mistakes. The main thesis is divided into two blocks: one for the games hardware components of the circuit, as a part of the software programming. In the h
7、ardware circuitry, including the main active part of the crystal, the direction and control of some of the liquid crystal display and other parts of the single-chip wiring design; software programming side of the main subroutine is the main program and the preparation, including: initialization code
8、, LCD Driver code, the direction of key code, customs code to determine, step-by-step record of the number of code, record time code, voice button code, customs code and select a number of forms of data code and so on. All of these are in the text in detail.Key words:MCU; Sokoban; PG160128A; T6963C
9、core; instruction set4目录1 推箱子游戏编译介绍 72 推箱子游戏的硬件部分设计 72.1 PG160128A 液晶屏介绍 .72.2 T6963C 及其指令集介绍 92.2.1 T6963C92.3 晶振、复位电路 .102.3.1 晶振电路 102.3.2 复位电路 112.4 液晶显示屏与单片机接口电路 .113 推箱子游戏的软件部分设计 133.1 液晶屏驱动代码设计 .153.1.1 读状态程序 153.1.2 是否可读写程序 153.1.3 是否可自动读写程序 163.1.4 写单参数程序 .163.1.5 写双参数程序 .163.1.6 写指令程序 .173
10、.1.7 写 8 字节数据程序 .173.1.8 设置数据显示在屏幕上的坐标程序 .173.1.9 设置数据存储起始地址 .173.1.10 CGRAM 偏置地址设置函数 .183.1.11 液晶初始化函数 .183.1.12 显示一个汉字子程序 .183.1.13 清屏程序 183.1.14 自定义字符写入 CGROM 函数 .193.1.15 设置点显示在屏幕上的坐标(以位为单位) .193.1.16 画圆子程序,其中 x0,y0 表示圆心,R 表示半径 .193.2 初始化代码设计 .203.3 游戏时间代码设计 .203.4 游戏选关代码设计 .203.5 步数、关数更新代码设计 .2
11、13.5.1 步数更新代码设计 213.5.2 关数更新代码设计 213.6 过关代码设计 .213.7 图形显示子程序 223.7.1 地图显示子程序 2253.7.2 原来位置显示子程序 .223.8 中断代码设计 .233.8.1 定时器 0 中断发声程序 233.8.2 定时器 1 中断计时程序 233.9 方向控制代码设计 .234 推箱子游戏的系统仿真 254.1 建立工程项目流程 254.2 Proteus 中原理图的绘制及文件的加载 .294.3 开机界面显示 .314.4 游戏界面显示 .314.5 仿真结果分析及解决方法 .335 总结 34参考文献 34致谢 3561 推
12、箱子游戏编译介绍现如今,游戏风靡全球,各种游戏层出不穷,大到网络型的复杂游戏,小到手机游戏、单机游戏、智力游戏等简单游戏。但是这种简单也是相对于网络游戏等大型游戏而言的,小游戏本身的代码还是相当繁杂,它要执行一系列指令才能正确的完成一个简单的操作,才能按照玩家的意志工作。所以我们现在见到的游戏多是在基于电脑这种高速执行指令的平台上运行的,脱离了它就什么事都做不了了。那么推箱子这种小游戏能否在单片机上编出来呢?答案是肯定的。首先,这个游戏是一个小型游戏,实现的功能比较简单,不像大型游戏那样功能复杂,它只要控制人物将所有箱子推到正确的位置即可,难度随着箱子的增多而加大,对于实现这样一个功能,程序不
13、是太复杂,用一块单片机足以达到目的。其次,它的控件也比较少只有 4 个方向键和 2 个辅助的功能键,这些控键在 Proteus 中用弹跳式按键代替即可。第三,游戏地图相对比较小、画面简单,只有箱子、人物和正确位置箱子等几个图形,这些在一块稍大的液晶屏上就足以显示,用不着电脑显示屏。第四,就编程语言方面来说,编写这样一个简单的小游戏不需要什么高级的语言,C 语言或汇编语言就足以完成,C语言是一种通用型的语言,编程灵活、可读性强、移植性好;汇编语言是一种直接面向硬件的基础语言,最接近机器语言,执行速度快(本游戏采用 C 语言编写)。所以,单片机上运行推箱子游戏在硬件和软件两个方面都是可行的。 2
14、推箱子游戏的硬件部分设计本部分内容包括介绍 PG160128A 及其引脚功能;介绍 T6963C 指令集;晶振电路、复位电路的硬件设计;控件及按键发声电路设计,最后给出游戏仿真的整体硬件电路图,接下来是具体的说明。2.1 PG160128A 液晶屏介绍 2PG160128A 为一个 128 行 160 列的点阵液晶屏,他能显示各种字符、图形、汉字,基于 T6963C 内核控制,自带字符库,同时用户也可以自己建立汉字、图形库,其在 Proteus 中的元器件图形如下: 7图 1 PG160128 各引脚的功能描叙如下表: 引脚序列引脚名称 引脚功能描述1 FG 信号设计引脚,此引脚为一个输出引脚
15、,在电路连接时悬空2 VDD 电源引脚,外接 5V 工作电压3 VSS 地引脚,接地4 CON 功能不详,在电路连接时悬空5 WR 写信号脚,当引脚为低电平时数据写入 T6963C 中6 RD 读信号脚,当引脚为低电平时数据从 T6963C 中读出7 CE 使能信号脚,正常工作时此脚接地,当为高电平时 CPU 不能与T6963C 通信8 C/D 指令、数据信号脚:当引脚为高电平且 WR = L 时可以写入指令;当引脚为高电平且 RD = L 时可以读 T6963C 状态;当引脚为低电平且WR = L 时可以写入数据;当引脚为低电平且 RD = L 时可以读出数据1118 D0D7 数据引脚,用
16、于液晶屏与单片机之间的数据通信10 RST 复位引脚,低电平有效,起复位作用,器件内部集成了上拉电阻,正常工作时此引脚接电源19 FS1 字形选择引脚 FS1,用于选择字形,当为高电平时是 5*8 点阵字体,8表一 PG160128 引脚功能表2.2 T6963C 及其指令集介绍2.2.1 T6963C3T6963C 是一个 LCD 控制器,可设计为用于液晶显示器控制驱动芯片和数据显示的存取器。该控制器有一个 8 位并行数据总线,控制线的读取或写入通过微控制器接口实现,可以直接连接到 TMPZ80 微处理器中。它有一个 128 字节的字符发生器也可以控制外部显示 RAM 中的数据,达 64K
17、字节。配置的文字,图形和外部字符发生器 RAM 数据能很容易控制其显示在窗口中,可以自由移动、分配内存范围。该器件支持非常广泛的字符格式,液晶显示器允许通过编程设置选择不同的组合。它可以用于文字,图形和结合文本模式及其他各种属性的功能。2.2.2 T6963C 指令集 4T6963C 共分为十大类,26 条指令,详细信息如下表:指令类型有无参数D7D0 引脚值 指令说明0 0 1 0 0 0 0 1光标指针设置 D1 水平位置(低 7 位有效) D2 垂直位置(低 5 位有效)0 0 1 0 0 0 1 0CGRAM 偏置地址设置 D1 地址 (低 5位有效) D2=00H指针设置D1/D20
18、 0 1 0 0 1 0 0 地址指针位;D1 低字节;D2 高字节0 1 0 0 0 0 0 0 文本区首址;D1 低字节;D2 高字节0 1 0 0 0 0 0 1文本区宽度字节数 D1=字节数 D2=00H0 1 0 0 0 0 1 1 图形区首址 D1 低字节 D2 高字节显示区域设置D1/D20 1 0 0 0 0 1 1图形区宽度(字节数)D1=字节数 D2=00H1 0 0 0 0 0 0 0 逻辑“或”合成显示方式设置无1 0 0 0 0 0 0 1 逻辑“异或”合成当为低电平时是 8*8 点阵字体91 0 0 0 0 0 1 1 逻辑“与”合成1 0 0 0 0 1 0 0
19、文本特征显示开关无 1 0 0 1N3N2N1N090H 显示开关;N0=1/0 光标闪烁启用 /禁用 N1=1/0 光标显示启用/禁用 ;N2=1/0 文本显示启用/禁用;N3=1/0 图形显示启用/禁用光标形状选择无 1 0 1 0 0N2N1N00xA0-0xA7 表示光标占的行数屏读 无 1 1 1 0 0 0 0 0 屏读1 1 0 0 0 0 0 0 数据写,地址加 11 1 0 0 0 0 0 1 数据读,地址加 11 1 0 0 0 0 1 0 数据写,地址减 11 1 0 0 0 0 1 1 数据读,地址减 11 1 0 0 0 1 0 0 数据写,地址不变数据一次读、写方式
20、设置D1 1 1 0 0 0 1 0 1 数据读,地址不变1 0 1 1 0 0 0 0 自动写设置1 0 1 1 0 0 0 1 自动读设置1 0 1 1 0 0 1 0 自动写结束数据自动读、写方式设置无1 0 1 1 0 0 1 1 自动读结束屏拷贝 无 1 1 1 0 1 0 0 0 屏拷贝位操作 无 1 1 1 1N3N2N1N0N3=1 置 1 N3=0 清表二 T6963C 指令集102.3 晶振、复位电路2.3.1 晶振电路单片机的晶振电路如图 2 所示,其中 XTAL1 和 XTAL2 分别为片内振荡电路的输入输出端。一般电容取 2047uF,本系统晶体的振荡频率为 24MH
21、z。晶振电路产生的振荡脉冲经过内部触发器进行二分频后,成为单片机的时钟脉冲信号,为单片机提供一个基本时钟信号。XTAL1XTAL2X1CRYSTALC130pFC230pF图 2 晶振电路2.3.2 复位电路复位操作是单片机的基本操作,单片机在进入运行前和在运行过程中程序出错或操作失误使系统不能正常运行时,需要进行复位操作,复位操作后,程序将从 0000H 开始重新执行。复位信号从单片机的 RST 引脚输入,复位操作有上电自动复位、按键电平复位和外部脉冲复位三种方式,本电路采用了按键电平复位,电路图如图 3.。EARSTCE7RD6C/D8VSS2VDD3CON4WR5D011FS119FG1
22、D112D213D314D415D516D617D718RST10LCD1PG160128AR11kR21kC3220uF图 3 复位电路112.4 液晶显示屏与单片机接口电路液晶显示屏共有 18 个引脚,其中 VDD、RST 两脚接电源,VSS、FS1、CE三脚接地,CON、FG 两脚悬空,D0D7 分别与单片机 P2.0P2.7 相连接,WR 与P1.7 脚相连,RD 与 P1.6 脚相连,C/D 与 P1.5 脚相连,电路图见图 4.2.5 控键、喇叭与单片机接口电路本游戏共有 6 个控件,分别是:四个方向键,用于控制箱子的移动方向;一个确定键,用于刷新初始化界面进入游戏界面;一个选关键
23、,用于选关。一个喇叭,用于按键发声,以提示按键是否有效,电路图见图 4.控件、喇叭与单片机的接线是:上移键接 P1.0;左移键接 P1.1;右移键接 P1.2;下移键接 P1.3;确定键接 P1.4;选关键接 P1.5;喇叭经过分压式偏置共射放大电路将信号放大再与单片机 P3.1 口相连,如图 4:P3.1 Q12N40C12uFR151kR220k R32.7k C220uFR45k C32uF LS1SPEAKER图 4 扬声器放大电路至此,游戏的硬件电路结构及连线全部介绍完成,仿真电路图如图 5 所示,整个电路图以网络标号的形式给出,避免连线过多显得电路拥挤。12GRWRDCDPD0D1
24、D2D3D4D5D6D7GP3P0GP4GP1 P2P GD0D1D2D3D4D5D6D7P0P1P2P3P4CDRDRWG P5P5GSPXTAL1XTAL2EARSTRSTEAXTAL2XTAL1GSPCE7RD6 C/D8VS2VD3CON4WR5 D01 FS119FG1 D12D213D314D415D516D617D718RST10LCD1PG160128A上下左 右确 定XTAL218XTAL119ALE30 EA31 PSEN29RST9P0.0/AD0 39P0.1/AD1 38P0.2/AD2 37P0.3/AD3 36P0.4/AD4 35P0.5/AD5 34P0.6/
25、AD6 3P0.7/AD7 32P2.7/A15 28P2.0/A8 21P2.1/A9 2P2.2/A10 23P2.3/A1 24P2.4/A12 25P2.5/A13 26P2.6/A14 27P1.01 P1.12 P1.23P1.34 P1.45 P1.56P1.67 P1.78P3.0/RXD10P3.1/TXD1P3.2/INT0 12P3.3/INT1 13P3.4/T0 14P3.7/RD17P3.6/WR16P3.5/T1 15U280C51选 关LS1SOUNDERX1CRYSTALC130pFC230pF R11kR21kC320uF复 位图 5 推箱子游戏硬件电路图3
26、 推箱子游戏的软件部分设计本部分主要介绍游戏的软件部分设计,包括液晶屏驱动代码设计;初始化代码设计游戏时间代码设计;游戏关数代码设计;游戏步数代码设计;过关代码设计;方向控制代码设计;按键发声代码设计;数据表格设计等几个方面,现就对这几个方面做具体分析。3.1 液晶屏驱动代码设计 53.1.1 读状态程序unsigned char Read_State()/返回液晶显示屏的当前状态unsigned char a;P2=0xff;/读状态之前先将数据线拉高_CD=1;/ 为指令、状态操作条件13_RD=0;/读操作条件_RD=1;/为下次读做准备a=Pin;/将状态保存return a;3.1.
27、2 是否可读写程序void Enable()while(1) /bit0 指令写状态位,bit1 数据读/写状态位,为 1 时候空闲if(Read_State()/如果状态的低 2 为 1 则可读写3.1.3 是否可自动读写程序void Aut_Write()while(1) /bit3 数据自动写状态位,为 1 时候空闲if(Read_State() /如果状态的第 4 为 1 则可自动读写3.1.4 写单参数程序/Data1 为传入的参数,Com 为传入的指令;写入顺序为先数据后写指令。void Write_Data1(unsigned char Data1,unsigned char C
28、om)Enable();/判断是否可读写_CD=0;/为数据操作条件Pin=Data1;/将数据送数据线_WR=0;/写操作_WR=1;/为下次写做装备Enable();_CD=1; / 为指令、状态操作条件Pin=Com; /将指令送数据线_WR=0;_WR=1;3.1.5 写双参数程序/ Data1/Data2 为传入的参数,Com 为传入的指令,先 Data1 后 Data2,最后写指令。void Write_Data2(unsigned char Data1,unsigned char Data2,unsigned 14char Com)Enable();/判断是否可读写_CD=0;
29、/为数据操作条件Pin=Data1; /将数据 1 送数据线_WR=0; /写操作_WR=1; /为下次写做装备Enable();_CD=0;Pin=Data2; /将数据 2 送数据线_WR=0;_WR=1;Enable();_CD=1;Pin=Com; /将指令送数据线_WR=0;_WR=1;3.1.6 写指令程序void Write_Com(unsigned char Com)Enable();/判断是否可读写_CD=1; / 为指令、状态操作条件Pin=Com; /将指令送数据线_WR=0;/写操作_WR=1;/为下次写做装备3.1.7 写 8 字节数据程序/ Addr 表示数据首地址
30、,Way 表示写的方式void Write_8_Data(unsigned char Addr,unsigned char Way)Aut_Write();/判断是否能自动写Write_Com(AUT_WR);/自动写开始Write_Data1(Addr,Way);Write_Com(AUT_WO);/自动写结束153.1.8 设置数据显示在屏幕上的坐标程序/ (以字节为单位),x 表示显示的行(015),y 表示显示的列(019)void Set_xy(unsigned char x,unsigned char y)unsigned int a;a=x*20+y;Write_Data2(a3
31、.1.9 设置数据存储起始地址void Set_Addr(unsigned char Addr1,unsigned char Addr2)Write_Data2(Addr1,Addr2,ADR_POS);3.1.10 CGRAM 偏置地址设置函数void Set_CGRAM()Write_Data2(1,0,CGR_POS);3.1.11 液晶初始化函数/(文本区首地址 D1,文本区首地址 D2, 文本区宽度, 图形区首地址 D1, /图形区首地址 D2, 图形区宽度, 光标形状, 显示方式, 显示开关)void LCD_Init(unsigned char Txt1,unsigned cha
32、r Txt2,unsigned char Txt_Wide,unsigned char Map1,unsigned char Map2,unsigned char Map_Wide,unsigned char Guang_Biao,unsigned char Disp_Mode,unsigned char Kai_Guan)Write_Data2(Txt1,Txt2,TXT_STP);Write_Data2(Txt_Wide,0,TXT_WID);Write_Data2(Map1,Map2,GRH_STP);Write_Data2(Map_Wide,0,GRH_WID);Write_Com(C
33、UR_SHP|Guang_Biao);Write_Com(Disp_Mode);Write_Com(DIS_SW|Kai_Guan);3.1.12 显示一个汉字子程序/x 表示显示的行(015),y 表示显示的列(019),n 表示字在表格中的位置16void Han_Zi(unsigned char x,unsigned char y,unsigned char Addr)Set_xy(x,y);Write_8_Data(Addr,INC_WR);Write_8_Data(Addr+2,INC_WR);Set_xy(x+1,y);Write_8_Data(Addr+1,INC_WR);Wri
34、te_8_Data(Addr+3,INC_WR);3.1.13 清屏程序void Clear_LCD()unsigned int a;Set_xy(0,0);/从最左上角开始for(a=0;a8,0x24); /设置写地址Write_Com(point);173.1.16 画圆子程序,其中 x0,y0 表示圆心,R 表示半径/先打第一象限内的 1/4 段圆弧,再依据对称原理打出其他 3 段圆弧void Circle(unsigned char x0,unsigned char y0,unsigned R,bit n)unsigned char i,j=0;Point(x0,y0,n);for(
35、i=0;i=R;i+) while(1) if(R*R-i*i=j*j)break; j+;Point(x0-j,y0+i,n);Point(x0-i,y0+j,n); /第一象限打点Point(x0+j,y0+i,n);Point(x0+i,y0+j,n); /第二象限打点Point(x0+j,y0-i,n);Point(x0+i,y0-j,n); /第三象限打点Point(x0-j,y0-i,n);Point(x0-i,y0-j,n); /第四象限打点j=0; 3.2 初始化代码设计 6/初始化代码里包含定时器 0、1 的相关参数设置,初始化开机界面显示等。EA=ET0=ET1=1;/开启
36、中断总开关,允许外部中断 0、1 中断TMOD=0x11;/将定时器 0、1 都设为定时模式且工作在方式一。TH0=64800/256;/定时器 0 初始值装载,用于按键发声TL0=64800%256;TH1=0x3c;/ 定时器 1 初始值装载,每 25ms 中断一次TL1=0xb0;Init_disply();/调用开机界面显示子函数,包含了开机界面的所有内容3.3 游戏时间代码设计if(F) /当程序检测到读时间标志位 F=1(由定时器 1 控制)时会刷新一次时间。F=0;/为下一次做准备Set_xy(13,17);/设置百位数字显示的位置Write_8_Data(0x10+Time/1
37、00,0xc4);/得到时间的百位数据Set_xy(13,18); /设置十位数字显示的位置Write_8_Data(0x10+Time%100/10,0xc4);/得到时间的十为数据Set_xy(13,19); /设置个位数字显示的位置18Write_8_Data(0x10+Time%10,0xc4);/得到时间的个位数据3.4 游戏选关代码设计/当按下选关按键后,主程序调用选关函数,程序代码如下:void Choice_Customs()Time=Steps=0;/选关时将时间、步数归零New_Step();/更新步数显示Custom=Cust;/将选得的关传给关数寄存器New_Custo
38、m();/更新关数显示Dispaly();/更新地图显示Cust+;/没按下一次键键关数加一if(Cust=18)Cust=1;/如果关数等于 18 则回到第一关(游戏总共 17 关)3.5 步数、关数更新代码设计 73.5.1 步数更新代码设计/当按下任意一个方向键,且箱子能移动时,会调用游戏步数更新子程序void New_Step()Set_xy(7,17); /设置百位数字显示的位置Write_8_Data(0x10+Steps/100,0xc4); /得到步数的百位数据Set_xy(7,18); /设置十位数字显示的位置Write_8_Data(0x10+Steps%100/10,0x
39、c4); /得到步数的十位数据Set_xy(7,19); /设置个位数字显示的位置Write_8_Data(0x10+Steps%10,0xc4); /得到步数的个位数据3.5.2 关数更新代码设计void New_Custom()Set_xy(1,18);/ 设置十位数字显示的位置Write_8_Data(0x10+Custom/10,0xc4);/ 得到关数的十位数据Set_xy(1,19);/ 设置个位数字显示的位置Write_8_Data(0x10+Custom%10,0xc4);/ 得到关数的个位数据3.6 过关代码设计/当所有箱子都推到指定位置时,会调用过关子程序,代码如下:19v
40、oid Pass()unsigned char i,j,a=1;/内存空间分配for(i=0;i8;i+)/扫描 8 行if(!a)break;/如果 a=0 则直接跳出函数for(j=0;j9;j+) /扫描 9 列 /如果关卡数组表格中此位置是叉图形或箱子和叉重合后的图 if(CustomsCustom-1ij=5|CustomsCustom-1ij=4)/如果动作跟踪数组里此位置是箱子和叉重合后的图,则将 a 置 1if(Follow_Actionij=5)a=1;/如果动作跟踪数组里此位置不是箱子和叉重合后的图,则将 a 置 0,并退出else a=0;break;if(a)Custo
41、m+;/如果 a=1 则将关数加一(因为所有箱子都已推好,可以过关)Steps=Time=0;/过关时将时间、步数归零New_Step();/更新步数显示if(Custom=18)Custom=1;/如果关数等于 18 则回到第一关(游戏总共 17 关)New_Custom();/更新关数显示Dispaly();/更新地图显示3.7 图形显示子程序图形显示子程序包括地图显示程序和原来位置显示子程序两个3.7.1 地图显示子程序/在调用过关函数或选关函数时,会调用到显示子函数,功能是刷新地图void Dispaly()unsigned char i,j,a;for(i=0;i8;i+)/扫描 8
42、 行for(j=0;j9;j+)/扫描 9 列Follow_Actionij=CustomsCustom-1ij;将关卡数组中的数据传给跟踪数组 a=Follow_Actionij;/将跟踪数组中的数据传给动态内存switch(a)/根据内存中的数据做出判断case 0:a=0x80;break;/如果是 0(空白)则将空白字模的地址 80H 传给内存/如果是 1(人物)则将人物字模的地址 94H 传给内存,并记录人物位置所在坐标case 1:a=0x94;x_Coordinate=i;y_Coordinate=j;break;20case 2:a=0x84;break;/ 如果是 2(墙壁)
43、则将墙壁字模的地址 84H 传给内存case 3:a=0x8c;break;/ 如果是 3(箱子)则将箱子字模的地址 8cH 传给内存case 4:a=0x88;break;/ 如果是 4(叉)则将叉字模的地址 88H 传给内存case 5:a=0x90;break;/如果是 5(箱子和叉重合)则将地址 90H 传给内存Han_Zi(2*i,2*j,a);/调用写汉字程序,将图形显示出来3.7.2 原来位置显示子程序/此程序显示当人物移动后,人物本身位置所要显示的图形void _Display()if(a=0|a=3|a=1) /如果原来人物这个位置是空白或是箱子则显示一个空白Han_Zi(2
44、*x_Coordinate,2*y_Coordinate,0x80);/ 将空白图形显示出来Follow_Actionx_Coordinatey_Coordinate=0;/更新跟踪数组中的内容/如果人物本身这里是一个叉图形或是箱子或叉重合后的图则显示一个叉if(a=4|a=5)Han_Zi(2*x_Coordinate,2*y_Coordinate,0x88);/ 将叉图形显示出来Follow_Actionx_Coordinatey_Coordinate=4;/ 更新跟踪数组中的内容3.8 中断代码设计中断代码设计包括定时器 0 和 1 两段,定时器 0 为中断发声代码,定时器1 为中断计时
45、代码,代码如下:3.8.1 定时器 0 中断发声程序void Time_0_Int() interrupt 1 using 0TH0=64800/256;TL0=64800%256;/定时器 0 初值设定Count+;/每次进入中断,发声计数数据加 1if(Count=150)TR0=Count=0;/发声 100ms 后 Count 中数据归零,并关定时器Speaker=Speaker;/喇叭引脚电平取反3.8.2 定时器 1 中断计时程序void Time_1_Int() interrupt 3 using 1TH1=0x3c;TL1=0xb0;/ 定时器 1 初值设定Counts+;/每
46、次进入中断,计时计数数据加 121if(Counts=40)/如果 1 秒中到Counts=0;Time+;F=1;/ Counts 数据归零,时间全局量加 1,读时间标志置 13.9 方向控制代码设计 8游戏共有 4 个方向键,每一个键代码编写的原理,判断顺序及执行何种操作都是一样的,不同的是方向各不相同,现已向上推箱子为例详细说明其执行过程。void On_Push()/向上推子函数Cust=1;/关数计数器置一,为选关做准备a=CustomsCustom-1x_Coordinatey_Coordinate;/原来人物这个位置是什么b=Follow_Actionx_Coordinate-1
47、y_Coordinate; /现在人物位置上面是什么 if(b=0|b=4)/如果现在人物位置上面是空白或是叉图形则显示一个人物Steps+;/箱子可以移动,步数加 1New_Step();/更新步数Han_Zi(2*(x_Coordinate-1),2*y_Coordinate,0x94);/在上面显示人物_Display();/调用原来位置显示子程序,还原人物本身位置图形x_Coordinate-;/更新人物坐标if(b=3|b=5)/如果现在人物位置上面是箱子或是箱子和叉重合的图形则还得判/断人物上面的上面是什么图形,如果人物上面的上面不是箱子、墙壁和箱子和叉/重合后的图形则可以移动if(Follow_Actionx_Coordinate-2y_Coordinate!=2/箱子可以移动,步数加 1New_Step();/更新步数/如果现在人物位置上面的上面是空白if(Follow_Actionx_Coordinate-2y_Coordinate=0)Han_Zi(2*(x_Coordinate-2),2*y_Coordinate,0x8c);/则在上面的上面显示个箱子Follow_Actionx_Coordinate-2y_Coordinate=3;/更新箱子的位置22/如果现在人物位置上面的上面是