popcap sexyframework - Demo1 基本框架

// gameapp.h
#ifndef __GAMEAPP_H__
#define __GAMEAPP_H__

//我们的游戏类必须从 SexyAppBase 类派生. 后者声明在这个头文件.
#include "SexyAppFramework/SexyAppBase.h"

// 声明我们定义在 Board.h 中的窗体部件类. 
class Board;

//////////////////////////////////////////////////////////////////////////
// 游戏类.
// 直接从 SexyAppBase 派生. 并实现基类中的几个函数(做初始化,加载资源等工作).
// 它的作用是创建窗体部件 Board (游戏的界面. 逻辑. 处理用户输入等等工作都由窗体部件来做)
// 并且要加载程序中用到的资源.
///////////////////////////////////////////////////////////////////////////
class GameApp : public SexyAppBase
{
  Board*  mBoard;   //我们的窗体部件
 public:
  GameApp();
  virtual ~GameApp();

  //////////////////////////////////////////////////////////////////////////  
  // 初始化.
  // 如果我们的程序要有一个前导. 放在这里.
  // 框架会在这个函数返回后自动调用 后边的 LoadingThreadProc()
  //////////////////////////////////////////////////////////////////////////
  virtual void Init();

  //////////////////////////////////////////////////////////////////////////
  // 加载程序用到的资源
  // 这个函数在一个单独的线程中进行. 
  // 如果加载时间稍长. 我们需要一个类似 " Loading ... "  的前导.
  // 可以在这个函数中更新加载进度条.
  // 这个函数执行完毕时. 框架自动调用后边的 LoadingThreadCompleted()
  //////////////////////////////////////////////////////////////////////////  
  virtual void LoadingThreadProc();

  //////////////////////////////////////////////////////////////////////////
  // 资源全部加载完毕以后 应该执行的动作.
  //////////////////////////////////////////////////////////////////////////  
  virtual void LoadingThreadCompleted();

};

 

#endif // __GAMEAPP_H__

//board.h

#ifndef __BOARD_H__
#define __BOARD_H__

#include "SexyAppFramework/Widget.h"


class Graphics;
class GameApp;

//////////////////////////////////////////////////////////////////////////
// Board 类
// 从 Widget 派生. 游戏的所有的功能. 游戏绘图,更新,处理输入. 都在这个类完成.
// 因为Widget(窗口部件)被加入到 GameApp 的 WidgetManager 时. 会自动启动游戏的消息循环.
// 自动调用Widget的 Update() 和 Draw(). 并在需要的时候处理用户输入. 每秒100帧.
// 这样游戏的逻辑应该不能执行的太慢. 
//////////////////////////////////////////////////////////////////////////
class Board : public Widget
{
  GameApp* mApp;  //持有主程序类的指针. 在本类中要调用GameApp的一些函数.
 public:
  Board(GameApp* theApp){ mApp = theApp;}
  virtual ~Board(){}


  //////////////////////////////////////////////////////////////////////////
  // 绘制
  // 这个函数被 GameApp 的 WidgetManager 自动调用.
  // 参数 g 用来在屏幕上绘制图像和文字
  //////////////////////////////////////////////////////////////////////////
  virtual void Draw(Graphics* g);

  //////////////////////////////////////////////////////////////////////////
  // 更新
  // 这个函数被 GameApp 的 WidgetManager 自动调用. (每秒100次).
  // 它处理游戏的逻辑. 
  //////////////////////////////////////////////////////////////////////////
  virtual void Update();

};


#endif // __BOARD_H__

//gameapp.cpp

#include "GameApp.h"
#include "Board.h"
#include "SexyAppFramework/WidgetManager.h"
#include "SexyAppFramework/Common.h"


//SexyAppFramework 把所有的东西都声明在名字空间 Sexy 中. 
using namespace Sexy;


//////////////////////////////////////////////////////////////////////////
GameApp::GameApp()
{
 // 游戏的名字. 在内部使用.
 mProdName = "Demo 1";

 // 版本
 mProductVersion = "1.0";

 // 游戏运行时. 在窗口的标题栏显示的内容
 mTitle = StringToSexyStringFast("SexyAppFramework: " + mProdName + " - " + mProductVersion);

 // 注册表读写的路径
 mRegKey = "PopCap\SexyAppFramework\Demo1";

 // 设置宽高. 这些成员都是在GameApp的基类中定义的.
 mWidth = 640;
 mHeight = 480;

 // 窗体部件. 在后边的函数中创建窗体. 
 mBoard = NULL;
}


