课设报告
题目:飞机大战
班级:
姓名:
学号:
指导老师:
日期:年月日
目录
1摘要 (3)
2.1 功能需求 (3)
2.2 设计要求 (3)
3 硬件设计及描述 (4)
3.1 总体描述 (4)
3.2 系统总体框图 (4)
3.3 各部分硬件介绍 (4)
3.31输入模块 (4)
3.32输入模块 (5)
4 软件设计流程及描述 (6)
4.1 程序流程图 (6)
4.2 主要函数模块及功能 (7)
4.2.1控制飞机模块 (7)
4.2.2 碰撞检测模块 (8)
5 功能实现 (10)
液晶显示 (10)
6 心得体会 (12)
1摘要
三星公司推出的16/32 位RISC 处理器S3C44B0X 为手持设备和一般类型的提供了一种高性能低成本的解决方案。为了降低整个系统的成本,S3C44B0X 内部集成了丰富的片内外设,包括:8K 的cache,可选的片内SRAM,LCD 控制器,带有握手信号的双同道UART,4 同道DMA,系统管理器(片选逻辑,FP/EDO/SDRAM 控制器),带有PWM 功能的5 通道定时器,I/O 端口,RTC 实时时钟,8 通道10 位ADC,IIC、IIS 总线接口,同步SIO 接口以及用于时钟管理的PLL 锁相环。
S3C44B0X 极低的功耗以及简单,只能的全静态设计使其非常适合对成本和功耗敏感的项目。同时S3C44B0X 还采用了一种新的总线结构,即 SAMBAII(三星 ARM CPU 嵌入式微处理器总线结构)S3C44B0X 通过集成全面、通用的片内外设,大大减少了系统电路中除处理器外的器件需求,从而最小化系统成本。
2.1 功能需求
1.以动漫的形式显示开机界面和加载游戏进入。
2.以位图的方式显示不同飞机的图像,开机界面。
3.使用碰撞检测机制,实现飞机与飞机,飞机与子弹的检测。
4.实现按键的控制,对子弹的发送和飞机的上下左右的自由控制。
5.敌机的随机出现,并实现无限架敌机,且游戏主界面需每次出现三架飞
机,供我机击落。
6.对击落的敌机实现计数,随着敌机击落的不同数量设置不同的难度级别。
7.飞机实现三次的生命值,即有三次机会。
2.2 设计要求
1.界面流畅,操控飞机灵活。
2.碰撞检测的算法设计
3 硬件设计及描述
3.1 总体描述
在实验开发板上,根据功能需求,设定了控制模块由ARM7为控制核心,具有在线编程功能,低功耗,输入模块由按键和触屏控制,通过触屏实现游戏的加载,通过按键实现飞机的上下移动,避开与敌机的相撞,子弹的发射可以将敌机击毁。
3.2 系统总体框图
按键模块
信号输入
ARM7
信号输出
液晶显示
3.3 各部分硬件介绍
3.31输入模块
矩阵式键盘适用于按键数量较多的场合,它由行线和列线组成,按键位于行、列的交叉点上。如图6—7所示,一个3 X 3的行、列结构可以构成一个有9个按键的键盘。同理一个4 X 4的行、列结构可以构成一个含有16个按键的键盘等等。很明显,在按键数量较多的场合,矩阵键盘与独立式按键键盘相比,要节省很多的I/O口。
按键设置在行、列线交点上,行、列线分别连接到按键开关的两端。行线通过上拉电阻接到VCC上。平时无按键动作时,行线处于高电平状态,而当有按键按下时,行线电平状态将由与此行线相连的列线电平决定。列线电平如果为低,则行线电平为低;列线电平如果为高,则行线电平亦为高。这一点是识别矩阵键盘按键是否被按下的关键所在。由于矩阵键盘中行、列线为多键共用,各按键均影响该键所在行和列的电平。因此各按键彼此将相互发生影响,所以必须将行、列线信号配合起来并作适当的处理,才能确定闭合键的位置。
3.32输入模块
LCD屏是中间夹有一些液晶材料的两块玻璃板,在此夹层的各个节点上通以微小的电流,就能够让液晶显现出图案,诸如计算器上的数字、PDA上的文本、笔记本电脑显示器上的图像之类的东西。LCD的主要特点:首要的是它们体积轻而且薄,只有几英寸厚。LCD第二大优点就是能耗少,比CRT显示器少90%。其三,LCD 的文本和图表显示要比CRT 显示器上的清晰。目前的不足之处也是显而易见的,如视角窄,颜色表现力欠佳。
图为S3C44BOX中内置的LCD控制器的逻辑框图,它用于传输显示数据并产生必要的控制信号,如VFRAME,VLINE,VCLK,和VM。除了控制信号,还有显示数据的数据端口VD[7:0]。LCD控制器包含REGBANK,LCDCDMA,VIDPRCS,和TIMEGEN。REGBANK 具有18 个可编程寄存器,用于配置LCD 控制器。LCDCDMA 为专用DMA,以自动地将显示数据从帧内存中传送到LCD 驱动器中。
4 软件设计流程及描述
4.1 程序流程图
图4-1 系统程序流程图
4.2 主要函数模块及功能
4.2.1控制飞机模块
采用扫描法判断按键的按下,根据对按键的不同键值实现对飞机的上下左右控制,每按一次,飞机均移动十个像素的位置。部分实现代码如下:
key = Key_Get();
switch(key) {
case '2':LCD_Clear_Plane(planeX, planeY, planeX+40, planeY+40); planeY -= 10;break;
case '*':LCD_Clear_Plane(planeX, planeY, planeX+40, planeY+40); planeX -= 10;break;
case '0':LCD_Clear_Plane(planeX, planeY, planeX+40, planeY+40); planeY += 10;break;
case '#':LCD_Clear_Plane(planeX, planeY, planeX+40, planeY+40); planeX += 10;break;
case '1':OrnotDrawBullet();break;
}
4.2.2 碰撞检测模块
分别实现飞机与飞机的碰撞检测和飞机和子弹的碰撞检测。下图分别为两个检测的流程图。
飞机与飞机的碰撞采用矩阵相交的方法,实现算法如下:假定矩形是用一对点表达的(minx, miny) (maxx, maxy),那么两个矩形rect1{(minx1, miny1)(maxx1, maxy1)}rect2{(minx2, miny2)(maxx2, maxy2)} 相交的结果一定是个矩形,构成这个相交矩形rect{(minx, miny) (maxx, maxy)}的点对坐标是:
minx = max(minx1, minx2)
miny = max(miny1, miny2)
maxx = min(maxx1, maxx2)
maxy = min(maxy1, maxy2)
如果两个矩形不相交,那么计算得到的点对坐标必然满足:(minx > maxx )或者(miny > maxy )
玩家游戏的飞机默认设置为三次机会,即有三次生命值,当判断生命值<0 时候游戏结束,并且跳出框显示击毁敌机的数量。
子弹的发射靠按键的按下实现,与敌机碰撞同样采用飞机与飞机的碰撞,当子弹与飞机碰撞的时候,接触部分会出现局部的爆炸,继而出现大爆炸,同时随着击毁敌机的数量增多,游戏的难度增加,敌机下落的速度增加。
5 功能实现
液晶显示
游戏初始化后,开机界面的显示。
进入游戏界面,实现对敌机的打击。
生命值的统计,击毁敌机数
6 心得体会
这次课程设计最大的收获就是只有把理论运用到实践中我们才能真正掌握所学的知识,在实践中,通过一系列问题的出现与解决,我对ARM有了更好的认识和理解,同时让我的动手能力有了一定的提高。
本次课程设计是以小组合作的形式进行,在这个过程中我们小组成员之间互相学习,互相帮助,团结协作,弥补彼此的不足,经过成员间的讨论及请教其他小组成员,我们的问题迎刃而解。
7源代码
/*
********************************************************* * Copyright (c) 2004 上海双实科技有限公司
* All rights reserved.
*
* 文件名称:main_lcd.c
* 文件标识:程序实现体
* 摘要:本文件是对lcd功能的测试
*
* 当前版本:1.0
* 作者:刘征
* 完成日期:2004.8.17
*
* 取代版本:
* 作者:
* 完成日期:
********************************************************* */
/*
********************************************************* * bmp头文件
********************************************************* */
#include "44b0x.h"
#include "44bConfig.h"
#include "define.h"
#include "LCD_Control.h"
#include "LCD_BMP.h"
#include "bmp_Color256.h"
/*
********************************************************* * key头文件
********************************************************* */
#include "uart.h"
#include "key.h"
#include
#include
/*
********************************************************* * Touch头文件
********************************************************* */
#include "TouchPanel.h"
#define DISABLE_TIMER2 (rTCON &= ~0x1000)
#define ENABLE_TIMER2 (rTCON |= 0x1000)
#define ENABLE_TOUCH (rPDATE &= 0xfe);
/*
********************************************************* * 变量
********************************************************* */
extern GUI_BITMAP *pBitmap;
char key = 0;//键值
int planeX=145,planeY=200;//初始飞机坐标
int a[5],b[5],c[5],d[5];
int i = 0 ,m = 0;
int color[2];
int ArmyX[3] ,ArmyY[3],live_Army[3];
int live_plane = 1;//飞机生命值
int Random1 = 80 , Random2 = 200 ,Random3 = 120;
int Count ;
int liveHeart[3];
int liveCount = 3;
int AccSign1 = 1 , AccSign2 = 1 , AccSign3 = 1 , AccSign4 = 1;
int HeartSign=1;
//int live_Army = 1;//敌机生命值
/*
********************************************************* * 函数声明
********************************************************* */
void LCD_Clear_Plane(int x0, int y0, int x1, int y1);
void LCD_Clear_Bullet(int x0, int y0, int x1, int y1);
void drawPlane(int x, int y, int arm);
void changeColor(int a)
{
int b;
if(a == 0)
b = a + 1;
if(a == 1)
b = a - 1;
LCD_Draw_FillRect(70, 2, 75, 37,color[a]);
LCD_Draw_FillRect(70, 40, 75, 77,color[b]);
LCD_Draw_FillRect(70, 80, 75, 117,color[a]);
LCD_Draw_FillRect(70, 120, 75, 157,color[b]);
LCD_Draw_FillRect(70, 160, 75, 197,color[a]);
LCD_Draw_FillRect(70, 200, 75, 237,color[b]);
LCD_Draw_FillRect(245, 2, 250, 37,color[a]);
LCD_Draw_FillRect(245, 40, 250, 77,color[b]);
LCD_Draw_FillRect(245, 80, 250, 117,color[a]);
LCD_Draw_FillRect(245, 120, 250, 157,color[b]);
LCD_Draw_FillRect(245, 160, 250, 197,color[a]);
LCD_Draw_FillRect(245, 200, 250, 237,color[b]);
}
/*
********************************************************* * 画飞机
********************************************************* */
/*
** 清除飞机运动轨迹
*/
void LCD_Clear_Plane(int x0, int y0, int x1, int y1)
{
int x,y;
for(x = x0;x <= x1; x++)
{
for(y = y0;y <= y1; y++)
{
SETPIXEL(x, y, 0xff);//clear lcd }
}
}
void drawPlane(int x, int y, int arm)
{
if(arm == 0)
{
BMP_Init(Army);
GUI_DrawBitmap(pBitmap,x,y);
}
if(arm == 1)
{
BMP_Init(Array);
GUI_DrawBitmap(pBitmap,x,y);
}
}
void drawBonb(int x, int y, int arm)
{
if(arm == 0)
{
BMP_Init(bonb1);
GUI_DrawBitmap(pBitmap,x,y);
}
if(arm == 1)
{
BMP_Init(bonb2);
GUI_DrawBitmap(pBitmap,x,y);
}
}
/*
********************************************************* * 飞机移动
********************************************************* */
void OrnotDrawBullet()
{
a[i] = planeX + 17;
b[i] = planeY - 6 ;
c[i] = planeX + 20;
d[i] = planeY;
i++;
if(i >= 5)
i = 0;
}
//避免越界
void avoidCrossLine()
{
if(planeX < 75)
planeX =75;
if(planeX > 205)
planeX = 205;
if(planeY < 0)
planeY = 0;
if(planeY > 200)
planeY = 200;
}
void movePlane()
{
int minx[3];
int miny[3];
int maxx[3];
int maxy[3];
int k = 0;
key = Key_Get();
switch(key) {
case '2':LCD_Clear_Plane(planeX, planeY, planeX+40, planeY+40); planeY -= 10;break;
case '*':LCD_Clear_Plane(planeX, planeY, planeX+40, planeY+40); planeX -= 10;break;
case '0':LCD_Clear_Plane(planeX, planeY, planeX+40, planeY+40); planeY += 10;break;
case '#':LCD_Clear_Plane(planeX, planeY, planeX+40, planeY+40); planeX += 10;break;
case '1':OrnotDrawBullet();break;
}
avoidCrossLine();
for(;k<3;k++)
{
minx[k] = (ArmyX[k] - planeX >0)? ArmyX[k] + 2:planeX;
miny[k] = (ArmyY[k] + 2 - planeY > 0)? ArmyY[k] + 2:planeY;
maxx[k] = (ArmyX[k] - 10 - planeX >0)? planeX + 40:ArmyX[k] + 30;
maxy[k] = (ArmyY[k] + 2 - 10 - planeY >0)? planeY + 40:ArmyY[k] +30 + 2;
}
for(k = 0;k < 3; k++)
{
if(minx[k] > maxx[k] || miny[k] > maxy[k])
{
}
else
{
if(live_plane == 1 && live_Army[k] == 1)
{
//live_plane = 0;
live_Army[k] = 0;
LCD_Clear_Plane(ArmyX[k], ArmyY[k], ArmyX[k] + 30, ArmyY[k] + 30);
drawBonb(planeX - 10, planeY - 10, 0);
Delay(2000);
LCD_Clear_Plane(planeX -10, planeY - 10, planeX + 25, planeY + 18);
LCD_Clear_Plane(planeX, planeY, planeX + 40, planeY + 40);
LCD_Clear_Plane(ArmyX[k], ArmyY[k] + 2, ArmyX[k] + 30, ArmyY[k] + 30 + 2);
drawBonb(planeX - 10, planeY - 10 , 1);
Delay(2000);
LCD_Clear_Plane(planeX -10, planeY - 10,planeX + 30, planeY + 20);
// planeX=-40,planeY=-40;
liveCount --;
if(liveCount < 1)
{
live_plane = 0;
}
}
}
}
if(live_plane == 1)
{
drawPlane(planeX,planeY,1);
}
}
void LCD_Clear_Bullet(int x0, int y0, int x1, int y1)
{
LCD_Clear_Plane(x0, y0, x1, y1);
}
/*
********************************************************* * 子弹
********************************************************* */
void draw_Bullet()
{
int j;
LCD_Draw_FillRect(a[0], b[0], c[0], d[0],0x00);
LCD_Draw_FillRect(a[1], b[1], c[1], d[1],0x00);
LCD_Draw_FillRect(a[2], b[2], c[2], d[2],0x00);
LCD_Draw_FillRect(a[3], b[3], c[3], d[3],0x00);
LCD_Draw_FillRect(a[4], b[4], c[4], d[4],0x00);
Delay(800);
LCD_Clear_Bullet(a[0], b[0], c[0], d[0]);
LCD_Clear_Bullet(a[1], b[1], c[1], d[1]);
LCD_Clear_Bullet(a[2], b[2], c[2], d[2]);
LCD_Clear_Bullet(a[3], b[3], c[3], d[3]);
LCD_Clear_Bullet(a[4], b[4], c[4], d[4]);
for(j = 0;j < 5; j++)
{
for(m = 0;m < 3; m++)
{