博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Windows GDI笔记

Posted on 2009-03-24 20:32  Zhiyett  阅读(702)  评论(0编辑  收藏  举报
1.Device Context
//取得DC
HDC GetDC(HWND hWnd)
//释放DC
int ReleaseDC(HWND hWnd,HDC DC名称);

2.GDI对象:建立->选用->删除
//建立画笔
HPEN CreatePen(int 样式,int 宽度, COLORREF 颜色);
//建立阴影画刷
HBRUSH CreateHatchBrush(int 样式,COLORREF 颜色);
//建立单色画刷
HBRUSH CreateSolidBrush(COLORREF 颜色);

//选用GDI对象
HGDIOBJ SelectObject(HDC hdc, HGDIOBJ GDI对象);
//删除GDI对象
BOOL DeleteObject(HGDIOBJ GDI对象);

3.
//画线
//移动画笔至线条起点
BOOL MoveToEx(HDC hdc,int x,int y,LPPOINT 目前坐标);
// 画线条到指定坐标
BOOL LineTo(HDC hdc,int x,int y);

//画矩形
BOOL Rectangle(HDC hdc,int x1,int y1,int x2,int y2);

//画多边形
BOOL Polygon(HDC hdc,CONST POINT 点数组指针,int 多边形点数);

BOOL PolylineTo(HDC hdc,CONST POINT 点数组指针,int 多边形点数);
BOOL Polyline(HDC hdc,CONST POINT 点数组指针,int 多边形点数);

typedef struct tagPOINT{
    LONG x;
    LONG y;
}POINT;

//画椭圆形
BOOL Ellipse(HDC hdc, int x1,int y1,int x2,int y2);

//画圆角矩形
BOOL RoundRect(HDC hdc,int x1,int y1,int x2,int y2,int 圆角上椭圆长,int 圆角上椭圆高);

//画扇形
BOOL Pie(HDC hdc,int 外围矩形左上点x坐标,int 外围矩形左上点y坐标,int 外围矩形右上点x坐标,int 外围矩形右上点y坐标,int x1,int y1,int x2,int y2);

//画弓形
Chord(hdc,300,210,550,340,50,50,600,300);

4.字符串
int x=LOWORD(lParam);
//设置字符串颜色
SetTextColor(hdc,#ff0000);
char str[20]="";
sprintf(str,"X坐标:%d",x);
//输出字符串
BOOL TextOut(HDC hdc, int x坐标,int y坐标,LPCTSTR 字符串指针,int 字符串长度);

5.绘制位图
(1)加载位图
HANDLE LoadImage(HINSTANCE 来源实体,LPCTSTR 名称,UINT 位图类型, int 加载宽度,int 加载高度,UINT 加载方式);
位图类型:IMAGE_BITMAP、IMAGE_CURSOR、IMAGE_ICON
加载方式:从文件中加载LR_LOADFROMFILE
(2)建立内存DC
HDC CreateCompatibleDC(HDC hdc);
DeleteDC(HDC hdc);
(3)选用位图对象
HGDIOBJ SelectObject(HDC hdc, HGDIOBJ GDI对象);
(4)贴图
BOOL BitBlt(HDC destDC,int destX,int destY,int destWidth,int destHeight,HDC srcDc,int srcX,int srcY,DWORD 贴图方式);
贴图方式:
SRCCOPY   将来源位图贴到目的DC上
SRCAND      将来源位图与目的DC做“AND”运算
SRCPAINT    将来源位图与目的DC做“OR”运算

6.透明处理
(1)透明效果
    SelectObject(mdc,bg);
    BitBlt(hdc,0,0,600,450,mdc,0,0,SRCCOPY);
    SelectObject(mdc,dra);
    BitBlt(hdc,280,320,85,99,mdc,85,0,SRCAND);
    BitBlt(hdc,280,320,85,99,mdc,0,0,SRCPAINT);
    
(2)半透明效果
半透明色彩=前景图色彩*不透明度+背景图色彩*(1-不透明度)
a.取得位图结构
int GetObject(HGDIOBJ GDI对象,int 结构大小,LPVOID 结构变量);
结构变量typedef struct tagBITMAP{
        LONG bmType;
        LONG bmWidth;
        LONG bmHeight;
        LONG bmWidthBytes;
        WORD bmPlanes;
        WORD bmBitsPixel;
        LPVOID bmBits;
  }BITMAP;
 
  GetObject(bitmap,sizeof(BITMAP),&bm);
b.建立暂存数组
  unsigned char *px = new unsigned char [bm.bmHeight * bm.bmWidthBytes];
c.取得位图位值
  LONG GetBitmapBits(HBITMAP 位图,LONG 取得的Byte数,LPVOID 存储的数组指针);
 
  GetBitmapBits(bitmap,bm.bmHeight*bm.bmWidthBytes.px);
d.合成像素颜色值
 
 e.重设位图颜色
  LONG SetBitmapBits(HBITMAP 位图,DWORD 颜色数组大小, CONST VOID 数组指针);
 
  (3)透明半透明效果
  //建立位图
  HBITMAP CreateCompatibleBitmap(HDC hdc,int width,int height);
 
 7.定时器
 UINT SetTimer(HWND hWnd,UINT 定时器代号, UINT 时间间隔, TIMERPROC 处理器响应函数);
 UINT 定时器代号在同一个窗口中必须是唯一的,且不为0
 
 //删除定时器
 BOOL KillTimer(int 定时器代号);
 
  8.游戏循环
  DWORD tPre,tNow;
 
  WinMain里
  while(msg.message!=WM_QUIT)
    {
        if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            tNow=GetTickCount();
            if(tNow-tPre>=40)
                MyPaint(hdc);
        }
    }
    
    InitInstance里
    hdc = GetDC(hWnd);
    mdc = CreateCompatibleDC(hdc);
    bufdc = CreateCompatibleDC(hdc);
    HBITMAP bmp=CreateCompatibleBitmap(hdc,640,480);
    SelectObject(mdc,bmp);
    dra=(HBITMAP)LoadImage(NULL,"dra2.bmp",IMAGE_BITMAP,760,198,LR_LOADFROMFILE);
    bg=(HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,640,480,LR_LOADFROMFILE);
    num=0;
    x=640;
    y=360;
    MyPaint(hdc);
 
 int frame=0;
int tCheck=0,fps;
void MyPaint(HDC hdc)
{
 if(num==8)
        num=0;
    SelectObject(bufdc,bg);
    BitBlt(mdc,0,0,640,480,bufdc,0,0,SRCCOPY);

    SelectObject(bufdc,dra);
    BitBlt(mdc,x,y,95,99,bufdc,num*95,99,SRCAND);
    BitBlt(mdc,x,y,95,99,bufdc,num*95,0,SRCPAINT);

    BitBlt(hdc,0,0,640,480,mdc,0,0,SRCCOPY);

    tPre=GetTickCount();
    num++;

    //显示文字
    frame++;
    if(tNow-tCheck>=1000)
    {
        fps=frame;
        frame=0;
        tCheck=tNow;
    }
    char str[40]="";
    sprintf(str,"每秒钟显示%d个画面 ",fps);
    TextOut(hdc,0,0,str,strlen(str));
}
 
9.动画显示问题
排序贴图
10.背景动画设计
a)单一背景滚动
b)循环背景滚动
c)多背景循环动画

