国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

基于C#的Windows游戲開發(fā)的方法與原理

2018-02-02 12:46畢文斌郭曉玉
電腦知識與技術(shù) 2018年1期
關(guān)鍵詞:窗體畫布控件

畢文斌+郭曉玉

摘要:在Visual Studio環(huán)境中使用C#編寫游戲項目是很多計算機相關(guān)專業(yè)的大學(xué)生非常愿意嘗試的課題,該文通過一個小的例子,給出這類游戲項目的開發(fā)方法與基本原理,這個方法的掌握可以使一些基于文件和數(shù)據(jù)庫的游戲項目的開發(fā)變得更加簡單。

關(guān)鍵詞:雙緩存(DoubleBuffered);計時器(Timer)

中圖分類號:TP311 文獻標(biāo)識碼:A 文章編號:1009-3044(2018)01-0106-02

一般以為游戲必須在專業(yè)的游戲開發(fā)平臺上去實現(xiàn),而基于C#的Winforms應(yīng)用程序一般用來開發(fā)基于數(shù)據(jù)庫的管理類應(yīng)用程序。但是各個平臺都有自身的長處,也都有自己的短板:基于C#的Winforms程序?qū)κ褂梦募皵?shù)據(jù)庫有著天然的優(yōu)勢,專業(yè)的游戲開發(fā)平臺更偏重圖像刷新的頻率和聲音的及時性,而要在這些平臺上使用文、數(shù)據(jù)庫及其他控件,明顯比前者不便。

在認(rèn)真觀察了XNA游戲開發(fā)的內(nèi)部體制之后,經(jīng)詳細(xì)的理解Winforms的DoubleBuffered(雙緩存)機制,加上靈活使用Winfroms自身提供的Timer(計時器)組件,也可以開發(fā)出像掃雷、連連看及中國象棋這類2D游戲,游戲體驗和專業(yè)游戲平臺并無明顯的差別,但要比使用C++語言或從另外學(xué)習(xí)新的平臺入手要簡單得多;尤其如果游戲是基于數(shù)據(jù)庫的,并且界面中需要給用戶提供輸入或選擇的控件,這種情況下Winfroms的優(yōu)勢更加明顯。

簡單地說,雙緩存機制就是就是在內(nèi)存中定義個圖片,繪圖時先在內(nèi)存中畫好,再使用這個圖片更新你要畫圖的地方,這個機制可以有效地避免圖像閃爍的問題,使用雙緩存機制的過程如下:

1) 新建一個Winforms應(yīng)用程序,將窗體的DoubleBuffered屬性設(shè)置為True;

2) 重載窗體的OnPaint函數(shù),在這個函數(shù)中“畫”游戲所需要的畫面;

3) 在窗體設(shè)計界面根據(jù)需要中拖入一個或多個Timer組件,根據(jù)游戲的實時情況更新數(shù)據(jù)并調(diào)用窗體的Invalidate()函數(shù),這個函數(shù)促發(fā)調(diào)用OnPaint()函數(shù),更新游戲畫面。

下面以一個簡單的例子來學(xué)習(xí)一般游戲的開發(fā)方法:

1) 新建一個Winforms項目,將其命名為Rotating,將Form1的DoubleBuffered屬性設(shè)置為True,在項目的Debug文件夾中粘貼圖片threerings,一般選擇png格式的圖片,如果是用來當(dāng)游戲背景圖,也可以使用其他格式的圖片。Threerings.png如圖1所示:

這是由三個環(huán)旋轉(zhuǎn)所截得的48個時刻的小圖片(80x100),就像電影的膠片一樣,如果連續(xù)“播放”它們,就會產(chǎn)生旋轉(zhuǎn)的效果;

2) 拖入一個Timer控件,其默認(rèn)名為timer1,將其Interval屬性設(shè)置為80;

3) 在Form1.cs文件中新建以下全局變量:

Bitmap bmpAll;

Bitmap[] bmpFragments=new Bitmap[48];//48張小圖片

int bmp_X = 0;//畫布左上角的橫坐標(biāo)

int bmp_Y = 0;//畫布左上角的縱坐標(biāo)

int DisplayIndex = 0; }//當(dāng)前顯示的小圖片的索引

4) 在窗體的Load事件中輸入以下代碼:

private void Form1_Load(object sender, EventArgs e)

