How To Make A Game Like Fruit Ninja with Box2D and Cocos2D – Part 1

ez az iOS Oktatócsapat tagja, Allen Tan, az iOS fejlesztő és a White Widget társalapítója. Megtalálható a Google + – on és a Twitteren is.

ebben az oktatóanyagban megtudhatja, hogyan készíthet sprite vágójátékot az iPhone-hoz hasonlóan a Fruit Ninja by Halfbrick Studios-hoz a nagy teljesítményű Cocos2D és Box2D könyvtárak, valamint néhány előre elkészített eszköz segítségével.

a legtöbb szeletelő játékban, amikor vágott vonalat húz egy sprite-on keresztül, a játék általában a sprite képet két előre megrajzolt sprite-képpé alakítja, a szelet mindig középen lefelé, függetlenül attól, hogy valójában hol vág.

de ez az oktatóanyag még hűvösebb technikát mutat be. A gyümölcsök többször is vághatók lesznek, és dinamikusan lesznek felosztva a pontos vágási vonalak alapján!

mint gondolnád, ez egy fejlett technika, ezért ez az oktatóanyag a fejlett Cocos2D és Box2D fejlesztőknek szól. Ha még nem ismeri a Cocos2D – t vagy a Box2D-t, akkor először át kell mennie (legalább) az intro to Cocos2D és az intro to Box2D oktatóanyagokon, mielőtt folytatná ezt az oktatóanyagot.

ez a bemutató sorozat három részre oszlik:

  • ebben az első részben a sorozat, akkor megalapozza a játék, és megtanulják, hogyan kell létrehozni texturált sokszögek.
  • a második rész megmutatja, hogyan kell szeletelni & ezeket a texturált sokszögeket.
  • a harmadik rész megmutatja, hogyan lehet ezt Teljes játékká alakítani játékmenet és effektusok hozzáadásával.

külön köszönetet szeretnék mondani Rick Smorawskinak, hogy megalapozta a projektet, amelyen ez az oktatóanyag alapul. Ő volt a felelős ennek a flash-alapú szeletelő demónak a Cocos2D-be történő portolásáért, valamint a CCBlade és a PRKit Cocos2D 2.0-ra történő portolásáért.

Olvass tovább, hogy nézd meg a videót arról, hogy mit fogsz csinálni, és kezdj el tanulni néhány vadi új technikát!

Game Demo

itt van egy demo videó, amely megmutatja, mit fogsz csinálni ebben a bemutató sorozatban:

mint már említettem, látni fogod, hogy a gyümölcsvágó hatás valóban dinamikus. A gyümölcsöt dinamikusan vágják az alapján, hogy hol szeleteljük, és mivel többször is szeletelhetünk tárgyakat, tényleg felapríthatjuk a dolgokat!

láthatjuk, hogy akkor is végre egy hűvös szeletelés trail hatás, néhány részecske rendszerek, játék logika, és a hangok, hogy vértezze fel a dolgokat.

van egy csomó, hogy fedezze – úgyhogy kezdjük!

első lépések: A Projekt beállítása

a Cocos2D 2-t fogja használni.X ebben a projektben, így megy előre, és töltse le, ha még nem rendelkezik vele. Vegye figyelembe, hogy szabadon használhatja a Cocos2D 1-et.X helyett 2.X. Az 1.X, kihagyhatja a PRKit és a CCBlade Cocos2D 2-re történő átalakításáról szóló részeket.X, de ügyeljen arra, hogy figyeljen a többi apró változtatásra, amelyet ezeken az osztályokon végez.

a letöltés után kattintson duplán a tar-ra az archiváláshoz, majd telepítse a sablonokat a következő parancsokkal a terminálba:

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

indítsa el az Xcode-ot, és hozzon létre egy új projektet az iOS\cocos2d v2-vel.x \ cocos2d iOS Box2d sablonnal és nevezze el CutCutCut.

az új projektnek valahogy így kell kinéznie:

projekt kezdete

először is – meg kell tisztítani a sablont egy kicsit, hogy egy jó kiindulási pont.

Nyílt HelloWorldLayer.h és távolítsa el a következő sort:

CCTexture2D *spriteTexture_;// weak ref

váltás HelloWorldLayer.mm és végezze el a következő változtatásokat

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

ezen a ponton eltávolította a Physicssprite összes hivatkozását a HelloWorldLayer-ből, de még nem távolította el a fájlokat a projektből. Később egy olyan módszert kell másolnia, amely PhysicsSprite.mm valahol máshol van, ezért hagyja egyelőre.

nyomja meg a Command+R parancsot a projekt fordításához és futtatásához, és egy üres képernyőt kell látnia, körülötte zöld szegéllyel:

tiszta lap

a fennmaradó sablonkód beállította a Box2D hibakeresési rajzot, amely a képernyőn a Box2D testek köré húzódik. Lásd a képernyő körül húzott vékony zöld vonalakat? Ezek azok a falak, amelyeket a sablonhoz mellékelt alapértelmezett initPhysics módszer generál.

vessen egy pillantást a fennmaradó sablonkódra, hogy biztosan megértse, mi történik eddig – inicializálja a Box2D világot, beállítja a talajt (zöld határok), beállítja a hibakeresési rajzot stb. Ez egy nagyon jó” szinte üres ” kiindulási pont a Box2D – vel, amelyre innen építhetünk.

Resource Kit

Ezután töltse le a projekt erőforrásait, és csomagolja ki a fájlt.

még ne adjon hozzá mindent a projekthez; néhány fájl valójában opcionális. Tartsa kéznél a mappát-miközben végigmegy az oktatóanyagon, időről időre megkérem, hogy adjon hozzá néhány ilyen fájlt a projektbe.

itt van, amit talál benne:

  • a háttérkép és egy csomó gyümölcs art által Vicki, és egyéb egyéb képek a képek mappában
  • a háttér hang mix készült gomix.ez a hangok mappában
  • hanghatások készült bfxr vagy letöltött freesound a hangok mappában
  • az összes részecske rendszerek létrehozott részecske tervező a részecskék mappában
  • a plist által generált fájl PhysicsEditor tartalmazó vertex információt a gyümölcsök & bomba osztályok a Misc mappában
  • gyümölcsök & bomba osztályok az osztályok mappában
  • a prkit és a Ccblade azon verziói, amelyeket a
  • classes mappában található oktatóanyagban fog használni, egy hozzárendelési lista olyan erőforrásokhoz, amelyek a Misc hozzárendelési licencéhez tartoznak mappa

texturált sokszögek rajzolása PRKit

célunk, hogy több darabra vágjuk a spriteket. Egy tipikus CCSprite tartalmaz egy textúrát és egy határoló dobozt, függetlenül attól, hogy milyen alakú a kép. Ez nem alkalmas a játékunkra, mivel a képeken belüli tényleges formák ismerete döntő lépés a vágható, szeletelhető és felosztható sprite-ek létrehozásához.

létre kell hoznia texturált sokszögeket, amelyek:

  • sokszög/alakzat és kép közötti megfeleltetés létrehozása (textúra leképezés)
  • csak a kép azon részeit jelenítse meg, amelyek a sokszög határain belül vannak (textúra kitöltés)

sem a Cocos2D, sem a Box2D nem tartalmaz beépített osztályt, amely kezeli a kívánt egyéni funkciókat, és általában ez némi háromszögelést igényel az egyéni OpenGL rajzkóddal együtt.

jól hangzik?

szerencsére az ehhez szükséges bonyolult számításokat és rajzkódokat a prekognitív kutatások jó emberei már megírták. Létrehoztak egy kiegészítést a Prkit nevű Cocos2D könyvtárhoz, amely a textúra leképezését és kitöltését kezeli.

a texturált sokszögek használatának megkezdéséhez töltse le a PRKit-et, bontsa ki, majd húzza a prkit mappát a projektbe. Győződjön meg arról, hogy az” Elemek másolása a célcsoport mappájába “jelölőnégyzet be van jelölve, és a” Csoportok létrehozása minden hozzáadott mappához ” jelölőnégyzet be van jelölve.

vegye figyelembe, hogy a PRKit-et Prekognitív kutatások tartják fenn, így időben frissíthető. A félreértések elkerülése érdekében az erőforrás-készletünk tartalmazza a prkit pontos verzióját is, amelyet az oktatóanyag elkészítéséhez használtam.

a projektnek tartalmaznia kell ezeket a fájlokat:

PRKit Yey!

fordítsd le és futtasd, és néhány hibával fogsz találkozni:

PRKit kell konvertálni

a hibák felbukkan, mert PRKit készült Cocos2D 1.X, amely az OpenGL ES 1.1-et használja, míg Ön a Cocos2D 2-t használja.X, amely OpenGL ES 2-t használ.0, és jelentős különbségek vannak a kettő között.

ennek kijavításához nyissa meg a Prfilledpolygont.m és végezze el ezeket a változtatásokat:

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

vegyük át ezeket a változásokat apránként.

először is, a Cocos2D-ben minden CCNode-hoz tartozik egy OpenGL ES 2.0 shader program. A Prfiledpolygon rajzolásához be kell perelnie a beépített “pozíció/textúra” árnyékolót, amelyet az init módszerben rendel hozzá.

ezután be kell állítania a helyes textúra koordinátákat a sokszög minden pontjához. Ehhez két változtatást kell végrehajtania a calculateTextureCoordinates módszerrel:

  • skála: mivel ez az osztály saját számításokat végez a textúra koordinátáin, nem kezeli automatikusan a retina kijelzőt. Ennek kijavításához csak megsokszorozza a textúrát.pixelsWide with CC_CONTENT_SCALE_FACTOR-a Cocos2D által biztosított kényelmes szorzó érték a normál és a retina ekvivalensek közötti értékek konvertálásához.
  • Flip Y: valamilyen oknál fogva a PRFIlledPolygon fejjel lefelé rajzolja a textúrákat, így itt egyszerűen megfordíthatja az y értéket.

végül a rajzkód az OpenGL ES 2-re frissül.0, hasonlóan ahhoz, ahogyan a Ccsprite rajz megváltozott a Cocos2D 1-től.X hogy Cocos2D 2.X:

  • először hívja meg a CC_NODE_DRAW_SETUP () függvényt, hogy előkészítse a csomópontot a rajzoláshoz.
  • a Gldisableclientstate() és a glEnableClientState() hívások elavultak és elvetésre kerülnek.
  • a glVertexPointer() és a glTexCoordPointer() parancsokat egyaránt felváltja a glVertexAttribPointer () parancs, amely első opcióként elfogadja a csúcspozíciót vagy a textúra koordinátát.
  • a gltexenvf () beállítását, amely a sprite megismétléséért volt felelős, ha a sokszög nagyobb volt, mint a textúra, a gltexparameteri () hívásai váltják fel.

ha ezek bármelyike megzavarja, érdemes megnéznie az OpenGL ES 2.0 iPhone-ra és az egyéni Cocos2D 2-re.X Shaders oktatóanyagok további háttér-információk. De nem kell túl sokat aggódnia emiatt, mert ezen a ponton csak annyit teszünk, hogy az osztályt a Cocos2D 2-Be visszük dolgozni.X:]

fordítsd le és futtasd, és minden PRKit hibának el kell tűnnie!

itt az ideje, hogy a PRKit működésbe lépjen. Lesz alosztályozás PRKit PRFilledPolygon osztály, hogy egy alap PolygonSprite osztály, amely felhívja a gyümölcsök.

a PolygonSprite a Prfilledpolygonra épül, egy Box2D testet csatolva a sprite-hez, és más egyéni változókat és módszereket is tartalmaz a játék megvalósításában.

térjünk rá. Nyomja meg a Command+N parancsot, és hozzon létre egy új fájlt az iOS\cocos2d v2 programmal.x \ CCNode osztály sablon. Legyen a PRFilledPolygon alosztálya, és nevezze el PolygonSprite-nek.m.

váltson át a PolygonSprite-re.h és végezze el a következő változtatásokat:

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

a fenti kód deklarálja a polygonsprite létrehozásához szükséges alapváltozókat és metódusokat. Ezek a következők:

  • test: ez a Box2D test, amely a sprite-hez van rögzítve. A fizikai szimulációhoz szükséges.
  • original: a teljes és a szeletelt spritek ugyanazt a PolygonSprite osztályt fogják használni, ezért fontos lesz a kettő megkülönböztetése. Ha ez igen, akkor azt jelenti, hogy a vágatlan vagy eredeti objektumot hozta létre, különben csak az egész darabja.
  • centroid: A sokszög középpontja a képen belül nem mindig lesz ugyanaz, mint a kép középpontja, ezért hasznos ezt az értéket tárolni.
  • tulajdonságok: tegye ki az összes változót a tulajdonságok használatával, hogy más osztályok szabadon hozzáférhessenek hozzájuk.
  • init/spriteWith*: fő init módszereink ugyanazt az elnevezési konvenciót követik, mint a Cocos2D.
  • egyéb módszerek: Ezek a módszerek & létrehozása foglalkozik a mellékelt Box2D testtel és annak tulajdonságaival.
  • PTM_RATIO: Pixel / méter Arány. A Box2D-nek szüksége van erre a konverziós értékre, mert pixelek helyett méterekkel foglalkozik.

gyorsan váltson PolygonSprite-re.m és nevezze át PolygonSprite.mm. minden osztálynak, amely az Objective-C (Cocos2D) és a C++ (Box2D) kódot keveri, rendelkeznie kell egy “.mm” kiterjesztéssel, hogy értesítse a fordítót a vegyes szintaxisról.

ezután végezze el a következő módosításokat 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;}

a Cocos2D-hez hasonlóan az összes spriteWith* metódus csak az initwith* metódusok automatikus kiadása, míg az initWithWorld-nek még nincs tényleges használata ehhez az osztályhoz, ehelyett később a PolygonSprite alosztályai fogják használni.

a változások nagy része az initWithFile és az initWithTexture metódusokban található. Ahhoz, hogy a dolgok áramlását, ami egy gyümölcs fogják hívni ebben a sorrendben:

Init sorozat

  • initWithWorld: ez a PolygonSprite alosztályainak szól, így nem csinálsz semmit, kivéve a nullát, és később foglalkozol vele.
  • initWithFile: ez hozzáadja a fájlunk textúráját, és mindent átad az initWithTexture-nek.
  • initWithTexture: fő inicializálásunk. A prfilledpolygonnak szüksége van egy textúrára és az általa kitöltött sokszög összes csúcsára. Mivel az előző lépés már kezelte a textúra részét, ez a lépés a csúcsokat úgy kezeli, hogy összegyűjti őket a sprite Box2D testéből. Miután átadta őket a Prfilledpolygonnak, folytatja a korábban deklarált változók inicializálását.
  • initWithPoints: minden, amit ez csinál, a PRKit-ben található, és a jó dolog az, hogy nem kell többé megérintenie a PRKit-et, most, hogy frissítette a kódját.

még mindig belül PolygonSprite.mm, adja hozzá a következő módszereket:

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

a fenti kódban először túlterheli a CCNode setPosition módszerét, így amikor frissíti a sprite pozícióját, a hozzá tartozó Box2D test helyzete is frissül.

ezután elkészíti a box2d test létrehozására és meghatározására szolgáló kényelmi módszert. Egy test létrehozásához meg kell adnia egy testdefiníciót, egy testobjektumot, egy alakzatot és egy fixture definíciót. Itt még nem rendelnek valódi kemény értékeket, mivel ezt a módszert később a PolygonSprite alosztályai fogják használni.

az egyetlen dolog, amit meg kell jegyeznibits és maskBits. Ez a kettő az objektumok közötti ütközések szűrésére szolgál, így ha egy objektum kategóriabitje megegyezik egy másik objektum maszkbitjével, és fordítva, akkor ütközés lesz a két objektum között. Ezeket először 0-ra állítja, mert nem akarja, hogy ütközések történjenek az objektumok első inicializálásakor.

végül két módszert határoz meg, amelyek egyszerűen helyettesítik a kategóriabiteket és a maskbiteket, így aktiválhatja és deaktiválhatja a sokszögek ütközését.

van még egy dolog, amit hozzá kell adni 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_;}

Emlékszel, amikor megemlítettem, hogy szükséged van valamire a PhysicsSprite-től? Nos, ez az. Mindez annak biztosítására szolgál, hogy a Box2D alakja és a sprite ugyanabban a helyzetben legyen, amikor mozog. A Cocos2D készítette nekünk, és ez még fantasztikusabbá teszi.

a fenti kód másolása után most törölheti mindkét PhysicsSprite-t.h és PhysicsSprite.mm a projektből, mivel teljesen megszüntette azok hasznosságát.

fordítsd le és futtasd, és minden rendben lesz. Most végeztél a PolygonSprite-vel.

gyümölcseink tervezése

mielőtt osztályokat hoznánk létre gyümölcseink számára, tisztában kell lennünk azokkal a szabályokkal, amelyeket a képeknek és alakjaiknak követniük kell. Mivel a textúráinkat egyetlen Box2D sokszögre fogja leképezni, be kell tartania a Box2D sokszög korlátozásait is. Két dolgot kell szem előtt tartania:

  • a Sokszögeknek konvexnek kell lenniük, ami azt jelenti, hogy egyetlen belső szög sem nagyobb, mint 180.
  • a sokszögek nem haladhatják meg a 8 csúcsot.

valójában megkerülheti ezt a korlátozást, ha engedélyezi, hogy minden test több alakot tartalmazzon. A Box2D képes kezelni a konkáv alakzatokat, ha háromszögelési módszert használ, és több háromszögből konkáv alakzatokat készít, de ez túlmutat Az oktatóprogram hatókörén.

ahhoz, hogy a dolgok egyszerűek legyenek, ebben az oktatóanyagban egy 1 Test 1 Alakú szabály lesz.

Megjegyzés: A PhysicsEditor, az eszköz, amelyet később bemutatunk ebben az oktatóanyagban, valójában olyan kódot tartalmaz, amely automatikusan háromszögeli a sokszögeket, amelyeket konvex alakzatokba rajzol. Azonban, mint mondtam, itt próbáljuk egyszerűvé tenni a dolgokat, így ügyelni fogunk arra, hogy formáinkat konvexre rajzoljuk, így testenként csak egy alakunk van.

nézd meg ezt a két gyümölcsöt:

konkáv vs konvex

a banán használata nem jó ötlet, mert természetesen konkáv. A görögdinnye viszont nagyon jó, mert meghatározhat egy konvex sokszöget, amely nagyon hasonlít az alakjára.

ha úgy döntesz, hogy meghatározza sokszög alakzatok, amelyek követik Box2D szabályait a két gyümölcs, akkor többé-kevésbé a végén ezeket:

Box2D alakú vázlat

a görögdinnye sokszög tökéletesen illeszkedik a képhez, míg a banán sokszögnek nagy üres helye van, ahol a kép befelé görbül. A Box2D ezt a helyet a tárgyunk részeként kezeli, és a banán természetellenesnek érezheti magát, amikor más tárgyakkal ütközik, vagy amikor elvágják.

ez nem azt jelenti, hogy nem használhatja a banánt, hanem azt, hogy egyszerűen nem ajánlott a banán használata. Valójában a játék, amelyet ebben az oktatóanyagban készít, ugyanazt a banánt fogja használni.

az első gyümölcs létrehozása

ideje elkészíteni az első gyümölcsöt: a görögdinnyét (legalább egy szelet).

Visszatekintve a PolygonSprite inicializálási folyamatának áramlására, tudod, hogy az initWithTexture egy Box2D testet vár, de az előző lépés, az initWithFile nem biztosítja ezt.

ennek az az oka, hogy a testet gyümölcsönként külön-külön kell megalkotni és meghatározni, tehát a legelső lépésnek, az initWithWorld-nek kell lennie, amely megteremti a testet, és meghatározza az egyes gyümölcsökre jellemző egyéb értékeket.

a Box2D test létrehozásához először ismernie kell a létrehozni kívánt sokszög alak csúcsait. Ennek különböző módjai vannak, de ehhez az oktatóanyaghoz egy remek eszközt fog használni PhysicsEditor. Ez az eszköz tele van funkciókkal, de csak arra fogja használni, hogy irányítson minket a sokszögünk csúcsainak koordinátáinak megszerzésében.

ha nem rendelkezik vele, töltse le a Physicseditort, telepítse és indítsa el. Kapsz egy üres projekt 3 panelek / oszlopok.

a Physicseditorral való munka meglehetősen egyszerű. A bal oldalon helyezze el az összes képet, amellyel dolgozni szeretne. Középen vizuálisan meghatároz egy sokszöget a képéhez. A jobb oldalon a test paraméterei vannak.

 Fizika Szerkesztő!

megragad görögdinnye.png az erőforrás-készlet képek mappájából húzza a bal oldali panelre. Most látnia kell a görögdinnyét a középső panelen.

növelje a panel alján található nagyítást kényelmes szintre, majd érintse meg a panel felső részén található ötszög gombot egy 3 oldalas sokszög alak létrehozásához.

kattintson a jobb gombbal a sokszögre, és válassza az “Add Vertex” lehetőséget, amíg összesen 5-8 csúcs nem lesz. Mozgassa a csúcsokat a görögdinnye szélei körül, miközben két dolgot ügyel:

  • a létrehozott sokszög konvex.
  • a görögdinnye összes képpontja a sokszög belsejében található.

Megjegyzés: Az alakzatok rajzolásának másik parancsikonja a PhysicsEditor varázspálca eszköz használata. Csak állítsa be a tolerancia magas (5-8), hogy a végén körülbelül 5-8 pontot, és csípés a pontokat onnan.

adja hozzá az összes többi gyümölcsöt és a bomba képet az erőforrás készlet képek mappájából, és tegye ugyanezt velük.

a következő képekhez alakzatokat kell meghatároznia:

  • banán.png
  • bomba.png
  • szőlő.PNG
  • ananász.png
  • eper.PNG
  • görögdinnye.png

ha elkészült, a jobb felső sarokban változtassa meg az exportőr értékét “Box2D generic (PLIST)” értékre, és így kell végződnie:

határozza formák könnyen PhysicsEditor!

nyomja meg a “Publish” vagy a “Publish As” gombot a csúcsinformációkat tartalmazó PLIST fájl exportálásához. Mentse el a fájlt gyümölcsként.pliszt.

példaként a gyümölcsök.az oktatóanyaghoz használt plist az erőforrás-készlet Egyéb mappájában található.

csak a PLIST fájlban található információkat szeretné megnézni, ezért ne adja hozzá ezt a fájlt a projektjéhez, hanem csak nyissa meg a gyümölcsöket.plist segítségével Xcode megtekintéséhez tartalmát szervezett módon.

kattintson a “testek” melletti háromszög ikonra a szakasz kibontásához, és látni fogja azoknak a képeknek a listáját, amelyekhez alakzatokat adott meg. Le kell fúrnia a legmélyebb szintre, hogy a görögdinnye sokszögének csúcsai így legyenek:

a PhysicsEditor PLIST

bontsa ki a görögdinnye/mérkőzések/tétel 0/sokszögeket, és most látnia kell egy másik elemet 0 típusú tömb a sokszögek alatt. Ez az utolsó tömb az Ön alakja. Ha megfelelően definiált egy konvex alakot 8 vagy kevesebb csúccsal, akkor csak egy tömböt kell látnia a sokszögek alatt.

ha többet lát, én.e tétel 0 tömb, tétel 1 tömb stb., akkor ez azt jelenti, hogy a PhysicsEditor összetett alakot készített, mert vagy túl sok csúcsot definiált, vagy konkáv sokszöget alkotott. Ha ez megtörténik, menj vissza a PhysicsEditor – hoz, és javítsd meg az alakodat.

ezután bontsa ki a tömb típusú 0 elemet az elemek végleges listájának megtekintéséhez. Ezek a csúcsok, és a jobb oldalon látható érték ezzel a formátummal { szám, szám } az X & y koordináták minden csúcshoz.

most, hogy megvan a sokszög csúcsainak pontos értéke, folytathatja a görögdinnye osztály létrehozását.

az Xcode-ban hozzon létre egy új fájlt az iOS\cocos2d v2-vel.x \ CCNode osztály sablon. Legyen a PolygonSprite alosztálya, és nevezze el görögdinnye. Nyitott Görögdinnye.h és végezze el a következő változtatásokat:

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

váltson görögdinnyére.m, nevezze át Watermelon.mm, majd adja hozzá a következő init metódust:

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

a fenti kódban először meghatározza, hogy hány csúcs van, ami ebben az esetben 7. Ezután létrehoz egy csúcstömböt, amely tartalmazza az összes koordinátát, amelyet éppen látott a PLIST-ben. Ezeket az információkat arra használja, hogy testet hozzon létre a polygonsprite-ben megadott kényelmi módszerrel.

egy kis súrlódást teszünk bele, hogy a formák ne csússzanak a végtelenségig, és egy kis kárpótlást is, hogy a formák ne álljanak meg, amikor egymásnak ugrálnak.

végül az objektumot úgy hozza létre, hogy meghívja a szuperosztály inicializálását és átadja a képfájl nevét, a Box2D testet, és kijelenti, hogy ez egy eredeti gyümölcs.

szüksége van a görögdinnye képekre az erőforráskészletből, ezért itt az ideje, hogy csak hozzáadja az összes grafikus erőforrást, amelyre szüksége van az oktatóanyag többi részéhez.

a Project Navigator panelen kattintson a jobb gombbal az erőforrások elemre, majd válassza a “Fájlok hozzáadása a CutCutCut-hoz”lehetőséget. Adja hozzá a képek mappát az erőforráskészletből a projekthez. Győződjön meg arról, hogy az” Elemek másolása a célcsoport mappájába “jelölőnégyzet be van jelölve, és a” Csoportok létrehozása minden hozzáadott mappához ” jelölőnégyzet be van jelölve.

kövesse ugyanazokat a lépéseket banán, szőlő, ananász, eper és bomba készítéséhez.

csak azzal foglalkozott, hogyan lehet lépésről lépésre létrehozni az első gyümölcsöt, mivel ez alapvetően öblítés & ismételje meg a folyamatot minden gyümölcs esetében. Az erőforráskészlet kész gyümölcs – és bombaosztályokat tartalmaz az osztályok mappában, amelyeket megnézhet arra az esetre, ha továbbra is útmutatásra van szüksége, vagy hozzáadhatja őket a projekthez, ha át akarja hagyni ezt a lépést.

fordítsd le és futtasd, és győződj meg róla, hogy minden rendben van.

gyümölcs hozzáadása a jelenethez

eddig még semmi sem történt a képernyőn, és nyilvánvalóan viszket, hogy lássa a munka gyümölcsét – szójáték célja! :]

váltás HelloWorldLayer.h és végezze el a következő változtatásokat:

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

váltás vissza HelloWorldLayer.mm és végezze el ezeket a változtatásokat:

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

akkor nyilvánítja a cache tömb, amely tartalmazza az összes gyümölcsöt és bombákat hoz létre a jövőben. Ezután hozzon létre 1 görögdinnyét, és adja hozzá a jelenethez. Hívja az activateCollisions-t, hogy a görögdinnye ne haladjon át a falakon.

fordítsd le és fuss, és látnod kell egy görögdinnyét, amely a képernyő középső területéről esik le, és alul landol, az alábbiak szerint.

a munka gyümölcse

észreveheti, hogy a görögdinnye nem pontosan a középpontban van. Ennek az az oka, hogy az objektumot a Box2D teste alapján helyezte el, a Box2D test eredete pedig az objektum bal alsó sarkában található. A görögdinnye körüli vékony körvonal látható, mert a hibakeresési rajz mód továbbra is be van kapcsolva.

Hová Menjünk Innen?

itt van egy minta projekt az összes kódot a fenti bemutató.

ennyi az 1.rész a sorozat. Eddig Van egy görögdinnye textúrájú sokszöge, amely csak a képernyő aljára esik.

de ahelyett, hogy téglalap alakú sprite-t rajzolna átlátszó térrel, mint amit általában a Box2D oktatóanyagokban lát, ez a PRKit segítségével csak a textúra azon részeit rajzolja meg, amelyek megfelelnek a Box2D test csúcsainak. Ez hamarosan hasznos lesz!

most már készen áll a bemutató 2. részére, ahol hozzáadhatja a gyümölcsök szeletelésének képességét!

addig is, ha bármilyen kérdése vagy észrevétele van ezzel a résszel kapcsolatban, kérjük, csatlakozzon az alábbi fórumbeszélgetéshez!


ez egy üzenet iOS Tutorial csapat tagja Allen Tan, egy iOS fejlesztő és társalapítója White Widget. Megtalálható a Google + – on és a Twitteren is.

raywenderlich.com Heti

a raywenderlich.com a hírlevél a legegyszerűbb módja annak, hogy naprakész maradjon mindenről, amit mobil fejlesztőként tudnia kell.

szerezzen heti összefoglalót oktatóanyagainkról és tanfolyamainkról, és bónuszként kapjon egy ingyenes, mélyreható e-mail tanfolyamot!

Leave a Reply

Az e-mail-címet nem tesszük közzé.