Whilstwedevelopedthegame, I thinkthisisquiteanimportantstrategyjusttomakesurethatfirstofall, youcangetittoworkon, thenmakeitworkwell.
Andwhen I say a topdowncity, I mean a topdowncity, sowe'llbelookingathowwe'rehandling.
Thethree D graphicswillbelookingatthingslikecollisiondetectionwill, ofcourse, beaddingnonplayerunitssuchaspolicecarsandpossiblypedestrianson.
We'llneedsomesortofmissionbasedsystem, sothere's quite a lottogetonwith.
But I quiteliketheaestheticalready.
I'vespentlotsof a lotoftimedevelopingthiscityonthatdrivingaroundit.
It's quitefun.
Nowwhenwe'reworkingwith a gamethathas a largeamountofrichdetailssuchasthis, it's quiteimportantthatwealsodevelopedthetoolstohelpusdevelopthegame.
Sointhisvideowillshowsomeverybasiccityeditingtoolsthat I canshowyousomething.
Now, usingthemousecursor, I canplaceitanywhereinthesceneandplaceadditionalroadsandyou'llseethattheroadsautomaticallyalignthemselveswiththecorrectjunctionsand I couldremovetheroadsaswell.
I canalsoplacebuildingsand I canplacebuildingsofdifferentheight, growthebuildingsupand I couldgrowthembackdownonthere's a littlebitofnovelinteraction.
I'm usingthecartocontrolthecamera, butediting a citylikethismighttakesometimedoingittilebytile.
So I'vealsoimplementedtheabilitytoselecttilesinthesceneandapplythesametransformationtoallthetilessimultaneouslyontheselectionworksatanyzoomlevel.
Oneoftheprinciples I triedtoadoptwhen I'm developing a gameisthatthegameonthegameeditorsshouldtryandusethesameengineonTheprimaryreasonforthisisthatyoucaneditthegameasnecessarywhilstyou'replayingitsoyoucanfindtuneitquiteeasily.
I'lljustshow a littlebitmoreroadbuildingthatwecanconnectthesetworoadstogether.
Asyoucanseerightnow, thegameisin a verybasicforthegraphicslook a littlebitrepetitiveand a littlebitsquareonthatsimplybecausethey'replaceholders.
Let's makeitworkbeforewemakeitwork.
Well, we'llhavetokeeprememberingthismantraonwhatisespeciallyimportantbeforetakingonanylargerprojectisthatyouhave a plan, solet's getstarted.
Clearly, thisgameisinspiredbytheclassicGrandTheftAuto, Siri's, but I don't intendtocloneitcompletely.
I'm goingtobemaking a muchmorecookeddown, simplerversion.
Sowhatarethefeaturesthat I'm aimingforinthisgame?
Well, thefirstthing I wantis a largecity, and I wanttheabilitytochooseanddrivecars.
Youneedcarstogetfrom A tobe, whichimpliessomesortofmissionbasedactivities.
Thecitywouldbe a bitboringifitwasempty, So I'm goingtoneedsometrafficinthereaswell, so I'm gonnahavetohavesomeothercartson.
AswiththeclassicGrandTheftAuto, theplayercouldliterallysteal a carthattheysawdrivingaround.
So I think a particulargamedynamicistoevadecaptureingames.
I personallylikecollectingthings, so I'llprobablyhavesomepickupsinthereaswellonbecausethecityisquitelarge, we'reprobablygoingtoneed a fewthingstohelpus.
We'regoingtoneed a degreeofpathfinding, perhapspotentiallysomesortof a I realistically, pickupsaretheeasyonesinthis.
Nowthenatureof a bigproject.
Isit a bigproject?
It's quitelarge.
It's got a lotofelementstoit, andthere's suchtypicallyduring a bigproject.
I don't gointoasmuchdetailonallofthepreciseelements, and I mightskipoversomeofthecodethatwe'regoingtowrite, whichmeansthesevideostendtomoveit a littlefasterpacethanmynormalvideos.
I'm goingtostartwith a blankvisualstudioprojectontothisproject.
I'veaddedtheoilseepixelgameengineon a blanksource, filethevideoccconedotcbpInthisinstance, thefirstthing I'm goingtodoistakethetemplatefromtheheadoffileandpasteitintothesourcefile.
Thisisjust a veryquickandeasywaytogetsettled.
What I willaddatthispointis, Pleasedon't forgettodefineolCPGapplicationbeforeyouincludethegameengine.
I'lljustquicklymodifythetemplatetosuitourneeds, and I'llremovethethingsthatwedon't need.
Anunusedcreateandonuserupdateifyouknewtopixelgameengineonusercreateis a placethatonlygetscalledonce, soyoucanusethistoloadyourresources.
Andanuserupdateiscalledeveryframe I'm goingtocreate a pixelgameengine, whichis 768 pixelswideby, 480 pixelshigh.
Soit's a widescreenapplication, so I'm goingtoreducethepixelsizebecauseit's quite a highresolutiontoSo I wantedtofitonmymonitor.
I wanttokeepmanyaspectsofthegamevery, verysimpleindeed.
So I'm goingtorestrictmycitytoreallyjustbeing a twodimensionalarray.
Soourquantis a onebyoneunitquadonourouterwallsaregoingtobe a onebyonebyone, not a cube, because I'venotgot a topor a bottom.
However, whenever I'm workingwiththree D onions, I alsowanttoinclude a cubesomewherebecauseit's a goodwayoftestingthatyou'vegoteverythingsettledcorrectly, havecreatedsomeverysimpleplaceholderassetsto, andyou'llnoticethatthesearealsobasedon a singlecellsites, particularlyfortheroadsandgrass.
Thetopdownstuffisindeedsquare.
Thesidesofthebuildingsherearen't, butlayingoutthetextureinthiswayhasrevealedwhatkindofjunctions I need.
So I got a northsouthEastandWest T Junction.
I'vegothorizontalandverticalroadsegments.
I'vegotfourcornersoninthemiddle.
I'vegot a crossroads, so I'vecoveredallofthetypesofroad I wanttohave.
Notonlydoesthismaketheproductionofthegraphicsimpler, it's alsogoingtohelplateronwhenwe'redealingwiththeartificialintelligenceandnonplayervehicles, because I'vegot a feelingthingslikeDeadends.
Mycauseis a problembecause I'm usingthepixelgameengine.
I canexportallofthisas a PNGfile.
When I firstcreatedthePixelgamemajor, oneofthethings I wantedtousewasextensions.
Thisisencapsulatedcodethatserves a particularpurpose.
We'vealreadyseenthegraphicstodeextensioninthe F FineTransformsvideo, allforthisseries.
I'vealsocreated a graphicsthree D pixelgameengineextensiononitusesexactlythesamecodethat I'veusedinthecodeityourselffortheengineSiri's.
But I'vemade a slightchangetothestructurejusttomakeit a biteasiertouse.
It's exactlythesame, however, tokeepthingsneatandtidyinoursourcecode, I'veintroducedtheconceptof a renderingpipeline, andthisimitatesthetechniqueusedbygraphicscardsfromquite a whileago.
Certainlybeforewehadshadeer's andshade, a modelbasedGPuse.
I eithernotgoingtoindexmytexturesheetatanyparticularlocation.
Rightnowit's takingthewholesheet.
So I'm actuallygoingtodo a littlebitof a hackhereinsteadofusingtexturetransformations, whichwewilllookatinthefuturepartofthisseries, I'm goingtobreakupmymainspriteintotheindividualtextures, andsoalongsignthemaid's bright.
I wasgoingtohave a spitefortheground, despitefortheroof, a spriteforthefirststories.
Butthenicethingis, I canuseinterviewdivisiontochoosethatspitelocationforusoutofthemaintextureso I canfindtheexoffsetbymodulatingbythewidthofeachofmyspritetiles.
Sointhistexture, oneofthesetilesis 96 by 96 pixels, sobymodulatingbythreeandtimesin 96 I canchoosetherightcolumnacrossthescreenand, conversely, doinganinterviewdivisionbythreetimesinby 96 I canchoosethecorrectrow.
I thinkthisisquiteimportantbecauseitshowsthathowyouorganizeyourgameassetscanactuallymakeyourcoding a lotsimpler.
Oncewe'redoneloadingallofthemainassettextures, I wanttosetthedrawertargetbacktoNoelPointer.
Ifyoudon't dothis, you'llalwaysbedrawingtotheSpritethatwaslastsetofthedrawertargets, andyoumayendupwith a blankscreenandfinally, a quick, easyone.
I'm justgoingtoloadthecarSprite, too.
Let's defineourselvesas a stroke s.
Soandweknowthatthisisgoingtocontaintheheightvalueasaninterjectondaflagtoindicatewhetherit's a roadornot, we'regoingtowanttodearrayofthes, so I'm goingtospecify a mapwithon a mapheightvariableon a pointertowhatwillultimatelybeanarrayoffcells.
Andi, I'llcreate a defaultmapinonusercreate.
Justfindthebottomhere.
Therewego, somymapisgoingtobe 64 wideby 32.
Hi, I'm justgoingtodynamicallyallocatethatmemorywillthencreatetwolittlefourloopstoiteratedoverallofthe X and Y locationswithinthattwo D array.
I wanttosetalloftheheightstozeroonalloftheroadflagstofalse.
So I'm going, goingtocreatefourinterviewvariables.
Start X andindex, whichisgoingfromzerotomapwithandstart.
Whyon N y formapheight, I wasgoingtorendereverything, evenifwecanseeitornot, whichmeansagain, I'm goingtowanttofourloopsthatthatiteratedthroughalloftheselocationsforeachcellthatwe'regoingtodraw, I'm goingtotest.
Isit a roadornot?
Rightnow, ifitis a road, I'm goingtoignoreit.
Itisnot a roadweredrawingsomescenery, solet's startwiththatfirst.
Ifyourememberbacktotheplan, weknowiftheheightiszero, thenwe'rejustdrawing a flatgrassquad.
Solet's configure a renderingpipelinetodojustthis.
Finally, I'm goingtotellthepipelinethatitssourceofitsgeometryshouldjustbetheflatquad, andthat's it.
So I'm goingtogetridofourcuberenderingstufffrombeforebecause I thinkblueis a slightlymoreappealingcoloronatthemoment.
I wantedtokindofrepresentwater.
I'm goingtochangeourclearcolortobluealso.
Solet's take a lookandseehowthisworks.
Well, wecancertainlysee a grasstextureinthebottomquarter.
It's ofthescreen.
Itlookslikeit's goingto 000 inthemiddle.
Excellent, though I'd liketoverifythatit's drawingthewholeworldbyincludingsomerudimentarycameracontrolwenttoaddthreevariableswhichrepresentwhereourcameraisgoingtobeoninonuserupdate.
Now, currently, afterallofthis, thecarisstill a 00 intheworld, so I don't needtotranslateitintotheworldintoitsrealisticpositiontotranslateinto a world.
Sothere's a bunchofmatrixtransformationsrequiredheretoputthecarintherightsize, therightorientationintherightplaceintheworld.
I'm goingtoaddsomeadditionalvaluablestoehandlethecarFirstvariableisgoingtobe a floatingpointvaluethatrepresentstheangleofthecaron.
Thesecondvalueisgoingtobethisspeed.
Thecarcanmovethatnow.
Wesawintheplanthatwemightwanttoexternalizethatlateron, butfornow I'm goingtohardcodeitinandthengoingtowanttoadditionalthree D vectorsthatrepresentthevelocityonthepositionofthecarp.
Rotationtransformsforus, so I'm goingtocreate a unitvector, and I'm goingtotake a rotationmatrixinthezedaccesssothatislookingdownfromaboveandrotatethatunitvectorbythecarangleon.
Sinceourvelocityvectorisnormalized, I'm goingtomultiplyitbycarspeedonmodulatedby F relapsetimewereeffectivelyintegratingourvelocitytogiveusourposition.
I'vedonethatforthe X axisneedstoexactlythesameforthe y axis.
Iftheflagissettotrue, that's where I'm goingtodeterminewhichparticularroadsection I shoulddrawon.
I'm notgoingtodoanythingtooclevertodeterminethis.
I'm justgoingtotestitexplicitly.
It'llstartoffbyassumingthattheroadvalueiszero.
Now I'm goingtobedoing a lotofindexingintoanoutofthearrayon.
I thinkthecodewillget a bitofworldlyif I'vegotwhitetimesandwithplus X allovertheplaceallthetime.
So I'm goingtocreate a littleautolambdafunction.
Oh, andthisisgoingtotakesomeoffsets.
Intereyeoninto J.
What I wantedtoreturnisthestateoftheroadflagfor a givencellrelativetothecellthat I'm currentlytryingtorenderinourfourloopsusingthe X and Y coordinates.
So I'm goingtolookatthemaparrayand I wanttocheckforthecurrentlocationthatwe'rerenderingwhybutplustheoffset J.
Andofcourse, that's timesandmapwith.
And I wanttodothesamefor X.
Butthistimeplustheoffset I Sothiswillallowmetointerrogatetheneighborsofthecellthat's currentlybeingrenderedon.
Ifthatisroadandtheroadbelowmeeggzeroagain, I'llput a plusone.
Andofcoursetheplusisn't necessary.
Butithelpsvisualizewhat's goingup.
Soiftheroadabovemeandtheroadbelowme, hisroadandthisisalsoimportantwastestforourleftandrightneighborsattheroadstotheleftofmeminusoneonthe x axisandnotroadplusoneinthe X axis.
Soifmyleftandrightneighborsarenotroad, then I wanttochoosetheverticalsection.
Soifallofthatistrue, then I knowthat I wanttheverticalstripofroadin a similarbutkindofoppositeway.
I cancheckforthehorizontalstripwhichhas a roadideaofoneHerewecanseewe'vegotnoverticalcomponents, butwe'vegotbothhorizontalcomponents.
That's thefirsttoprowofourspritecheatThenextroaddown, we'relookingfor a cornersection a T junctionon a cornersection.
I wantedtousethefrontage, butifit's offthegroundfloor, I wantedtousethewindows, so I'm justgoingtousetheturnoftheoperatortoquicklychoosewhichSpriteitshouldandfinallyrenderthewallsin a verysimilarway.
I wanttodrawtheroofforthebuilding.
Now.
Thisisjusttheflatquadthatwe'vebeenusingbefore, but I needtochangeit.
Zeddisplacement.
Andinfact, I'm justgoingtousethe H valuethatwereleftwithattheendofthisloop.
Normallyyouwon't beabletoonif I pressthe e key, we'redecreasingtheheight, andif I setitbelowzero, thecelldoesn't getrendered a tall.
Infact, wecanhavevery, verytallbuildingsindeed.
Seehowgoodwecango, pressingthekey a lot.
That's verynice.
Sowecanhavelike a massiveskyscraperinourcity.
Usingthecaris a selectionmechanismtodeterminewhichcellwewanttooperate.
Ourisfun, butnotverypractical.
I'd ratherusethemouse, butthishadsomecomplicationsin a two D game, workingoutwherethemouseisrelativetothegameworldisquitesimple, butin a three D game, itisn't quite a simplebecausewecanzoominandout.