?? qt教程一 —— 第十三章:游戲結(jié)束.htm
字號:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0061)http://www.qtopia.org.cn/doc/qiliang.net/qt/tutorial1-13.html -->
<!-- /home/reggie/tmp/qt-3.0-reggie-5401/qt-win-commercial-3.0.5/doc/tutorial.doc:2035 --><HTML><HEAD><TITLE>Qt教程一 —— 第十三章:游戲結(jié)束</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content=Cavendish name=Translator>
<META content=http://www.qiliang.net/qt name="Qt zh_CN Documents Website">
<STYLE type=text/css>H3.fn {
MARGIN-LEFT: 1cm; TEXT-INDENT: -1cm
}
SPAN.fn {
MARGIN-LEFT: 1cm; TEXT-INDENT: -1cm
}
A:link {
COLOR: #004faf; TEXT-DECORATION: none
}
A:visited {
COLOR: #672967; TEXT-DECORATION: none
}
BODY {
BACKGROUND: #ffffff; COLOR: black; FONT-FAMILY: "Times New Roman"
}
</STYLE>
<META content="MSHTML 6.00.2900.2180" name=GENERATOR></HEAD>
<BODY>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR bgColor=#e5e5e5>
<TD vAlign=center><A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/index.html"><FONT
color=#004faf>主頁</FONT></A> | <A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/classes.html"><FONT
color=#004faf>所有的類</FONT></A> | <A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/mainclasses.html"><FONT
color=#004faf>主要的類</FONT></A> | <A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/annotated.html"><FONT
color=#004faf>注釋的類</FONT></A> | <A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/groups.html"><FONT
color=#004faf>分組的類</FONT></A> | <A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/functions.html"><FONT
color=#004faf>函數(shù)</FONT></A> </TD>
<TD vAlign=center align=right><IMG height=32
src="Qt教程一 —— 第十三章:游戲結(jié)束.files/logo32.png" width=64 align=right
border=0></TD></TR></TBODY></TABLE>
<H1 align=center>Qt教程一 —— 第十三章:游戲結(jié)束</H1>
<P>
<CENTER><IMG alt="Screenshot of tutorial thirteen"
src="Qt教程一 —— 第十三章:游戲結(jié)束.files/t13.png"></CENTER>
<P>在這個例子中我們開始研究一個帶有記分的真正可玩的游戲。我們給MyWidget一個新的名字(GameBoard)并添加一些槽。
<P>我們把定義放在gamebrd.h并把實現(xiàn)放在gamebrd.cpp。
<P>CannonField現(xiàn)在有了一個游戲結(jié)束狀態(tài)。
<P>在LCDRange中的布局問題已經(jīng)修好了。
<P>
<UL>
<LI><A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/t13-lcdrange-h.html">t13/lcdrange.h</A>包含LCDRange類定義。
<LI><A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/t13-lcdrange-cpp.html">t13/lcdrange.cpp</A>包含LCDRange類實現(xiàn)。
<LI><A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/t13-cannon-h.html">t13/cannon.h</A>包含CannonField類定義。
<LI><A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/t13-cannon-cpp.html">t13/cannon.cpp</A>包含CannonField類實現(xiàn)。
<LI><A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/t13-gamebrd-h.html">t13/gamebrd.h</A>包含GameBoard類定義。
<LI><A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/t13-gamebrd-cpp.html">t13/gamebrd.cpp</A>包含GameBoard類實現(xiàn)。
<LI><A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/t13-main-cpp.html">t13/main.cpp</A>包含MyWidget和main。
</LI></UL>
<P>
<H2>一行一行地解說 </H2><A name=1></A>
<P>
<H3><A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/t13-lcdrange-h.html">t13/lcdrange.h</A>
</H3><A name=1-1></A>
<P>
<P><PRE> #include <<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwidget-h.html">qwidget.h</A>>
class QSlider;
class QLabel;
class LCDRange : public <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwidget.html">QWidget</A>
</PRE>
<P>我們繼承了<A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwidget.html">QWidget</A>而不是<A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qvbox.html">QVBox</A>。QVBox是非常容易使用的,但是它也顯示了它的局域性,所以我們選擇使用更加強(qiáng)大和稍微有一些難的<A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qvboxlayout.html">QVBoxLayout</A>。(和你記憶中的一樣,QVBoxLayout不是一個窗口部件,它管理窗口部件。)
<P>
<H3><A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/t13-lcdrange-cpp.html">t13/lcdrange.cpp</A>
</H3><A name=1-2></A>
<P>
<P><PRE> #include <<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qlayout-h.html">qlayout.h</A>>
</PRE>
<P>我們現(xiàn)在需要包含qlayout.h來獲得其它布局管理API。
<P><PRE> LCDRange::LCDRange( <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwidget.html">QWidget</A> *parent, const char *name )
: <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwidget.html">QWidget</A>( parent, name )
</PRE>
<P>我們使用一種平常的方式繼承QWidget。
<P>另外一個構(gòu)造函數(shù)作了同樣的改動。init()沒有變化,除了我們在最后加了幾行:
<P><PRE> <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qvboxlayout.html">QVBoxLayout</A> * l = new <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qvboxlayout.html">QVBoxLayout</A>( this );
</PRE>
<P>我們使用所有默認(rèn)值創(chuàng)建一個QVBoxLayout,管理這個窗口部件的子窗口部件。
<P><PRE> <A name=x2333></A> l-><A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qboxlayout.html#addWidget">addWidget</A>( lcd, 1 );
</PRE>
<P>At the top we add the <A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qlcdnumber.html">QLCDNumber</A>
with a non-zero stretch.
<P><PRE> l-><A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qboxlayout.html#addWidget">addWidget</A>( slider );
l-><A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qboxlayout.html#addWidget">addWidget</A>( label );
</PRE>
<P>然后我們添加另外兩個,它們都使用默認(rèn)的零伸展因數(shù)。
<P>這個伸展控制是<A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qvboxlayout.html">QVBoxLayout</A>(和<A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qhboxlayout.html">QHBoxLayout</A>,和<A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qgridlayout.html">QGridLayout</A>)所提供的,而像<A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qvbox.html">QVBox</A>這樣的類卻不提供。在這種情況下我們讓QLCDNumber可以伸展,而其它的不可以。
<P>
<H3><A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/t13-cannon-h.html">t13/cannon.h</A>
</H3><A name=1-3></A>
<P>CannonField現(xiàn)在有一個游戲結(jié)束狀態(tài)和一些新的函數(shù)。
<P>
<P><PRE> bool gameOver() const { return gameEnded; }
</PRE>
<P>如果游戲結(jié)束了,這個函數(shù)返回TRUE,或者如果游戲還在繼續(xù),返回FALSE。
<P><PRE> void setGameOver();
void restartGame();
</PRE>
<P>這里是兩個新槽:setGameOver()和restartGame()。
<P><PRE> void canShoot( bool );
</PRE>
<P>這個新的信號表明CannonField使shoot()槽生效的狀態(tài)。我們將在下面使用它用來使Shoot按鈕生效或失效。
<P><PRE> bool gameEnded;
</PRE>
<P>這個私有變量包含游戲的狀態(tài)。TRUE說明游戲結(jié)束,F(xiàn)ALSE說明游戲還將繼續(xù)。
<P>
<H3><A
href="http://www.qtopia.org.cn/doc/qiliang.net/qt/t13-cannon-cpp.html">t13/cannon.cpp</A>
</H3><A name=1-4></A>
<P>
<P><PRE> gameEnded = FALSE;
</PRE>
<P>這一行已經(jīng)被加入到構(gòu)造函數(shù)中。最開始的時候,游戲沒有結(jié)束(對于玩家是很幸運(yùn)的 :-)。
<P><PRE> void CannonField::shoot()
{
if ( isShooting() )
return;
timerCount = 0;
shoot_ang = ang;
shoot_f = f;
<A name=x2339></A> autoShootTimer-><A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qtimer.html#start">start</A>( 50 );
emit canShoot( FALSE );
}
</PRE>
<P>我們添加一個新的isShooting()函數(shù),所以shoot()使用它替代直接的測試。同樣,shoot告訴世界CannonField現(xiàn)在不可以射擊。
<P><PRE> void CannonField::setGameOver()
{
if ( gameEnded )
return;
if ( isShooting() )
autoShootTimer-><A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qtimer.html#stop">stop</A>();
gameEnded = TRUE;
<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwidget.html#repaint">repaint</A>();
}
</PRE>
<P>這個槽終止游戲。它必須被CannonField外面的調(diào)用,因為這個窗口部件不知道什么時候終止游戲。這是組件編程中一條重要設(shè)計原則。我們選擇使組件可以盡可能靈活以適應(yīng)不同的規(guī)則(比如,在一個首先射中十次的人勝利的多人游戲版本可能使用不變的CannonField)。
<P>如果游戲已經(jīng)被終止,我們立即返回。如果游戲會繼續(xù)到我們的設(shè)計完成,設(shè)置游戲結(jié)束標(biāo)志,并且重新繪制整個窗口部件。
<P><PRE> void CannonField::restartGame()
{
if ( isShooting() )
<A name=x2340></A> autoShootTimer-><A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qtimer.html#stop">stop</A>();
gameEnded = FALSE;
<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwidget.html#repaint">repaint</A>();
emit canShoot( TRUE );
}
</PRE>
<P>這個槽開始一個新游戲。如果炮彈還在空中,我們停止設(shè)計。然后我們重置<TT>gameEnded</TT>變量并重新繪制窗口部件。
<P>就像hit()或miss()一樣,moveShot()同時也發(fā)射新的canShoot(TRUE)信號。
<P>CannonField::paintEvent()的修改:
<P><PRE> void CannonField::<A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qwidget.html#paintEvent">paintEvent</A>( <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qpaintevent.html">QPaintEvent</A> *e )
{
<A name=x2337></A> <A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qrect.html">QRect</A> updateR = e-><A href="http://www.qtopia.org.cn/doc/qiliang.net/qt/qpaintevent.html#rect">rect</A>();
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -