Delphi 环境下使用DirectDraw实现简单的全屏游戏

来源:互联网 发布:云计算数据中心 用电 编辑:程序博客网 时间:2024/05/20 20:56

注:demo来源于《windows游戏编程大师技巧》demo6-3,本文章用Delphi实现该demo。

首先,使用Windows API函数实现原生态窗体,然后调用DDraw类实现效果。

部分注释用英文写在代码里(为了能无障碍看懂英文文档,所以在边学代码边学好英语,呵呵~~)

运行效果为,循环随机在全屏幕上绘制像素点:
按下Escape键退出全屏

program Test_6_1;uses  Windows,  Messages,  DirectX, DXDraws,  uUtil in '..\Library\DirectDraw_demo\uUtil.pas';const//set the resolution of displayer of you  SCREEN_WIDTH = 1920;  SCREEN_HEIGHT = 1080;                    var  MyClassName : string;  MyWindowName : string;var  gbl_MSG : MSG;  gbl_HDC : HDC;  gbl_HW : HWND;  gbl_hinst : HINST;var  FDirectDrawSurface : TDirectDrawSurface;  FDirectDraw : TDirectDraw;  ddsd : TDDSurfaceDesc_DX6;//call back functionfunction MyWndProc(hW: HWnd; messages: UInt; wParams: WPARAM; lParams: LPARAM): LRESULT; stdcall;var  ps : PAINTSTRUCT;  local_hdc : HDC;begin  Result := 0;  case messages of    WM_COMMAND:    begin    end;    WM_PAINT:    begin      local_hdc := BeginPaint(hW, ps);      EndPaint(hW, ps);    end;    WM_DESTROY:    begin      PostQuitMessage(0);    end  else    Result := DefWindowProc(hW, messages, wParams, lParams);  end;end;//initializefunction Game_Init(pParam: PChar = nil; num_Params : Integer = 0): Integer;begin  Randomize;  //create a instance of TDirectDraw,use DDraw7 by default  FDirectDraw := TDirectDraw.Create(nil);  //set ccoperative level between window and dx  //you can simply set flag to ddscl_normal, to be a windowed game  //if you use ddscl_fullscreen please ddscl_exclusive  FDirectDraw.IDDraw7.SetCooperativeLevel(gbl_HW, DDSCL_FULLSCREEN or DDSCL_EXCLUSIVE or DDSCL_ALLOWREBOOT);  //set display mode  FDirectDraw.IDDraw7.SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, 0, 0);  FDirectDrawSurface := TDirectDrawSurface.Create(FDirectDraw);  //fill structure TDDSurfaceDesc  FillChar(ddsd, SizeOf(TDDSurfaceDesc_DX6), #0);  ddsd.dwSize := SizeOf(TDDSurfaceDesc_DX6);  ddsd.dwFlags := DDSD_CAPS;  ddsd.ddsCaps.dwCaps := DDSCAPS_PRIMARYSURFACE;  //create surface  FDirectDrawSurface.CreateSurface(ddsd);end;//finalizefunction Game_ShutDown(pParam: PChar = nil; num_Params : Integer = 0): Integer;begin  if Assigned(FDirectDraw) then  begin    FDirectDraw.Free;    FDirectDraw := nil;  end;  if Assigned(FDirectDrawSurface) then  begin    FDirectDrawSurface.Free;    FDirectDrawSurface := nil;  end;end;//game loopfunction Game_Main(pParam: PChar = nil; num_Params : Integer = 0): Integer;var  ddsd : TDDSurfaceDesc_DX6;  iPitch : Integer;  pSurface : PChar;  i, x, y: Integer;  color : COLOR16;begin  if KeyDown(VK_ESCAPE) then    SendMessage(gbl_HW, WM_CLOSE, 0, 0);  FillChar(ddsd, SizeOf(TDDSurfaceDesc_DX6), #0);  ddsd.dwSize := Sizeof(TDDSurfaceDesc_DX6);  //lock  FDirectDrawSurface.Lock(ddsd);  iPitch := ddsd.lPitch;  pSurface := ddsd.lpSurface;  color := RGB(255, 0, 0);  for i := 0 to 1000 - 1 do  begin    x := Random(SCREEN_WIDTH) * 2;    y := Random(SCREEN_HEIGHT);    move(color, pSurface[x + y * iPitch], SizeOf(COLOR16));  end;  //unlock  FDirectDrawSurface.UnLock;end;{$R *.res}// main loopbegin  gbl_hinst := GetModuleHandle(nil);  MyClassName := 'Test';  MyWindowName := 'MyTest_6_1';  if MyRegisterClass(gbl_hinst, @MyWndProc, PChar(MyClassName)) = 0 then  begin    MessageBox(0, 'RegisterClass defeat', 'Error', MB_OKCANCEL);    Exit;  end;  if not InitInstance(gbl_hinst, SW_SHOW, PChar(MyClassName), PChar(MyWindowName), gbl_HW) then  begin    MessageBox(0, 'InitInstance defeat', 'Error', MB_OKCANCEL);    Exit;  end;  Game_Init();  //if use peekmessage,please add one line code : 'Sleep(100);' ,used to slow the effect//  while True do//  begin//    if PeekMessage(gbl_MSG, 0, 0, 0, PM_REMOVE) then//    begin//      if gbl_MSG.message = WM_QUIT then//        Break;////      TranslateMessage(gbl_MSG);//      DispatchMessage(gbl_MSG);//    end;////    Game_Main();//  end;  while GetMessage(gbl_MSG, 0, 0, 0) do  begin    TranslateMessage(gbl_MSG);    DispatchMessage(gbl_MSG);    Game_Main();  end;  Game_ShutDown();end.

然后,请包含下面这个单元:

unit uUtil;interfaceuses  Windows, Messages;function KeyDown(const Key : Integer): Boolean;function MyRegisterClass(hInst : HINST; pProc: Pointer; pClassName : PChar): WORD; overload;function MyRegisterClass(const wClass : TWndClassEx): WORD; overload;function InitInstance(hInst : HINST; nCmdShow : Integer; pClassName, pWindowName : PChar; out hW : HWND): Boolean;implementationfunction KeyDown(const Key : Integer): Boolean;begin  Result := GetAsyncKeyState(Key) <> 0;end;function MyRegisterClass(hInst : HINST; pProc: Pointer; pClassName : PChar): WORD;var  wclass: TWndClassEx;begin  //Don't forget to set all the properties, or you will failed to register  wclass.cbSize := SizeOf(WNDCLASSEXW);                                 //set size of this structure  wclass.style := CS_HREDRAW or CS_VREDRAW;                             //set style of general property of this form  wclass.lpfnWndProc := pProc;                                         //callback function  wclass.cbClsExtra := 0;  wclass.cbWndExtra := 0;  wclass.hInstance := hInst;                                           //set instance  wclass.hIcon := LoadIcon(0, IDI_APPLICATION);  wclass.hCursor := LoadCursor(0, IDC_ARROW);  wclass.hbrBackground := GetStockObject(WHITE_BRUSH);  wclass.lpszMenuName := nil;  wclass.lpszClassName := pClassName;  wclass.hIconSm := LoadIcon(wclass.hInstance, MAKEINTRESOURCE(0));   //set small icon  Result := RegisterClassEx(wclass);end;function MyRegisterClass(const wClass : TWndClassEx): WORD;begin  Result := RegisterClassEx(wClass);end;function InitInstance(hInst : HINST; nCmdShow : Integer; pClassName, pWindowName: PChar; out hW : HWND): Boolean;begin  Result := False;  hW := CreateWindow(pClassName, pWindowName, WS_OVERLAPPEDWINDOW,      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInst, nil);  if hW <> 0 then  begin    ShowWindow(hW, nCmdShow);    UpdateWindow(hW);    Result := True;  end;end;end.

注意:请将:

const  SCREEN_WIDTH = 1920;  SCREEN_HEIGHT = 1080;   

设置为你电脑当前的分辨率,否者效果可能会有问题。

另外,不要用在win10系统下使用或者学习,因为win10已经将DDraw抛弃(集成到d3d中去了)。我在win10下试验过,显示效果会有问题。

最后,请包含一下DelphiX中的DirectX, DXDraws单元,或者编译一下DelphiX的dpk工程文件,即可编译通过。DelphiX源代码网上有很多前辈已经共享过,下载下来即可。(我也上传了DelphiX全部源代码,访问我的资源页能找到。)

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 婷美护肤品 婷美广告 婷美化妆品 婷美代言人 婷美塑身衣 婷美瘦身衣 婷美肌底液 婷美洗发水 婷美厂家 婷美洗面奶 婷美丰胸 婷美内裤 婷美塑型衣 婷美美肌 婷美塑身内衣 婷美小屋属于什么档次 无双的婷美广告 婷美小屋护肤品怎么样 婷美内衣广告 祝无双婷美广告 婷美魔力21产后恢复 婷美小屋亏了几十万 婷美减肥塑身内衣 婷美内衣怎么样 婷美文胸怎么样 婷美眼霜怎么样 婷美塑身衣有效果吗 婷美化妆品套装 婷美塑身衣效果怎样 婷美化妆品价格表 婷美护肤品怎么样 婷美化妆品怎么样 倪虹洁婷美内衣广告 婷美丰胸内衣 婷美肌底液怎么样 婷美化妆品专卖店 婷美内衣多少钱一套 婷美化妆品批发 婷美精华肌底液价格 婷美内衣代理 婷美产后修复