11.
1)
//设定获取窗口外的鼠标消息
HWND SetCapture(HWND hWnd);

//释放获取窗口外的鼠标消息
BOOL ReleaseCapture(VOID);
2)
//设置鼠标光标位置,注意:(x,y)对应的是屏幕坐标而不是窗口坐标
BOOL SetCursorPos(int x,int y);

//窗口坐标转换为屏幕坐标
BOOL ClientToScreen(HWND hWnd, LPPOINT 窗口点坐标);

//屏幕坐标转换为窗口坐标
BOOL ScreenToClient(HWND hWnd, LPPOINT 屏幕点坐标);

POINT pt;
pt.x=0;
pt.y=0;
ClientToScreen(hWnd,&pt);
SetCursorPos(pt.x,pt.y);
3)显示或隐藏鼠标
int ShowCursor(BOOL true或false);
4)
//限制鼠标光标移动区域
BOOL ClipCursor(CONST RECT 移动区域矩形);

//解除限制
BOOL ClipCursor(NULL);

typedef struct RECT{
                    LONG left;
                    LONG top;
                    LONG right;
                    LONG bottom;
               }RECT;
               
 //取得窗口外部区域矩形
 BOOL GetWindowRect(HWND hWnd,LPRECT 矩形结构);
 
 //取得窗口内部矩形区域
 BOOL GetClientRect(HWND hWnd,LPRECT 矩形结构);
 
 例如:要限制鼠标光标移动区域
 RECT rect;
 POINT lt,rb;
GetClientRect(hWnd,&rect);
lt.x=rect.left;
lt.y=rect.top;
rb.x=rect.right;
rb.y=rect.bottom;
ClientToScreen(hWnd,&lt);
ClientToScreen(hWnd,&rb);
rect.left=lt.x;
rect.top=lt.y;
rect.right=rb.x;
rect.bottom=rb.y;
ClipCursor(&rect);

12.AI
类神经网络
基因算法
模糊逻辑

1)怪物追逐
if(怪物HP>200)
{
    p=rand()%3;
    if(p!=1)   //有2/3的概率能正确的朝向玩家
    {
        if(怪物X>玩家X)
            怪物X--;
        else
            怪物X++;
            
        if(怪物Y>玩家Y)
            怪物Y--;
        else
            怪物Y++;
     }
}
else
    怪物HP+=5;//怪物不动,休息补血
2)躲避移动
if(怪物X>玩家X)
    怪物++;
else
    怪物X--;
 
if(怪物Y>玩家Y)
    怪物Y++;
else
    怪物Y--;
3)模式移动:追逐、躲避、随机、固定移动等

4)怪物行为
a.普通攻击
b.施放攻击魔法
c.使尽全力攻击
d.补血
e.逃跑

if(生命值>20)
{
    if(rand()%10!=1)  //普通攻击概率为9/10
        普通攻击;
    else
        施放魔法攻击;
 }
 else
 {
     switch(rand()%5)
     {
        case0:
                普通攻击;
                break;
        case 1:
                施放魔法攻击;
                break;
        case 2:
                使尽全力攻击;
                break;
        case 3:
                补血;
                break;
        case 4:
                逃跑;
                if(rand()%3==1)    //逃跑成功几率为1/3
                        逃跑成功;
                else
                        逃跑失败;
                break;
    }
}
 
 }