实例介绍
【实例截图】
【核心代码】
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <ddraw.h>
#include "resource.h"
#include "stdio.h"
#include "ddutil.h"
#include "CMidi.h"
#include "CDSound.h"
#define TITLE "突袭II" // 窗口标题
#define CLASSNAME "突袭II" // 窗口类名
HINSTANCE hInst; // 应用程序实例句柄
HWND hWndMain; // 主窗口句柄
LPDIRECTDRAW lpDD; // DirectDraw对象
LPDIRECTDRAWSURFACE lpDDSPrimary; // 主页面 640x480
LPDIRECTDRAWSURFACE lpDDSBack; // 后台缓冲区 640x480
LPDIRECTDRAWSURFACE lpDDSPic1; // 离屏页面1 640x480
LPDIRECTDRAWSURFACE lpDDSPic2; // 离屏页面2 1980x320
LPDIRECTDRAWSURFACE lpDDSPic3; // 离屏页面3 340x200
LPDIRECTDRAWSURFACE lpDDSPic4; // 离屏页面4 220x480
LPDIRECTDRAWSURFACE lpDDSPic5; // 离屏页面5 220x480
LPDIRECTDRAWSURFACE lpDDSPic6; // 离屏页面6 200x480
LPDIRECTDRAWSURFACE lpDDSPic7; // 离屏页面7 300x200
LPDIRECTDRAWSURFACE lpDDSPic8; // 离屏页面8 640x2400
LPDIRECTDRAWSURFACE lpDDSPig; // 离屏页面 100x200
LPDIRECTDRAWPALETTE lpDDPal; // 调色板
BOOL bActive; // 应用程序激活标志T为激活
// 函数声明
BOOL InitThread( void ); // 准备进程
bool FreeThread(void); // 释放进程
void MainLoop( void ); // 程序循环
void TitleDisplay(void); // 标题
void FreeResource( void ); // 释放资源
HRESULT RestoreAll( void ); // 恢复
void QuitOneThread( void); // 退出一个进程并且销毁分配的资源
void InfoDisplay(void ); // 显示序
void MainMenu(void ); // 显示主菜单
void LetGo(void); // 进入主要程序
void SetRect(RECT *rect, long left, long top, long right, long bottom);
// 设置填充矩形参数
// 扩展类
CMidi cMidi; // 定义播放Midi的类
CDSound cDSound; // 定义播放DirectSound的类
// 全局变量说明
int iThread = 0; // 程序进程唯一编号
// 0 播放序
// 1 显示标题
// 2 显示主选单
// 3 开始
// 999 退出
int iFps=0; // 刷新率计数器
int iDelayB=1; // 刷新分配倍数
int iSelectMainMenuNo=0; // 主选菜单项号,0为无
int iMoveTitleStep=320; // 序移动偏移量(左->右,右->左,中->右)
int iMouseMoveX=0; // 鼠标移动变量.左右
int iMouseMoveY=0; // 鼠标移动变量.上下
bool bTitleAbort=FALSE; // 序完成或者被用户中断标志
bool bSoundDrive=FALSE; // 音频设备备妥标志
int iMoveWay=5; // 移动标志8上2下4左6右5不动
bool bMouseLButton=false; // 鼠标左键按下标志
int iMoveFlag=4; // 移动标志8上2下4左6右5不动
bool bMoveFlag=false; // 移动允许标志
bool bInitAgain=true; // 重新初始化标志
bool bTimeToUp=false; // 计时标志
bool bTimeToUp2=false; // 计时标志2
bool bTimeToUp2_back=false; // 计时背景标志2
bool bFire=false; // 发射允许标志
int iFX,iFY,iFSpeed; // 飞弹位置,速度
int iBomX[40],iBomY[40];
bool bBomBI[40];
int iBom=0;
int iFang=16; // 左右偏移位标
int iGameLife=5; // 玩家飞机数
int iGameBom=3; // 玩家保护数
int iGameBlood=5; // 玩家能量
unsigned int iEnemyWay[512][512]; // 敌人运行轨迹
char cExeFullPath[256]; // 程序工作目录
int i,j; // 临时变量
// *******************************************************************
// 函数:FreeResource
// 功能:释放我们用过的所有DirectDraw对象
// *******************************************************************
void FreeResource( void ) // 释放资源
{
if (lpDD != NULL ) // 释放DirectDraw对象
{
if (lpDDSPrimary != NULL ) // 释放主页面
{
lpDDSPrimary->Release();
lpDDSPrimary = NULL;
}
if (lpDDSBack!= NULL ) // 释放后台缓冲区
{
lpDDSBack->Release();
lpDDSBack = NULL;
}
if (lpDDSPic1 != NULL ) // 释放离屏页面1
{
lpDDSPic1->Release();
lpDDSPic1 = NULL;
}
if (lpDDSPic2 != NULL ) // 释放离屏页面2
{
lpDDSPic2->Release();
lpDDSPic2 = NULL;
}
if (lpDDSPic3 != NULL ) // 释放离屏页面3
{
lpDDSPic3->Release();
lpDDSPic3 = NULL;
}
if (lpDDSPic4 != NULL ) // 释放离屏页面4
{
lpDDSPic4->Release();
lpDDSPic4 = NULL;
}
if (lpDDSPic5 != NULL ) // 释放离屏页面5
{
lpDDSPic5->Release();
lpDDSPic5 = NULL;
}
if (lpDDSPic6 != NULL ) // 释放离屏页面6
{
lpDDSPic6->Release();
lpDDSPic6 = NULL;
}
if (lpDDSPic7 != NULL ) // 释放离屏页面7
{
lpDDSPic7->Release();
lpDDSPic7 = NULL;
}
if (lpDDSPic8 != NULL ) // 释放离屏页面8
{
lpDDSPic8->Release();
lpDDSPic8 = NULL;
}
if (lpDDSPig != NULL ) // 释放离屏页面
{
lpDDSPig->Release();
lpDDSPig = NULL;
}
if (lpDDPal != NULL ) // 释放调色板
{
lpDDPal->Release();
lpDDPal = NULL;
}
lpDD->Release();
lpDD = NULL;
}
KillTimer(hWndMain,1);
KillTimer(hWndMain,2);
}
// *******************************************************************
// 函数:WindowProc
// 功能:主窗口的消息处理过程
// *******************************************************************
LRESULT CALLBACK WinProc( HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
switch ( message )
{
case WM_ACTIVATEAPP: // 应用程序激活消息
bActive = wParam;
break;
case WM_KEYUP: // 按键释放判断
switch( wParam )
{
case VK_DOWN:
if (iMoveWay==2)
iMoveWay=5;
break;
case VK_UP:
if (iMoveWay==8)
iMoveWay=5;
break;
case VK_LEFT:
if (iMoveWay==4)
iMoveWay=5;
break;
case VK_RIGHT:
if (iMoveWay==6)
iMoveWay=5;
break;
case VK_CONTROL:
bFire=false;
break;
}
break;
case WM_KEYDOWN: // 按键按下判断
switch( wParam )
{
case VK_ESCAPE: // 如果按下Esc就返回上级操作
QuitOneThread();
break;
case 0x36: // no 6
if (iFSpeed<=800)
iFSpeed =1;
break;
case 0x37: // no 7
if (iFSpeed>1)
iFSpeed-=1;
else iFSpeed=1;
break;
case VK_DOWN: // 下
iMoveWay=2;
if (iThread==1) // 如果在菜单选择
{
if (iSelectMainMenuNo<=3)
{
iSelectMainMenuNo =1;
}
else
iSelectMainMenuNo=1;
}
break;
case VK_UP: // 上
iMoveWay=8;
if (iThread==1) // 如果在菜单选择
{
if (iSelectMainMenuNo>=2)
{
iSelectMainMenuNo-=1;
}
else
iSelectMainMenuNo=4;
}
break;
case VK_LEFT: // 左
iMoveWay=4;
if (bTimeToUp2)
{
bTimeToUp2=false;
if (iFang>10)
iFang-=1;
}
break;
case VK_RIGHT: // 右
iMoveWay=6;
if (bTimeToUp2)
{
bTimeToUp2=false;
if (iFang<23)
iFang =1;
}
break;
case VK_RETURN: // 回车
if (iThread==1) // 如果是在菜单选择,有效
{
if (iSelectMainMenuNo==4) // 选择了退出
{
iThread=999;
QuitOneThread();
}
if (iSelectMainMenuNo==1) // 选择了NewG
{
bInitAgain=true;
iThread=3;
}
}
break;
case VK_CONTROL: // Ctrl键
bFire=true;
break;
}
break;
/*case WM_MOUSEMOVE: // 鼠标移动
if (iThread==2) // 在主选单中
{
iMouseMoveX=lParam&0xffff;
iMouseMoveY=lParam>>16;
iSelectMainMenuNo=0;
if (iMouseMoveX>250&&iMouseMoveX<390)
{
if (iMouseMoveY>=260&&iMouseMoveY<310)
iSelectMainMenuNo=1;
if (iMouseMoveY>=310&&iMouseMoveY<360)
iSelectMainMenuNo=2;
if (iMouseMoveY>=360&&iMouseMoveY<410)
iSelectMainMenuNo=3;
if (iMouseMoveY>=410&&iMouseMoveY<460)
iSelectMainMenuNo=4;
}
}
case WM_LBUTTONDOWN: // 鼠标左击
switch(wParam)
{
case MK_LBUTTON:
iMouseMoveX=lParam&0xffff;
iMouseMoveY=lParam>>16;
bMouseLButton=true;
if (iThread==2)
{
if (iSelectMainMenuNo==4)
{
iThread=999;
QuitOneThread();
}
if (iSelectMainMenuNo==1)
{
bInitAgain=true;
iThread=3;
}
}
break;
}
break;*/
case WM_TIMER:
switch ( wParam )
{
case 1:
bTimeToUp=!bTimeToUp; // 计时器到点,用于动画切换
break;
case 2:
bTimeToUp2=true;
bTimeToUp2_back=true;
default:
break;
}
break;
case MM_MCINOTIFY: // Midi播送完
if (bSoundDrive)
cMidi.Replay();
break;
case WM_DESTROY: // 销毁窗口消息
FreeResource();
PostQuitMessage(0);
break;
}
// 调用缺省的过程处理过程
return DefWindowProc(hWnd, message, wParam, lParam);
}
// ******************************************************************
// 函数:InitWindow()
// 功能:创建主窗口。
// ******************************************************************
BOOL InitWindow( HINSTANCE hInstance, int nCmdShow )
{
WNDCLASS wc; // 窗口类结构
// 填充窗口类结构
wc.style = 0;
wc.lpfnWndProc = WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(IDR_MAINFRAME));
// 在任务切换中显示图标
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
// 提取鼠标样式
wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); // 选择黑色刷做为窗口背景
wc.lpszMenuName = NULL; // windows未用保留为NULL
wc.lpszClassName = CLASSNAME;
// 注册窗口类
RegisterClass( &wc );
// 创建主窗口
hWndMain= CreateWindowEx(
0,
CLASSNAME, // 窗口的类名称,必须与上面的wc.lpszClassName一致
TITLE, // 窗口的标题名
WS_POPUP,
0,
0,
GetSystemMetrics( SM_CXSCREEN ),
GetSystemMetrics( SM_CYSCREEN ),
NULL,
NULL,
hInstance,
NULL );
if (!hWndMain )
return FALSE; // 创建失败就返回报告错误
// SetCursor(LoadCursor(hInstance,"IDC_CUR")); // 指定使用光标
// ShowCursor(FALSE); // 隐藏光标
// 显示并更新窗口
ShowWindow( hWndMain, nCmdShow );
UpdateWindow( hWndMain );
return TRUE;
}
// ******************************************************************
// 函数:InitDDraw()
// 功能:初始化DirectDraw环境,创建换页链(主页面,一个后台缓冲区)
// 以及创建一个定时器。
// ******************************************************************
BOOL InitDDraw(void)
{
DDSURFACEDESC ddsd;
DDSCAPS ddscaps;
HRESULT ddrval;
// 创建DirectDraw对象
ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
if (ddrval != DD_OK )
return FALSE;
// 取得全屏独占模式
ddrval = lpDD->SetCooperativeLevel( hWndMain, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
if (ddrval != DD_OK )
return FALSE;
// 设置显示器显示模式为640x480x256(8bit)色
ddrval = lpDD->SetDisplayMode( 640, 480, 16);
if (ddrval != DD_OK )
return FALSE;
// 填充换页链结构
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
DDSCAPS_FLIP |
DDSCAPS_COMPLEX;
// 指定后台缓冲区数量为1
ddsd.dwBackBufferCount = 1;
// 创建换页链,包括了主页面及其后台缓冲区
ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
if (ddrval != DD_OK )
return FALSE;
// 获得指向后台缓冲区的页面指针
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
if (ddrval != DD_OK )
return FALSE;
// 创建与主页面等大小的两个离屏页面
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = 640;
ddsd.dwHeight = 480;
if (lpDD->CreateSurface(&ddsd, &lpDDSPic1, NULL) != DD_OK)
return FALSE;
ddsd.dwWidth = 1980;
ddsd.dwHeight = 320; // 60X80 x(16 1 16) X 4
if (lpDD->CreateSurface(&ddsd, &lpDDSPic2, NULL) != DD_OK)
return FALSE;
ddsd.dwWidth=340;
ddsd.dwHeight=200; // 创建辅助离屏页面
if (lpDD->CreateSurface(&ddsd, &lpDDSPic3, NULL) != DD_OK)
return FALSE;
ddsd.dwWidth=220;
ddsd.dwHeight=480; // 创建辅助离屏页面
if (lpDD->CreateSurface(&ddsd, &lpDDSPic4, NULL) != DD_OK)
return FALSE;
ddsd.dwWidth=220;
ddsd.dwHeight=480; // 创建辅助离屏页面
if (lpDD->CreateSurface(&ddsd, &lpDDSPic5, NULL) != DD_OK)
return FALSE;
ddsd.dwWidth=200;
ddsd.dwHeight=480; // 创建辅助离屏页面
if (lpDD->CreateSurface(&ddsd, &lpDDSPic6, NULL) != DD_OK)
return FALSE;
ddsd.dwWidth=300;
ddsd.dwHeight=200; // 创建辅助离屏页面
if (lpDD->CreateSurface(&ddsd, &lpDDSPic7, NULL) != DD_OK)
return FALSE;
ddsd.dwWidth=640;
ddsd.dwHeight=2400; // 创建辅助离屏页面
if (lpDD->CreateSurface(&ddsd, &lpDDSPic8, NULL) != DD_OK)
return FALSE;
ddsd.dwWidth=100;
ddsd.dwHeight=200; // 创建辅助离屏页面
if (lpDD->CreateSurface(&ddsd, &lpDDSPig, NULL) != DD_OK)
return FALSE;
// 从磁盘文件或者资源中载入调色板
lpDDPal = DDLoadPalette(lpDD, "IDB_TITLE");
// 将调色板设置给主页面
if (lpDDPal)
lpDDSPrimary->SetPalette( lpDDPal );
// 初始化音频设备
if (cDSound.Init(hWndMain))bSoundDrive=true;
// 调用页面初始化函数
// if (!InitThread() )
// return FALSE;
return TRUE;
}
// ******************************************************************
// 函数:WinMain()
// 功能:应用程序入口
// ******************************************************************
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
hInst=hInstance;
// 初始化主窗口
if (!InitWindow( hInstance, nCmdShow))
return FALSE;
// 初始化DirectDraw环境
if (!InitDDraw())
{
MessageBox(hWndMain, "初始化DirectDraw过程中出错!", "Error", MB_OK);
FreeResource(); // 释放资源
DestroyWindow(hWndMain);
return FALSE;
}
SetTimer(hWndMain,1,100,NULL); // 动画切换计时器
SetTimer(hWndMain,2,20,NULL); // 动画切换计时器2
// 进入消息循环
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) // 程序处于激活状态
{
MainLoop();
}
else WaitMessage(); // 否则等待
}
// return msg.wParam;
}
// ******************************************************************
// 函数:InitTitle()
// 功能:初始化页面图象
// ******************************************************************
BOOL InitThread( void )
{
bInitAgain=false;
HBITMAP hbm;
switch (iThread)
{
case 0: // 序
ShowCursor(FALSE); // 隐藏光标
if (bSoundDrive)
{
cDSound.SetTrack("wav\\info.wav",0);
// cDSound.SetTrack("wav\\di1.wav",1);
cDSound.Play(false,0);
}
hbm = (HBITMAP)LoadImage(hInst, "IDB_TITLE", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
if (hbm == NULL)
return FALSE;
DDCopyBitmap(lpDDSPic3, hbm, 300, 680, 340, 200);
// 释放hbm位图对象
DeleteObject(hbm);
return true;
case 1: // 菜单
cDSound.SetTrack("wav\\gun.wav",1);
cDSound.SetTrack("wav\\ack.wav",2);
cDSound.SetTrack("wav\\dead.wav",3);
cDSound.SetTrack("wav\\fire.wav",4);
iSelectMainMenuNo=1;
// 从磁盘文件中将我们所需要的图象载入到一个hbm位图对象中
hbm = (HBITMAP)LoadImage(hInst, "IDB_TITLE", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); // |LR_LOADFROMFILE);
if (hbm == NULL)
return FALSE;
DDCopyBitmap(lpDDSPic1, hbm, 0, 0, 640, 480);
DDCopyBitmap(lpDDSPic7, hbm, 0, 680, 300, 200);
DDCopyBitmap(lpDDSPig, hbm, 0, 0, 100, 200);
DDSetColorKey(lpDDSPic1, CLR_INVALID);
DDSetColorKey(lpDDSPic7, CLR_INVALID);
DDSetColorKey(lpDDSPig, CLR_INVALID);
// 释放hbm位图对象
DeleteObject(hbm);
return true;
case 3: // 开始1关
// ShowCursor(false); // 隐藏光标
// FILE *fin;
// fin=fopen("data\\enemy.001","rb");
// if (fin==NULL)
// return false;
// for(i=0;i<512;i )
// for(j=0;j<512;j )
// fscanf(fin,"%d",&iEnemyWay[i][j]);
// fprintf(fin,"200\r\n");
// fclose(fin);
iFX=300;
iFY=400;
iFSpeed=2;
int i;
// ,j=0;
for (i=0;i<40;i )
{
// if (j==0)j=1;
// else j=0;
iBomX[i]=-100;
iBomY[i]=-100;
bBomBI[i]=false;
}
cMidi.Stop();
cMidi.ChangePlay("wav\\fight.mid");
// 从磁盘文件中将我们所需要的图象载入到一个hbm位图对象中
hbm = (HBITMAP)LoadImage(hInst, "IDB_FJ1", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); // |LR_LOADFROMFILE);
if (hbm == NULL)
return FALSE;
DDCopyBitmap(lpDDSPic1, hbm, 0, 0, 640, 480); // 设置一个640*480的页面
DDSetColorKey(lpDDSPic1, CLR_INVALID);
// 释放hbm位图对象
DeleteObject(hbm);
hbm = (HBITMAP)LoadImage(hInst, "IDB_FJ01", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); // |LR_LOADFROMFILE);
if (hbm == NULL)
return FALSE;
DDCopyBitmap(lpDDSPic2, hbm, 0, 0, 1980, 320);
DDSetColorKey(lpDDSPic2, CLR_INVALID);
// 设置一个1980 x 320 的页面
// 释放hbm位图对象
DeleteObject(hbm);
hbm = (HBITMAP)LoadImage(hInst, "pic\\map01.bmp", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE);
// LR_CREATEDIBSECTION如果缺少,将导致颜色偏差
if (hbm == NULL)
return FALSE;
DDCopyBitmap(lpDDSPic8, hbm, 0, 0, 640, 2400);
DDSetColorKey(lpDDSPic8, CLR_INVALID);
// 设置一个640 x 2400 的页面
// 释放hbm位图对象
DeleteObject(hbm);
return true;
}
return false;
}
// 更新屏幕
void MainLoop( void ) // 程序循环
{
// 计算刷新率
static int siFrame=0, siNewTime=0, siOldTime=0;
static int siNewUpTime=0,siOldUpTime=0;
siFrame ;
siNewTime=timeGetTime();
siNewUpTime=siNewTime;
if (siNewTime > siOldTime 1000)
{
siOldTime=siNewTime;
iFps=siFrame;
siFrame=0;
iDelayB=iFps/48;
}
if (siNewUpTime>siOldUpTime 2)
{
siOldUpTime=siNewUpTime;
iMoveTitleStep =1;
// bMoveFlag=true;
}
if (bInitAgain)
{
if (InitThread()==false)
{
iThread=999;
QuitOneThread();
}
}
switch (iThread)
{
case 0: // info display
InfoDisplay();
break;
case 1: // title display
/*TitleDisplay();
break;
case 2:*/
MainMenu();
break;
case 3:
LetGo();
break;
}
}
void SetRect(RECT *rect, long left, long top, long right, long bottom)
{
rect->left=left;
rect->top=top;
rect->right=right;
rect->bottom=bottom;
}
void InfoDisplay()
{
HRESULT ddrval;
static n=0;
RECT backR1, frontR1;
SetRect(&backR1, 0, 0, 340, 200);
SetRect(&frontR1, 150,150, 490, 350);
// 清屏后台缓冲区
DDBLTFX ddBltFx;
ddBltFx.dwSize = sizeof(DDBLTFX);
ddBltFx.dwFillColor = DDColorMatch(lpDDSBack, RGB(0,0,0));
lpDDSBack->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx);
// 将背景图象Blit到后台缓冲区
lpDDSBack->Blt(&frontR1, lpDDSPic3, &backR1, DDBLT_WAIT, NULL);
if (bTimeToUp) // 没有按Esc时自动计时
{
bTimeToUp=false;
n =1;
if (n>100)
{
// FreeThread();
// iThread=1;
// bInitAgain=true;
QuitOneThread();
}
}
// 打印刷新率fps
HDC hdc;
char temp[32];
lpDDSBack->GetDC(&hdc);
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(0,255,0));
sprintf(temp, "%d 帧/秒", iFps);
TextOut(hdc, 0, 0, temp, strlen(temp));
lpDDSBack->ReleaseDC(hdc);
// 换页
while ( 1 )
{
ddrval = lpDDSPrimary->Flip( NULL, DDFLIP_WAIT ); // 调用换页函数
if (ddrval == DD_OK ) // 成功则退出while循环
break;
if (ddrval == DDERR_SURFACELOST ) // 如果页面丢失,则恢复页面
{
ddrval = lpDDSPrimary->Restore(); // 恢复主页面
if (ddrval!=DD_OK)
break;
ddrval=lpDDSPic3->Restore(); // 恢复离屏页面3
if (ddrval!=DD_OK)
break;
if (!InitThread())
break; // 重新提取背景
}
if (ddrval != DDERR_WASSTILLDRAWING)
break;
}
}
void MainMenu()
{
HRESULT ddrval;
RECT backR1, frontR1,backR2, frontR2,backR3, frontR3;
SetRect(&backR1, 0, 0, 640, 480);
SetRect(&frontR1, 0,0, 640, 480);
SetRect(&backR2, 0, 0, 150, 200);
SetRect(&frontR2, 245,260, 395, 460);
// 清屏后台缓冲区
DDBLTFX ddBltFx;
ddBltFx.dwSize = sizeof(DDBLTFX);
ddBltFx.dwFillColor = DDColorMatch(lpDDSBack, RGB(0,0,0));
lpDDSBack->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx);
// 将背景图象Blit到后台缓冲区
lpDDSBack->Blt(&frontR1, lpDDSPic1, &backR1, DDBLT_WAIT|DDBLT_KEYSRC, NULL);
lpDDSBack->Blt(&frontR2, lpDDSPic7, &backR2, DDBLT_WAIT|DDBLT_KEYSRC, NULL);
switch (iSelectMainMenuNo)
{
case 1:
SetRect(&backR3, 150, 0, 300, 50);
SetRect(&frontR3, 245,260, 395, 310);
break;
case 2:
SetRect(&backR3, 150, 50, 300, 100);
SetRect(&frontR3, 245,310, 395, 360);
break;
case 3:
SetRect(&backR3, 150, 100, 300, 150);
SetRect(&frontR3, 245,360, 395, 410);
break;
case 4:
SetRect(&backR3, 150, 150, 300, 200);
SetRect(&frontR3, 245,410, 395, 460);
break;
default:
SetRect(&backR3, 0, 0, 150, 200);
SetRect(&frontR3, 245,260, 395, 460);
break;
}
lpDDSBack->Blt(&frontR3, lpDDSPic7, &backR3, DDBLT_WAIT|DDBLT_KEYSRC, NULL);
// 打印刷新率fps
HDC hdc;
char temp[32];
lpDDSBack->GetDC(&hdc);
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(0,255,0));
sprintf(temp, "%d 帧/秒", iFps);
TextOut(hdc, 0, 0, temp, strlen(temp));
lpDDSBack->ReleaseDC(hdc);
// 换页
while ( 1 )
{
ddrval = lpDDSPrimary->Flip( NULL, DDFLIP_WAIT ); // 调用换页函数
if (ddrval == DD_OK ) // 成功则退出while循环
break;
if (ddrval == DDERR_SURFACELOST ) // 如果页面丢失,则恢复页面
{
ddrval = lpDDSPrimary->Restore(); // 恢复主页面
if (ddrval!=DD_OK)
break;
ddrval=lpDDSPic1->Restore(); // 恢复离屏页面1
if (ddrval!=DD_OK)
break;
ddrval=lpDDSPic7->Restore(); // 恢复离屏页面7
if (ddrval!=DD_OK)
break;
ddrval=lpDDSPig->Restore(); // 恢复离屏页面pig
if (ddrval!=DD_OK)
break;
if (!InitThread())
break; // 重新提取背景
}
if (ddrval != DDERR_WASSTILLDRAWING)
break;
}
}
bool FreeThread()
{
switch (iThread)
{
case 0:
if (bSoundDrive)cDSound.Stop(0);
break;
case 999:
// FreeResource();
break;
default :
return false;
}
return true;
}
void QuitOneThread()
{
switch (iThread)
{
case 0: // info display
FreeThread();
cMidi.Play(hWndMain,"wav\\menu.mid");
iThread=1;
bInitAgain=true;
break;
case 1: // menu display
/*FreeThread();
iThread=2;
bInitAgain=true;
break;
case 2: // menu
// FreeThread();
// iThread=999;
// bInitAgain=true;*/
break;
case 3: // let go!!
FreeThread();
cMidi.Stop();
cMidi.ChangePlay("wav\\menu.mid");
iThread=1;
bInitAgain=true;
break;
case 999: // exit system
cMidi.Stop();
FreeResource();
PostQuitMessage(0);
break;
default:
FreeThread();
iThread=0;
bInitAgain=true;
break;
}
}
void LetGo() // 游戏开始...
{
RECT backR1, frontR1,backR2, frontR2,backR3, frontR3;
static bool bFireLeftFlag=false; //
static bool bAckFlag=false; //
static int iBoosX=200,iBoosY=10; //
static int iBack=1480; // 背景位置
int i,j;
switch (iMoveWay)
{
case 4:
if ((iFX-iFSpeed)>=0)
iFX-=iFSpeed;
else
iFX=0;
break;
case 6:
if ((iFX iFSpeed)<=580)
iFX =iFSpeed;
else
iFX=580;
break;
case 8:
if ((iFY-iFSpeed)>=0)
iFY-=iFSpeed;
else
iFY=0;
break;
case 2:
if ((iFY iFSpeed)<=400)
iFY =iFSpeed;
else
iFY=400;
break;
case 5: // 如果没有按下方向键
if (bTimeToUp2)
{
bTimeToUp2=false;
if (iFang>16)
iFang-=1; // 右返回
if (iFang<16)
iFang =1; // 左返回
}
break;
}
// 清屏后台缓冲区 不作这步将出现拖尾现象
DDBLTFX ddBltFx;
ddBltFx.dwSize = sizeof(DDBLTFX);
ddBltFx.dwFillColor = DDColorMatch(lpDDSBack, RGB(0,0,0));
lpDDSBack->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx);
// 将背景图象Blit到后台缓冲区
SetRect(&backR3, 0, iBack, 640, iBack 480);
SetRect(&frontR3, 0, 0, 640, 480);
iBack--;
if (iBack<0)
iBack=2399;
if (iBack>1919)
{
SetRect(&backR3,0, iBack, 640, 2400);
SetRect(&frontR3, 0, 0, 640, 2400-iBack);
lpDDSBack->Blt(&frontR3, lpDDSPic8, &backR3, DDBLT_WAIT, NULL);
SetRect(&backR3,0, 0, 640, 480-(2400-iBack));
SetRect(&frontR3, 0,2400-iBack , 640, 480);
lpDDSBack->Blt(&frontR3, lpDDSPic8, &backR3, DDBLT_WAIT, NULL);
}
else
{
lpDDSBack->Blt(&frontR3, lpDDSPic8, &backR3, DDBLT_WAIT, NULL);
}
static int iBoosHP=1000;
// if (iBoosY >400)
// iBoosY=0;
// if (iBoosHP>800)
// iBoosY ;
if (bTimeToUp)
{
SetRect(&backR2, 510, 264, 524, 300);
// if (iBoosHP<300)
// iBoosY-=1;
}
else
SetRect(&backR2, 533, 264, 547,300);
for (i=0;i<2;i ) // 两颗飞弹轨迹
{
if (iBomY[i]-3>=0&&bBomBI[i])
{
iBomY[i]-=3;
if (iBomY[i]<iBoosY 50&&iBomY[i]>iBoosY&&iBomX[i]<iBoosX 90&&iBomX[i]>iBoosX 30)
{
iBoosHP-=5;
bAckFlag=true;
bBomBI[i]=false;
cDSound.Play(false,2);
}
}
else
{
iBoosHP =1;
bFireLeftFlag=!bFireLeftFlag;
j=1;
if (bFireLeftFlag)
{
j=0;
}
iBomX[i]=iFX 6 j*34;
iBomY[i]=iFY 40;
bBomBI[i]=true;
cDSound.Play(false,4);
}
SetRect(&frontR2,iBomX[i],iBomY[i],iBomX[i] 14,iBomY[i] 36);
lpDDSBack->Blt(&frontR2, lpDDSPic1, &backR2, DDBLT_WAIT|DDBLT_KEYSRC, NULL);
// 飞弹
}
SetRect(&backR1, iFang*60, 0, iFang*60 60, 80);
// 设置飞机样式
SetRect(&frontR1, iFX,iFY, iFX 60, iFY 80);
// 设置飞机位置
lpDDSBack->Blt(&frontR1, lpDDSPic2, &backR1, DDBLT_WAIT|DDBLT_KEYSRC, NULL);
// 画出飞机
// if (bTimeToUp)
// SetRect(&backR1, 510, 286,524, 300);
// else
// SetRect(&backR1, 533, 286, 547,300);
// SetRect(&frontR1, iFX 23,iFY 83, iFX 37, iFY 97);
// lpDDSBack->Blt(&frontR1, lpDDSPic1, &backR1, DDBLT_WAIT|DDBLT_KEYSRC, NULL);
// 尾气
SetRect(&backR2,350,390,490,460);
SetRect(&frontR2,iBoosX,iBoosY,iBoosX 140,iBoosY 70);
lpDDSBack->Blt(&frontR2, lpDDSPic1, &backR2, DDBLT_WAIT|DDBLT_KEYSRC, NULL);
// A10
if (bAckFlag)
{
static int iAckDly=0;
SetRect(&backR2, iAckDly*65, 0, (iAckDly 1)*65, 65);
SetRect(&frontR2,iBoosX 43,iBoosY 20,iBoosX 108,iBoosY 85);
lpDDSBack->Blt(&frontR2, lpDDSPic1, &backR2, DDBLT_WAIT|DDBLT_KEYSRC, NULL);
// 击中
if (iAckDly<8)
iAckDly ;
else
{
iAckDly=0;
bAckFlag=false;
}
}
/*
SetRect(&backR2, 128, 450, 192, 480);
for(i=4;i<8;i ) // 背景在顶上流过
{
SetRect(&frontR2, 40 (i-4)*140,iBackY[i], (i-4)*140 104, iBackY[i] 30);
lpDDSBack->Blt(&frontR2, lpDDSPic1, &backR2, DDBLT_WAIT|DDBLT_KEYSRC, NULL);
if (bTimeToUp2_back)
iBackY[i] =1;
if (iBackY[i]>400)iBackY[i]=0;
}*/
if (bTimeToUp2_back)
bTimeToUp2_back=false; // 标记背景已经刷新
for (i=0;i<iGameBom;i )
{
// 显示保护数
SetRect(&backR2,0,290,20,305);
SetRect(&frontR2,i*20,430,i*20 20,445);
lpDDSBack->Blt(&frontR2, lpDDSPic1, &backR2, DDBLT_WAIT|DDBLT_KEYSRC, NULL);
}
for (i=0;i<iGameBlood;i )
{
// 显示血
SetRect(&backR2,0,310,8,320);
SetRect(&frontR2,i*8,445,(i 1)*8,455);
lpDDSBack->Blt(&frontR2, lpDDSPic1, &backR2, DDBLT_WAIT|DDBLT_KEYSRC, NULL);
}
for (i=0;i<iGameLife;i )
{
// 显示飞机数
SetRect(&backR2,0,260,20,292);
SetRect(&frontR2,i*20,448,i*20 20,480);
lpDDSBack->Blt(&frontR2, lpDDSPic1, &backR2, DDBLT_WAIT|DDBLT_KEYSRC, NULL);
}
if (iBoosHP>=0)
{
for(i=0;i<(iBoosHP/100 1);i )
{
// 显示Boss
SetRect(&backR2,0,310,8,320);
SetRect(&frontR2,i*8 70,2,(i 1)*8 70,12);
lpDDSBack->Blt(&frontR2, lpDDSPic1, &backR2, DDBLT_WAIT|DDBLT_KEYSRC, NULL);
}
}
// 打印刷新率fps
HDC hdc;
char temp[32];
lpDDSBack->GetDC(&hdc);
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(0,255,0));
sprintf(temp, "%d 帧/秒", iFps);
TextOut(hdc, 560, 0, temp, strlen(temp));
if (iBoosHP>=0)
{
sprintf(temp, "无敌金刚"); // %d", iBoosHP);
}
else
sprintf(temp,"要死不活 %d", iBoosHP);
TextOut(hdc, 0, 0, temp, strlen(temp));
lpDDSBack->ReleaseDC(hdc);
// 换页
HRESULT ddrval;
while ( 1 )
{
ddrval = lpDDSPrimary->Flip( NULL, DDFLIP_WAIT ); // 调用换页函数
if (ddrval == DD_OK ) // 成功则退出while循环
break;
if (ddrval == DDERR_SURFACELOST ) // 如果页面丢失,则恢复页面
{
ddrval = lpDDSPrimary->Restore(); // 恢复主页面
if (ddrval!=DD_OK)
break;
ddrval=lpDDSPic1->Restore(); // 恢复离屏页面1
if (ddrval!=DD_OK)
break;
ddrval=lpDDSPic2->Restore(); // 恢复离屏页面2
if (ddrval!=DD_OK)
break;
ddrval=lpDDSPic8->Restore(); // 恢复离屏页面8
if (ddrval!=DD_OK)
break;
if (!InitThread())
break; // 重新提取背景
}
if (ddrval != DDERR_WASSTILLDRAWING)
break;
}
}
标签: 游戏
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论