Let's make a simpletitlebasedplatformgameonashiscustomerliketostartthesevideosbyshowyouwhatwewillbecreatingtodayandyou'llnoticethatit's quitegraphicaltoday.
We'llmakeitlookgraphicaltowardstheendofthisvideo, buttostartwithwhereit's goingtobedrawingcoloredrectanglesonscreenonthisis a simplificationthat I thinkisnecessarytoreallyunderstandwhattheengineisdoingbeneath.
Asusual, I'llbedemonstratingeverything, usingthemonelonecode, a consolegameengine, whichyoucandownloadfromthegethope.
Thegameengineis a simpleclass, whichhandlesdrawingtothescreenanduserinputs, andallweneedtodoisfillinthesetwomethodsonmusiccreate, whichwecanusetoallocateresources.
AndanuserupdateWherewedoallofthefunstuff.
I'm creatinganinstanceofmynewclasscalledGameon I'm creating a consolewhich 160 characterswideby 120 characters.
Hioneachcharacteriseightbyeightpixels, butnowWhenwetalkabouttilebasedgames, wetypicallytalkabout a twodimensionalarrayoffsomethingthatrepresents a space, thetwo D arraysbrokenupintorowsandcolumns.
Asyoucanseehere, I'm drawingthemouttoSyria.
12345 Onwefill a particularcellwithinthetwo D arraywithinformationthatdefineswhatwewantedthatself.
So, forexample, let's say I want a solidblockhere.
I'm goingtousethehashsymbol.
Sohere's a littleplatformoffthreesolidblocksforemptyspace.
I don't wanttousespace.
I liketousetheperiodcharacterfullstop, andthatway I cancounthowmanyspaces I'vegoneacrossthescreen.
Andthisisreallynice, becausewedon't need a complexsystemofsearchestoworkoutwhereweareinsideourtilemap.
I thinkthisapproachisquiteelegant, willbeexploitingitforallaspectsofourplatformgame.
Forexample, if I wantedtotrack a particleinandseeifitcollidesatanypointonthemap, let's sayit's movedtohearfromoneframetothenext, accessingthatinformationisreallytrivial.
Wejustsimply x and y into R two d arraytoextractwhatevercharacteristhere.
Sointhiscaseofitsequaltothehashsymbol, a collisionhasoccurred.
Therearesomecaveatstothisapproach.
Itdoesassumethateachtileis a rectangleorsquare, andthisboundariesaresolid.
Solet's startbydefiningthelevel, and I'm goingtorepresentmylevelas a string.
And I'm alsogoingtostorethewitonDTH e heightoffthelevelasinstitches.
I'llcreatethelevelintheonuser, createfunction.
I'm goingtodeclarethelevelfornowtobe 64 tileswide, my 16 tileshigh.
Don't forget a tilecurrentlyisunitlis, andthenicethingaboutusing a stringtorepresentyourlevelisitcanbequitegraphicalsothatwe'vegot 16 roseoffleveland I'm notcreated a to D array.
I'm justsimply a pendingitalltoonebigstringnowDesigningthelevelcanbequitefunusingtheinsertkey.
I canputinhasheswherever I needthem.
Takethatvisualstudiocodeandso I'm goingtoputin a groundplane.
Sothisisjust a singleplanegoingacrossthelevelthatthecharactercan't gobelow.
Whatweneedismoreof a playgroundthatwecanusetotestthecollision.
So I'm gonnaputin a singleblockonitsownon.
I'm alsogoingtoputin, Ah, a morecomplicatedformhereforthecharactertotryandnavigate.
And I alwaysthinkit's usefultohavesomesortoftunnelaswell, becausethiswillreallytestthepowerofyourcollisiondetectionroutineandyou'llnoticethatmytunnelisonecellwide.
Wewanttodrawtilestothescreensowe'llcreatetwonestedfourloopsfor X and Y, andthesearethesamesizeasthenumberofvisibletilesonthescreen.
I feelatthispointwe'regoingtoneed a coupleoflittleutilitylambdafunctionsandthentocreateonecalledGetTile, whichtakesthe X and y coordinateonreturnsthecharacterinourstringforthatlocation.
But I'm goingtodosomeboundarycheckingaswell, because I don't wanttogetanyinvalidmemoryaccesses, sowe'llmakesureit's inboundsintheExdirection, andwe'llalsocheckthe Y axis.
Ifitiswithinbounds, I'm goingtoreturnthecharacteratthatpointinthestring, simplybyaccessingthestringis a singledimensionalcharacterrayusingourgoodoldfavorite.
WhyTimesWithplus X.
Ifwe'renotwithinbounds, I'm goingtogetittoreturn.
A spacewhichrepresentsournoblecharacterisnotquitethesameas a fullstopspace, butperhapswecanusethespacecharactertoindicateanerrorhasoccurred.
Buttoset a particularcharacterwithinthetwo D locationinthestring, goingbacktoourdrawingroutine, I cannoextract a characterfromourstringforgivenlocation.
I callitTile, I d.
We'llusetheLambdafunctionwejustcreatedonwillpassintoitthe X onthe Y coordinateandallwe'regoingtodowiththis.
I d.
Isworkouthowtodrawit.
Soifit's a fullstop, weprobablywanttodrawsomesky.
Comebacktothatin a minute.
Ifit's a hashsymbol, wewanttodrawsomethingthat's solid.
Andifit's anythingelse, we'rejustgoingtodraw a black.
Soifitis a periodwhichrepresentsnothinginourgame, then I'm goingtousetheoneLakotaPhilCommandtodraw a rectangleinthatlocation.
So I'm takingthe X and Y values, scalingitbythetilewithandalsotakingthe X and Y valuesplusoneeachandscalingthosetwo.
Becausewe'regoingtobedrawing a squarefromthetoplefttothebottomrightofthatrectangleon, I'vechosenthecolortobescience.
Let's takeexactlythesamecodeforhash.
What I'llsetthecolortobereadtoindicate a solidsurface.
Incontrast, when I'm gettingthetilefromthearray, I wanttoaddtheofficer.
Sointhiscase, theoffsetismovingusfurtherintothetwo D array, andinthiscase, theoffsetispullingtheplayerbackintothescreen, theviewablearea.
Solet's take a lookandseewhatwe'reuptosoyoucanseewe'vegottheScionbackground, whichrepresentsemptyspace, and I'vegot a greenrectanglemovingsmoothlyaroundrepresentingtheplayerwiththearrowkeys.
I cansee a redrectangleand I canmovearoundthelevel.
Infact, there's thelevelwecansee.
We'vedecidedonthestring, sothatshouldbe a tunneldownheresomewhere.
Wehad a similarproblemwiththecodeityourselfFroggergame, butinthiscase, what I'm goingtodoiscalculateCemoffsetsintotheindividualtilestoe, workouthowmuchtodisplacethembywhenwedrawthemonthescreen.
Solet's seewhatthismeans.
Weknowthatourmapoffsetvalueinthiscase, F offsetaxeiscontinuousandcanhavedecimalpointsquitelegitimately.
Thistileis a statictileAspartofthescenery, we'vejustupdatedthevelocityvectoron, thenjustupdatedthepositionvector, anditworksoutthatwe'regoingtobecollidingwiththediagonalcorneroffthescenerytilethat's describedbythisimage.
Whatisthecorrectcourseofactionhere?
Dowedisplacetheplayertilethatway?
Dowedisplacedtheplay a tilethatway?
Dowedisplacetheplayertileinbothdirections?
SomesituationsThismaybemoreobviousthanothers.
Perhapsdisplacingbytheminimumdirectionofoverlapis a goodstrategy.
Soweknowhowmuch.
Whyhas a CZoverlappedhereandhowmuchexesoverlapped?
Andperhaps, if D X inthiscaseislessthan D y, that's theminimumamountofmovement.
SowechoosetodisplacetheplayerSpriteinthe X axis, andthisisalsostartingtobringingeometryonsomerealwell, simplebutstillthemathematics, which I don't thinkweneedtodo.
Well, let's consider a situationwhere I'vegotmyspitetileoftheplayerrestingupon a scenerytileIftheplayerismovingtowardstheleft, I'm checkingthispointontothispoint.
Don't forgetallofourtiledataisstoredin a two D array.
Solet's assumeour P X on P Y valuesareequalto 3.2 commafive.
As I'm movingthecharactertowardstheleft, I wanttobecheckingthesetwopointsagainstmyarray, whichwouldresolvetosomethinglikethis.
So 3.2 fiveonwithoutthe 0.9.
Willwealsobelookingat 3.2 commafiveplusone?
Well, ofcourse, this 3.2 getsroundeddowntothreebecauseofAh, truncation.
That's fine.
That's great.
Onthisthreerepresentswhichcellinthe X axisareweincurrently, However, forthewhitecomponentofthismapcheck.
Wenoticedthatthisactuallytrunk 8 to 6, whichmeansourcheckpointsareactuallyintwodifferentcellsinthe Y axis.
Butthisiscompletelyirrelevantbecausewe'reonlycheckinginthe X axis.
Soineffect, whatwe'redoingisjustshrinkingthecellslightlysoitdoesn't get a falsepositivehitforthecollisiononwillbechangingwhichsideofthecellweshrink, dependingonwhichcollisiondirectionwerecheckingfor.
Wewantittoclampbacktowardsthefourthboundary, anditgoeswithoutsayingthatallofthesethingsthatwe'redoinginthe X axisappliedtothe Y axis.
Sojusttorecapwereusingthenewexpositionontheold Y positiontogetridofthe Y componentofthevelocityvector.
We'recheckingwith a plus 0.9 offsetinsteadof a plusoneoffsettomakesurethattruncationdoesn't catchisout.
Andthiswillallowthecharactertofitingapsthatareonlyoneunitsacrossandfinallywereusingtruncationagaintoaligntheplayerto a boundaryintheeventof a collisionoccurring.
I'm goingtouseverysimilarcodenowforthe Y axis, exceptthistimewedon't wanttoseparatethe X and Y velocitycomponentvectorWehavenoresolvedcollisionin X, sowe'regoingtousethenewexhibitionandthenewwhiteposition.
Youcan't have a Mariogamewithoutsomecoins, so I'm goingtouse a lowercase O torepresentcoins.
Firstly, let's justseeiftheydrawproperly.
Verynice.
Butrightnowthecoinsbehavelike a solidobject.
Wewanttocheckforpickupcollectionbeforewehandlethecollision, becausewedon't wantthepickuptocause a collision.
Iftheplayercanactuallypickitup.
Sowetakethenewposition X and Y on.
We'regoingtocheckthefourcornerboundaries, andinthiscaseitwillbepluszeroonplusone, not 10.9, asitwasbeforeondoingthisreally, quitesimplyandnaively, I'm justsimplycheckingisthatpoint a coin?
Ifitis, thensetittobackgroundspacefornow.
I'm notdoinganythingelse.
I'm notincreasingaccountoranythingelse.
Thisisjusttoshowyouthat.
Yes, youcaninteractwiththetilesthatyouhit.
Nowweneedtodothat.
Checkforallfourcorners.
Now, asthegameincreasesitsnumberofpickups, there'llprobablybe a muchmoreelegantwaytodothis.