jak si vyrobit hru jako Fruit Ninja s Box2D a Cocos2D-Část 1

Toto je příspěvek člena výukového týmu iOS Allen Tan, vývojáře iOS a spoluzakladatele White Widget. Najdete ho také na Google+ a Twitteru.

v tomto tutoriálu se naučíte, jak vytvořit stříhací hru sprite pro iPhone podobnou Fruit Ninja od Halfbrick Studios pomocí výkonných knihoven Cocos2D a Box2D spolu s některými předem připravenými nástroji.

ve většině krájecích her, když nakreslíte čáru řezu skrz sprite, hra obvykle převede obraz sprite na dva předem nakreslené obrázky sprite s řezem vždy uprostřed, bez ohledu na to, kde jste skutečně řezali.

ale tento tutoriál bude demonstrovat ještě chladnější techniku. Naše plody budou moci být řezány vícekrát a budou rozděleny dynamicky na základě přesných řezných linií!

jak si můžete představit, jedná se o pokročilou techniku, takže tento tutoriál je určen pro pokročilé vývojáře Cocos2D a Box2D. Pokud jste v Cocos2D nebo Box2D noví, měli byste nejprve projít (alespoň) úvod do Cocos2d a úvod do Box2D tutoriálů, než budete pokračovat v tomto tutoriálu.

tato řada tutoriálů je rozdělena na tři části:

  • v této první části série položíte základy hry a naučíte se vytvářet texturované polygony.
  • druhá část vám ukáže, jak rozdělit & rozdělit tyto texturované polygony.
  • třetí část vám ukáže, jak z toho udělat kompletní hru přidáním hry a efektů.

chtěl bych poděkovat Rickovi Smorawskému za položení základů projektu, na kterém je tento tutoriál založen. Byl zodpovědný za Portování této ukázky krájení založené na blesku do Cocos2D a také za Portování CCBlade a PRKit na Cocos2D 2.0.

Pokračujte ve čtení a podívejte se na video o tom, co uděláte, a začněte se učit nějaké skvělé nové techniky!

demo hry

zde je ukázkové video, které vám ukáže, co uděláte v této sérii tutoriálů:

jak jsem zmínil, uvidíte, že efekt řezání ovoce je opravdu dynamický. Ovoce je řez dynamicky na základě toho, kde si plátek, a protože můžete krájet objekty vícekrát, můžete opravdu rozsekat věci!

můžete vidět, že budete také implementovat skvělý efekt krájení stezky, některé částicové systémy, herní logiku a zvuky, které okořeníte věci.

je toho hodně co pokrýt – tak začněme!

Začínáme: Nastavení projektu

budete používat Cocos2D 2.X v tomto projektu, tak jděte do toho a stáhněte si ji, pokud ji ještě nemáte. Všimněte si, že máte možnost používat Cocos2D 1.X místo 2.X.S 1.X, můžete přeskočit části o převodu PRKit a CCBlade na Cocos2D 2.X, ale nezapomeňte věnovat pozornost dalším malým změnám, které v těchto třídách provedete.

po stažení poklepejte na tar, abyste jej zrušili, a poté nainstalujte šablony s následujícími příkazy do terminálu:

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

spusťte Xcode a vytvořte nový projekt s iOS\cocos2d v2.x\cocos2d iOS s Box2d šablonou a pojmenujte ji CutCutCut.

váš nový projekt by měl vypadat nějak takto:

 zahájení projektu

pěkně popořádku – měli byste šablonu trochu vyčistit, abyste se dostali k dobrému výchozímu bodu.

Otevřete HelloWorldLayer.h a odstraňte následující řádek:

CCTexture2D *spriteTexture_;// weak ref

Přepnout na HelloWorldLayer.mm a proveďte následující změny

// 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;

v tomto okamžiku jste odstranili všechny odkazy na PhysicsSprite z HelloWorldLayer, ale ještě neodstraňujte soubory z projektu. Později budete muset zkopírovat metodu, která PhysicsSprite.mm obsahuje někde jinde, takže to nechte prozatím.

