📄 a10.cpp
字号:
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <mmsystem.h>
#include <time.h>
#include <direct.h>
#include <ddraw.h>
#include "ddutil.h"
#include "resource.h"
#define WINDOW_WIDTH 350//窗口宽度
#define WINDOW_HEIGHT 450//窗口高度
#define TIMER_CHANGEMAP 1//定时器ID
#define TIMER_GAME 2
LPDIRECTDRAW lpDD; //DirectDraw对象
LPDIRECTDRAWCLIPPER lpClipper; //DirectDrawClipper对象
LPDIRECTDRAWSURFACE lpDDSFront; //以下均为DirectDrawSurface对象
LPDIRECTDRAWSURFACE lpDDSBack;
LPDIRECTDRAWSURFACE lpDDSPlane[3];
LPDIRECTDRAWSURFACE lpDDSBall;
LPDIRECTDRAWSURFACE lpDDSBom[2];
LPDIRECTDRAWSURFACE lpDDSMap;
LPDIRECTDRAWSURFACE lpDDSBulet[2];
LPDIRECTDRAWSURFACE lpDDSFlame;
LPDIRECTDRAWSURFACE lpDDSDead;
LPDIRECTDRAWSURFACE lpDDSEnemy;
const int BOMNUMBER=5; //炸弹总数
const int BULETNUMBER=10; //子弹总数
const int ENEMYNUMBER=16; //敌机总数
HWND hWnd; //主窗口句柄
BOOL bActive = TRUE; //应用程序是否活跃
char apppath[50]; //应用程序路径
char openmidi[50]; //打开midi命令字符串
char closemidi[50]; //关闭midi命令字符串
int speed=12; //延时速度
int movespeed=2; //移动速度
int fps; //帧频率
int gamestatus; //游戏进程
#define GAME_LOG 0
#define GAME_START 1
#define GAME_OVER 2
BOOL super=FALSE; //我机是否无敌
BOOL cancontrol=FALSE; //我机是否能控制
int Plane=1; //我机姿态
POINT pos; //我机位置
int forewidth, foreheight;//前台页面的宽度和高度
RECT backrect; //后台页面映射矩形
int backwidth, backheight;//后台页面的宽度和高度
int enemylost; //敌机损失数量
int planeremain; //我机剩余数量
POINT bompos[BOMNUMBER]; //炸弹位置
int bom=0; //当前炸弹记录
POINT buletposleft[BULETNUMBER];//左侧子弹位置
POINT buletposright[BULETNUMBER];//右侧子弹位置
int bulet=0; //当前子弹记录
POINT enemypos[ENEMYNUMBER]; //敌机位置
int enemyspeed[ENEMYNUMBER];//敌机速度
int enemydir[ENEMYNUMBER]; //敌机方向
int enemystyle[ENEMYNUMBER];//敌机是子弹还是飞机
int enemydead[ENEMYNUMBER]; //敌机是否已死
POINT flamepos[ENEMYNUMBER]; //火焰位置
int flamestatus[ENEMYNUMBER];//火焰状态记录
POINT deadflamepos; //我机死时的火焰位置
int deadflamestatus=0; //火焰状态记录
//函数声明
LRESULT CALLBACK WinProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
HWND InitWindow( HINSTANCE hInstance, int nCmdShow );
BOOL InitDDraw( void );
void FreeDDraw( void );
void Flip(void);
void DrawPlane(void);
void DrawBom(void);
void DrawMap(void );
void DrawText(void );
void UpdateFrame(void );
void ChangeMap(void);
void DrawBulet(void);
void DrawFlame(void);
void DrawEnemy(void);
void CheckHit(void);
BOOL OutOfRange(POINT p);
void GetRect(RECT* rect, long left, long top, long width, long height);
//*******************************************************************
//应用程序入口
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
//初始化主窗口
hWnd=InitWindow( hInstance, nCmdShow ) ;
if (hWnd == NULL )
return FALSE;
//初始化DirectDraw环境,并实现DirectDraw功能
if (!InitDDraw())
{
MessageBox(GetActiveWindow(), "初始化DirectDraw过程中出错!请检查你是否正确的安装了DirectX。", "Error", MB_OK );
FreeDDraw();
return FALSE;
}
while(1)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!GetMessage(&msg, NULL, 0, 0 )) return msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if(bActive)
{
//计算帧频率
static int frame=0, nt, ot=0;
nt=GetTickCount();
if (nt > ot+1000)
{
ot=nt;
fps=frame;
frame=0;
}
//画面延时
static int NewCount, OldCount=0;
NewCount=GetTickCount();
if (NewCount > OldCount+speed)
{
frame++;
OldCount=NewCount;
UpdateFrame();//更新画面
}
}
//等待消息
else WaitMessage();
}
}
//******************************************************************
//创建主窗口。
HWND InitWindow( HINSTANCE hInstance, int nCmdShow )
{
HWND hwnd;
WNDCLASS wc;
//填充窗口类结构
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_ICON1) );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "A-10";
//注册窗口类
RegisterClass( &wc );
//创建主窗口
hwnd = CreateWindowEx(
0,
"A-10",
"A10攻击机",
WS_OVERLAPPEDWINDOW|WS_VISIBLE|WS_SYSMENU,
(GetSystemMetrics(SM_CXFULLSCREEN)-WINDOW_WIDTH)/2,
(GetSystemMetrics(SM_CYFULLSCREEN)-WINDOW_HEIGHT)/2,
WINDOW_WIDTH,
WINDOW_HEIGHT,
NULL,
NULL,
hInstance,
NULL );
if( !hwnd ) return FALSE;
//显示并更新窗口
ShowWindow( hwnd, nCmdShow );
UpdateWindow( hwnd );
return hwnd;
}
//*****************************
//处理主窗口消息
LRESULT CALLBACK WinProc( HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
switch( message )
{
case WM_ACTIVATEAPP://
bActive = wParam;
break;
case WM_KEYDOWN://击键消息
switch( wParam )
{
case VK_ESCAPE://退出
PostMessage(hWnd, WM_CLOSE, 0, 0);
break;
case VK_ADD ://加速
movespeed++;
if (movespeed>5 ) movespeed=5;
break;
case VK_SUBTRACT ://减速
movespeed--;
if (movespeed<2) movespeed=2;
break;
case VK_RETURN :
if (gamestatus!=GAME_START)//开始游戏,进行初始化
{
for (int k=0; k<ENEMYNUMBER; k++)
enemydead[k]=0;
enemylost=0;
planeremain=2;
gamestatus=GAME_START;
movespeed=2;
SetTimer(hWnd, TIMER_CHANGEMAP, 20000, NULL);
}
else//改变地图
ChangeMap();
break;
case VK_SPACE://炸弹
bompos[bom].x=pos.x+25-7;
bompos[bom].y=pos.y;
bom++;
if (bom==BOMNUMBER) bom=0;
break;
}
break;
case WM_TIMER://定时器消息
switch (wParam)
{
case TIMER_CHANGEMAP:
ChangeMap();//改变地图
movespeed++;//加速
if (movespeed>5) movespeed=5;
break;
}
break;
case WM_DESTROY://退出消息
FreeDDraw();//释放所有DirectDraw对象
//关闭midi
char buf[256];
mciSendString( closemidi, buf, sizeof(buf), NULL);
PostQuitMessage( 0 );
break;
}
//调用缺省消息处理过程
return DefWindowProc(hWnd, message, wParam, lParam);
}
//******************************************************************
//初始化DirectDraw环境
BOOL InitDDraw(void)
{
DWORD dwFlags;
DDSURFACEDESC ddsd;
//创建DirectDraw对象
DirectDrawCreate(NULL, &lpDD, NULL);
//设置协作级别为窗口模式
dwFlags = DDSCL_NORMAL;
lpDD->SetCooperativeLevel(hWnd, dwFlags);
//创建主页面
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
lpDD->CreateSurface(&ddsd, &lpDDSFront, NULL);
//创建离屏页面
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
RECT rect;
GetClientRect(hWnd, &rect);
forewidth=rect.right-rect.left;
foreheight=rect.bottom-rect.top;
GetRect(&backrect, 65, 65, forewidth, foreheight);
ddsd.dwWidth = backwidth=forewidth+130;
ddsd.dwHeight = backheight=foreheight+130;
lpDD->CreateSurface( &ddsd, &lpDDSBack, NULL );
//创建地图页面
ddsd.dwWidth = 64;
ddsd.dwHeight = 64;
lpDD->CreateSurface( &ddsd, &lpDDSMap, NULL );
DDReLoadBitmap(lpDDSMap, "map1.bmp");
//创建飞机页面
ddsd.dwWidth = 50;
ddsd.dwHeight = 60;
lpDD->CreateSurface( &ddsd, &lpDDSPlane[0], NULL );
lpDD->CreateSurface( &ddsd, &lpDDSPlane[1], NULL );
lpDD->CreateSurface( &ddsd, &lpDDSPlane[2], NULL );
DDReLoadBitmap(lpDDSPlane[0], "left.bmp");
DDReLoadBitmap(lpDDSPlane[1], "center.bmp");
DDReLoadBitmap(lpDDSPlane[2], "right.bmp");
DDSetColorKey(lpDDSPlane[0],RGB(0,0,0));
DDSetColorKey(lpDDSPlane[1],RGB(0,0,0));
DDSetColorKey(lpDDSPlane[2],RGB(0,0,0));
//创建炸弹页面
ddsd.dwWidth = 14;
ddsd.dwHeight = 36;
lpDD->CreateSurface( &ddsd, &lpDDSBom[0], NULL );
lpDD->CreateSurface( &ddsd, &lpDDSBom[1], NULL );
DDReLoadBitmap(lpDDSBom[0], "bom1.bmp");
DDReLoadBitmap(lpDDSBom[1], "bom2.bmp");
DDSetColorKey(lpDDSBom[0],RGB(0,0,0));
DDSetColorKey(lpDDSBom[1],RGB(0,0,0));
//创建敌机
ddsd.dwWidth = 35;
ddsd.dwHeight = 35;
lpDD->CreateSurface( &ddsd, &lpDDSEnemy, NULL );
DDReLoadBitmap(lpDDSEnemy, "enemy.bmp");
DDSetColorKey(lpDDSEnemy,RGB(0,0,0));
//创建火焰页面
ddsd.dwWidth = 540;
ddsd.dwHeight = 50;
lpDD->CreateSurface( &ddsd, &lpDDSFlame, NULL );
DDReLoadBitmap(lpDDSFlame, "flame.bmp");
DDSetColorKey(lpDDSFlame,RGB(0,0,0));
//创建我机撞毁火焰页面
ddsd.dwWidth = 528;
ddsd.dwHeight = 66;
lpDD->CreateSurface( &ddsd, &lpDDSDead, NULL );
DDReLoadBitmap(lpDDSDead, "flamedead.bmp");
DDSetColorKey(lpDDSDead,RGB(0,0,0));
//创建敌机子弹页面
ddsd.dwWidth = 8;
ddsd.dwHeight = 8;
lpDD->CreateSurface( &ddsd, &lpDDSBall, NULL );
DDReLoadBitmap(lpDDSBall, "ball.bmp");
DDSetColorKey(lpDDSBall,RGB(0,0,0));
//创建我机子弹页面
ddsd.dwWidth = 5;
ddsd.dwHeight = 13;
lpDD->CreateSurface( &ddsd, &lpDDSBulet[0], NULL );
lpDD->CreateSurface( &ddsd, &lpDDSBulet[1], NULL );
DDReLoadBitmap(lpDDSBulet[0], "bulet0.bmp");
DDReLoadBitmap(lpDDSBulet[1], "bulet1.bmp");
DDSetColorKey(lpDDSBulet[0],RGB(0,0,0));
DDSetColorKey(lpDDSBulet[1],RGB(0,0,0));
//创建Clipper裁剪器
lpDD->CreateClipper(0, &lpClipper, NULL);
lpClipper->SetHWnd(0, hWnd);
lpDDSFront->SetClipper(lpClipper);
//取得当前路径
_getcwd( apppath, sizeof(apppath));
strcpy(openmidi, "play ");
strcat(openmidi, apppath);
strcat(openmidi, "\\a.mid");
strcpy(closemidi, "close ");
strcat(closemidi, apppath);
strcat(closemidi, "\\a.mid");
//播放midi
char buf[256];
mciSendString(openmidi, buf, sizeof(buf), NULL);
//开始游戏初始化
for (int k=0; k<ENEMYNUMBER; k++)
enemydead[k]=0;
enemylost=0;
planeremain=2;
gamestatus=GAME_LOG;
//设置定时器
SetTimer(hWnd, TIMER_CHANGEMAP, 20000, NULL);
return TRUE;
}
//*****************************************************
//释放所有的DirectDraw对象。
void FreeDDraw( void )
{
if( lpDD != NULL )
{
if( lpDDSFront != NULL )
{
lpDDSFront->Release(); lpDDSFront = NULL;
}
if( lpDDSBack!= NULL )
{
lpDDSBack->Release(); lpDDSBack= NULL;
}
for (int i=0 ;i<3; i++)
{
if( lpDDSPlane[i]!= NULL )
{
lpDDSPlane[i]->Release(); lpDDSPlane[i]= NULL;
}
}
for (i=0 ;i<2; i++)
{
if( lpDDSBom[i]!= NULL )
{
lpDDSBom[i]->Release(); lpDDSBom[i]= NULL;
}
}
for (i=0 ;i<2; i++)
{
if( lpDDSBulet[i]!= NULL )
{
lpDDSBulet[i]->Release(); lpDDSBulet[i]= NULL;
}
}
if( lpDDSMap != NULL )
{
lpDDSMap->Release(); lpDDSMap = NULL;
}
if( lpDDSFlame != NULL )
{
lpDDSFlame->Release(); lpDDSFlame = NULL;
}
if( lpDDSEnemy != NULL )
{
lpDDSEnemy->Release(); lpDDSEnemy = NULL;
}
if( lpDDSDead != NULL )
{
lpDDSDead->Release(); lpDDSDead = NULL;
}
if( lpDDSBall != NULL )
{
lpDDSBall->Release(); lpDDSBall = NULL;
}
lpDD->Release();
lpDD = NULL;
}
}
//*****************************************************
//换页
void Flip(void)
{
RECT Window;
POINT pt;
GetClientRect(hWnd, &Window);
pt.x=pt.y=0;
ClientToScreen(hWnd, &pt);
OffsetRect(&Window, pt.x, pt.y);
HRESULT rval=lpDDSFront->Blt(&Window, lpDDSBack, &backrect, DDBLT_WAIT, NULL);
if(rval == DDERR_SURFACELOST) lpDDSFront->Restore();
return ;
}
//**********************************
//绘制我机
void DrawPlane( void )
{
if (gamestatus!=GAME_START) return;//游戏结束
static int planenumber;
static unsigned int oldtime=0;
if (planenumber!=planeremain)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -