幻想森林

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2102|回复: 3

标题还有限制,刚才话没说完,用的是GDI,在MFC程

[复制链接]

4

主题

5

帖子

39

积分

②入门

积分
39
发表于 2005-9-24 21:26:24 | 显示全部楼层 |阅读模式
精灵链表类
#ifndef AVGSPRITELIST_H//如果出现少;看看是不是这里错了
#define AVGSPRITELIST_H
#include "AvgBmp.h"
class AvgSpriteList //负责单个物体的显示,如动画等
{
public:
       AvgSpriteList();
       AvgSpriteList(CPtrList *SpriteList);
    CPtrList *pSpriteList;
    void AddSprite(AvgBmp *Sprite);
       void DeleteSprite(CString bmpID);
       void SortSprite();
       void ClearSprite();
};//是否少一个标点符号,也会出错
#endif

实现文件
#include "stdafx.h"//应放在第一个
#include "AvgSpriteList.h"

AvgSpriteList::AvgSpriteList(CPtrList *SpriteList)
{
     pSpriteList = SpriteList;
}

AvgSpriteList::AvgSpriteList()
{
}

void AvgSpriteList::AddSprite(AvgBmp *Sprite)
{
    if(pSpriteList->GetCount()<=0)//如果列表为空,插入一个新的SPRITE
       {
              pSpriteList->AddHead(Sprite);
       }
       else
       {
        pSpriteList->AddTail(Sprite);
              SortSprite();
       }
}

void AvgSpriteList:eleteSprite(CString bmpID)//在列表中删除一个精灵
{
    AvgBmp *pSprite;
       POSITION nPosition;
    if(pSpriteList->GetCount()>0)
       {
              for(int i=0; i<pSpriteList->GetCount(); i++)
              {
                     nPosition = pSpriteList->FindIndex(i);
            pSprite = static_cast<AvgBmp *>(pSpriteList->GetAt(nPosition));
                     if(pSprite->bmpID == bmpID)
                     {
                            pSpriteList->RemoveAt(nPosition);
                     }
              }
       }
       if(pSpriteList->GetCount()>1)
       {
              SortSprite();
       }
}

void AvgSpriteList::SortSprite()
{
       AvgBmp* TempBmpBefore;
       AvgBmp* TempBmpAfter;
       void* Swap = NULL;
       POSITION TempPositionBefore;
       POSITION TempPositionAfter;
       int n = pSpriteList->GetCount();
       for( int i = n-1; i>0; i--)
       {
              for(int j = 0; j<i; j++)
              {
                     TempPositionBefore = pSpriteList->FindIndex(j);
                     TempBmpBefore =  static_cast<AvgBmp*>(pSpriteList->GetAt(TempPositionBefore));
                     TempPositionAfter = pSpriteList->FindIndex(j+1);
                     TempBmpAfter = static_cast<AvgBmp*>(pSpriteList->GetAt(TempPositionAfter));
                     if(TempBmpBefore->z > TempBmpAfter->z)
                     {
                            void*& BmpBefore = pSpriteList->GetAt(TempPositionBefore);
                            void*& BmpAfter = pSpriteList->GetAt(TempPositionAfter);
                            Swap = BmpBefore;
                            BmpBefore = BmpAfter;
                            BmpAfter = Swap;
                     }
              }
       }
}

void AvgSpriteList::ClearSprite()
{
       pSpriteList->RemoveAll();
}


场景类
#ifndef AVGSCENE_H//如果出现少;看看是不是这里错了
#define AVGSCENE_H
#include "Collection\ListEx.h"
#include "AvgBmp.h"
class AvgScene : public AvgBmp//负责前景与合景的合并
{
public:
       AvgScene();
       AvgScene(CString bmpname, CString IDbmp ,int bmpx,
  int bmpy, int bmpz, int attribute, int bmpalpha, CPtrList *pList);
       //AvgBmp avganimation[10];
public:
       bool IfHcAfter;//是否合成前景
       bool IfHcBefore;
    //*CListEx <AvgBmp , AvgBmp&> Spritelist;
       //CPtrList Spritelist;
       CPtrList *pSpriteList;//指向一个精灵链表
       void HcScene(HDC MbDC, HDC MemDC, bool FLAG);//合成场景
       void HcSceneInclude(HDC MbDC, HDC MemDC, bool FLAG);//含对象自身合成
       //void AddMovement(sMovement Movement);
};
#endif

实现文件
#include "stdafx.h"
#include "AvgScene.h"

AvgScene::AvgScene()
{
}

AvgScene::AvgScene(CString bmpname, CString IDbmp ,int bmpx,
  int bmpy, int bmpz, int attribute, int bmpalpha, CPtrList *pList):AvgBmp(bmpname, IDbmp ,bmpx,
  bmpy, bmpz, attribute, bmpalpha)
{
   pSpriteList = pList;
}


//场景合成类,由于GDI太慢,因此,只有进行场景合成,而非全部重写来加快速度
//如可以合成背景,然后显示图象,再用一个合成的背景拷上去,这样三层也只要三个BIT
void AvgScene::HcScene(HDC  MbDC, HDC MemDC, bool FLAG/*用以标示是正向还是反向*/)
{//1      
       IfHcAfter = true;
       IfHcBefore = true;
       if(pSpriteList->IsEmpty() != 0)
       {
              AfxMessageBox("没有精灵,无法合成");
       }
       else
       {//2
              POSITION n ;
              AvgBmp *sprite;//精灵指针
              int Count = pSpriteList->GetCount();//列表总数
              int position = 0;//精灵位置
        for(int i=0; i<Count; i++)//找到精灵在列表中的位置
              {
                     n = pSpriteList->FindIndex(i);
                     sprite = static_cast<AvgBmp *>(pSpriteList->GetAt(n));
                     if(sprite->bmpID == bmpID)
                     {
                            position = i;
                            i=Count;
                     }
              }
              if(position == 0 )//如果位置已在0和最后一个单位,则不进行合成前景
              {
                     IfHcBefore = false;
              }
              if(position == Count - 1 )//不再进行合成背景
              {
                     IfHcAfter = false;
              }
        if( IfHcBefore == true)
              {
                     if(FLAG == true)//正向合并,合并时不包括图片自身,合成的是前景
                     {
                            for(i =0; i<position; i++)
                            {
                                   n = pSpriteList->FindIndex(i);
                                   sprite = static_cast<AvgBmp *> (pSpriteList->GetAt(n));
                                   if(sprite->ifshow == true)//如果该精灵仍然在显示
                                   {
                                          switch (sprite->showattribute)//NORMAL
                                          {
                                          case 0://NORMAL
                                                 sprite->ShowBmp( MbDC, sprite->x,sprite->y,
                                                        sprite->bmpwidth,sprite->bmpheight, MemDC,
                                                        0, 0, sprite->bmpwidth, sprite->bmpheight);
                                                 break;
                                          case 1://ALPHA
                                                 sprite->AlphaBmp( MbDC, sprite->x, sprite->y,
                                                        sprite->bmpwidth, sprite->bmpheight, MemDC,
                                                        0, 0, sprite->bmpwidth, sprite->bmpheight, sprite->alpha);
                                                 break;
                                          case 2://TRANS
                                                 sprite->TransBmp( MbDC, sprite->x, sprite->y,
                                                        sprite->bmpwidth, sprite->bmpheight, MemDC,
                                                        0, 0, sprite->bmpwidth, sprite->bmpheight, RGB(191, 191, 191));
                                                 break;
                                          default:
                                                 break;
                                          }
                                   }
                                   
                            }
                     }
              }
              if(IfHcAfter == true)
              {
                     if(FLAG == false)//反向合并,合成的是背景
                     {
                            for(i = position+1; i<Count; i++)
                            {
                                   n = pSpriteList->FindIndex(i);
                                   sprite = static_cast<AvgBmp *>(pSpriteList->GetAt(n));
                                   if(sprite->ifshow == true)//如果该精灵仍然在显示
                                   {
                                          switch (sprite->showattribute)//NORMAL
                                          {//SWITCH
                                          case 0://NORMAL
                                                 sprite->ShowBmp( MbDC, sprite->x,sprite->y,
                                                        sprite->bmpwidth,sprite->bmpheight, MemDC,
                                                        0, 0, sprite->bmpwidth, sprite->bmpheight);
                                                 break;
                                          case 1://ALPHA
                                                 sprite->AlphaBmp( MbDC, sprite->x, sprite->y,
                                                        sprite->bmpwidth, sprite->bmpheight, MemDC,
                                                        0, 0, sprite->bmpwidth, sprite->bmpheight, sprite->alpha);
                                                 break;
                                          case 2://TRANS
                                                 sprite->TransBmp( MbDC, sprite->x, sprite->y,
                                                        sprite->bmpwidth, sprite->bmpheight, MemDC,
                                                        0, 0, sprite->bmpwidth, sprite->bmpheight, RGB(191, 191, 191));
                                                 break;
                                          default:
                                                 break;
                                          }//SWITCH
                                   }
                            }//FORPOSITION
                     }//FLAG
              }
       }//2
}//1

void AvgScene::HcSceneInclude(HDC  MbDC, HDC MemDC, bool FLAG)
{
       IfHcAfter = true;
       IfHcBefore = true;
       if(pSpriteList->IsEmpty() != 0)
       {
              AfxMessageBox("没有精灵,无法合成");
       }
       else
       {//2
              POSITION n ;
              AvgBmp *sprite;//精灵指针
              int Count = pSpriteList->GetCount();//列表总数
              int position = 0;//精灵位置
        for(int i=0; i<Count; i++)//找到精灵在列表中的位置
              {
                     n = pSpriteList->FindIndex(i);
                     sprite = static_cast<AvgBmp *>(pSpriteList->GetAt(n));
                     if(sprite->bmpID == bmpID)
                     {
                            position = i;
                            i=Count;
                     }
              }
              if(position == 0 )//如果位置已在0和最后一个单位,则不进行合成前景
              {
                     IfHcBefore = false;
              }
              if(position == Count - 1 )//不再进行合成背景
              {
                     IfHcAfter = false;
              }
        if( IfHcBefore == true)
              {
                     if(FLAG == true)//正向合并,合并时不包括图片自身,合成的是前景
                     {
                            for(i =0; i<=position; i++)
                            {
                                   n = pSpriteList->FindIndex(i);
                                   sprite = static_cast<AvgBmp *> (pSpriteList->GetAt(n));
                                   if(sprite->ifshow == true)//如果该精灵仍然在显示
                                   {
                                          switch (sprite->showattribute)//NORMAL
                                          {
                                          case 0://NORMAL
                                                 sprite->ShowBmp( MbDC, sprite->x,sprite->y,
                                                        sprite->bmpwidth,sprite->bmpheight, MemDC,
                                                        0, 0, sprite->bmpwidth, sprite->bmpheight);
                                                 break;
                                          case 1://ALPHA
                                                 sprite->AlphaBmp( MbDC, sprite->x, sprite->y,
                                                        sprite->bmpwidth, sprite->bmpheight, MemDC,
                                                        0, 0, sprite->bmpwidth, sprite->bmpheight, sprite->alpha);
                                                 break;
                                          case 2://TRANS
                                                 sprite->TransBmp( MbDC, sprite->x, sprite->y,
                                                        sprite->bmpwidth, sprite->bmpheight, MemDC,
                                                        0, 0, sprite->bmpwidth, sprite->bmpheight, RGB(191, 191, 191));
                                                 break;
                                          default:
                                                 break;
                                          }
                                   }
                                   
                            }
                     }
              }
              if(IfHcAfter == true)
              {
                     if(FLAG == false)//反向合并,合成的是背景
                     {
                            for(i = position; i<Count; i++)
                            {
                                   n = pSpriteList->FindIndex(i);
                                   sprite = static_cast<AvgBmp *>(pSpriteList->GetAt(n));
                                   if(sprite->ifshow == true)//如果该精灵仍然在显示
                                   {
                                          switch (sprite->showattribute)//NORMAL
                                          {//SWITCH
                                          case 0://NORMAL
                                                 sprite->ShowBmp( MbDC, sprite->x,sprite->y,
                                                        sprite->bmpwidth,sprite->bmpheight, MemDC,
                                                        0, 0, sprite->bmpwidth, sprite->bmpheight);
                                                 break;
                                          case 1://ALPHA
                                                 sprite->AlphaBmp( MbDC, sprite->x, sprite->y,
                                                        sprite->bmpwidth, sprite->bmpheight, MemDC,
                                                        0, 0, sprite->bmpwidth, sprite->bmpheight, sprite->alpha);
                                                 break;
                                          case 2://TRANS
                                                 sprite->TransBmp( MbDC, sprite->x, sprite->y,
                                                        sprite->bmpwidth, sprite->bmpheight, MemDC,
                                                        0, 0, sprite->bmpwidth, sprite->bmpheight, RGB(191, 191, 191));
                                                 break;
                                          default:
                                                 break;
                                          }//SWITCH
                                   }
                            }//FORPOSITION
                     }//FLAG
              }
       }//2
}


对话框类
#ifndef AVGDIALOG_H//如果出现少;看看是不是这里错了
#define AVGDIALOG_H
#include "AvgAnimation.h"
class AvgDialog : public AvgAnimation//普通透明对话框
{
     public:
        AvgDialog();
        AvgDialog(CString bmpname, CString IDbmp ,int bmpx,
int bmpy, int bmpz, int attribute, int bmpalpha, CPtrList *pList);
     virtual void ShowAvgDialog(HDC ShowDC, HDC MbDC, HDC MemDC);
        CStdioFile wordfile;//建立一个流文件对像
        public:
        virtual void Clean(HDC ShowDC, HDC MbDC, HDC MemDC, HDC BackDC);
        virtual void ShowWord(HDC MbDC, int wx, int wy, int iLength, int iHeight, int delay);
     virtual void SetWord(CString word);
        void CloseWord();
};
#endif

实现文件
#include "stdafx.h"
#include "AvgDialog.h"
AvgDialog::AvgDialog()
{
}

AvgDialog::AvgDialog(CString bmpname, CString IDbmp ,int bmpx,
                                    int bmpy, int bmpz, int attribute, int bmpalpha, CPtrList *pList):
AvgAnimation(bmpname, IDbmp ,bmpx, bmpy, bmpz, attribute, bmpalpha, pList)
{
      //buttonbottom = new AvgBmp("buttonbottom.bmp", "buttonbottom", x+100, y+50, 0, 2, 255);
      //buttontop = new AvgBmp("buttontop.bmp", "buttontop", x+140, y+50, 0, 2, 255);
}

void AvgDialog::ShowAvgDialog(HDC ShowDC, HDC MbDC, HDC MemDC)
{
      AlphaBmp(ShowDC, x, y, bmpwidth, bmpheight, MemDC, 0, 0,
                bmpwidth, bmpheight, alpha);
}

void AvgDialog::Clean(HDC ShowDC, HDC MbDC, HDC MemDC, HDC BackDC)
{
      HcScene(BackDC, MemDC, true);
         ShowAvgDialog(BackDC, MbDC, MemDC);
         StretchBlt(ShowDC, x, y, bmpwidth, bmpheight, BackDC, x, y, bmpwidth, bmpheight, SRCCOPY);
         StretchBlt(MbDC, x, y, bmpwidth, bmpheight, BackDC, x, y, bmpwidth, bmpheight, SRCCOPY);
}

void AvgDialog::ShowWord(HDC MbDC, int wx, int wy, int iLength, int iHeight, int delay)
{
       SetTextColor(MbDC, RGB(255, 255, 255));//设置文本颜色
       SetBkMode(MbDC, TRANSPARENT);//设置背景模式
       CString ShowWord;//用于显示文本的字符串
    int i = 1;
       for(int n = 0; n<3; n++)
       {
              if(i != NULL)
              {
                 i = wordfile.ReadString(ShowWord);
                 TextOut(MbDC, x+wx, y+wy+20*n, ShowWord, ShowWord.GetLength());
              }
       }
    if( i == NULL)
       {
           wordfile.SeekToBegin();
              i = 1;
       }
}

void AvgDialog::SetWord(CString wordfilename)
{
        wordfile.Open( wordfilename, CFile::modeRead, NULL);//打开文件
        wordfile.SeekToBegin();//寻找到开头
}

void AvgDialog::CloseWord()
{
     wordfile.Close();
}

另一个对话框
#ifndef AVGNANNOUNCEDIALOG_H//如果出现少;看看是不是这里错了
#define AVGNANNOUNCEDIALOG_H
#include "AvgAnimation.h"
class AvgNAnnounceDialog : public AvgAnimation//普通不透明对话框
{
public:
       AvgNAnnounceDialog();
       AvgNAnnounceDialog(CString bmpname, CString IDbmp ,int bmpx,
              int bmpy, int bmpz, int attribute, int bmpalpha, CPtrList *pList);
   
public:

       CStdioFile wordfile;

public:
       void ShowAnnounceDialog(HDC ShowDC, HDC MbDC, HDC MemDC, int wx, int wy);
    virtual void Clean(HDC ShowDC, HDC MemDC);
       void SetWord(CString wordfilename);
    void CloseWord();
       void ShowWord(HDC MbDC, int wx, int wy, int iLength, int iHeight, int delay);
};
#endif


实现文件
#include "stdafx.h"
#include "AvgNAnnounceDialog.h"

AvgNAnnounceDialog::AvgNAnnounceDialog()
{
}

AvgNAnnounceDialog::AvgNAnnounceDialog(CString bmpname, CString IDbmp ,int bmpx,
int bmpy, int bmpz, int attribute, int bmpalpha, CPtrList *pList):AvgAnimation(bmpname, IDbmp ,bmpx,
bmpy, bmpz, attribute, bmpalpha, pList)
{
}

void AvgNAnnounceDialog::Clean(HDC ShowDC, HDC MemDC)//清除对象自己
{
       AnimationShowBmp(ShowDC, MemDC);
}

void AvgNAnnounceDialog::ShowAnnounceDialog(HDC ShowDC, HDC MbDC, HDC MemDC, int wx, int wy)
{
       AvgNAnnounceDialog::Clean(MbDC, MemDC);
       AvgNAnnounceDialog::ShowWord(MbDC, wx, wy, 0, 0, 0);
       StretchBlt(ShowDC, x, y, bmpwidth, bmpheight, MbDC, x, y, bmpwidth, bmpheight, SRCCOPY);
}

void AvgNAnnounceDialog::SetWord(CString wordfilename)
{
        wordfile.Open( wordfilename, CFile::modeRead, NULL);//打开文件
        wordfile.SeekToBegin();//寻找到开头
}

void AvgNAnnounceDialog::CloseWord()
{
     wordfile.Close();
}

void AvgNAnnounceDialog::ShowWord(HDC MbDC, int wx, int wy, int iLength, int iHeight, int delay)
{
       SetTextColor(MbDC, RGB(255, 255, 255));
       SetBkMode(MbDC, TRANSPARENT);
       CString ShowWord;
    int i = 1;
       int n = 0;
    while(i != NULL)
       {
                 i = wordfile.ReadString(ShowWord);
                 TextOut(MbDC, x+wx, y+wy+20*n, ShowWord, ShowWord.GetLength());
                 n++;
       }
}

使用方法:
#include "AvgAnimation.h"
#include "AvgSpriteList.h"
#include "AvgAnnounceDialog.h"
#include "AvgDialog.h"

在头文件中做如下定义:
       /*通用定义*/
       HDC MemDC;/**///存放照片的DC
       HDC MbDC;/**///双缓冲目标DC
       HDC FrontDC;/**///前景DC
       HDC BackDC;/**///后景DC
       HBITMAP doublebufferbitmap;/**///被选入双缓冲的图像的句柄
       HBITMAP doublebufferbitmapfront;/**///被选入双缓冲的图像的句柄
       HBITMAP doublebufferbitmapafter;/**///被选入双缓冲的图像的句柄
       CPtrList SpriteList;
       AvgSpriteList *Avgspritelist;
       /*通用定义结束*/

定义图片指针
       AvgAnimation *GuideBmp;//向导图片指针
       AvgAnimation *BackBmp;//背景图片指针
    AvgAnimation *Dialog;//对话框指针