Hit Command + R zkompilovat a spustit svůj projekt, a měli byste vidět prázdnou obrazovku se zeleným okrajem kolem něj:

čistá břidlice

zbývající kód šablony nastavil výkres ladění Box2D, který kreslí okraje kolem těl Box2D na obrazovce. Vidíte tenké zelené čáry nakreslené kolem obrazovky? Jedná se o stěny generované výchozí metodou initPhysics, která byla dodána se šablonou.

podívejte se na zbývající kód šablony, abyste se ujistili, že rozumíte tomu, co se zatím děje – inicializuje svět Box2D, nastaví zemi (zelené okraje), nastaví kresbu ladění atd. Toto je docela dobrý“ téměř prázdný “ výchozí bod s Box2D, na kterém můžeme stavět.

Sada zdrojů

dále stáhněte zdroje pro tento projekt a rozbalte soubor.

do projektu ještě nepřidávejte vše; některé soubory jsou ve skutečnosti volitelné. Mějte složku po ruce – když procházíte tutoriálem, čas od času vás požádám o přidání některých z těchto souborů do projektu.

zde je to, co najdete uvnitř:

  • obrázek na pozadí a spoustu ovocného umění od Vicki a další různé obrázky ve složce Obrázky
  • mix zvuku na pozadí vytvořený pomocí gomixu.je ve složce zvuky
  • zvukové efekty provedené pomocí bfxr nebo stažené z freesound ve složce zvuky
  • všechny systémy částic vytvořené pomocí Particle Designer ve složce částice
  • soubor PLIST generovaný Physicseditorem obsahující informace o vertexu pro třídy ovoce & Bomb ve složce různé
  • ovoce & třídy Bomb ve složce třídy
  • verze PRKit a CCBlade, které budete používat v výukový program ve složce třídy
  • seznam atributů pro zdroje, které jsou pod licencí atribuce v různých složka

kreslení texturovaných polygonů pomocí PRKit

Naším cílem je rozřezat skřítky na více kusů. Typický CCSprite obsahuje texturu a ohraničující rámeček bez ohledu na to, jaký je tvar obrázku. To není vhodné pro naši hru, protože znalost skutečných tvarů v obrázcích je zásadním krokem k vytvoření skřítků,které lze řezat, krájet a dělit.

musíte vytvořit texturované polygony, které:

  • Vytvořte korespondenci mezi mnohoúhelníkem / tvarem a obrázkem (mapování textury)
  • zobrazit pouze části obrazu, které jsou v mezích mnohoúhelníku (vyplnění textury)

ani Cocos2D ani Box2D přichází s vestavěnou třídou, která zpracovává vlastní funkce, které chcete, a normálně by to vyžadovalo nějakou triangulaci spojenou s vlastním výkresovým kódem OpenGL.

Zní to tvrdě správně?

naštěstí všechny složité výpočty a kód výkresu potřebné k dosažení tohoto cíle již byly napsány dobrými lidmi v Prekognitivním výzkumu. Vytvořili doplněk k knihovně Cocos2d s názvem PRKit, který zpracovává mapování a vyplňování textur.

Chcete-li začít s texturovanými polygony, stáhněte si PRKit, rozbalte jej a přetáhněte složku PRKit do projektu. Ujistěte se, že je zaškrtnuto „Kopírovat položky do složky cílové skupiny“ a je vybráno „vytvořit skupiny pro všechny přidané složky“.

Všimněte si, že PRKit je udržován Prekognitivním výzkumem, takže se může včas aktualizovat. Aby nedošlo k záměně, naše sada zdrojů také obsahuje přesnou verzi PRKit, kterou jsem použil při vytváření tohoto tutoriálu.

váš projekt by nyní měl obsahovat tyto soubory:

PRKit Yey!

zkompilujte a spusťte a narazíte na několik chyb:

PRKit musí být převeden

chyby se objevují, protože PRKit byl vytvořen pro Cocos2D 1.X, který používá OpenGL ES 1.1, zatímco používáte Cocos2D 2.X, který používá OpenGL ES 2.0, a mezi nimi existují významné rozdíly.

Chcete-li to opravit, otevřete PRFilledPolygon.m a provést tyto změny:

// 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);}

projděme si tyto změny kousek po kousku.

Za prvé, v Cocos2D má každý CCNode připojený program OpenGL ES 2.0 shader. Chcete-li nakreslit PRFilledPolygon, musíte žalovat vestavěný shader „Position/Texture“, který přiřadíte metodou init.

dále je třeba nastavit správné souřadnice textury pro každý bod v mnohoúhelníku. Chcete-li to provést, musíte provést dvě změny metody calculateTextureCoordinates:

  • měřítko: protože tato třída provádí vlastní výpočty na souřadnicích své textury, nezpracovává automaticky displej sítnice. Chcete-li to opravit, stačí znásobit texturu.pixelsWide s CC_CONTENT_SCALE_FACTOR-výhodná multiplikační hodnota poskytovaná společností Cocos2D pro převod hodnot mezi normálními ekvivalenty a sítnicí.
  • Flip Y: Z nějakého důvodu prfilledpolygon kreslí textury vzhůru nohama, takže zde jednoduše otočíte hodnotu y.

Poslední, kód výkresu je aktualizován na OpenGL ES 2.0, podobným způsobem, jakým se kresba CCSprite změnila z Cocos2D 1.X na Cocos2D 2.X:

  • začněte voláním CC_NODE_DRAW_SETUP () a připravte uzel pro kreslení.
  • volání do glDisableClientState () a glEnableClientState() jsou zastaralá a jsou vyřazena.
  • příkazy glVertexPointer() a glTexCoordPointer() jsou nahrazeny glVertexAttribPointer (), který nyní přijímá pozici vrcholu nebo souřadnici textury jako první možnost.
  • nastavení glTexEnvf(), které bylo zodpovědné za opakování sprite v případě, že polygon byl větší než textura, je nahrazeno voláním do glTexParameteri().

pokud jste z toho zmateni, možná budete chtít vyzkoušet náš OpenGL ES 2.0 pro iPhone a vlastní Cocos2D 2.X shadery návody pro více informací o pozadí. Ale nemusíte se o to příliš starat, protože v tuto chvíli vše, co děláme, je přenést třídu na práci v Cocos2D 2.X:]

zkompilujte a spusťte a všechny chyby PRKit by měly zmizet!

je čas uvést PRKit do akce. Budete sub-classing prkit prfilledpolygon třídu vytvořit základní PolygonSprite třídu, která bude čerpat naše ovoce.

PolygonSprite staví na Prfilledpolygonu připojením těla Box2D ke sprite a bude také obsahovat další vlastní proměnné a metody pro ovoce v naší implementaci hry.

pojďme na to. Stiskněte příkaz + N a vytvořte nový soubor s iOS\cocos2d v2.x\CCNode třída šablony. Udělejte z něj podtřídu PRFilledPolygon a pojmenujte ji PolygonSprite.m.

přepněte na PolygonSprite.h a provést následující změny:

// 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;

výše uvedený kód deklaruje základní proměnné a metody, které potřebujete k vytvoření PolygonSprite. Jedná se o:

  • tělo: Toto je tělo Box2D, které je připojeno k našemu sprite. Je potřeba pro simulaci fyziky.
  • originál: kompletní a krájené skřítci budou používat stejnou třídu PolygonSprite, jako takové bude důležité rozlišovat mezi těmito dvěma. Pokud je to ano, znamená to, že je to nesestříhaný nebo původní objekt, který jste vytvořili, jinak je to jen kus celku.
  • těžiště: Střed mnohoúhelníku v obraze nebude vždy stejný jako střed obrázku, takže je užitečné tuto hodnotu uložit.
  • vlastnosti: vystavte všechny proměnné pomocí vlastností, aby k nim měly ostatní třídy volný přístup.
  • init / spriteWith*: naše hlavní metody init po stejné konvenci pojmenování jako Cocos2D.
  • další metody: Jedná se o metody vytvářející & zabývající se připojeným tělem Box2D a jeho vlastnostmi.
  • PTM_RATIO: poměr Pixelů k metrům. Box2D potřebuje tuto konverzní hodnotu, protože se zabývá metry místo Pixelů.

