-
-
[原创]vc++游戏源码
-
发表于: 2008-9-23 14:03 4815
-
背景位图:800*600 IDB_BITMAP1
我方飞机:50*50 IDB_BITMAP2
敌方飞机:50*50 IDB_BITMAP3
我方子弹:50*50 IDB_BITMAP4
对方子弹:50*50 IDB_BITMAP6
炸毁飞机:60*60 IDB_BITMAP5 为了更好显示爆炸效果
火力位图:50*50 IDB_BITMAP7
飞机游戏,主角当然是飞机。飞机分成两方:玩者的一方(分为单人和双人,由于前面已经实现了俄罗斯方块游戏和老鼠游戏的双人游戏,这里只是实现游戏的单人版,双人版就作为读者的练习)和计算机的一方。我们称为正方和对方。
正方:具有生命力(本游戏设置为5),有火力(本游戏包括三种:单火力、双火力和强火力),生命力每次被炸毁就减一,而当火力值大于5时,生命力和火力强度同增。而火力,开始是0,表示单火力,之后,每次添加一个火力值就加一。
反方:由计算机按时地、随机地产生飞机,按时地发射子弹,按时地移动子弹的位置。(游戏的实现,往往就是因为要实现计算机的这些按时的“智能”的操作。)
火力:之所以把火力作为一个角色,因为它的存在,是独立的;它的作用又是为正方服务的,它的产生也是我们对程序的专门设置而实现的。我们可以忽略它的存在,同时,由于本游戏的特点(其实也是许多游戏的特点),我们由必须依靠它的存在,它可以给我们生命力和火力。
背景:我把背景做为一个角色,确实有一点不大合理,但是,每个人做事都是有他的原因的。我在这里把它提出来,只是为了强调一下它的作用。
游戏的实现:
依然是全屏,而且是更彻底的全屏,或许应该说是真正的全屏。
支持多种分辨率,当然,前面一章后面我们已经讲了一种方案,这里介绍的是另外一种。由于位图的限制,我们不可能总是画那么多的位图,我们也不可能利用放大缩小位图的方法,这样会产生严重的闪烁。那么,我们可以利用留空白的方法,我们制造最基本的位图,宽800,然后,利用获取屏幕大小的函数取得屏幕分辨率的大小,然后设法把位图显示在屏幕的中间。
背景位图的显示,由于我们的背景位图大小是有限制的,高度不可以大于2000
添加类名为:CGame
所有的变量和函数都添加到这个类里面。如下:
//显示信息
void DrawMessage(CDC*pDC,int width,int height);
//火力位图是否出现
void FireOutIf();
//子弹移动
void shotmove();
//敌机发射子弹
void Enemyshot();
//敌机出现
void Enemyplaneout();
//我方射击
void Shot();
//设置透明位图
void TransparentBitmap(HDC hdc, HBITMAP hBitmap,
short xStart, short yStart, short xadd,short yadd,
COLORREF cTransparentColor);
//透明色
COLORREF cTransparentColor;
//飞机爆炸位图
CBitmap enemydead;
//敌机子弹位图
CBitmap bmenemyshot;
//敌机位图
CBitmap enemy;
//我方子弹
CBitmap bmshot;
//我方飞机
CBitmap plane;
//我方飞机数量
short numplane;
//背景数组
int back[15][12];
//飞机出现位置
int xStart,yStart;
//火力位图
CBitmap bmfire;
//火力位置
CPoint pointfire;
//是否出现
bool iffire;
//火力强度
int fire;
CmainFrame:
CRect m_FullScreenRect;//全屏显示时的窗口位置
void OnFullScreen();
、、、、、、、、、、、、、、、、、、
class CMy6_1View :
//暂停
bool bPause;
//屏幕宽度
int width;
//屏幕高度
int height;
//类CGame
CGame game;
//背景位图移动大小:10
int goup;
//背景位图
CBitmap backmap;
当然,下面三个函数是少不了的:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
显示界面:
我方子弹:2
敌方飞机:3
敌机子弹:向左下角:4
敌机子弹:向正下方:5
敌机子弹:向右下角:6
敌机炸毁:7
我机炸毁:8
说明:敌机子弹的不同的值是为了下一次下移的需要。
我方飞机和火力分别用一个点表示。
void CMy6_1View::OnDraw(CDC* pDC)
{
int i,j;
CMy6_1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CRect WindowRect;
GetWindowRect(&WindowRect);
//屏幕宽度
width=WindowRect.right-WindowRect.left;
//屏幕高度
height=WindowRect.bottom-WindowRect.top;
CDC Dc;
if(Dc.CreateCompatibleDC(pDC)==FALSE)
AfxMessageBox("Can't create DC");
//在不同位置显示位图
Dc.SelectObject(backmap);
//显示两张位图使它们连接
pDC->BitBlt((width-800)/2,0,800,height,&Dc,0,goup-2000,SRCCOPY);
pDC->BitBlt((width-800)/2,0,800,height,&Dc,0,goup,SRCCOPY);
CClientDC dc(this);
//显示
//检查背景数组
for(i=0;i<15;i++)
for(j=0;j<12;j++)
{
//显示我方子弹
if(game.back[i][j]==2)
//利用透明显示函数
game.TransparentBitmap(dc.GetSafeHdc(), game.bmshot,(width-800)/2+i*50+20,j*height/600*50, 0,0, game.cTransparentColor);
//显示敌机
if(game.back[i][j]==3)
game.TransparentBitmap(dc.GetSafeHdc(), game.enemy,(width-800)/2+i*50+20,j*height/600*50, 0,0, game.cTransparentColor);
//飞机炸毁
if(game.back[i][j]==7||game.back[i][j]==8)
game.TransparentBitmap(dc.GetSafeHdc(), game.enemydead,(width-800)/2+i*50+20,j*height/600*50, 0,0, game.cTransparentColor);
//敌机子弹
if((game.back[i][j]==5)||(game.back[i][j]==4)||(game.back[i][j]==6))
game.TransparentBitmap(dc.GetSafeHdc(), game.bmenemyshot,(width-800)/2+i*50+20,j*height/600*50, 0,0, game.cTransparentColor);
}
//显示火力位图
game.TransparentBitmap(dc.GetSafeHdc(), game.bmfire,(width-800)/2+game.pointfire.x*50+20, game.pointfire.y*height/600*50, 0,0, game.cTransparentColor);
//显示我方飞机
game.TransparentBitmap(dc.GetSafeHdc(), game.plane,(width-800)/2+game.xStart*50+20, game.yStart*height/600*50, 0,0, game.cTransparentColor);
//显示信息
game.DrawMessage(pDC,width,height);
//信息的飞机位图
game.TransparentBitmap(dc.GetSafeHdc(), game.plane,(width-800)/2+20, height-80, 0,0, game.cTransparentColor);
//信息的火力位图
game.TransparentBitmap(dc.GetSafeHdc(), game.bmfire,(width-800)/2+800-120, height-80, 0,0, game.cTransparentColor);
}
添加信息提示:
void CGame::DrawMessage(CDC *pDC,int width,int height)
{
int nOldDC=pDC->SaveDC();
//设置字体
CFont font;
if(0==font.CreatePointFont(250,"Comic Sans MS"))
{
AfxMessageBox("Can't Create Font");
}
pDC->SelectObject(&font);
//设置字体颜色及其背景颜色
CString str;
pDC->SetTextColor(RGB(0,10,244));
pDC->SetBkColor(RGB(0,255,0));
//输出数字
str.Format("%d",numplane);
pDC->TextOut((width-800)/2+70,height-80,str);
str.Format("%d",fire);
pDC->TextOut((width-800)/2+800-70,height-80,str);
pDC->TextOut((width-800)/2+200,height-40,"暂停:F3 退出:Esc");
pDC->RestoreDC(nOldDC);
}
下面设置时间间隔:
int CMy6_1View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
SetTimer(1,200,NULL);
return 0;
}
时间段的操作:
第一点就是移动背景位图。
第二点是实现对方的智能操作。
第三点是清理背景数组不该再出现的位图。
void CMy6_1View::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
int i,j;
//背景位图下移
goup- =10;
//位图到了边界
if(goup<0)
//位图在开头
goup=2000;
//每100点,即两秒执行一次
if(goup%100==0)
{
//出现敌机
game.Enemyplaneout();
//敌机发射
game.Enemyshot();
}
if(goup%1100==0)
//火力位图操作
game.FireOutIf();
//重画
OnDraw(GetDC());
//数组清空
for(i=0;i<15;i++)
for(j=0;j<12;j++)
if(game.back[i][j]==2||game.back[i][j]==7||game.back[i][j]==8)
game.back[i][j]=0;
//敌机子弹移动
game.shotmove();
CView::OnTimer(nIDEvent);
}
键盘操作:
void CMy6_1View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
switch(nChar)
{
case VK_F3:
//暂停是否
bPause=!bPause;
//是,设置计时器
if(bPause)
SetTimer(1,200,NULL);
//否,停止计时
else
KillTimer(1);
break;
//子弹按钮
case VK_SPACE:
//我方发射子弹
game.Shot();
break;
//左移
case VK_LEFT:
//位置减1
game.xStart--;
//边界
if(game.xStart<0)
game.xStart=0;
break;
//道理同上
case VK_RIGHT:
game.xStart++;
if(game.xStart>14)
game.xStart=14;
break;
//上移
case VK_UP:
if(game.yStart>0)
game.yStart--;
break;
//下移
case VK_DOWN:
if(game.yStart<10)
game.yStart++;
break;
}
//如果火力位图位置和我方飞机位置相同
if((game.pointfire.x==game.xStart)&&(game.pointfire.y==game.yStart))
{
//火力位图消失
game.iffire=false;
if(game.fire>5)
{
game.fire++;
game.numplane++;
}
else
game.fire++;
//火力位图移动到见不到的地方
game.pointfire.y=-1;
}
OnDraw(GetDC());
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
透明位图函数的添加:
void CGame::TransparentBitmap(HDC hdc, HBITMAP hBitmap,
short xStart, short yStart, short xadd,short yadd,
COLORREF cTransparentColor){}
我方发射子弹:
//以2表示子弹
void CGame::Shot()
{
int i;
//火力0 一线火力
if(fire==0)
//从飞机前方到尽头
for(i=0;i<yStart;i++)
{
//如果有敌机
if(back[xStart][i]==3)
//敌机被炸位图
back[xStart][i]=7;
else
//我方子弹位图
back[xStart][i]=2;
}
//火力1 两线火力
if(fire==1)
{
for(i=1;i<=yStart;i++)
{
//如果不出界
if((xStart-i)>=0)
{
//左上角
if(back[xStart-i][yStart-i]==3)
back[xStart-i][yStart-i]=7;
else
back[xStart-i][yStart-i]=2;
}
//如果不出界
if((xStart+i)<15)
{
//右上角
if(back[xStart+i][yStart-i]==3)
back[xStart+i][yStart-i]=7;
else
back[xStart+i][yStart-i]=2;
}
}
}
//其他 三线火力
if(fire>1)
{
for(i=1;i<=yStart;i++)
{
if((xStart-i)>=0)
{
if(back[xStart-i][yStart-i]==3)
back[xStart-i][yStart-i]=7;
else
back[xStart-i][yStart-i]=2;
}
//正前方
if(back[xStart][i]==3)
//敌机被炸位图
back[xStart][yStart-i]=7;
else
back[xStart][yStart-i]=2;
if((xStart+i)<15)
{
if(back[xStart+i][yStart-i]==3)
back[xStart+i][yStart-i]=7;
else
back[xStart+i][yStart-i]=2;
}
}
}
}
敌机出现:
利用随机函数,让敌机在前面三排随意出现。其中,do~while循环语句表示必定要产生一只敌机。
void CGame::Enemyplaneout()
{
int x,y;
//初始化随即数种子
srand(GetTickCount());
//循环到飞机出现为止
do
{
x=rand()%15;
y=rand()%3;
//如果位置空
if(back[x][y]==0)
//显示敌机
back[x][y]=3;
}while(back[x][y]==0);
}
敌机发射子弹:
检查前面三排,如果有敌机,如果敌机的前面三个位置有不为零的,给相应的值。注释如下:
void CGame::Enemyshot()
{
int i,j;
for(i=0;i<15;i++)
for(j=0;j<12;j++)
if(back[i][j]==3)
{
//如果左下方空
if(back[i-1][j+1]==0)
//数组赋值4,表示子弹向左下方移动
back[i-1][j+1]=4;
//如果下方空
if(back[i][j+1]==0)
//数组赋值5,表示子弹向下方移动
back[i][j+1]=5;
//如果右下方空
if(back[i+1][j+1]==0)
//数组赋值5,表示子弹向右下方移动
back[i+1][j+1]=6;
}
}
敌机子弹移动:
具体情况是,清除这一次的背景数组的值,移动,检查是否出界,否则赋相应的值。接着检查我方飞机是否被炸,并做相应处理。
void CGame::shotmove()
{
int i,j;
for(j=11;j>=0;j--)
for(i=14;i>=0;i--)
{
//数组赋值4,表示子弹向左下方移动
if(back[i][j]==4)
{
//清除数组
back[i][j]=0;
//如果不出界
if(i>0)
//如果左下方空
if(back[i-1][j+1]==0)
//数组赋值4,表示子弹向左下方移动
back[i-1][j+1]=4;
}
if(back[i][j]==5)
{
back[i][j]=0;
if(back[i][j+1]==0)
back[i][j+1]=5;
}
if(back[i][j]==6)
{
back[i][j]=0;
if(i<14)
if(back[i+1][j+1]==0)
back[i+1][j+1]=6;
}
//如果有敌机或子弹
if((back[xStart][yStart]==3)||(back[xStart][yStart]==4)||(back[xStart][yStart]==5)||(back[xStart][yStart]==6))
{
//数组赋值8,表示我方被炸
back[xStart][yStart]=8;
//飞机数量减1
numplane--;
}
//如果敌方子弹到了下方边界
if((back[i][11]==4)||(back[i][11]==5)||(back[i][11]==6))
//赋值0
back[i][11]=0;
}
}
火力实现:
火力位图是定时地出现,位置当然是随机的。但是,出现时必须先判断,如果已经出现,下移;如果没有出现,才出现。而当它的位置和我方飞机位置相同时,我方火力增强,甚至生命力增强。
//火力位图是否出现
void CGame::FireOutIf()
{
//没有出现
if(!iffire)
{
//随机位置
pointfire.x=rand()%15;
pointfire.y=rand()%8;
//出现
iffire=true;
}
//出现
else
{
//如果和我方飞机位置相同
if((pointfire.x==xStart)&&(pointfire.y==yStart))
{
//不出现
iffire=false;
//如果火力大于5
if(fire>5)
{
//火力加强
fire++;
//飞机数量加强
numplane++;
}
//否则
else
//火力加强
fire++;
//消失
pointfire.y=-1;
}
else
{
//位置下移
pointfire.y++;
//出界
if(pointfire.y>11)
//不出现
iffire=false;
}
}
}
我方飞机:50*50 IDB_BITMAP2
敌方飞机:50*50 IDB_BITMAP3
我方子弹:50*50 IDB_BITMAP4
对方子弹:50*50 IDB_BITMAP6
炸毁飞机:60*60 IDB_BITMAP5 为了更好显示爆炸效果
火力位图:50*50 IDB_BITMAP7
飞机游戏,主角当然是飞机。飞机分成两方:玩者的一方(分为单人和双人,由于前面已经实现了俄罗斯方块游戏和老鼠游戏的双人游戏,这里只是实现游戏的单人版,双人版就作为读者的练习)和计算机的一方。我们称为正方和对方。
正方:具有生命力(本游戏设置为5),有火力(本游戏包括三种:单火力、双火力和强火力),生命力每次被炸毁就减一,而当火力值大于5时,生命力和火力强度同增。而火力,开始是0,表示单火力,之后,每次添加一个火力值就加一。
反方:由计算机按时地、随机地产生飞机,按时地发射子弹,按时地移动子弹的位置。(游戏的实现,往往就是因为要实现计算机的这些按时的“智能”的操作。)
火力:之所以把火力作为一个角色,因为它的存在,是独立的;它的作用又是为正方服务的,它的产生也是我们对程序的专门设置而实现的。我们可以忽略它的存在,同时,由于本游戏的特点(其实也是许多游戏的特点),我们由必须依靠它的存在,它可以给我们生命力和火力。
背景:我把背景做为一个角色,确实有一点不大合理,但是,每个人做事都是有他的原因的。我在这里把它提出来,只是为了强调一下它的作用。
游戏的实现:
依然是全屏,而且是更彻底的全屏,或许应该说是真正的全屏。
支持多种分辨率,当然,前面一章后面我们已经讲了一种方案,这里介绍的是另外一种。由于位图的限制,我们不可能总是画那么多的位图,我们也不可能利用放大缩小位图的方法,这样会产生严重的闪烁。那么,我们可以利用留空白的方法,我们制造最基本的位图,宽800,然后,利用获取屏幕大小的函数取得屏幕分辨率的大小,然后设法把位图显示在屏幕的中间。
背景位图的显示,由于我们的背景位图大小是有限制的,高度不可以大于2000
添加类名为:CGame
所有的变量和函数都添加到这个类里面。如下:
//显示信息
void DrawMessage(CDC*pDC,int width,int height);
//火力位图是否出现
void FireOutIf();
//子弹移动
void shotmove();
//敌机发射子弹
void Enemyshot();
//敌机出现
void Enemyplaneout();
//我方射击
void Shot();
//设置透明位图
void TransparentBitmap(HDC hdc, HBITMAP hBitmap,
short xStart, short yStart, short xadd,short yadd,
COLORREF cTransparentColor);
//透明色
COLORREF cTransparentColor;
//飞机爆炸位图
CBitmap enemydead;
//敌机子弹位图
CBitmap bmenemyshot;
//敌机位图
CBitmap enemy;
//我方子弹
CBitmap bmshot;
//我方飞机
CBitmap plane;
//我方飞机数量
short numplane;
//背景数组
int back[15][12];
//飞机出现位置
int xStart,yStart;
//火力位图
CBitmap bmfire;
//火力位置
CPoint pointfire;
//是否出现
bool iffire;
//火力强度
int fire;
CmainFrame:
CRect m_FullScreenRect;//全屏显示时的窗口位置
void OnFullScreen();
、、、、、、、、、、、、、、、、、、
class CMy6_1View :
//暂停
bool bPause;
//屏幕宽度
int width;
//屏幕高度
int height;
//类CGame
CGame game;
//背景位图移动大小:10
int goup;
//背景位图
CBitmap backmap;
当然,下面三个函数是少不了的:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
显示界面:
我方子弹:2
敌方飞机:3
敌机子弹:向左下角:4
敌机子弹:向正下方:5
敌机子弹:向右下角:6
敌机炸毁:7
我机炸毁:8
说明:敌机子弹的不同的值是为了下一次下移的需要。
我方飞机和火力分别用一个点表示。
void CMy6_1View::OnDraw(CDC* pDC)
{
int i,j;
CMy6_1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CRect WindowRect;
GetWindowRect(&WindowRect);
//屏幕宽度
width=WindowRect.right-WindowRect.left;
//屏幕高度
height=WindowRect.bottom-WindowRect.top;
CDC Dc;
if(Dc.CreateCompatibleDC(pDC)==FALSE)
AfxMessageBox("Can't create DC");
//在不同位置显示位图
Dc.SelectObject(backmap);
//显示两张位图使它们连接
pDC->BitBlt((width-800)/2,0,800,height,&Dc,0,goup-2000,SRCCOPY);
pDC->BitBlt((width-800)/2,0,800,height,&Dc,0,goup,SRCCOPY);
CClientDC dc(this);
//显示
//检查背景数组
for(i=0;i<15;i++)
for(j=0;j<12;j++)
{
//显示我方子弹
if(game.back[i][j]==2)
//利用透明显示函数
game.TransparentBitmap(dc.GetSafeHdc(), game.bmshot,(width-800)/2+i*50+20,j*height/600*50, 0,0, game.cTransparentColor);
//显示敌机
if(game.back[i][j]==3)
game.TransparentBitmap(dc.GetSafeHdc(), game.enemy,(width-800)/2+i*50+20,j*height/600*50, 0,0, game.cTransparentColor);
//飞机炸毁
if(game.back[i][j]==7||game.back[i][j]==8)
game.TransparentBitmap(dc.GetSafeHdc(), game.enemydead,(width-800)/2+i*50+20,j*height/600*50, 0,0, game.cTransparentColor);
//敌机子弹
if((game.back[i][j]==5)||(game.back[i][j]==4)||(game.back[i][j]==6))
game.TransparentBitmap(dc.GetSafeHdc(), game.bmenemyshot,(width-800)/2+i*50+20,j*height/600*50, 0,0, game.cTransparentColor);
}
//显示火力位图
game.TransparentBitmap(dc.GetSafeHdc(), game.bmfire,(width-800)/2+game.pointfire.x*50+20, game.pointfire.y*height/600*50, 0,0, game.cTransparentColor);
//显示我方飞机
game.TransparentBitmap(dc.GetSafeHdc(), game.plane,(width-800)/2+game.xStart*50+20, game.yStart*height/600*50, 0,0, game.cTransparentColor);
//显示信息
game.DrawMessage(pDC,width,height);
//信息的飞机位图
game.TransparentBitmap(dc.GetSafeHdc(), game.plane,(width-800)/2+20, height-80, 0,0, game.cTransparentColor);
//信息的火力位图
game.TransparentBitmap(dc.GetSafeHdc(), game.bmfire,(width-800)/2+800-120, height-80, 0,0, game.cTransparentColor);
}
添加信息提示:
void CGame::DrawMessage(CDC *pDC,int width,int height)
{
int nOldDC=pDC->SaveDC();
//设置字体
CFont font;
if(0==font.CreatePointFont(250,"Comic Sans MS"))
{
AfxMessageBox("Can't Create Font");
}
pDC->SelectObject(&font);
//设置字体颜色及其背景颜色
CString str;
pDC->SetTextColor(RGB(0,10,244));
pDC->SetBkColor(RGB(0,255,0));
//输出数字
str.Format("%d",numplane);
pDC->TextOut((width-800)/2+70,height-80,str);
str.Format("%d",fire);
pDC->TextOut((width-800)/2+800-70,height-80,str);
pDC->TextOut((width-800)/2+200,height-40,"暂停:F3 退出:Esc");
pDC->RestoreDC(nOldDC);
}
下面设置时间间隔:
int CMy6_1View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
SetTimer(1,200,NULL);
return 0;
}
时间段的操作:
第一点就是移动背景位图。
第二点是实现对方的智能操作。
第三点是清理背景数组不该再出现的位图。
void CMy6_1View::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
int i,j;
//背景位图下移
goup- =10;
//位图到了边界
if(goup<0)
//位图在开头
goup=2000;
//每100点,即两秒执行一次
if(goup%100==0)
{
//出现敌机
game.Enemyplaneout();
//敌机发射
game.Enemyshot();
}
if(goup%1100==0)
//火力位图操作
game.FireOutIf();
//重画
OnDraw(GetDC());
//数组清空
for(i=0;i<15;i++)
for(j=0;j<12;j++)
if(game.back[i][j]==2||game.back[i][j]==7||game.back[i][j]==8)
game.back[i][j]=0;
//敌机子弹移动
game.shotmove();
CView::OnTimer(nIDEvent);
}
键盘操作:
void CMy6_1View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
switch(nChar)
{
case VK_F3:
//暂停是否
bPause=!bPause;
//是,设置计时器
if(bPause)
SetTimer(1,200,NULL);
//否,停止计时
else
KillTimer(1);
break;
//子弹按钮
case VK_SPACE:
//我方发射子弹
game.Shot();
break;
//左移
case VK_LEFT:
//位置减1
game.xStart--;
//边界
if(game.xStart<0)
game.xStart=0;
break;
//道理同上
case VK_RIGHT:
game.xStart++;
if(game.xStart>14)
game.xStart=14;
break;
//上移
case VK_UP:
if(game.yStart>0)
game.yStart--;
break;
//下移
case VK_DOWN:
if(game.yStart<10)
game.yStart++;
break;
}
//如果火力位图位置和我方飞机位置相同
if((game.pointfire.x==game.xStart)&&(game.pointfire.y==game.yStart))
{
//火力位图消失
game.iffire=false;
if(game.fire>5)
{
game.fire++;
game.numplane++;
}
else
game.fire++;
//火力位图移动到见不到的地方
game.pointfire.y=-1;
}
OnDraw(GetDC());
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
透明位图函数的添加:
void CGame::TransparentBitmap(HDC hdc, HBITMAP hBitmap,
short xStart, short yStart, short xadd,short yadd,
COLORREF cTransparentColor){}
我方发射子弹:
//以2表示子弹
void CGame::Shot()
{
int i;
//火力0 一线火力
if(fire==0)
//从飞机前方到尽头
for(i=0;i<yStart;i++)
{
//如果有敌机
if(back[xStart][i]==3)
//敌机被炸位图
back[xStart][i]=7;
else
//我方子弹位图
back[xStart][i]=2;
}
//火力1 两线火力
if(fire==1)
{
for(i=1;i<=yStart;i++)
{
//如果不出界
if((xStart-i)>=0)
{
//左上角
if(back[xStart-i][yStart-i]==3)
back[xStart-i][yStart-i]=7;
else
back[xStart-i][yStart-i]=2;
}
//如果不出界
if((xStart+i)<15)
{
//右上角
if(back[xStart+i][yStart-i]==3)
back[xStart+i][yStart-i]=7;
else
back[xStart+i][yStart-i]=2;
}
}
}
//其他 三线火力
if(fire>1)
{
for(i=1;i<=yStart;i++)
{
if((xStart-i)>=0)
{
if(back[xStart-i][yStart-i]==3)
back[xStart-i][yStart-i]=7;
else
back[xStart-i][yStart-i]=2;
}
//正前方
if(back[xStart][i]==3)
//敌机被炸位图
back[xStart][yStart-i]=7;
else
back[xStart][yStart-i]=2;
if((xStart+i)<15)
{
if(back[xStart+i][yStart-i]==3)
back[xStart+i][yStart-i]=7;
else
back[xStart+i][yStart-i]=2;
}
}
}
}
敌机出现:
利用随机函数,让敌机在前面三排随意出现。其中,do~while循环语句表示必定要产生一只敌机。
void CGame::Enemyplaneout()
{
int x,y;
//初始化随即数种子
srand(GetTickCount());
//循环到飞机出现为止
do
{
x=rand()%15;
y=rand()%3;
//如果位置空
if(back[x][y]==0)
//显示敌机
back[x][y]=3;
}while(back[x][y]==0);
}
敌机发射子弹:
检查前面三排,如果有敌机,如果敌机的前面三个位置有不为零的,给相应的值。注释如下:
void CGame::Enemyshot()
{
int i,j;
for(i=0;i<15;i++)
for(j=0;j<12;j++)
if(back[i][j]==3)
{
//如果左下方空
if(back[i-1][j+1]==0)
//数组赋值4,表示子弹向左下方移动
back[i-1][j+1]=4;
//如果下方空
if(back[i][j+1]==0)
//数组赋值5,表示子弹向下方移动
back[i][j+1]=5;
//如果右下方空
if(back[i+1][j+1]==0)
//数组赋值5,表示子弹向右下方移动
back[i+1][j+1]=6;
}
}
敌机子弹移动:
具体情况是,清除这一次的背景数组的值,移动,检查是否出界,否则赋相应的值。接着检查我方飞机是否被炸,并做相应处理。
void CGame::shotmove()
{
int i,j;
for(j=11;j>=0;j--)
for(i=14;i>=0;i--)
{
//数组赋值4,表示子弹向左下方移动
if(back[i][j]==4)
{
//清除数组
back[i][j]=0;
//如果不出界
if(i>0)
//如果左下方空
if(back[i-1][j+1]==0)
//数组赋值4,表示子弹向左下方移动
back[i-1][j+1]=4;
}
if(back[i][j]==5)
{
back[i][j]=0;
if(back[i][j+1]==0)
back[i][j+1]=5;
}
if(back[i][j]==6)
{
back[i][j]=0;
if(i<14)
if(back[i+1][j+1]==0)
back[i+1][j+1]=6;
}
//如果有敌机或子弹
if((back[xStart][yStart]==3)||(back[xStart][yStart]==4)||(back[xStart][yStart]==5)||(back[xStart][yStart]==6))
{
//数组赋值8,表示我方被炸
back[xStart][yStart]=8;
//飞机数量减1
numplane--;
}
//如果敌方子弹到了下方边界
if((back[i][11]==4)||(back[i][11]==5)||(back[i][11]==6))
//赋值0
back[i][11]=0;
}
}
火力实现:
火力位图是定时地出现,位置当然是随机的。但是,出现时必须先判断,如果已经出现,下移;如果没有出现,才出现。而当它的位置和我方飞机位置相同时,我方火力增强,甚至生命力增强。
//火力位图是否出现
void CGame::FireOutIf()
{
//没有出现
if(!iffire)
{
//随机位置
pointfire.x=rand()%15;
pointfire.y=rand()%8;
//出现
iffire=true;
}
//出现
else
{
//如果和我方飞机位置相同
if((pointfire.x==xStart)&&(pointfire.y==yStart))
{
//不出现
iffire=false;
//如果火力大于5
if(fire>5)
{
//火力加强
fire++;
//飞机数量加强
numplane++;
}
//否则
else
//火力加强
fire++;
//消失
pointfire.y=-1;
}
else
{
//位置下移
pointfire.y++;
//出界
if(pointfire.y>11)
//不出现
iffire=false;
}
}
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
- [分享]今天开始翻译《计算几何 C语言描述》Joseph O'Rourke 5742
- [原创]vc++ 5867
- [原创]浅谈国产软件 4812
看原图
赞赏
雪币:
留言: