Tải bản đầy đủ - 0 (trang)
Chapter 15. Captain Chloride Gets Going

Chapter 15. Captain Chloride Gets Going

Tải bản đầy đủ - 0trang

IntroducingCaptainChloride

CaptainChloride,erstwhiledefenderoftheplanetEarth,

requirestheuseofanimatedspritestoseemlifelike.Hismost

commonmovementiswalking,sothat'sthefirstthingI'll

implement.

BecauseInvasionoftheSlugwrothsisaside-scrollinggame,

CaptainChloridemustbeabletowalkeitherleftorright.Each

ofthesemovementsrequiresitsownanimation.Also,thegame

mustdisplayanimagewhenheisnotmoving.Iliketostart

simply,soI'lldemonstratewalkingCaptainChlorideusingan

animatedspriteforallofCaptainChloride'swalking

movements.Althoughitdoesn'tlookallthatprofessional,I'll

haveCaptainChloridejustfreezeinplacewhenhestops

walking.



Note

Whenthemaincharacterisnotmoving,many

gamesdomorethanjustdisplayanimageofit

frozeninawalkingposition.Theytypicallyshow

somethinglikeananimationofthecharacterlooking

outattheplayerandimpatientlytappingitsfoot.It

addsbothlifeandhumortothegame.



MakingCaptainChloridewalkinaparticulardirectionrequires

severalanimationframes.Figure15.1displaystheframesfor

walkingleft.



Figure15.1.EachframeshowsCaptainChloride



inaslightlydifferentposition.



Note

Theframesforwalkingleftaremirrorimagesof

thoseusedforwalkingright.Graphicsprogramslet

youflipbitmaps.Iactuallyonlydrewtheframesfor

walkingright.Ithenflippedeachframesothatthe

Captainfacedleftandsavedtheflippedframes

underdifferentfilenames.Thisisatechniqueyou

shouldusewheneverpossible.



TodisplayCaptainChloridewalkingright,thegameneedsaset

ofanimationsthataremirrorimagesoftheonesshownin

Figure15.1.ThesearegiveninFigure15.2.



Figure15.2.Thisseriesofframesisamirror

imageofthoseusedtowalkleft.



Bothsetsofframesareincludedwiththesampleprogramson

theCD.Youcanfindtheminthefolder

Source\Chapter15\Prog_15_01.Idrewtheseanimationframes

usingCorelDraw,buttheycouldhavebeendonejustaseasily

withGIMP,whichI'veprovidedforfreeontheCD.WhenIdrew

eachframe,IsaveditasaWindowsBMPfile.



DesigningtheChlorideClass

It'softenthecaseinyourgamesthatthemaincharacterwillbe

implementedinaclassespeciallydesignedforthatcharacter.

Therefore,that'sthewayI'llwriteInvasionoftheSlugwroths.

Listing15.1showsthechlorideclass.



Listing15.1.TheclassthatimplementsCaptain

Chloride



1classchloride

2{

3//Publictypes.

4public:

5enumchloride_state

6{

7STAND,

8WALK_LEFT,

9WALK_RIGHT

10};

11

12//Publicmemberfunctions

13public:

14chloride();

15

16boolLoadResources();

17

18boolUpdate();

19boolRender();

20

21voidX(



22floatupLeftX);

23floatX();

24

25voidY(

26floatupLeftY);

27floatY();

28

29voidGetKeyboardInput();

30

31voidMovement(

32vectorfnew_velocity);

33

34intBitmapHeight();

35intBitmapWidth();

36

37private:

38animated_spriteleftWalk;

39animated_spriterightWalk;

40animated_sprite*standingSprite;

41soundleftWalkSound;

42soundrightWalkSound;

43vectorfvelocity;

44floatx,y;

45chloride_statestate;

46chloride_statelastWalkState;

47intlastStepIndex;

48};



Thechlorideclassdefinesasetofconstantsonlines510.The

classusestheseconstantstokeeptrackofwhatCaptain

Chlorideisdoingduringanygivenframeofscreenanimation.



Factoid

ManyWindowsprogrammersusefunctionnames

likeLoadResources()intheirclassesbecausesounds

andimagesarereferredtoasresourcesinWindows.



Next,thechlorideclasscontainstheprototypesforitsmember

functions.Thereareafewnoteworthyitemshere.First,the



chlorideclasshasamemberfunctioncalledLoadResources().This



function,aswe'llseeshortly,loadsalloftheimagesandsounds

thatthechlorideclassuses.

Thesecondimportantiteminthechlorideclassmember

functionsisthefactthatthechlorideclasscontainsitsownX()

andY()functions.Theseversionsusefloating-pointnumbers

ratherthanintegers.Althoughthisisnotnecessaryforthisfirst

exampleprogram,implementingthechlorideclassthisway

makesiteasiertoputCaptainChlorideintoacustom

gamespacelater.

Noticealsothatthereisamemberfunctioninthechlorideclass

calledGetKeyboardInput().Thisfunctiongetstheplayer'sinputand

tellsCaptainChloridetomoveleftorrightaccordingly.Itisin

thisclassratherthanthegameclassbecauseit'saneasyway

tocontrolCaptainChloride.Youdon'thavetodoitthisway.You

couldputthisintoyourgameclassinstead.

Lines3840showthatI'musingthreedifferentanimatedsprites

inthisprogramtostoreCaptainChloride'sanimations.Inthe

nextchapter,I'llshowhowtoputallofthemintooneanimated

sprite.

Lastly,noticethatlines4546introducetwodatamembersof

typechloride_state.Theseprivatememberskeeptrackofwhat

thegoodCaptainiscurrentlydoingandwhathewasdoingin

thelastframe.Ifhewaswalking,thedatamemberonline46

storestheanimationframethatwascurrentatthattime.



Note

Abluebackgroundisthedefaultbackgroundin

LlamaWorks2D.



ImplementingtheChlorideClass

Listing15.2showstheimplementationsofseveralofthemost

importantmemberfunctions.Tosavespace,Iwon'tshowallof

thememberfunctions.However,youcanfindthemontheCDin

thefolderSource\Chapter15\Prog_15_01.Thefilethatcontains

thechlorideclassisChloride.cpp.



Listing15.2.Somememberfunctionsofthe

chlorideclass



1voidchloride::GetKeyboardInput()

2{

3vectorfcaptainDirection;

4

5if(theApp.IsKeyPressed(KC_UP_ARROW))

6{

7captainDirection.Y(-1);

8}

9elseif(theApp.IsKeyPressed(KC_DOWN_ARROW))

10{

11captainDirection.Y(1);

12}

13if(theApp.IsKeyPressed(KC_LEFT_ARROW))

14{

15captainDirection.X(-1);

16}

17elseif(theApp.IsKeyPressed(KC_RIGHT_ARROW))

18{

19captainDirection.X(1);

20}

21

22if(captainDirection.MagnitudeSquared()==0.0)

23{

24state=STAND;

25}

26else

27{

28//Makethedirectionbeaunitvector,in

29//caseheismovingdiagonally,thenscale

30//itbythespeed.

31captainDirection=captainDirection.Normalize();

32captainDirection*=15.0;

33

34if(captainDirection.X()<0.0)

35{



36state=WALK_LEFT;

37}

38elseif(captainDirection.X()>0.0)

39{

40state=WALK_RIGHT;

41}

42else

43{

44state=lastWalkState;

45}

46}

47

48Movement(captainDirection);

49}

50

51

52bool

53chloride::Update()

54{

55x+=velocity.X();

56y+=velocity.Y();

57

58if(x<0.0)

59{

60x=0.0;

61}

62elseif(x>theApp.ScreenWidth()-BitmapWidth())

63{

64x=theApp.ScreenWidth()-BitmapWidth();

65}

66

67if(y<0.0)

68{

69y=0.0;

70}

71elseif(y>theApp.ScreenHeight()-BitmapHeight())

72{

73y=theApp.ScreenHeight()-BitmapHeight();

74}

75

76returntrue;

77}

78

79

80bool

81chloride::Render()

82{

83boolrenderOK=true;

84animated_sprite*currentSprite;

85

86switch(state)

87{

88caseSTAND:

89//pausetheanimation

90

standingSprite->Animation(0)->CurrentFrame

91(lastStepIndex);



92currentSprite=standingSprite;

93break;

94

95caseWALK_LEFT:

96lastWalkState=WALK_LEFT;

97standingSprite=&leftWalk;

98

99lastStepIndex=

100leftWalk.Animation(0)->CurrentFrame();

101if(lastStepIndex==3)

102{

103leftWalkSound.Play();

104}

105

106currentSprite=&leftWalk;

107break;

108

109caseWALK_RIGHT:

110lastWalkState=WALK_RIGHT;

111standingSprite=&rightWalk;

112

113lastStepIndex=

114rightWalk.Animation(0)->CurrentFrame();

115if(lastStepIndex==3)

116{

117rightWalkSound.Play();

118}

119

120currentSprite=&rightWalk;

121break;

122

123default:

124ASSERT(0);//Unhandledstate!

125break;

126}

127

128currentSprite->X((int)x);

129currentSprite->Y((int)y);

130currentSprite->Render();

131

132return(renderOK);

133}



ThefirstmemberfunctioninListing15.2istheGetKeyboardInput()

function.Itbeginsbydeclaringavectorthatisusedtostore

thedirectionCaptainChloridemoves.Thisvariableisoftype

vectorfratherthanvector.Recallfromchapter5,"Functionand

OperatorOverloading,"thatthedifferencebetweenvectorfand

vectoristhatvectorfusesfloating-pointnumbersforitsxandy



componentsratherthanintegers.ThevariablecaptainDirectionis

oftypevectorfbecauseCaptainChloridewillbeinagamespace

definedwithfloating-pointnumbersinthefinalgame.

Onlines520,theGetKeyboardInput()functioncontainsstatements

thattestthedirectionarrowthattheplayerpressesandsets

CaptainChloride'sdirectionaccordingly.Noticeinparticular

that,inadditiontotheleftandrightarrows,thisfunction

handlesmovingCaptainChlorideupanddown.Tryrunningthis

program,whichiscalledProg_15_01.exeontheCD.You'llsee

thatCaptainChloridemovesupanddownwhenyoupressthe

upordownarrow.Ifhe'sfacingleft,helookslikehe'swalking

left,buthejustmovesup.We'llfixthatlater.Fornow,try

pressingboththeleftanduparrows.Whenyoudo,you'llsee

thereasonIputinthecodeonlines512ofListing15.2;

CaptainChloridewalksdiagonallyupandleftacrossthescreen.

Ifyouwantyourcharactertowalkdiagonally,thisishowyou

doit.

Next,line22oftheGetKeyboardInput()functionteststosee

whetherCaptainChloride'svelocityiszero.Ifitis,line24sets

hiscurrentstatetoindicatethathe'sstandingstill.



Tip

I'vepointedthisoutbeforeinpreviouschaptersbut

itbearsrepeating.Wheneveryoucan,testthe

magnitudesquaredofavectorratherthanthe

magnitudeitself.Calculatingthemagnitudesquared

isfasterforyourgamethancalculatingthe

magnitude.



IfCaptainChlorideismoving,line31ofListing15.2setshis

directionvectortoaunitvector.Recallthatunitvectorscan



pointinanydirection,buttheyalwayshaveamagnitudeof1.

Line32multipliestheunitvectorby15tomakeCaptain

Chloridemoveby15.

TheGetKeyboardInput()functionsetsCaptainChloride'scurrent

stateonlines3445.Thisenablestheobjectthatrepresents

CaptainChloridetokeeptrackofwhathe'sdoing.Atanygiven

time,thisobjectmust"know"whetherCaptainChlorideis

walking,standing,andsoforth.

JustbeforetheGetKeyboardInput()functionends,itsetsCaptain

Chloride'smovementvector.

Duringeachframeofscreenanimation,theprogramcallsthe

chloride::Update()function.IfyoulookinthefileInvasion.cppon

theCD,you'llseethatthegameclass'sUpdate()functiongets

thekeyboardinputandthencallsthechloride::Update()function.



Note

You'llfindthefileInvasion.cppinthefolder

\Source\Chapter15\Prog_15_01.



Thechloride::Update()functionmovesCaptainChloridebysetting

hisxandypositiononlines5556.Ifhehitstheedgeofthe

screen(anyedge),lines5874adjusthisxandypositionto

keephimonthescreen.

Thechloride::Render()functionbeginsonline81ofListing15.2.

Itdeclaresapointertoananimated_spriteobjectasatemporary

variableonline84.Onlines72108thechloride::Render()function

figuresoutwhatCaptainChlorideisdoingandpointsthe

variablecurrentSpriteattheappropriateanimated_spriteobject.For

instance,ifhe'swalkingleft,theswitchstatementexecutesthe



casestatementthatbeginsonline95.Thisresultsinsetting

currentSpritetopointattheanimatedspritecontainingthe



animationofCaptainChloridewalkingleftonline106.When

theRender()functionactuallyrendersCaptainChloride,it

renderstheanimatedspritethatcurrentSpritepointsat(seeline

130).

NoticealsothatthecasestatementsintheRender()functionset

theprivatedatamemberstandingSprite.Thisisnecessaryto

correctlyfreezeCaptainChlorideinplacewhenhe'sstanding

still.WheneverCaptainChloridetakesastep,theRender()

functionsetsstandingSpritesothatitpointseitheratthe

animatedspriteofhimwalkingleftortheoneofhimwalking

right.If,duringthenextframeofscreenanimation,Captain

Chlorideisstandingstill,theRender()functiondisplaysCaptain

Chloridefrozeninthelastpositionhewasin.Itdoesthisby

settingthecurrentSpritevariabletopointatthesameanimation

asthestandingSpritedatamemberonline78.Inaddition,ituses

thedatamemberlastStepIndextosetthecurrentanimation

frame.Inthisway,CaptainChloridefreezeswhentheplayer

stopswalkinghim.



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 15. Captain Chloride Gets Going

Tải bản đầy đủ ngay(0 tr)

×