rychle přepněte na PolygonSprite.m a přejmenujte ji PolygonSprite.mm. všechny třídy, které kombinují kód Objective-C (Cocos2D) a C++ (Box2D), musí mít příponu“. mm“, aby informovaly kompilátor o smíšené syntaxi.

dále proveďte následující změny 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;}

podobně jako Cocos2D, všechny spriteWith* metody jsou jen autorelease protějšky initwith * metody, zatímco initWithWorld nemá žádné skutečné použití pro tuto třídu ještě, ale místo toho bude použit PolygonSprite podtřídy později.

většinu změn lze nalézt v metodách initWithFile a initWithTexture. Chcete-li získat tok věcí, bude v tomto pořadí voláno vytvoření ovoce:

Init sekvence

  • initWithWorld: Toto je určeno pro podtřídy PolygonSprite, takže neděláte nic jiného než návrat nula, a vypořádat se s tím později.
  • initWithFile: to přidá texturu z našeho souboru a předá vše initWithTexture.
  • initWithTexture: naše hlavní inicializace. PRFilledPolygon potřebuje texturu a všechny vrcholy mnohoúhelníku, který vyplňuje. Vzhledem k tomu, že předchozí krok již zpracoval texturovou část, tento krok zpracovává vrcholy jejich sběrem z těla sprite Box2D. Po jejich předání do PRFilledPolygon pokračuje v inicializaci proměnných, které jste dříve deklarovali.
  • initWithPoints: vše, co to dělá, je obsaženo v PRKit a dobrá věc je, že se už nemusíte dotýkat PRKit, když jste aktualizovali jeho kód.

stále uvnitř PolygonSprite.mm, přidejte následující metody:

-(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);}

ve výše uvedeném kódu nejprve přetížíte metodu setPosition CCNode, takže při aktualizaci pozice sprite se aktualizuje také přidružená pozice těla Box2D.

poté vytvoříte pohodlnou metodu pro vytvoření a definování těla Box2D. Chcete-li vytvořit tělo, musíte definovat definici těla, objekt těla, tvar a definici svítidla. Zatím zde nejsou přiřazeny žádné skutečné tvrdé hodnoty, protože tato metoda bude později použita podtřídy PolygonSprite.

jediné, co je třeba poznamenat, je kategoriebity a maskBits. Tyto dva se používají pro filtrování kolizí mezi objekty tak, že pokud se Bit Kategorie objektu shoduje s bitem masky jiného objektu a naopak, dojde ke kolizi mezi těmito dvěma objekty. Nejprve je nastavíte na 0, protože nechcete, aby při první inicializaci objektů došlo ke kolizím.

nakonec definujete dvě metody, které jednoduše nahradí kategoriebity a maskBits, abyste mohli aktivovat a deaktivovat kolize našich PolygonSprites.

je tu ještě jedna věc, kterou přidat do 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_;}

Vzpomeňte si, když jsem se zmínil, že potřebujete něco z fyziky? No, to je ono. To vše dělá, je, aby se ujistil, že náš Box2D tvar a naše sprite jsou ve stejné poloze při pohybu. Je pro nás připraven Cocos2D a to je o to úžasnější.

po zkopírování výše uvedeného kódu můžete nyní smazat obě PhysicsSprite.h a PhysicsSprite.mm z projektu, jak jste zcela vyloučili jejich užitečnost.

zkompilujte a spusťte a vše by mělo být v pořádku. S PolygonSprite jste prozatím hotovi.

plánování našich plodů

před vytvořením tříd pro naše ovoce musíte mít jasno v pravidlech, která musí obrázky a jejich tvary dodržovat. Protože budete mapovat naše textury na jednotlivé polygony Box2D, musíte také dodržovat omezení polygonů Box2D. Musíte mít na paměti dvě věci:

  • polygony musí být konvexní, což znamená, že žádný vnitřní úhel není větší než 180.
  • mnohoúhelníky nesmí přesáhnout 8 vrcholů.

toto omezení můžete skutečně obejít, pokud dovolíte, aby každé tělo obsahovalo více tvarů. Box2D zvládne konkávní tvary, pokud použijete metodu triangulace a vytvoříte konkávní tvary z několika trojúhelníků, ale to je nad rámec tutoriálu.

Chcete-li udržet věci jednoduché, v tomto tutoriálu budete mít 1 tělo je 1 Tvar pravidlo.

Poznámka: PhysicsEditor, nástroj, který budeme pokrývat později v tomto tutoriálu, ve skutečnosti obsahuje kód pro automatickou triangulaci polygonů, které nakreslíte do sady konvexních tvarů. Nicméně, jak jsem řekl, snažíme se udržet věci jednoduché, takže se ujistěte, že nakreslíme naše tvary konvexní, takže máme pouze jeden tvar na tělo.

podívejte se na tyto dva plody:

konkávní vs konvexní

použití banánu není dobrý nápad, protože je přirozeně konkávní. Meloun na druhé straně je velmi dobrý, protože můžete definovat konvexní mnohoúhelník, který se velmi podobá jeho tvaru.

pokud byste měli definovat mnohoúhelníkové tvary, které se řídí pravidly Box2D pro dva plody, víceméně byste skončili s těmito:

obrys tvaru Box2D

mnohoúhelník melounu dokonale zapadá do obrazu, zatímco mnohoúhelník banánů má velký prázdný prostor, kde se obraz zakřivuje dovnitř. Box2D bude tento prostor považovat za součást našeho objektu, a to by mohlo způsobit, že se banán bude cítit nepřirozený, když se srazí s jinými objekty, nebo když se odřízne.

to neznamená, že nemůžete použít banán, ale spíše to, že se nedoporučuje používat banán. Ve skutečnosti bude hra, kterou vytvoříte v tomto tutoriálu, používat stejný banán.

vytvoření prvního ovoce

je čas vytvořit první ovoce: meloun(alespoň jeho plátek).

když si vzpomenete na tok inicializačního procesu našeho PolygonSprite, víte, že initWithTexture očekává tělo Box2D, ale krok před initWithFile to neposkytuje.

důvodem je to, že musíte vytvářet a definovat tělo jednotlivě na ovoce, takže to bude muset být úplně první krok, initWithWorld, který vytvoří tělo a nastaví jakékoli další hodnoty specifické pro každé ovoce.

Chcete-li vytvořit naše tělo Box2D, musíte nejprve znát vrcholy tvaru mnohoúhelníku, který chcete vytvořit. Existují různé způsoby, jak to udělat, ale pro tento tutoriál budete používat šikovný nástroj s názvem PhysicsEditor. Tento nástroj je plný funkcí, ale budete jej používat pouze k tomu, abyste nás vedli při získávání souřadnic vrcholů našeho mnohoúhelníku.

pokud jej nemáte, stáhněte si PhysicsEditor, nainstalujte jej a spusťte jej. Získáte prázdný projekt se 3 panely / sloupci.

práce s Fyzikemeditor je docela přímočarý. Vlevo umístíte všechny obrázky, se kterými chcete pracovat. Uprostřed vizuálně definujete mnohoúhelník pro svůj obrázek. Vpravo máte parametry pro tělo.

Editor Fyziky!

Chyť meloun.png ze složky Obrázky sady zdrojů a přetáhněte ji na levý panel. Nyní byste měli vidět meloun na středovém panelu.

zvětšete zvětšení, které se nachází ve spodní části tohoto panelu, na pohodlnou úroveň a poté klepnutím na tlačítko pětiúhelníku v horní části tohoto panelu vytvořte 3stranný tvar mnohoúhelníku.

klepněte pravým tlačítkem myši na mnohoúhelník a zvolte „Přidat vrchol“, dokud nebudete mít ve všech vrcholech 5-8. Přesuňte vrcholy kolem okrajů melounu a ujistěte se o dvou věcech:

  • mnohoúhelník, který vytváříte, je konvexní.
  • všechny pixely melounu jsou uvnitř mnohoúhelníku.

poznámka: Další zkratkou pro kreslení tvarů je použití nástroje PhysicsEditor magic wand. Stačí nastavit toleranci vysoko (5-8), takže skončíte s asi 5-8 body, a vyladit body odtamtud.

přidejte všechny ostatní ovoce a obrázek bomby ze složky Obrázky sady zdrojů a udělejte pro ně totéž.

měli byste definovat tvary pro následující obrázky:

  • banán.png
  • bomba.png
  • hrozny.png
  • ananas.png
  • strawberry.png
  • meloun.png

až budete hotovi, v pravém horním rohu změňte hodnotu exportéra na „Box2D generic (PLIST)“ a měli byste skončit s něčím takovým:

Definujte tvary snadno pomocí PhysicsEditor!

stisknutím tlačítka „Publikovat “ nebo“ publikovat jako “ exportujete soubor PLIST obsahující informace o vrcholu. Uložte soubor jako ovoce.plist.

jako příklad lze uvést plody.plist, který jste použili pro tento tutoriál, je uvnitř složky Misc sady zdrojů.

chcete se podívat pouze na informace obsažené v souboru PLIST, takže tento soubor nepřidávejte do svého projektu, ale spíše jen otevřete ovoce.plist pomocí Xcode zobrazit jeho obsah organizovaným způsobem.

kliknutím na ikonu trojúhelníku vedle „těla“ rozbalte tuto sekci a uvidíte seznam obrázků, pro které jste definovali tvary. Musíte se vrtat dolů na nejhlubší úroveň, abyste získali vrcholy mnohoúhelníku melounu:

PhysicsEditor PLIST

rozbalte meloun / příslušenství / položka 0 / polygony a nyní byste měli vidět další položku 0 pole typu pod polygony. Toto poslední pole je váš tvar. Pokud jste správně definovali konvexní tvar s 8 nebo méně vrcholy, měli byste vidět pouze jedno pole pod polygony.

pokud vidíte více než jednu, i.e položka 0 pole, Položka 1 pole, atd, pak to znamená, že PhysicsEditor vytvořil složitý tvar, protože jste buď definovali příliš mnoho vrcholů, nebo jste vytvořili konkávní mnohoúhelník. Pokud k tomu dojde, vraťte se do Fyzikyeditor a opravte svůj tvar.

dále rozbalte položku 0 pole typu a zobrazte konečný seznam položek. Toto jsou vaše vrcholy a hodnota, kterou vidíte na pravé straně s tímto formátem { číslo, číslo}, jsou vaše x & Y souřadnice pro každý vrchol.

Nyní, když máte přesné hodnoty pro vrcholy polygonu, můžete pokračovat ve vytváření třídy melounu.

v Xcode vytvořte nový soubor s iOS\cocos2d v2.x\CCNode třída šablony. Udělejte z něj podtřídu Polygonůprit a pojmenujte jej Meloun. Otevřete Meloun.h a provést následující změny:

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

přepněte na meloun.m, přejmenujte ji na Watermelon.mm, a přidejte následující metodu init:

// 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;}

ve výše uvedeném kódu nejprve definujete, kolik vrcholů je, což je v tomto případě 7. Dále vytvoříte pole vrcholů obsahující všechny souřadnice, které jste právě viděli v seznamu. Tyto informace použijete k vytvoření těla pomocí metody pohodlí, kterou jste definovali v PolygonSprite.

vložíte malé tření, aby tvary nekonečně neklouzaly, a také vložíte malou restituci, aby se tvary nezastavily, když se odrazí proti sobě.

nakonec vytvoříte objekt voláním inicializace superclass a předáte název obrazového souboru, tělo Box2D a uvedete, že se jedná o původní ovoce.

potřebujete obrázky melounu ze sady zdrojů, takže nyní by bylo vhodné přidat všechny grafické zdroje, které potřebujete pro zbytek tutoriálu.

v panelu Navigátor projektu klepněte pravým tlačítkem myši na zdroje a vyberte „Přidat soubory do CutCutCut“. Přidejte do projektu složku obrázky ze sady zdrojů. Ujistěte se, že je zaškrtnuto „Kopírovat položky do složky cílové skupiny“ a je vybráno „vytvořit skupiny pro všechny přidané složky“.

postupujte stejným způsobem a vytvořte banán, hrozny, ananas, jahodu a bombu.

řešili jste pouze to, jak vytvořit první ovoce krok za krokem, protože se jedná v podstatě o oplach & opakujte proces pro každé ovoce. Sada zdrojů obsahuje hotové třídy ovoce a bomby ve složce třídy, na které se můžete podívat v případě, že stále potřebujete vedení, nebo je můžete přidat do svého projektu, pokud chcete tento krok přeskočit.

zkompilujte a spusťte a ujistěte se, že je vše v pořádku.

přidání ovoce na scénu

zatím se na obrazovce nic neděje a zjevně svědí, abyste viděli plody své práce – slovní hříčka! :]

přepněte na HelloWorldLayer.h a provést následující změny:

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

přepnout zpět na HelloWorldLayer.mm a provést tyto změny:

// 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]; ; ; ;}

deklarujete pole mezipaměti, které bude obsahovat všechny ovoce a bomby, které vytvoříte v budoucnu. Dále vytvoříte 1 meloun a přidáte jej do scény. Voláte aktivníkolize tak, aby meloun neprošel stěnami.

zkompilujte a spusťte a měli byste vidět Meloun padající ze středové oblasti obrazovky a přistát dole, jak je znázorněno níže.

ovoce vaší práce

můžete si všimnout, že meloun není přesně uprostřed. Důvodem je to, že jste umístili objekt na základě jeho těla Box2D a původ těla Box2D je v levém dolním rohu objektu. Tenký obrys kolem melounu je viditelný, protože režim kreslení ladění je stále zapnutý.

Kam Jít Odtud?

zde je ukázkový projekt se všemi kódy z výše uvedeného tutoriálu.

to je vše pro část 1 série. Zatím máte mnohoúhelník s texturou melounu, který právě padá na spodní část obrazovky.

ale místo kreslení obdélníkového sprite s průhledným prostorem, jak obvykle vidíte v tutoriálech Box2D, používá PRKit pouze k nakreslení částí textury, které odpovídají vrcholům těla Box2D. To se brzy hodí!

Nyní jste připraveni na část 2 tutoriálu, kde přidáte možnost krájet ovoce!

mezitím, pokud máte nějaké dotazy nebo připomínky k této části, připojte se k diskuzi na fóru níže!


toto je příspěvek člena výukového týmu iOS Allen Tan, vývojář iOS a spoluzakladatel společnosti White Widget. Najdete ho také na Google+ a Twitteru.

raywenderlich.com týdenní

raywenderlich.com newsletter je nejjednodušší způsob, jak zůstat up-to-date na vše, co potřebujete vědět jako mobilní vývojář.

Získejte týdenní přehled našich výukových programů a kurzů a získejte bezplatný podrobný e-mailový kurz jako bonus!

Leave a Reply

Vaše e-mailová adresa nebude zveřejněna.