{

bmp_X = this.ClientRectangle.Width / 2 - 40;

bmp_Y = this.ClientRectangle.Height / 2 - 50;

bmpAll = new Bitmap(Application.StartupPath + "\\threerings.bmp");

for (int row = 0; row < 8; row++)

for (int col = 0; col < 6; col++)

bmpFragments[row * 6 + col] = bmpAll.Clone(new Rectangle(col*75,row*75,75,75),bmpAll.PixelFormat);

this.timer1.Start();

5) 在Form1.cs文件中手動輸入重載函數(shù)OnPaint函數(shù),代碼如下:

protected override void OnPaint(PaintEventArgs e)

{

Bitmap bufferBmp = new Bitmap(this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1);//空背景的畫布

Graphics g = Graphics.FromImage(bufferBmp);

g.DrawImage(bmpFragments[DisplayIndex], new Point(bmp_X, bmp_Y));

e.Graphics.DrawImage(bufferBmp, 0, 0);

g.Dispose();

base.OnPaint(e);

}

6) timer1的Tick事件代碼如下:

private void timer1_Tick(object sender, EventArgs e)

{

DisplayIndex = (++DisplayIndex) % 48;

if (DisplayIndex == 47 && this.timer1.Interval>=20)

this.timer1.Interval -= 10;

this.Invalidate();//促發(fā)調(diào)用OnPaint()函數(shù)

}

現(xiàn)在運行程序,就可以看到一個旋轉(zhuǎn)的三色環(huán),每旋轉(zhuǎn)一個周期,由于timer1的Interval減少了10,所以會旋轉(zhuǎn)的比上個周期更快。

當(dāng)游戲上有更多的變化的元素時,如:移動的棋子、控制游戲時間的進度條、

爆炸特效等,需要為每個元素創(chuàng)建不同的Timer,以更新與這個元素相關(guān)的位置、百分比、爆炸圖片索引等數(shù)據(jù)信息,當(dāng)這些信息更新時,調(diào)用代碼this.Invalidate();以更新畫面。

最后說一下游戲聲音的處理:一般播放流暢的背景音樂時,使用Visual Studio自帶的多媒體播放控件,如果需要及時響應(yīng)的聲音,如點擊棋子、碰撞等,可以使用Windows自帶的PlaySound函數(shù)。

就當(dāng)前的實踐來說,圖像的顯示與更新非常好,即使像掃雷這種畫有很多方格的游戲都非常流暢,但一些特定的游戲聲音會出現(xiàn)卡頓:比如彈球游戲,上一個碰撞聲音正在播放,下一個碰撞已經(jīng)到來,這時PlaySound函數(shù)不會自動結(jié)束正在進行的播放,所以還需要添加額外的變量進行控制—即使專業(yè)的游戲開發(fā)平臺,也會出現(xiàn)這種情況,需要設(shè)計人根據(jù)游戲體驗做出合理的取舍。

備注:上述例子是以整個窗體作為游戲畫布,如果界面中除了顯示圖像,還想加入Visual Studio的自帶的輸入或選擇類控件,可以將界面的某個不包含這些控件的區(qū)域作為畫布(在OnPaint()函數(shù)中定義),這樣更新畫面時僅更新游戲畫面,而不會同時重繪這些控件。

參考文獻:

[1] 楊關(guān)勝,栗俊霞.精通XNA圖形與游戲程序設(shè)計[M].北京:人民郵電出版社, 2012.

[2] 畢文斌,孫明亮.C# Windows游戲設(shè)計[M].北京:清華大學(xué)出版社, 2014.endprint

猜你喜歡
窗體畫布控件
為什么要在畫布上割一刀?
試談Access 2007數(shù)據(jù)庫在林業(yè)檔案管理中的應(yīng)用
讓鮮花在畫布上盛開
大師的畫布
ASP.NET服務(wù)器端驗證控件的使用
巧設(shè)WPS窗體控件讓表格填寫更規(guī)范
WinCE.net下圖形用戶界面的開發(fā)
Spreadsheet控件在Delphi數(shù)據(jù)庫系統(tǒng)中的編程與應(yīng)用
临猗县| 尉氏县| 安图县| 正蓝旗| 福建省| 阜宁县| 昌平区| 平山县| 疏勒县| 资溪县| 龙胜| 漳州市| 渭南市| 柳河县| 横峰县| 吉首市| 周至县| 石泉县| 和政县| 柳河县| 宝山区| 资溪县| 绍兴县| 西乌珠穆沁旗| 蓝山县| 措美县| 成都市| 璧山县| 四会市| 芦溪县| 清水河县| 嵊泗县| 定西市| 浦城县| 秦安县| 建阳市| 普宁市| 宜兰县| 海兴县| 额尔古纳市| 孝昌县|