在ONINITIALUPDATE()中
       /*标准定义开始*/
    CClientDC dc(this);
       CRect rc;//获取用户区大小
       GetClientRect(rc);
       doublebufferbitmap = CreateCompatibleBitmap
              (dc.m_hDC, rc.Width() , rc.Height());//建立一个用于双缓冲的位图
       doublebufferbitmapfront = CreateCompatibleBitmap
              (dc.m_hDC, rc.Width() , rc.Height());
    doublebufferbitmapafter = CreateCompatibleBitmap
              (dc.m_hDC, rc.Width() , rc.Height());

       MbDC= CreateCompatibleDC(dc.m_hDC);//建立双缓冲区DC,此处做为全局变量,如何在程序的其他地方再次定义,就会出错
    BackDC = CreateCompatibleDC(dc.m_hDC);//后景DC
       FrontDC = CreateCompatibleDC(dc.m_hDC);//前景DC
       SelectObject(MbDC, doublebufferbitmap);//将图选入双缓冲区以便绘图
       SelectObject(BackDC, doublebufferbitmapafter);
       SelectObject(FrontDC, doublebufferbitmapfront);
       MemDC = CreateCompatibleDC(dc.m_hDC);//创建用于储存图形的dc;
       Avgspritelist = new AvgSpriteList(&SpriteList);
       /*标准定义结束*/
    DeleteDC(dc);

       //创建背景图片
       BackBmp = new AvgAnimation("FighterScene.bmp", "back", 0, 0, 0, 0, 255, &SpriteList);
    Avgspritelist->AddSprite(BackBmp);
    //创建向导
       GuideBmp = new AvgAnimation("GuideGirl1.bmp", "guide1", 300, 100, 1, 2, 255, &SpriteList);
    Avgspritelist->AddSprite(GuideBmp);
    //创建对话框
       Dialog = new AvgAnimation("dialog.bmp", "guide1", 220, 400, 2, 1, 128, &SpriteList);
    Avgspritelist->AddSprite(Dialog);

然后您就可以自由的使用了,
在ONTIME()中使用
       CClientDC dc(this);
      
       BackBmp->AnimationShowBmp(dc.m_hDC, MbDC, MemDC);//显示飞机场
    GuideBmp->AnimationShowBmp(dc.m_hDC, MbDC, MemDC);//显示向导
       Dialog->AnimationShowBmp(dc.m_hDC, MbDC, MemDC);
       DeleteDC(dc);
就可以显示图片了,您也可以做各种转过场,已实现的有淡入淡出,马赛克等.见ANIMATION类.

你可以从ANIMATION类派生出自己的新的类.

由于使用的是GDI,因此速度不如DIRECTX,但就AVG来讲也还行了.
由于没写完,因此不完善处不少,但绝对可用,我用他写了几个页面.
希望有MFC基础又是如我一样是初学者的喜欢.

不过我还是推荐大家用CDX,可在MFC程序中用的,不像HGE或HOHO一样,只能是WIN32程序
回复

使用道具 举报

9

主题

1512

帖子

9136

积分

荣誉群

Cod3r

积分
9136

终身成就奖

发表于 2005-9-24 21:30:23 | 显示全部楼层
那個....打成壓縮包,找個空間傳上不就成了?
(\\__/) (O.o ) (> < ) This is Bunny.
回复 支持 反对

使用道具 举报

50

主题

742

帖子

402

积分

版主

自定义头衔

Rank: 7Rank: 7Rank: 7

积分
402
发表于 2005-10-1 08:02:14 | 显示全部楼层
源代码……我想这里不会有太多人能够理解吧^^:
Style-C
回复 支持 反对

使用道具 举报

50

主题

994

帖子

6699

积分

管理员

爱干啥干啥!

Rank: 9Rank: 9Rank: 9

积分
6699
发表于 2005-10-1 12:33:25 | 显示全部楼层
自己开发的游戏库?
GDI...-_-bbbbbb

汗……只能做AVG了呀。而且其实现在AVG里面也有大量的效果,比如AlphaBlend。GDI的速度……那可真不是盖的。

“放下屠刀,立地成佛” 故应先杀生,然后再成佛。

(\\_/) (-_-) ()+() this is bunny priest.
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|幻想森林

GMT+8, 2025-6-24 05:31 , Processed in 0.011471 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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