一、定義
享元模式的定義:
運用共享技術來有效的支持大量細粒度物件的復用,它通過共享已經存在的物件來大幅度減少需要創建的物件數量、避免大量相似類的開銷,從而提高系統資源的利用率,
享元模式主要包含以下角色:
(1)抽象享元角色:所有具體享元類的基類,為具體享元規范需要實作的公共介面,
(2)具體享元角色:實作抽象享元角色中所規定的的介面,
(3)非享元角色:是不可以共享的外部狀態,
(4)享元工廠角色:負責創建和管理享元角色,
其結構如下圖所示:
該部分主要參考:享元模式(詳解版),詳情請點擊該鏈接,
二、創建世界功能
如果我們希望創建一個游戲世界,那個可以能會有草地、丘陵、河流等很多地形,為了方便我們便基于區塊來建立地形表:將世界劃分為由微小區塊組成的巨大網格,每個區塊都被一種地形覆寫,
地形有以下特性:
(1)移動開銷
(2)是否可通行
(3)用于渲染的紋理,
由此,我們直接宣告一個Terrain類,來保存這些資料,
在創建地形表的時候,如果我們選擇1000*1000的地形,為每個位置都創建一個地形物件,便會占用大量的時間和記憶體(創建物件消耗的時間),此外,我們可以發現這些創建的地形物件大部分都是重復的,其唯一的區別是地形在哪里,使用享元的術語來說,就是地形的所有狀態都是“背景關系無關的”,因此對于這些地形物件,我們進行共享,使用享元模式和不使用享元模式的性能差距還是很大的,
我們計算一下使用享元模式和不使用享元模式,64位系統下,100*100的地圖的花銷上的不同,
如:
共有部分介紹:
Terrain類的三個屬性分別為int、bool、char三種型別,其大小為:8位元組,
創建一個Terrain物件,要0.01ms,
地形表中有10000個指標,總大小為:80000位元組,
不使用享元模式:
創建10000個物件,占用記憶體:80000位元組,時間消耗:100ms
使用享元模式:
由于本文中只有三種地形,因此只需3個物件,占用記憶體:24位元組,時間消耗:0.03ms,
可以看見在100100的地圖上,使用享元和不使用享元的差距都如此之大,如果是10001000的地圖呢?10000*10000呢?
詳情請點擊以下鏈接:
游戲設計模式-享元模式
三、具體代碼實作
3.1、前置準備
匯入頭檔案和設定地圖大小,
/*
作者:lbb
版本:v0.1
更改時間:2021/10/21
*/
#include<iostream>
//世界大小
const int HEIGHT=10;
const int WIDTH=20;
3.2、地形類
宣告三個屬性特性,提供獲取屬性函式,具體享元類,
//地形類
class Terrain{
public:
//建構式
Terrain(int movementCost,bool isWater,const char texture):movementCost_(movementCost),isWater_(isWater),texture_(texture){}
//獲取屬性函式
int GetMovementCost(){return movementCost_;}
int IsWater() const {return isWater_;}
const char& GetTexture()const{return texture_;}
private:
int movementCost_;//移動花費
bool isWater_;//是否是墻
char texture_;//貼圖
};
3.3、世界類
初始化三種地形,隨機生成世界地形,存盤地形表,變相的享元工廠類,
//世界類
class World{
public:
//創建時初始化三種地形
World():grassTerrain_(1,false,' '),
hillTerrain_(2,false,'^'),
riverTerrain_(3,true,'w')
{
GenerateTerrain();
}
//生成世界地形
void GenerateTerrain();
//獲取(x,y)的地區
const Terrain& GetTile(int x,int y)const;
private:
Terrain grassTerrain_;//草原地形
Terrain hillTerrain_;//丘陵地形
Terrain riverTerrain_;//河流地形
Terrain* tiles_[HEIGHT][WIDTH];//世界地形陣列
};
void World::GenerateTerrain(){
for(int i=0;i<HEIGHT;i++)
{
for(int j=0;j<WIDTH;j++)
{
if(rand()%10==0){
tiles_[i][j]=&hillTerrain_;
}
else{
tiles_[i][j]=&grassTerrain_;
}
}
}
int i=rand()%HEIGHT;
for(int j=0;j<WIDTH;j++)
{
tiles_[(i-1)%HEIGHT][j]=&riverTerrain_;
tiles_[i][j]=&riverTerrain_;
tiles_[(i+1)%HEIGHT][j]=&riverTerrain_;
}
}
const Terrain& World::GetTile(int x,int y) const{
return *tiles_[x][y];
}
3.4、主函式
輸出游戲世界
int main(void)
{
World myWorld;
//輸出世界
for(int i=0;i<HEIGHT;i++)
{
for(int j=0;j<WIDTH;j++)
{
std::cout<<myWorld.GetTile(i,j).GetTexture();
}
std::cout<<std::endl;
}
return 0;
}
四、輸出結果
輸出截圖如下:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/335314.html
標籤:其他
上一篇:外星人入侵(二.外星人來了)
下一篇:KN戰爭游戲(文字版)
