📄 ch28.htm
字号:
public:
__fastcall TForm1(TComponent* Owner);
};
extern TForm1 *Form1;
</FONT></PRE>
<P><FONT
COLOR="#0066FF"><TT>#endif</TT></FONT>
<H4><FONT COLOR="#000077">Listing 28.6. The main form for the unit that tests the
TScene object.</FONT></H4>
<PRE><FONT COLOR="#0066FF">
///////////////////////////////////////
// Main.cpp
// Test the TScene
object
// Copyright (c) 1997 by Charlie Calvert
//
#include <vcl\vcl.h>
#pragma hdrstop
#include "Main.h"
#pragma link "Mercury2"
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall
TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TForm1::Run1Click(TObject *Sender)
{
Hermes1->Run();
}
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{
if
((Shift.Contains(ssAlt)) && (Key == `X'))
Close();
</FONT></PRE>
<P><FONT COLOR="#0066FF"><TT>}</TT> </FONT><BR>
<BR>
The program shown here can switch you into <TT>Exclusive</TT> mode and show a picture
like the one shown in Figure
28.1.</P>
<P><A HREF="28ebu01.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/28/28ebu01.jpg">Figure 28.1.</A><B> </B><I>The main screen of the
TestScenel program in windowed mode.</I></P>
<P>To get started with the <TT>TScene</TT> object, drop both it and the <TT>THermes</TT>
object on a form. Use the
<TT>Scene</TT> property of <TT>THermes</TT> to connect
it to the <TT>TScene</TT> object. Click the <TT>TScene</TT> object, and select a
background bitmap by browsing the <TT>Chap28/Media</TT> directory included on the
CD that accompanies this book.
Select any bitmap that is smaller than or equal to
640x480 and that has 256 colors in it. For example, you might choose <TT>BackGrd2.bmp</TT>.
Set the Transparent color to black, which will appear at offset zero on the bitmaps.
Set the
<TT>BackColor</TT> property of the bitmap to the same shade, and set <TT>BlankScene</TT>
to <TT>True</TT>:</P>
<PRE><FONT COLOR="#0066FF">TransparentColor = 0;
BackColor = clBlack;
BlankScene = True;
</FONT></PRE>
<BLOCKQUOTE>
<DL>
<DD>
<HR>
<FONT COLOR="#000077"><B>NOTE:</B></FONT><B> </B><TT>TransparentColor</TT> refers
to the color in a bitmap that will be transparent. That is, the areas in the bitmap
where this color is present become transparent. You need a transparent color when
you want to blit an irregularly shaped bitmap on top of a background bitmap. For
example, if you have a picture of a bird that you want to blit onto a picture of
the sky, just set the background area in the picture of the bird to the transparent
color, and it will not show up when the bird is blitted to the screen. In other words,
the picture of the sky will show through the transparent area, so the bird will appear
directly against the sky, with no intervening border.<BR>
<BR>
You choose
the selected transparent color from an offset in the palette of the bitmap
you're using. For example, if you set <TT>TransparentColor</TT> to <TT>0</TT>, the
first color in the bitmap's palette will be the transparent color. Most good paint
programs will show you the palette for a picture. For example, Paint Shop Pro provides
this service.
<HR>
</DL>
</BLOCKQUOTE>
<P>If you select a prominently used color from a picture as the transparent color,
the portions of the picture with
that color in them will look strange at runtime.
To avoid this situation, set the <TT>BackColor</TT> property of <TT>TScene</TT> and
the <TT>TransparentColor</TT> for the picture to the same shade. Also set <TT>BlankScene</TT>
to <TT>True</TT>. This
way, the transparent color will look through onto a background
that is the same shade as the color you're making transparent.</P>
<P>The <TT>BlankScene</TT> property blanks the background of the <TT>TScene</TT>
object to the color found in the
<TT>BackColor</TT> property. This capability can
be useful in the current situation and also when you have a small bitmap that you
want to show against a blank window set to some particular color.</P>
<P>When you're creating multimedia applications in
Windows, the palette of your bitmaps
is very important. In particular, you should usually create the same 256-color palette
for all your bitmaps. Use a program such as Paint Shop Pro to set up these bitmaps.
Most of the bitmaps included in the
<TT>Chap28/Media</TT> directory on the CD that
comes with this book have a palette designed for pictures that have lots of green
fields, brown earth, and a range of skin tones.</P>
<P>When you're working with only one bitmap in a scene, all this
business about palettes
seems unnecessarily complicated. However, after you start adding sprites to the scene,
you will be glad that you have some way to set up background colors and to set up
<TT>TransparentColor</TT>. I explain more about palettes
in the next section of this
chapter.</P>
<P>The <TT>TScene</TT> object also has a built-in timer that will continually redraw
the picture at preset intervals. This capability is not particularly useful in the
case of a program that blits only one
picture to the screen. However, when you start
working with multiple bitmaps, some of which are animated, this capability becomes
a key feature. In particular, DirectX allows you to draw to an offscreen buffer,
which is then blitted to the screen
almost instantly. Using this method is an excellent
way to achieve smooth animation.</P>
<P>Instead of using a timer, you can also handle the <TT>TApplication::OnIdle</TT>
event, and then call <TT>Hermes1->Flip</TT> inside that event handler.
The<TT>
OnIdle</TT> event will be called whenever the CPU is not otherwise occupied.</P>
<P>To get the <TT>TScene</TT> object set up correctly, you should turn on the timer
and set the <TT>TimerInterval</TT> property to some reasonable value, such as
250
milliseconds. Setting this property will cause the picture to be refreshed four times
a second. This number is too slow for animation, but it works fine for the simple
scene created here. In particular, if you press Alt+Tab to move away from the
DirectX
program, the timer will automatically restore the picture when you press Alt+Tab
to move back to the main scene.</P>
<P>On the CD that accompanies this book, you will find a program called TestScene1.
The source for this program is shown in
Listings 28.5 and 28.6. You can use this
code as a guide for using the <TT>TScene</TT> object. Remember that <TT>TScene</TT>
is not really meant to be used in a real program. It is just a base object from which
other, more useful objects can descend.
<H2><FONT COLOR="#000077">Art and Palettes</FONT></H2>
<P>In Windows and DOS games, you almost always work with a 256-color palette. Someday
this will change, but for now you should get used to working with these palettes
and come to understand them
well. An in-depth description of palettes is available
in some of the books and Web sites mentioned in the section called "Games Resources"
at the beginning of this chapter.</P>
<P>Using Paint Shop Pro, you can save a palette to disk as a
text file:</P>
<PRE><FONT COLOR="#0066FF">
JASC-PAL
0100
256
0 0 0
128 0 0
0 128 0
128 128 0
0 0 128
128 0 128
0 128 128
192 192 192
176 136 72
216 192 160
... // Many numbers omitted here...
240 224 208
160 160 164
128 128 128
255 0
0
0 255 0
255 255 0
0 0 255
255 0 255
0 255 255
255 255 255
</FONT></PRE>
<P>Here is how to decode the first few lines of this file:</P>
<PRE><FONT COLOR="#0066FF">JASC-PAL
0100
256
0 0 0
</FONT></PRE>
<P><TT>JASC-PAL</TT> identifies the
palette as belonging to Paint Shop Pro. The second
line defines the number of entries in the palette in hexadecimal format. The third
line has the number of entries in base ten notation. The fourth line is the first
member of the palette in RGB
format, with all values set to <TT>0</TT>, which is
black.</P>
<P>Notice that my palette runs through various shades:</P>
<PRE><FONT COLOR="#0066FF">118 102 237
117 116 240
129 113 249
155 110 239
107 144 140
115 144 140
123 136 140
123 148 140
111 148 148
</FONT></PRE>
<P>Clearly, I'm interested in this area of the palette.</P>
<P>Obviously, you don't want to have to work with raw numbers like this. Paint Shop
Pro will let you view a palette as an array of colors, as shown in Figure 28.2.
Having
some kind of tool that will help you design your palette is essential. You should
also find books, such as this one and the ones mentioned previously, that include
sample palettes.</P>
<P><A HREF="28ebu02.jpg" tppabs="http://pbs.mcp.com/ebooks/0672310228/art/28/28ebu02.jpg">Figure 28.2.</A><B>
</B><I>Using Paint Shop Pro to
view an array of shades that make up a 256-color palette.</I></P>
<P>
<H2><FONT COLOR="#000077"><BR>
Working with TSpriteScene</FONT></H2>
<P>Now that you know how to show a simple picture in DirectX mode, and now that
you
know a bit about palettes, you're ready to start working with sprites. The sprite
support I have at this time is very rudimentary, as you can see in Listings 28.7
through 28.9. You could, however, use these base sprite classes to create sprites
that are more full-featured. You should also check my Web site for updates to this
code.
<H4><FONT COLOR="#000077">Listing 28.7. The declarations for the TSpriteScene and
TScene classes.</FONT></H4>
<PRE><FONT COLOR="#0066FF">
class TSprite : public
Classes::TComponent
{
typedef Classes::TComponent inherited;
friend TSpriteScene;
private:
System::AnsiString FBitmap;
tagPOINT FPosition;
IDirectDrawSurface* FSurface;
RECT FRect;
public:
bool __fastcall IsHit(int X, int
Y);
__property IDirectDrawSurface* Surface=
{read=FSurface, write=FSurface, nodefault};
__property RECT Rect = {read=FRect, write=FRect};
__published:
__property System::AnsiString Bitmap={read=FBitmap, write=FBitmap, nodefault};
__property long XPos = {read=FPosition.x, write=FPosition.x, nodefault};
__property long YPos = {read=FPosition.y, write=FPosition.y, nodefault};
public:
__fastcall virtual TSprite(Classes::TComponent* AOwner)
: Classes::TComponent(AOwner)
{ }
__fastcall virtual ~TSprite(void) { }
};
class TSpriteScene : public TScene
{
typedef TScene inherited;
private:
Classes::TList* FSpriteList;
protected:
__fastcall virtual ~TSpriteScene(void);
virtual void __fastcall
SetupSurfaces(System::TObject* Sender);
public:
__fastcall virtual TSpriteScene(Classes::TComponent* AOwner);
virtual void __fastcall DestroyObjects(void);
void __fastcall AddSprite(TSprite* Sprite);
virtual void __fastcall
DrawScene(void);
virtual long __fastcall RestoreSurfaces(void);
__property Classes::TList* SpriteList = {read=FSpriteList, write=FSpriteList, nodefault};
__published:
__property TransparentColor;
</FONT></PRE>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -