Iniziamo oggi una serie di articoli/appunti/idee sullo sviluppo di un prototipo di gioco per mac osx, iphone e ipad.
Il gioco è un incrocio tra un tower defence e un rpg, in cui si deve gestire il Kingdom, il “regno” di un manipolo di sopravvissuti all’infezione zombie.
Il tutto sarà incentrato nella gestione e nella crescita di questo Kingdom, un insieme di bunker e container che vengono assemblati man mano che si acquisiscono le materie prime.
Lo sviluppo per ora è su XCode 4.2 utilizzando obiective-c e la libreria Cocos2d .
Per semplificare il disegno, sto iniziando a definire tutti i modelli grafici abbozzandoli a matita, e poi scannerizzandoli e scontornandoli a mano.
Consiglio l’uso di PixelMator per questo tipo di attività. E’ un software dal costo moderato e dalle grandi potenzialità. Quando il gioco si troverà ad uno stadio abbastanza maturo, e avrò finito di definire con esattezza la dimensione di ogni singolo asset di gioco, allora passerò il lavoro a uno o più grafici 2d per ridisegnare il tutto.
Non conoscendo bene objective-c e cocos2d, inizio per gradi facendo direttamente training on the job, molte cose quindi magari ovvie a chi conosce meglio questo linguaggio, a primo acchitto potrebbero sfuggirmi. Già nella situazione attuale, iniziata oramai da 2 settimane, mi sono accorto di carenze nel disegno delle classi e ho iniziato a utilizzare funzionalità non previste inizialmente, come CoreData, il NotificationCenter , i Protocolli, e tante altre cose.
Alcuni ignobili schizzi da me eseguiti:
Che trasformati, diventeranno la base dei nostri spritesheet dove mettere tutte le animazioni per i sopravvissuti e per gli zombie, e i tileset per la nostra mappa.
Per la creazione del Kingdom invece sto utilizzando una CCTMXTiledMap composta da due righe, una per il piano base e una per il piano superiore, composta da 3 strati di layer, il primo che contiene lo sfondo di ogni cella, il secondo che contiene il centro della cella, con i mobili e soprammobili, il terzo strato che contiene le immagini frontali, le cornici dei bunker. i personaggi si troveranno tra lo sfondo e il layer centrale. Questo permetterà di avere una mappa modulare in cui andare a mischiare diversi background, foreground e middle per ottenere un numero maggiore di personalizzazioni della mappa.
Una prima bozza dopo una settimana di lavoro inizia a prendere forma:
Ci sono già diverse scene per l’implementazione dei credits iniziali, del menu di gioco e della schermata principale, basata su uno sfondo con scrolling in parallasse e la nostra mappa di bunker al centro.
Per poter lavorare al meglio, ho esteso la CCTXMTiledMap, per aggiungere tutte quelle proprietà e metodi che dovranno snellire e semplificare lo sviluppo e la gestione della mappa.
ecco un esempio della sua interfaccia:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #import "cocos2d.h" #import "CCTMXTiledMap.h" @interface BunkerMap : CCTMXTiledMap { CCTMXLayer *_baseLayer; int _homeBunkerPosition; int _lastSelectedBunkerId; CCSprite* _lastSelectedBunker; } @property(nonatomic,retain)CCTMXLayer *baseLayer; @property(nonatomic,readwrite)int homeBunkerPosition; @property(nonatomic,readonly)int lastSelectedBunkerId; //TODO: convertire il lastSelectedBunker da sprite a oggetto Bunker @property(nonatomic,readonly)CCSprite *lastSelectedBunker; -(void)selectBunker:(int)bunkerNumber; -(void)centerToBunkerNumber:(int)bunkerNumber select:(BOOL)flag; -(int)centerToBunkerPosition:(CGPoint)location select:(BOOL)flag; -(int) findBunkerByPosition:(CGPoint)location; @end |
ed un esempio di implementazione della funzione per capire su che bunker ho selezionato (per poterlo centrare ad esempio o visualizzarne la sua scheda):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | -(int) findBunkerByPosition:(CGPoint)location{ CGSize s = [self.baseLayer layerSize]; for( int x=0; x<s.width;x++) { for( int y=0; y< s.height; y++ ) { CCTMXLayer *l; CCARRAY_FOREACH(self.children, l) { if([l isKindOfClass:[CCTMXLayer class]]){ CCSprite *tile = [l tileAt:ccp(x,y)]; if (CGRectContainsPoint([tile boundingBox],[self convertToNodeSpace:location])){ // NSLog(@"TILE:%@",[tile position]); return x; } } } // unsigned int tmpgid =[layer tileGIDAt:ccp(x,y)]; } } return -1; } |