游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2818|回复: 6

游戏窗口闪烁

[复制链接]

1

主题

1

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2006-7-23 13:23:00 | 显示全部楼层 |阅读模式
我用Directx和MFC开发一个坦克游戏,是窗口模式(非全屏模式)的,贴图是在OnTimer函数循环实现的,为什么坦克和背景图老是闪烁??请各位高手帮帮忙~!~!小弟谢谢了~!~
代码如下:
void CanvasForm::OnTimer(UINT nIDEvent)          //时间控制
{
        // TODO: Add your message handler code here and/or call default
       
       

        //获取键盘输入状态
        result=DIms->GetDeviceState(sizeof(buffer),(LPVOID)&buffer);
        if(result!=DD_OK)
        {
                MessageBox("获取键盘输入状态失败!");
                return;
        }
        DDSur->BltFast(x1,y1,DDPla[1],NULL,DDBLTFAST_WAIT);     //背景图


//坦克图
        DDSur->BltFast(x1+20+x,y1+20+y,DDPla[16],CRect(t,0,60+t,60),DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);


        CFrameWnd::OnTimer(nIDEvent);

}

18

主题

631

帖子

660

积分

高级会员

Rank: 4

积分
660
发表于 2006-7-24 16:00:00 | 显示全部楼层 |阅读模式
你如果是直接绘制主表面上肯定是要闪烁的。看看上面代码的方式就知道了。

18

主题

631

帖子

660

积分

高级会员

Rank: 4

积分
660
发表于 2006-7-24 09:33:00 | 显示全部楼层

Re:游戏窗口闪烁

你好像直接画到表面,没有在后备缓冲区上绘制。

45

主题

1163

帖子

1165

积分

金牌会员

Rank: 6Rank: 6

积分
1165
发表于 2006-7-24 11:24:00 | 显示全部楼层

Re:游戏窗口闪烁

是的,窗口模式下要用BLT代替换页

18

主题

631

帖子

660

积分

高级会员

Rank: 4

积分
660
发表于 2006-7-24 15:59:00 | 显示全部楼层

Re:游戏窗口闪烁

//******************************************************************
//初始化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;
}

18

主题

631

帖子

660

积分

高级会员

Rank: 4

积分
660
发表于 2006-7-24 15:59:00 | 显示全部楼层

Re:游戏窗口闪烁

//*****************************************************
//换页
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)
        {
                oldtime=GetTickCount();
                planenumber=planeremain;
                super=TRUE;
                cancontrol=FALSE;
                pos.x=backwidth/2-25;
                pos.y=backrect.bottom;
        }
        if (super==TRUE)
                if (GetTickCount()>oldtime+3000)//无敌时间3秒
                        super=FALSE;

        if (cancontrol==FALSE)
        {
                if (pos.y>backrect.bottom-100) //飞机刚出现时是无法控制的
                {
                        pos.y-=movespeed;
                        Plane=1;
                }
                else
                        cancontrol=TRUE;
        }
        else
        {
                //检测方向键
                Plane=1;
                if(GetAsyncKeyState(VK_UP))                {pos.y=pos.y-movespeed;}
                if(GetAsyncKeyState(VK_DOWN))        {pos.y=pos.y+movespeed;}
                if(GetAsyncKeyState(VK_LEFT))        {pos.x=pos.x-movespeedlane=0;}
                if(GetAsyncKeyState(VK_RIGHT))        {pos.x=pos.x+movespeed;Plane=2;}
       
                //范围检查
                if (pos.x<65)        pos.x=65;
                if (pos.x>backwidth-65-50)        pos.x=backwidth-65-50;
                if (pos.y<65)        pos.y=65;
                if (pos.y>backheight-65-60)        pos.y=backheight-65-60;
        }

        if (super==TRUE) //无敌时的闪烁效果
        {
                static int ot=0;//延时
                if (GetTickCount()-ot>30)
                        ot=GetTickCount();
                else
                        return;
        }

        //绘制飞机
        RECT rect;
        GetRect(&rect, pos.x, pos.y, 50, 60);
        HRESULT rval=lpDDSBack->Blt( &rect, lpDDSPlane[Plane], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
        if(rval == DDERR_SURFACELOST)    lpDDSBack->Restore();
}

1

主题

5

帖子

11

积分

新手上路

Rank: 1

积分
11
发表于 2006-7-25 14:38:00 | 显示全部楼层

Re:游戏窗口闪烁

那个,要是画静态的你的code或许可以,但是动态的移动画面你最好用DDraw然后在缓冲区上画下一张才可以得说。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-25 00:08

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表