//////////////////////////////////////////////////////////////////////////
GameApp::~GameApp()
{
 // 对所有的窗体部件来说. 在 delete 之前. 必须将之从 mWidgetManager 中 RemoveWidget().
 // 否则运行的时候会有一个 assert.
 mWidgetManager->RemoveWidget(mBoard);
 delete mBoard;
}


//////////////////////////////////////////////////////////////////////////
void GameApp::Init()
{
 // 在这里总是必须先调用基类的 Init().
 SexyAppBase::Init();

 //在这个例子中. 我们的Init()无事可作. 但以后的例子中会使用它.
 
 // 这个函数执行完后. 框架自动调用 LoadingThreadProc() 来加载资源.
}


//////////////////////////////////////////////////////////////////////////
void GameApp::LoadingThreadProc()
{
 // 这个函数用一个单独的线程来加载资源. 并更新加载进度(如果有的话).

 // 在这个例子中. 它没有什么资源要加载. 但以后的例子中会使用它.

 // 它执行完毕后. 框架会自动调用 LoadingThreadCompleted().
}


//////////////////////////////////////////////////////////////////////////
void GameApp::LoadingThreadCompleted()
{
 //调用基类的LoadingThreadCompleted()
 SexyAppBase::LoadingThreadCompleted();

 // 当所有的资源加载都没有失败时. mloadingfailed被设置为false. 否则设置为 true.
 // 所以在这里要检查该变量. 若资源加载失败则返回. 
 if (mLoadingFailed)
  return;

 // 创建我们定义的 Board 窗体部件.
 mBoard = new Board(this);

 // 设置窗体部件的大小和位置. 这个步骤不可以省略. 因为缺省时它们是0,0. 我们看不到.
 // 这里mBoard是我们的主窗口控件. 所以设置它的大小为 GameApp 的大小(mWidth, mHeight). 
 // 其中(mWidth, mHeight)我们已经在构造函数中指定了值.
 mBoard->Resize(0, 0, mWidth, mHeight);

 // 然后将刚才创建的窗体部件加入 mWidgetManager.
 // 这也是一个重要的步骤. 它意味着我们的 mBoard 对象从此可以自动的被调用 Update(). Draw(). 以及处理输入事件.
 mWidgetManager->AddWidget(mBoard);
}

//board.cpp

#include "Board.h"
#include "SexyAppFramework/Graphics.h"

#include "SexyAppFramework/Color.h"     // 使用 Color 类.
#include "SexyAppFramework/Point.h"  // 使用 Point 类.

using namespace Sexy;

 

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void Board::Update()
{
 // 调用基类的 Update(). 将会++mUpdateCnt. (它表示Update()被调用了多少次)
 // 因为这个函数每秒被调用100次. 所以我们也可以用 mUpdateCnt 的值做为游戏的计时器使用.
 Widget::Update();

 // 下边这个函数告诉 widget manager 该部件已经变脏. 这样就会重画它.
 // 如果不需要重画(比如游戏变为不活动的)也可以不调用它. 节约一点cpu时间.
 MarkDirty();
}


// 绘制函数. 它自动被 WidgetManager 调用. 而且是自动双缓冲的. 
void Board::Draw(Graphics* g)
{
 //填充矩形.
 //缺省时. 颜色是黑色. 
 g->FillRect(0, 0, mWidth, mHeight);
 
 //设置当前颜色
 g->SetColor(Color(255, 128, 64)); //Color可以有3个或4个参数. 
 
 //画线 
 //参数为X1, Y1, X2, Y2
 g->DrawLine(0, 0, 200, 150);


 //绘制矩形(但不填充矩形内部)
 g->DrawRect(200, 150, (mWidth - 200) - 200, (mHeight - 150) - 150);

 //绘制多边形
 // 先定义一个 Point数组. 保存多边形的每个顶点的坐标. 
 // 然后用 PolyFill() 来绘制多边形.
 Point trianglePoints[3];
 trianglePoints[0] = Point(30, 30);
 trianglePoints[1] = Point(30, 60);
 trianglePoints[2] = Point(60, 45);
 g->SetColor(Color(255, 255, 0)); // yellow
 g->PolyFill(trianglePoints, 3);
}

// main.cpp

 

#include "GameApp.h"
 
using namespace Sexy;

// 主函数
// 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{ 

 // 设置 gHInstance . 这个动作不能省略.
 gHInstance = hInstance;

 // 创建并初始化游戏主类.
 GameApp* anApp = new GameApp();
 anApp->Init();

 // 开始执行. 
 anApp->Start();


 delete anApp;

 return 0;
}

你可能感兴趣的:(popcap sexyframework - Demo1 基本框架)