<!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教程一 —— 第十三章:游戏结束</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.3395" 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>函数</FONT></A> </TD>
<TD vAlign=center align=right><IMG height=32
src="Qt教程一 —— 第十三章:游戏结束.files/logo32.png" width=64 align=right
border=0></TD></TR></TBODY></TABLE>
<H1 align=center>Qt教程一 —— 第十三章:游戏结束</H1>
<P>
<CENTER><IMG alt="Screenshot of tutorial thirteen"
src="Qt教程一 —— 第十三章:游戏结束.files/t13.png"></CENTER>
<P>在这个例子中我们开始研究一个带有记分的真正可玩的游戏。我们给MyWidget一个新的名字(GameBoard)并添加一些槽。
<P>我们把定义放在gamebrd.h并把实现放在gamebrd.cpp。
<P>CannonField现在有了一个游戏结束状态。
<P>在LCDRange中的布局问题已经修好了。
<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类实现。
<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类实现。
<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类实现。
<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是非常容易使用的,但是它也显示了它的局域性,所以我们选择使用更加强大和稍微有一些难的<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>我们现在需要包含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>另外一个构造函数作了同样的改动。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>我们使用所有默认值创建一个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>然后我们添加另外两个,它们都使用默认的零伸展因数。
<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现在有一个游戏结束状态和一些新的函数。
<P>
<P><PRE> bool gameOver() const { return gameEnded; }
</PRE>
<P>如果游戏结束了,这个函数返回TRUE,或者如果游戏还在继续,返回FALSE。
<P><PRE> void setGameOver();
void restartGame();
</PRE>
<P>这里是两个新槽:setGameOver()和restartGame()。
<P><PRE> void canShoot( bool );
</PRE>
<P>这个新的信号表明CannonField使shoot()槽生效的状态。我们将在下面使用它用来使Shoot按钮生效或失效。
<P><PRE> bool gameEnded;
</PRE>
<P>这个私有变量包含游戏的状态。TRUE说明游戏结束,FALSE说明游戏还将继续。
<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>这一行已经被加入到构造函数中。最开始的时候,游戏没有结束(对于玩家是很幸运的 :-)。
<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()函数,所以shoot()使用它替代直接的测试。同样,shoot告诉世界CannonField现在不可以射击。
<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.ht
评论0