Hvordan Lage Et Spill Som Fruit Ninja Med Box2D Og Cocos2D-Del 1

Dette er et innlegg av iOS Tutorial Teammedlem Allen Tan, en iOS-utvikler og medstifter På White Widget. Du kan også finne Ham På Google + Og Twitter.

i denne opplæringen lærer du hvordan du lager et sprite cutting-spill for iPhone som Ligner Fruit Ninja Av Halfbrick Studios ved hjelp av de kraftige Cocos2D-og Box2D-bibliotekene sammen med noen pre-laget verktøy.

i de fleste slicing-spill, når du tegner en kuttlinje gjennom en sprite, konverterer spillet vanligvis sprite-bildet til to pre-drawn sprite-bilder med skiven alltid nedover midten, uansett hvor du faktisk kutter.

men denne opplæringen vil demonstrere en enda kulere teknikk. Våre frukter vil kunne kuttes flere ganger, og de vil bli delt dynamisk basert på de nøyaktige kuttlinjene!

som du kanskje tror, er dette en avansert teknikk, så denne opplæringen er for avanserte Cocos2D og Box2D utviklere. Hvis Du er ny På Cocos2D Eller Box2D, bør du gå gjennom (minst) introen Til Cocos2D og intro Til Box2D tutorials først før du fortsetter med denne opplæringen.

denne opplæringen serien er delt inn i tre deler:

  • I denne første delen av serien, vil du legge grunnlaget for spillet, og lære å lage teksturerte polygoner.
  • den andre delen viser deg hvordan du skal skjære & dele disse teksturerte polygonene.
  • den tredje delen viser deg hvordan du gjør dette til et komplett spill ved å legge til spill og effekter.

Jeg vil gjerne gi Spesiell takk Til Rick Smorawski for å legge grunnlaget for prosjektet denne opplæringen er basert på. Han var ansvarlig for porting denne flash-baserte slicing demo I Cocos2D, og også for porting CCBlade Og PRKit Til Cocos2D 2.0.

Fortsett å lese for å sjekke ut videoen av hva du skal lage og for å komme i gang med å lære noen kule nye teknikker!

Spill Demo

her er en demo video som viser deg hva du vil gjøre i denne opplæringen serien:

som jeg nevnte, vil du se at frukten kutte effekten er virkelig dynamisk. Frukten er kuttet dynamisk basert på hvor du skjære, og siden du kan skjære objekter flere ganger, kan du virkelig hogge ting opp!

Du kan se at du også vil implementere en kul slicing trail-effekt, noen partikkelsystemer, spilllogikk og lyder for å krydre ting opp.

Det er mye å dekke – så la oss komme i gang!

Komme i Gang: Prosjektoppsett

Du skal bruke Cocos2D 2.X i dette prosjektet, så gå videre og laste den ned hvis du ikke har det allerede. Merk at Du er fri til å bruke Cocos2D 1.X i stedet for 2.X. Med 1.X, du kan hoppe over delene om å konvertere PRKit og CCBlade til Cocos2D 2.X, men sørg for å ta hensyn til de andre små endringene du gjør i disse klassene.

etter nedlasting, dobbeltklikk på tjære for å unarchive den, og installer deretter malene med følgende kommandoer i Terminalen:

cd ~/Downloads/cocos2d-iphone-2.0-beta./install-templates.sh -f -u

Start Opp Xcode og opprett et nytt prosjekt med iOS \ cocos2d v2.x \ cocos2d iOS Med Box2d mal og navnet Det CutCutCut.

ditt nye prosjekt skal se omtrent slik ut:

Prosjektstart

Første ting først-du bør rydde opp malen litt for å komme til et godt utgangspunkt.

Åpne HelloWorldLayer.h og fjern følgende linje:

CCTexture2D *spriteTexture_;// weak ref

Bytt til HelloWorldLayer.mm og gjør følgende endringer

// Remove this line from the top#import "PhysicsSprite.h"// Replace the init method with this-(id) init{ if( (self=)) { // enable events self.isTouchEnabled = YES; self.isAccelerometerEnabled = YES; CGSize s = .winSize; // init physics ; ; } return self;}// Remove these two methods-(void) createMenu { //all content}-(void) addNewSpriteAtPosition:(CGPoint)p methods { //all content}// Remove this line from ccTouchesEnded;

På dette punktet har du fjernet alle referanser Til Physicsprite Fra HelloWorldLayer,men fjern ikke filene fra prosjektet helt ennå. Senere må du kopiere en metode som PhysicsSprite.mm inneholder et annet sted, så la det sette for nå.

Hit Command + R for å kompilere og kjøre prosjektet, og du bør se en tom skjerm med en grønn ramme rundt den:

Clean Slate

den gjenværende malkoden har satt Opp Box2D debug-tegning, som trekker grenser rundt Box2D-kroppene på skjermen. Se de tynne grønne linjene trukket rundt skjermen? Det er veggene generert av standard initphysics-metoden som fulgte med malen.

Ta en titt på den gjenværende malkoden for å sikre at du forstår hva som skjer så langt – det initialiserer En Box2D-verden – setter opp bakken( grønne grenser), setter opp feilsøkingstegning, etc. Dette er et ganske bra» nesten tomt » utgangspunkt med Box2D vi kan bygge videre herfra.

Resource Kit

neste last ned ressursene for dette prosjektet og pakk ut filen.

ikke legg til alt i prosjektet ennå; noen av filene er faktisk valgfrie. Hold mappen hendig skjønt-når du går gjennom opplæringen, vil jeg fra tid til annen be deg om å legge til noen av disse filene i prosjektet.

Her er hva du finner inni:

  • et bakgrunnsbilde og en haug med frukt kunst laget Av Vicki, og andre diverse bilder i Bilder-mappen
  • bakgrunnslyd mix laget med gomix.det i Lydmappen
  • Lydeffekter laget med bfxr eller lastet ned fra freesound i Lydmappen
  • alle partikkelsystemene opprettet Med Partikkeldesigner i Partikkelmappen
  • EN PLISTFIL generert av PhysicsEditor som inneholder toppunktinformasjon for Fruktene & Bomb-klasser I Misc-mappen
  • Frukt & Bomb-klasser i Klassemappen
  • versjonene av prkit Og Ccblade du vil bruke i opplæringen i klassemappen
  • en attribusjonsliste For Ressurser som er under attribusjonslisensen I Misc folder

Tegning Teksturerte Polygoner Med PRKit

Vårt mål er å kutte sprites i flere stykker. En Typisk CCSprite inneholder en tekstur, og en markeringsrammen uansett hvilken form bildet er. Dette er ikke egnet for spillet vårt siden å vite de faktiske figurene i bildene er et viktig skritt for å skape sprites som kan kuttes, skiver og splittes.

du må opprette Teksturerte Polygoner, som:

  • Opprette en korrespondanse mellom et polygon / form og et bilde (Teksturtilordning)
  • Vis bare de delene av bildet som er innenfor polygonets grenser (Teksturfylling)

Verken Cocos2D Eller Box2D kommer med en innebygd klasse som håndterer de tilpassede funksjonene du vil ha, og normalt vil dette ta litt triangulering kombinert med tilpasset OpenGL tegningskode.

Høres hardt ut?

Heldigvis har alle de kompliserte beregningene og tegnekoden som trengs for å oppnå dette, allerede blitt skrevet av de gode folkene på Prekognitiv Forskning. De opprettet et tillegg Til Cocos2D biblioteket Heter PRKit, som håndterer Tekstur Kartlegging og Fylling.

for å komme i gang Med Teksturerte Polygoner, last Ned PRKit, pakk den ut og dra prkit-mappen inn i prosjektet. Pass på at «Kopier elementer til målgruppens mappe» er merket og «Opprett grupper for eventuelle ekstra mapper» er valgt.

Merk At PRKit vedlikeholdes av Prekognitiv Forskning, slik at Den kan bli oppdatert i tide. For å unngå forvirring inneholder ressurssettet også den nøyaktige versjonen Av PRKit jeg brukte i å lage denne opplæringen.

prosjektet ditt skal nå inkludere disse filene:

PRKit Yey!

Kompilere og kjøre, og du vil støte på noen feil:

PRKit Må Konverteres

feilene dukker opp fordi PRKit ble laget for Cocos2D 1.X, som bruker OpenGL ES 1.1, mens Du bruker Cocos2D 2.X, som bruker OpenGL ES 2.0, og det er betydelige forskjeller mellom de to.

for å fikse Dette, åpne PRFilledPolygon.m og gjøre disse endringene:

// Add inside the initWithPoints: andTexture: usingTriangulator: methodself.shaderProgram = programForKey:kCCShader_PositionTexture];// Replace the calculateTextureCoordinates method with this-(void) calculateTextureCoordinates { for (int j = 0; j < areaTrianglePointCount; j++) { textureCoordinates = ccpMult(areaTrianglePoints,1.0f/texture.pixelsWide*CC_CONTENT_SCALE_FACTOR()); textureCoordinates.y = 1 - textureCoordinates.y; }}// Replace the draw method with this-(void) draw{ CC_NODE_DRAW_SETUP(); ccGLBindTexture2D( self.texture.name ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); ccGLBlendFunc( blendFunc.src, blendFunc.dst); ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position | kCCVertexAttribFlag_TexCoords ); glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, areaTrianglePoints); glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinates); glDrawArrays(GL_TRIANGLES, 0, areaTrianglePointCount);}

La oss gå over disse endringene litt etter litt.

Først i Cocos2D har Hver CCNode Et OpenGL ES 2.0 shader-program knyttet til det. Å tegne PRFilledPolygon, må du saksøke den innebygde» Posisjon/Tekstur » shader, som du tilordner i init-metoden.

deretter må du sette opp de riktige teksturkoordinatene for hvert punkt i polygonen. For å gjøre dette må du gjøre to endringer i calculateTextureCoordinates-metoden:

  • Skala: siden denne klassen gjør egne beregninger på koordinatene til tekstur, håndterer den ikke automatisk retina-skjermen. For å fikse dette, multipliserer du bare tekstur.pixelsWide MED CC_CONTENT_SCALE_FACTOR – en praktisk multiplikator verdi levert Av Cocos2D for å konvertere verdier mellom vanlige og netthinnen ekvivalenter.
  • Flip Y: Av En eller annen grunn trekker PRFIlledPolygon teksturer opp ned, slik at du bare vender y-verdien her.

sist oppdateres tegningskoden Til OpenGL ES 2.0, på samme måte som Hvordan CCSprite tegning endret Fra Cocos2D 1.X Til Cocos2D 2.X:

  • Start med Å ringe CC_NODE_DRAW_SETUP () for å klargjøre noden for tegning.
  • Kall til glDisableClientState() og glEnableClientState () er foreldet og forkastes.
  • kommandoene glVertexPointer() og glTexCoordPointer () er begge erstattet av glVertexAttribPointer (), som nå aksepterer Vertexposisjon Eller Teksturkoordinat som sitt første alternativ.
  • oppsettet av glTexEnvf (), som var ansvarlig for å gjenta sprite i tilfelle polygonen var større enn tekstur, erstattes av samtaler til glTexParameteri ().

hvis du er forvirret av noe av dette, vil du kanskje sjekke Ut Vår OpenGL ES 2.0 for iPhone og Custom Cocos2D 2.X Shaders tutorials for mer bakgrunnsinformasjon. Men du trenger ikke å bekymre deg for det for mye, for på dette punktet er alt vi gjør å portere klassen til jobb I Cocos2D 2.X:]

Kompilere og kjør, og Alle PRKit-feil skal forsvinne!

Det er På tide Å sette PRKit i aksjon. Du vil være sub-classing PRKit Er PRFilledPolygon klasse for å lage en base PolygonSprite klasse som vil trekke våre frukter.

PolygonSprite bygger På PRFilledPolygon ved å feste En Box2D-kropp til sprite, og den vil også inneholde andre tilpassede variabler og metoder for fruktene i vår spillimplementering.

La oss komme til det. Hit Kommando + N og opprett en ny fil med iOS \ cocos2d v2.x \ CCNode Class template. Gjør Det til En underklasse Av PRFilledPolygon og navngi Det PolygonSprite.m.

Bytt til PolygonSprite.h og gjør følgende endringer:

// Add to top of file#import "Box2D.h"#import "PRFilledPolygon.h"#define PTM_RATIO 32// Add inside @interfaceb2Body *_body;BOOL _original;b2Vec2 _centroid;// Add after the @interface@property(nonatomic,assign)b2Body *body;@property(nonatomic,readwrite)BOOL original;@property(nonatomic,readwrite)b2Vec2 centroid;// Add before the @end-(id)initWithTexture:(CCTexture2D*)texture body:(b2Body*)body original:(BOOL)original;-(id)initWithFile:(NSString*)filename body:(b2Body*)body original:(BOOL)original;+(id)spriteWithFile:(NSString*)filename body:(b2Body*)body original:(BOOL)original;+(id)spriteWithTexture:(CCTexture2D*)texture body:(b2Body*)body original:(BOOL)original;-(id)initWithWorld:(b2World*)world;+(id)spriteWithWorld:(b2World*)world;-(b2Body*)createBodyForWorld:(b2World*)world position:(b2Vec2)position rotation:(float)rotation vertices:(b2Vec2*)vertices vertexCount:(int32)count density:(float)density friction:(float)friction restitution:(float)restitution;-(void)activateCollisions;-(void)deactivateCollisions;

ovennevnte kode erklærer basisvariablene og metodene du trenger for å opprette En PolygonSprite. Disse er:

  • kropp: Dette Er Box2D-kroppen som er festet til vår sprite. Det er nødvendig for fysikk simulering.
  • original: Komplett og skiver sprites vil bruke samme PolygonSprite klasse, som sådan, skille mellom de to vil være viktig. HVIS DETTE ER JA, betyr DET at det er det uutviklede eller originale objektet du opprettet, ellers er det bare et stykke av det hele.
  • sentroid: Midten av polygonet i bildet vil ikke alltid være det samme som midten av bildet, så det er nyttig å lagre denne verdien.
  • egenskaper: Utsett alle variablene ved hjelp av egenskaper slik at andre klasser kan få tilgang til dem fritt.
  • init/ spriteWith*: våre viktigste init-metoder følger samme navnekonvensjon Som Cocos2D.
  • andre metoder: dette er metoder som skaper & som håndterer Den vedlagte Box2D-kroppen og dens egenskaper.
  • PTM_RATIO: Piksler Til Meter-forhold. Box2D trenger denne konverteringsverdien fordi Den omhandler Meter i stedet For Piksler.

Bytt Raskt Til PolygonSprite.m og endre navn på den PolygonSprite.mm. Alle klasser som blander Objective-C (Cocos2D) og C++ (Box2D) kode må ha en». mm » forlengelse for å varsle kompilatoren av blandet syntaks.

gjør Deretter følgende endringer til PolygonSprite.mm:

// Add inside the @implementation@synthesize body = _body;@synthesize original = _original;@synthesize centroid = _centroid;+(id)spriteWithFile:(NSString *)filename body:(b2Body *)body original:(BOOL)original{ return initWithFile:filename body:body original:original] autorelease];}+(id)spriteWithTexture:(CCTexture2D *)texture body:(b2Body *)body original:(BOOL)original{ return initWithTexture:texture body:body original:original] autorelease];}+(id)spriteWithWorld:(b2World *)world{ return initWithWorld:world] autorelease];}-(id)initWithFile:(NSString*)filename body:(b2Body*)body original:(BOOL)original{ NSAssert(filename != nil, @"Invalid filename for sprite"); CCTexture2D *texture = addImage: filename]; return ;}-(id)initWithTexture:(CCTexture2D*)texture body:(b2Body*)body original:(BOOL)original{ // gather all the vertices from our Box2D shape b2Fixture *originalFixture = body->GetFixtureList(); b2PolygonShape *shape = (b2PolygonShape*)originalFixture->GetShape(); int vertexCount = shape->GetVertexCount(); NSMutableArray *points = ; for(int i = 0; i < vertexCount; i++) { CGPoint p = ccp(shape->GetVertex(i).x * PTM_RATIO, shape->GetVertex(i).y * PTM_RATIO); ]; } if ((self = )) { _body = body; _body->SetUserData(self); _original = original; // gets the center of the polygon _centroid = self.body->GetLocalCenter(); // assign an anchor point based on the center self.anchorPoint = ccp(_centroid.x * PTM_RATIO / texture.contentSize.width, _centroid.y * PTM_RATIO / texture.contentSize.height); // more init stuff here later when you expand PolygonSprite } return self;}-(id)initWithWorld:(b2World *)world{ //nothing to do here return nil;}

I Likhet Med Cocos2D, alle spriteWith * metoder er bare autorelease kolleger av initWith * metoder, mens initWithWorld har ingen faktisk bruk for denne klassen ennå, men i stedet vil det bli brukt av PolygonSprite subklasser senere.

hoveddelen av endringene kan bli funnet i initWithFile og initWithTexture metoder. For å få strømmen av ting, vil skape en frukt bli kalt i denne sekvensen:

Init-Sekvens

  • initWithWorld: Dette er ment for Underklasser Av PolygonSprite, slik at du ikke gjør noe annet enn å returnere null, og håndtere det senere.
  • initWithFile: dette legger til tekstur fra filen vår og sender alt til initWithTexture.
  • initWithTexture: vår viktigste initialisering. PRFilledPolygon trenger en tekstur og alle polygonens hjørner fyller den. Siden forrige trinn allerede håndtert teksturdelen, håndterer dette trinnet hjørnene ved å samle dem Fra sprite Box2D kroppen. Etter å ha passert Dem Til PRFilledPolygon, fortsetter den å initialisere variablene du tidligere har erklært.
  • initWithPoints: Alt dette gjør er inneholdt I PRKit, og det gode er at du ikke trenger å røre PRKit lenger nå som du har oppdatert koden sin.

Fortsatt inne PolygonSprite.mm, legg til følgende metoder:

-(void)setPosition:(CGPoint)position{ ; _body->SetTransform(b2Vec2(position.x/PTM_RATIO,position.y/PTM_RATIO), _body->GetAngle());}-(b2Body*)createBodyForWorld:(b2World *)world position:(b2Vec2)position rotation:(float)rotation vertices:(b2Vec2*)vertices vertexCount:(int32)count density:(float)density friction:(float)friction restitution:(float)restitution{ b2BodyDef bodyDef; bodyDef.type = b2_dynamicBody; bodyDef.position = position; bodyDef.angle = rotation; b2Body *body = world->CreateBody(&bodyDef); b2FixtureDef fixtureDef; fixtureDef.density = density; fixtureDef.friction = friction; fixtureDef.restitution = restitution; fixtureDef.filter.categoryBits = 0; fixtureDef.filter.maskBits = 0; b2PolygonShape shape; shape.Set(vertices, count); fixtureDef.shape = &shape; body->CreateFixture(&fixtureDef); return body;}-(void)activateCollisions{ b2Fixture *fixture = _body->GetFixtureList(); b2Filter filter = fixture->GetFilterData(); filter.categoryBits = 0x0001; filter.maskBits = 0x0001; fixture->SetFilterData(filter);}-(void)deactivateCollisions{ b2Fixture *fixture = _body->GetFixtureList(); b2Filter filter = fixture->GetFilterData(); filter.categoryBits = 0; filter.maskBits = 0; fixture->SetFilterData(filter);}

i koden ovenfor overbelaster du først setPosition-metoden For CCNode, slik at når du oppdaterer sprite-posisjonen, blir den tilhørende Box2D-kroppens posisjon også oppdatert.

du gjør deretter en praktisk metode for å lage Og definere En Box2D-kropp. For å lage en kropp må du definere en kroppsdefinisjon, et kroppsobjekt, en form og en fixturdefinisjon. Ingen virkelige harde verdier blir tildelt her ennå, siden denne metoden vil bli brukt av Underklasser Av PolygonSprite senere.

det eneste å merke seg er kategoribits og maskBits. Disse to brukes til å filtrere kollisjoner mellom objekter slik at hvis en kategoribit av et objekt samsvarer med en maskebit av et annet objekt og omvendt, vil det være en kollisjon mellom de to objektene. Du setter disse til 0 først fordi du ikke vil at noen kollisjoner skjer når objektene først initialiseres.

til Slutt definerer du to metoder som bare erstatter categoryBits og maskBits slik at du kan aktivere og deaktivere kollisjonene til Våre PolygonSprites.

Det er enda en ting å legge til PolygonSprite.mm:

-(CGAffineTransform) nodeToParentTransform{ b2Vec2 pos = _body->GetPosition(); float x = pos.x * PTM_RATIO; float y = pos.y * PTM_RATIO; if ( !isRelativeAnchorPoint_ ) { x += anchorPointInPoints_.x; y += anchorPointInPoints_.y; } // Make matrix float radians = _body->GetAngle(); float c = cosf(radians); float s = sinf(radians); if( ! CGPointEqualToPoint(anchorPointInPoints_, CGPointZero) ){ x += c*-anchorPointInPoints_.x+ -s*-anchorPointInPoints_.y; y += s*-anchorPointInPoints_.x+ c*-anchorPointInPoints_.y; } // Rot, Translate Matrix transform_ = CGAffineTransformMake( c, s, -s,c, x,y ); return transform_;}

Husk da jeg nevnte at du trengte Noe Fra Physicsprite? Vel, dette er det. Alt dette gjør er å sørge for at Vår Box2D form og vår sprite er i samme posisjon når du beveger deg. Den er forberedt for Oss Av Cocos2D, og det gjør det enda mer fantastisk.

etter å ha kopiert koden ovenfor, kan du nå slette Begge Physicsprite.h og PhysicsSprite.mm fra prosjektet som du har helt eliminert deres nytte.

Kompilere og kjøre, og alt skal være i orden. Du er ferdig Med PolygonSprite for nå.

Planlegger Fruktene Våre

før du lager klasser for fruktene våre, må du være klar over reglene som bildene og deres former må følge. Siden du skal kartlegge våre teksturer til enkelt Box2D polygoner, må du også følge Box2D polygon begrensninger. Du må holde to ting i tankene:

  • Polygoner må være konvekse, noe som betyr at ingen indre vinkel er større enn 180.
  • Polygoner må ikke overstige 8 hjørner.

du kan faktisk omgå denne begrensningen hvis du tillater at hver kropp inneholder flere former. Box2D kan håndtere konkave former hvis du bruker en trianguleringsmetode og lager konkave former ut av flere trekanter, men dette er utenfor rammen av opplæringen.

for å holde ting enkelt, i denne opplæringen vil du ha en 1 Kropp er til 1 Form regel.

Merk: PhysicsEditor, verktøyet vi vil dekke senere i denne opplæringen, inneholder faktisk kode for å automatisk triangulere polygoner du tegner inn i et sett med konvekse former. Men som jeg sa, prøver vi å holde ting enkelt her, så sørg for å tegne våre former konvekse, slik at vi bare har en form per kropp.

ta en titt på disse to fruktene:

Konkav vs Konveks

Bruk Av Banan er ikke en god ide fordi den er naturlig konkav. Vannmelon derimot er veldig bra fordi du kan definere en konveks polygon som ligner på sin form.

hvis du skulle definere polygonformer som følger Box2ds regler for de to fruktene, ville du mer eller mindre ende opp med disse:

 Box2D Shape Outline

Vannmelonpolygonen passer perfekt til bildet, Mens Bananpolygonen har et stort tomrom hvor bildet kurver innover. Box2D vil behandle det rommet som en del av vårt objekt, og Det kan få Bananen til å føle seg unaturlig når den kolliderer med andre gjenstander, eller når den blir kuttet.

Dette betyr ikke at Du ikke kan bruke Banan, men heller at Det bare ikke anbefales Å bruke Banan. Faktisk vil spillet du skal lage i denne opplæringen, bruke samme Banan.

Å Lage Den Første Frukten

Det er på tide å lage Den første frukten: Vannmelon(et stykke av det minst).

Tenker tilbake til strømmen av PolygonSprite ‘ s initialiseringsprosess, vet du at initWithTexture forventer En Box2D-kropp, men trinnet før, initWithFile, gir ikke dette.

årsaken til dette er at du må skape og definere kroppen individuelt per frukt, så det må være det aller første skrittet, initWithWorld, som skaper kroppen og setter andre verdier som er spesifikke for hver frukt.

for å lage Vår Box2D-kropp må du først kjenne kryssene i polygonformen du vil opprette. Det er forskjellige måter å gjøre dette på, men for denne opplæringen bruker du et nifty verktøy kalt PhysicsEditor. Dette verktøyet er fylt med funksjoner, men du vil bare bruke det til å veilede oss i å få koordinatene til polygonens hjørner.

hvis du ikke har Det, last Ned PhysicsEditor, installer den og brann den opp. Du får et tomt prosjekt med 3 paneler / kolonner.

Arbeide Med PhysicsEditor er ganske grei. Til venstre legger du alle bildene du vil jobbe med. På midten definerer du visuelt et polygon for bildet ditt. Til høyre har du parametrene for kroppen.

 Fysikk Redaktør!

Ta vannmelon.png Fra Bilder-mappen på resource kit og dra den til venstre panel. Du bør nå se Vannmelon på midtpanelet.

Øk forstørrelsen, funnet nederst på dette panelet, til et behagelig nivå, og trykk Deretter På Pentagon-Knappen på den øvre delen av dette panelet for å lage en 3-sidig polygonform.

Høyreklikk på polygonen og velg «Legg Til Toppunkt» til du har 5-8 toppunkter i alt. Flytt hjørnene rundt Kantene På Vannmelon, mens du sørger for to ting:

  • Polygonen du lager er Konveks.
  • Alle piksler Av Vannmelon er inne I Polygonen.

Merk: en annen snarvei for å tegne figurene er å bruke PhysicsEditor ‘ s magic wand tool. Bare sett toleransen høy (5-8) slik at du ender med ca 5-8 poeng, og juster poengene derfra.

Legg inn alle de andre fruktene og bombebildet fra Images-mappen til resource kit og gjør det samme for dem.

du bør definere figurer for følgende bilder:

  • banan.png
  • bombe.png
  • druer.png
  • ananas.png
  • jordbær.png
  • vannmelon.png

når du er ferdig, endrer du Verdien Av Eksportør til «Box2D generic (PLIST)», og du bør ende opp med noe slikt:

Definer Former Enkelt med PhysicsEditor!

Trykk På «Publiser», Eller «Publiser Som», for å eksportere PLISTFILEN som inneholder toppunktinformasjonen. Lagre filen som frukt.plist.

som et eksempel, fruktene.plist du brukte for denne opplæringen er inne I Misc-mappen i resource kit.

du vil bare se på informasjonen I PLIST-filen, så legg ikke denne filen til prosjektet ditt, men bare åpne frukt.plist bruker Xcode for å vise innholdet på en organisert måte.

Klikk på trekantikonet ved siden av «kropper» for å utvide denne delen, og du vil se listen over bilder du definerte figurer for. Du må bore ned til det dypeste nivået for å få Vannmelonens polygon-hjørner slik:

PhysicsEditor PLIST

Utvid vannmelon/inventar/Element 0/polygoner, og du bør nå se et Annet Element 0 Av Typen Array under polygoner. Dette siste arrayet er din form. Hvis du hadde riktig definert en konveks form med 8 eller mindre hjørner, bør du bare se en matrise under polygoner.

hvis du ser mer enn en, jeg.e Element 0 Array, Element 1 Array, etc, så betyr Det PhysicsEditor laget en kompleks form fordi du enten definerte for mange hjørner, eller du dannet en konkav polygon. Hvis dette skjer, gå tilbake Til Fysikkredaktør og fikse formen din.

utvid Deretter Element 0 av typen Matrise for å se den endelige listen over elementer. Dette er dine hjørner, og verdien du ser på høyre side med dette formatet { nummer, nummer } er x & y koordinater for hvert toppunkt.

Nå som du har de nøyaktige verdiene for polygonens hjørner, kan du fortsette med å lage Vannmelonklassen.

opprett En ny fil med iOS\cocos2d v2 i Xcode.x \ CCNode Class template. Gjør Det til En Underklasse Av PolygonSprite og navn Det Vannmelon. Åpne Vannmelon.h og gjør følgende endringer:

// Add to top of file#import "PolygonSprite.h"

Bytt Til Vannmelon.m, endre navn på den til Watermelon.mm, og legg til følgende init-metode:

// Add inside the @implementation-(id)initWithWorld:(b2World *)world{ int32 count = 7; NSString *file = @"watermelon.png"; b2Vec2 vertices = { b2Vec2(5.0/PTM_RATIO,15.0/PTM_RATIO), b2Vec2(18.0/PTM_RATIO,7.0/PTM_RATIO), b2Vec2(32.0/PTM_RATIO,5.0/PTM_RATIO), b2Vec2(48.0/PTM_RATIO,7.0/PTM_RATIO), b2Vec2(60.0/PTM_RATIO,14.0/PTM_RATIO), b2Vec2(34.0/PTM_RATIO,59.0/PTM_RATIO), b2Vec2(28.0/PTM_RATIO,59.0/PTM_RATIO) }; CGSize screen = winSize]; b2Body *body = ; if ((self = )) { // We will initialize more values for the fruit here later } return self;}

i koden ovenfor definerer du først hvor mange hjørner det er, som i dette tilfellet er 7. Deretter lager du en rekke hjørner som inneholder alle koordinatene du nettopp så i PLIST. Du bruker denne informasjonen til å lage en kropp ved hjelp av bekvemmelighetsmetoden du definerte I PolygonSprite.

du legger inn litt friksjon slik at figurene ikke glir uendelig, og du legger også inn litt restitusjon slik at figurene ikke stopper når de spretter mot hverandre.

Sist oppretter du objektet ved å ringe superklassens initialisering og passere i navnet på bildefilen, Box2D-kroppen, og angi at dette er en original frukt.

du trenger vannmelon bilder fra resource kit, så nå ville være en god tid å bare legge til alle de grafiske ressursene du trenger for resten av opplæringen.

høyreklikk På Ressurser i Project Navigator-panelet og velg «Legg Til Filer Til CutCutCut». Legg Til Bilder-mappen fra ressurssettet i prosjektet. Pass på at «Kopier elementer til målgruppens mappe» er merket og «Opprett grupper for eventuelle ekstra mapper» er valgt.

Følg de samme trinnene for å lage Banan, Druer, Ananas, Jordbær og Bombe.

du taklet bare hvordan du lager den første frukten trinnvis, siden det i utgangspunktet er en skyll & gjenta prosess for hver frukt. Ressurssettet inneholder ferdige frukt-og bombeklasser i Klassemappen som du kan se på hvis du fortsatt trenger veiledning, eller du kan legge dem til i prosjektet ditt hvis du vil hoppe over dette trinnet.

Kompilere og kjøre, og sørge for at alt er i orden.

Legge Til En Frukt Til Scenen

Så langt har ingenting skjedd på skjermen ennå, og du er åpenbart spent på å se fruktene av ditt arbeid – ordspill ment! :]

Bytt Til HelloWorldLayer.h og gjør følgende endringer:

// Add to top of file#import "PolygonSprite.h"// Add inside the @interfaceCCArray *_cache;// Add after the @interface@property(nonatomic,retain)CCArray *cache;

Bytt tilbake til HelloWorldLayer.mm og gjøre disse endringene:

// Add to top of file#import "Watermelon.h"// Add inside the @implementation@synthesize cache = _cache;// Add inside the init method, below ;// Add inside the dealloc method, before calling ;_cache = nil;// Add anywhere inside the @implementation and before the @end-(void)initSprites{ _cache = initWithCapacity:53]; // Just create one sprite for now. This whole method will be replaced later. PolygonSprite *sprite = initWithWorld:world]; ; ; ;}

du erklærer en cache array, som vil holde alle frukter og bomber du oppretter i fremtiden. Deretter lager du 1 Vannmelon og legger den til scenen. Du kaller aktivkollisjoner slik At Vannmelon ikke passerer gjennom veggene.

Kompilere og kjøre, og du bør se En Vannmelon faller fra midten området av skjermen, og land nederst som vist nedenfor.

 Frukten Av Arbeidskraft

Du kan merke At Vannmelon er ikke akkurat i sentrum. Årsaken til dette er at du plasserte objektet basert På Box2D-kroppen, og Box2D-kroppens opprinnelse er nederst til venstre på objektet. Den tynne omrisset rundt Vannmelon er synlig fordi feilsøkingstegningsmodus fortsatt er slått på.

Hvor Skal Du Gå Herfra?

Her er et prøveprosjekt med all koden fra opplæringen ovenfor.

Det er det for del 1 av serien. Så langt har Du En Vannmelon Teksturert Polygon som bare faller til bunnen av skjermen.

men i stedet for å tegne en rektangulær sprite med gjennomsiktig plass som du vanligvis ser I Box2D tutorials, bruker Dette PRKit å bare tegne de delene av tekstur som tilsvarer hjørnene I Box2D kroppen. Dette vil komme til nytte snart!

Nå er du klar For Del 2 av opplæringen, der du legger til muligheten til å skjære fruktene!

I mellomtiden, hvis du har spørsmål eller kommentarer om denne delen, vennligst bli med i forumdiskusjonen nedenfor!


Dette er et innlegg av iOS Tutorial Teammedlem Allen Tan, en iOS-utvikler og medstifter På White Widget. Du kan også finne Ham På Google + Og Twitter.

raywenderlich.com Ukentlig

raywenderlich.com nyhetsbrev er den enkleste måten å holde deg oppdatert på alt du trenger å vite som mobilutvikler.

Få en ukentlig oversikt over våre opplæringsprogrammer og kurs, og motta et gratis, grundig e-postkurs som en bonus!

Leave a Reply

Din e-postadresse vil ikke bli publisert.