{"id":9214,"date":"2012-07-16T11:01:40","date_gmt":"2012-07-16T09:01:40","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=9214"},"modified":"2012-07-17T09:09:26","modified_gmt":"2012-07-17T07:09:26","slug":"03-realizziamo-il-nostro-primo-videogioco-muoviamo-un-personaggio-con-il-joystick","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/03-realizziamo-il-nostro-primo-videogioco-muoviamo-un-personaggio-con-il-joystick\/","title":{"rendered":"03. Realizziamo il nostro primo videogioco: muoviamo un personaggio con il joystick"},"content":{"rendered":"<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/corso-programmazione-videogame-cocos2d-03.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/corso-programmazione-videogame-cocos2d-03.jpg\" alt=\"corso-programmazione-videogame-cocos2d-03\" title=\"corso-programmazione-videogame-cocos2d-03\" width=\"200\" height=\"100\" class=\"alignleft size-full wp-image-9226\" \/><\/a> Nelle due precedenti lezioni del nostro corso di programmazione videogame con cocos2d abbiamo analizzato le principali classi che compongono un videogioco realizzato con questo framework, in questa lezione proseguiremo il discorso iniziato creando il primo esempio pratico: realizzeremo la prima bozza di un videogioco.<br \/>\nE&#8217; chiaro che per questo primo esempio non avremo molte pretese, il nostro gioco sar\u00e0 infatti ridotto all&#8217;osso: sar\u00e0 composto da una singola scena e avr\u00e0 un unico (e solo sigh) personaggio che andr\u00e0 in giro su \u00e8 gi\u00f9 per il nostro schermo, comandato dal nostro fantastico primo joystick. Ok ok,  vita piuttosto monotona per il nostro personaggio, ma da qualche parte dobbiamo pur iniziare, no? Eh allora bando alle ciance. Avviamo XCode, creiamo un nuovo progetto di tipo cocos2s e chiamiamolo &#8220;Stickman&#8221;.<!--more--><\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-01.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-01.png\" alt=\"primo-videogioco-cocos2d-joystick-01\" title=\"primo-videogioco-cocos2d-joystick-01\" width=\"550\" height=\"368\" class=\"aligncenter size-full wp-image-9229\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-01.png 732w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-01-300x200.png 300w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-02.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-02.png\" alt=\"primo-videogioco-cocos2d-joystick-02\" title=\"primo-videogioco-cocos2d-joystick-02\" width=\"550\" height=\"368\" class=\"aligncenter size-full wp-image-9230\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Salviamo il progetto in una cartella di nostro gradimento e fermiamoci ad esaminare il codice generato.<\/p>\n<p>Come abbiamo gi\u00e0 visto si tratta di un progetto completo, avviabile e gi\u00e0 dotato di una scena e un layer. Non vogliamo per\u00f2 continuare ad utilizzare il nome &#8220;helloworldLayer&#8221; nel nostro progetto, abbiamo quindi due possibilit\u00e0: <\/p>\n<ul>\n<li>possiamo cancellare completamente la classe (ricordandoci di eliminare anche la riga <code>#import \"HelloWorldLayer.h\"<\/code> nel file AppDelegate.m<\/li>\n<li>oppure possiamo ricorrere ad una comoda scorciatoia chiamata &#8220;refactoring&#8221;.<\/li>\n<\/ul>\n<p>Il refactoring (<a href=\"http:\/\/it.wikipedia.org\/wiki\/Refactoring\" target=\"_blank\">wikipedia<\/a>) \u00e8 una operazione in cui si modifica il codice sorgente per migliorarlo senza modificarne il comportamento finale (altrimenti si chiamerebbe debugging!). In questo caso possiamo quindi cambiare il nome di questa classe e tutti i riferimenti cliccando semplicemente con il tasto destro del mouse (o se preferite tramite la combinazione &#8220;ctrl + click&#8221;) sulla parola &#8220;HelloWorldLayer&#8221; della riga <code>@interface HelloWorldLayer : CCLayer<\/code> all&#8217;interno del file HelloWorldLayer.h e scegliendo la voce &#8220;refactor->renane&#8221;.<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-03.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-03.png\" alt=\"primo-videogioco-cocos2d-joystick-03\" title=\"primo-videogioco-cocos2d-joystick-03\" width=\"550\" height=\"318\" class=\"aligncenter size-full wp-image-9231\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-03.png 631w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-03-300x173.png 300w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Diamogli quindi un nome pi\u00f9 significativo come &#8220;BackgroundLayer&#8221;. Assicuriamoci di aver messo il segno di spunta su &#8220;rename related files&#8221; e clicchiamo su &#8220;preview&#8221;. Tutto corretto? Allora clicchiamo su &#8220;Save&#8221;.<\/p>\n<h4>Un approfondimento per i curiosi<\/h4>\n<p>Non paragoniamo quello che abbiamo appena fatto con una forma evoluta di un semplice &#8220;trova e sostituisci&#8221;. Il refactoring \u00e8 quasi una scienza ed entra spesso in campo nelle strategie di sviluppo del software, esistono interi libri (<a href=\"http:\/\/www.amazon.it\/gp\/product\/0201485672\/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&#038;tag=de0d-21&#038;linkCode=as2&#038;camp=3370&#038;creative=23322&#038;creativeASIN=0201485672\" target=\"_blank\">qui un esempio<\/a>) sull&#8217;argomento e XCode fornisce un eccellente supporto alle tecniche di refactoring pi\u00f9 comuni, come il rename che abbiamo appena visto e altre come extract (avete mai avuto voglia di mettere quelle 30 righe di codice in un metodo separato? provate extract e poi commentate sul forum il risultato!). Per avere una lista pi\u00f9 o meno completa delle tecniche di refactoring potete consultare il sito del guru <a href=\"http:\/\/martinfowler.com\/refactoring\/catalog\/index.html\" target=\"_blank\">Martin Fowler<\/a>.<\/p>\n<p>Una volta effettuato il refactoring della classe dobbiamo modificarne il metodo init, perch\u00e9 questo livello servir\u00e0 solo per visualizzare l&#8217;immagine di sfondo. Modifichiamo quindi il metodo con questo codice:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n-(id)init {\r\n    self = [super init];\r\n    if (self != nil) {\r\n        CCSprite *backgroundImage;\r\n        backgroundImage = [CCSprite spriteWithFile:@\"background.png\"];\r\n        CGSize screenSize = [[CCDirector sharedDirector] winSize];\r\n        [backgroundImage setPosition: CGPointMake(screenSize.width\/2, screenSize.height\/2)];\r\n        [self addChild:backgroundImage z:0 tag:0];\r\n    }\r\n     return self;\r\n}\r\n<\/pre>\n<p>Il codice che ho riportato dovrebbe esservi familiare, abbiamo creato una sprite usando l&#8217;immagine background.png e l&#8217;abbiamo posizionata al centro dello schermo, successivamente l&#8217;abbiamo aggiunta al layer.<\/p>\n<p>Potete scaricare le due immagini per il background da qui: [<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/background.png\">background.png<\/a>] e [<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/background-hd.png\">background-hd.png<\/a>]. Sono due perch\u00e9 cos\u00ec come avviene per le immagini @2x dell&#8217;UIKit possiamo aggiungere il suffisso <strong>-hd<\/strong> alle immagini per far s\u00ec che vengano utilizzate automaticamente sui device dotati di retina display.<\/p>\n<h4>Il livello dei personaggi<\/h4>\n<p>Una volta creato il livello dello sfondo passiamo al livello dove si muover\u00e0 il nostro personaggio. Va fatta una precisazione: la suddivisione in layer \u00e8 arbitraria e del tutto non obbligatoria, avremmo potuto infatti tenere tutto nello stesso livello, ma un pizzico di buon senso ci suggerisce di mantenere un&#8217;ordinata separazione dei ruoli.<\/p>\n<p>Aggiungiamo quindi un nuovo file, selezioniamo il tipo cocos2d &#8211; CCNode Class, subclass di CCLayer e chiamiamolo &#8220;StickLayer&#8221;.<\/p>\n<p>Aggiungiamo una variabile di istanza modificando l&#8217;header (.h) della classe in questo modo:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n#import <Foundation\/Foundation.h>\r\n#import \"cocos2d.h\"\r\n@interface StickLayer : CCLayer {\r\n    CCSprite *stickMan;\r\n}\r\n@end\r\n<\/pre>\n<p>Aggiungiamo ora il metodo -(id)init nel file di implementazione (.m)<\/p>\n<p>Potete scaricare le due immagini da qui:<\/p>\n<ul>\n<li><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/sprite_run0.png\" target=\"_blank\">sprite_run0.png<\/a><\/li>\n<li><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/sprite_run0-hd.png\">sprite_run0-hd.png<\/a><\/li>\n<\/ul>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n-(id)init {\r\n    self = [super init];\r\n    if (self != nil) {\r\n        CGSize screenSize = [CCDirector sharedDirector].winSize;  \/\/ 1\r\n        stickMan = [CCSprite spriteWithFile:@\"sprite_run0.png\"];\/\/ 2\r\n        [stickMan setPosition: CGPointMake(screenSize.width\/2, 72.5)]; \/\/3\r\n        [self addChild:stickMan]; \/\/ 4\r\n    }\r\n    return self;\r\n}\r\n<\/pre>\n<p>Anche questo codice non presenta particolari novit\u00e0 se non alla riga \/\/3, dove posizioniamo la nostra sprite. ho inserito 72.5 come parametro dell&#8217;altezza perch\u00e9 la sprite \u00e8 alta 55 pixel, la barra che simula il pavimento \u00e8 alta 45 quindi (45 + (55 \/ 2) = 72.5. In questo modo la prite sembrer\u00e0 appoggiata sul pavimento.<\/p>\n<h4>Un altro approfondimento per i curiosi<\/h4>\n<p>Pi\u00f9 che per i curiosi questo approfondimento \u00e8 per chi vuole migliorare il proprio stile di programmazione. Il valore 72.5 che abbiamo inserito nel codice sarebbe stato definito da Kernighan &#8220;a magic number&#8221; (vedi: <a href=\"http:\/\/www.amazon.it\/gp\/product\/020161586X\/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&#038;tag=de0d-21&#038;linkCode=as2&#038;camp=3370&#038;creative=23322&#038;creativeASIN=020161586X\" target=\"_blank\">book<\/a>). Magico in quanto non c&#8217;\u00e8 nel codice spiegazione del perch\u00e9 si sia scelto quel valore e non un altro, sappiamo solo che quel 72.5 &#8220;magicamente&#8221; funziona.<\/p>\n<p>Chiaramente tutto questo non fa bene alla leggibilti\u00e0 del codice! Se un&#8217;altro programmatore dovesse vedere quella riga di codice non potrebbe comprendere il ragionamento che ci sta dietro.<\/p>\n<p>Esistono diverse possibilti\u00e0 per rendere il tutto pi\u00f9 chiaro: la prima (e pi\u00f9 semplice) \u00e8 quella di aggiungere un commento a quella riga di codice, in modo da spiegare come si \u00e8 ottenuto il valore 72.5, questo per\u00f2 significa che dobbiamo assicurarci di tenere aggiornato anche il commento, perch\u00e9 se dovessimo cambiare l&#8217;immagine di sfondo o la sprite dovremmo sia cambiare il valore 72.5 che il commento stesso. Come si dice in gergo &#8220;Se il codice \u00e8 in disaccordo con il commento, uno dei due \u00e8 sbagliato&#8221;.<\/p>\n<p>Il secondo metodo \u00e8 quello di rendrere pi\u00f9 esplicito il calcolo utilizzando delle variabili che rendano tutto pi\u00f9 chiaro, ad esempio avremmo potuto scrivere:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\nfloat floorHeight = 45;\r\nfloat spriteCenter = [stickMan boundingBox].size.height \/ 2;\r\n[stickMan setPosition: CGPointMake(screenSize.width\/2, floorHeight + spriteCenter)];\r\n<\/pre>\n<p>Anche se abbiamo aggiunto due variabili abbiamo reso il codice molto pi\u00f9 comprensibile ed anche questa \u00e8 una qualit\u00e0 da ricercare nei nostri programmi.<br \/>\nSe compilassimo in questo momento non noteremmo alcun cambiamento. Questo perch\u00e9 il layer StickLayer non viene mai usato, ci servir\u00e0 visualizzarlo insieme al livello background.<\/p>\n<p>Facciamo un passo indietro: quando abbiamo deciso di effettuare il refactoring della classe HelloWorldLayer non avevamo messo in conto che quella classe era anche responsabile di fornire una scena (CCScene) standard che veniva creata all&#8217;interno del metodo di classe +(CCScene *)scene. (ne abbiamo parlato nella precedente lezione)<br \/>\nQuesto poteva andar bene per un gioco in cui c&#8217;\u00e8 un solo layer, ma se ci sono pi\u00f9 layer chi dovrebbe prendersi la responsabilit\u00e0 di creare la scena? Il primo? ll secondo?<br \/>\n\u00c8 pi\u00f9 corretto creare una specifica subclass di CCScene liberando cos\u00ec i layer da questo ingrato compito.<\/p>\n<p>Aggiungiamo quindi un nuovo file ti dipo cocos2d -> CCnode Class e selezioniamo il tipo di subclass &#8220;CCNode&#8221;, perch\u00e9 non \u00e8 presente la voce CCScene.<br \/>\nPossiamo modificare il contenuto dell&#8217;intestazione della classe appena generata in modo che appaia in questo modo:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n#import <Foundation\/Foundation.h>\r\n#import \"cocos2d.h\"\r\n@interface Game0Scene : CCScene {\r\n   \r\n}\r\n@end\r\n<\/pre>\n<p>e cos\u00ec l&#8217;implementazione:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n#import \"Game0Scene.h\"\r\n#import\"BackgroundLayer.h\"\r\n#import\"StickLayer.h\"\r\n\r\n@implementation Game0Scene\r\n-(id)init {\r\n    self = [super init];\r\n    if (self != nil) {\r\n       \r\nBackgroundLayer *backgroundLayer = [BackgroundLayer node]; \/\/ 1\r\n[self addChild:backgroundLayer z:0];\r\nStickLayer *sticklayer = [StickLayer node];\r\n[self addChild:sticklayer z:5];\r\n }\r\nreturn self;\r\n}\r\n@end\r\n<\/pre>\n<p>Che cosa facciamo in questa classe? Niente che non abbiate gi\u00e0 visto: semplicemente allochiamo due layer (BackgroundLayer e StickLayer) e li aggiungiamo alla scena corrente.<\/p>\n<p>Dobbiamo modificare adesso il file AppDelegate.h in modo da far caricare questa scena e non pi\u00f9 quella generata dal layer, aggiungiamo quindi un:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n#import \"Game0Scene.h\"\r\n<\/pre>\n<p>e sostituiamo la riga:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n[[CCDirector sharedDirector] runWithScene: [BackgroundLayer scene]];\r\n<\/pre>\n<p>con questa:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n[[CCDirector sharedDirector] runWithScene: [Game0Scene node]];\r\n<\/pre>\n<p>Se tutto \u00e8 andato secondo i piani dovreste poter compilare e vedere l&#8217;interfaccia di questo nostro &#8220;gioco&#8221;:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-04.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-04.png\" alt=\"primo-videogioco-cocos2d-joystick-04\" title=\"primo-videogioco-cocos2d-joystick-04\" width=\"550\" height=\"293\" class=\"aligncenter size-full wp-image-9232\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-04.png 744w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-04-300x159.png 300w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Carino, no?<\/p>\n<p>Certo sarebbe pi\u00f9 bello se magari tutto fosse corredato da un pizzico di interattivit\u00e0! Perch\u00e9 allora non aggiungere un bel joystick da utilizzare per muovere il personaggio? Bella idea, facciamolo!<\/p>\n<p>Possiamo, a tal fine, sfruttare il progetto SneakyJoystick che troviamo a questo indirizzo: <a href=\"https:\/\/github.com\/cjhanson\/SneakyJoystick\" target=\"_blank\">https:\/\/github.com\/cjhanson\/SneakyJoystick<\/a>. Per comodit\u00e0 eccovi un file zip con tutte le classi che dovete copiare all&#8217;interno del vostro progetto. [<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/JoystickClasses.zip\" target=\"_blank\">FILE ZIP<\/a>]<\/p>\n<p>Per semplicit\u00e0 aggiungeremo il joystick nello stesso livello del personaggio, cos\u00ec sar\u00e0 pi\u00f9 facile gestirne i movimenti.<\/p>\n<p>Selezioniamo quindi il file StickLayer.h e modifichiamolo in questo modo:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n#import <Foundation\/Foundation.h>\r\n#import \"cocos2d.h\"\r\n#import \"SneakyJoystick.h\" \/\/1\r\n#import \"SneakyJoystickSkinnedBase.h\" \/\/2\r\n@interface StickLayer : CCLayer {\r\n    CCSprite *stickMan;\r\n    SneakyJoystick *leftJoystick; \/\/3\r\n}\r\n@end\r\n<\/pre>\n<p>Abbiamo aggiunto le righe \/\/1 \/\/2 e \/\/3 con cui importiamo le classi che ci servono e per dichiarare una variabile di istanza di tipo SneakyJoystick.<\/p>\n<p>Nel file StickLayer.m aggiungiamo ora un metodo che ci servir\u00e0 per configurare il joystick:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n-(void)initJoystick{\r\n    SneakyJoystickSkinnedBase *joystickBase = [[[SneakyJoystickSkinnedBase alloc] init] autorelease]; \/\/1\r\n    joystickBase.position = ccp(50,50); \/\/2\r\n    joystickBase.backgroundSprite =  [CCSprite spriteWithFile:@\"dpadDown.png\"]; \/\/3\r\n    joystickBase.thumbSprite = [CCSprite spriteWithFile:@\"joystickCenter.png\"]; \/\/4\r\n    joystickBase.joystick = [[SneakyJoystick alloc] initWithRect:CGRectMake(0, 0, 128.0f, 128.0f)]; \/\/5\r\n    leftJoystick = joystickBase.joystick; \/\/6\r\n    [self addChild:joystickBase]; \/\/7\r\n}\r\n<\/pre>\n<p>Analizziamo il codice:<\/p>\n<p>#1 Allochiamo e inizializziamo un oggetto di tipo SneakyJoystickSkinnedBase<br \/>\n#2 ne impostiamo la posizione nell&#8217;angolo in basso a sinistra<br \/>\n#3 ne impostiamo l&#8217;immagine di sfondo<br \/>\n#4 impostiamo l&#8217;immagine della parte centrale del joystick<br \/>\n#5 Allochiamo e inizializziamo un oggetto di tipo SneakyJoystik di 128 pixel per 128 pixel.<br \/>\n#6 Impostiamo la variabile di istanza all&#8217;oggetto appena creato<br \/>\n#7 Aggiungiamo al layer corrente il joystick<\/p>\n<p>Modifichiamo il metodo init di questa stessa classe per richiamare il metodo che abbiamo appena scritto e per aggiungere una nuova istruzione:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n-(id)init {\r\n    self = [super init];\r\n    if (self != nil) {\r\n        CGSize screenSize = [CCDirector sharedDirector].winSize;  \r\n        stickMan = [CCSprite spriteWithFile:@\"sprite_run0.png\"];\r\n        [stickMan setPosition: CGPointMake(screenSize.width\/2, 72.5 )];\r\n        [self addChild:stickMan];\r\n        [self initJoystick]; \/\/1\r\n        [self scheduleUpdate]; \/\/2\r\n    }\r\n    return self;\r\n}\r\n<\/pre>\n<p>Le righe aggiunte sono la \/\/1 e la \/\/2. Vediamole nel dettaglio.<\/p>\n<p>La \/\/1 richiama il metodo per la configurazione del joystick, la \/\/2, invece, fa una cosa un p\u00f2 pi\u00f9 complessa. In pratica dichiarando quel metodo ad ogni iterazione (in questo caso 60 volte al sec) verr\u00e0 invocato sulla nostra classe un metodo con questa signature:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n-(void) update:(ccTime)deltaTime\r\n<\/pre>\n<p>Noi useremo questo metodo per esaminare il valore del joystick e spostare il nostro personaggio di conseguenza. Aggiungiamo qiundi questo metodo:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n-(void) update:(ccTime)deltaTime\r\n{\r\n    [self applyJoystick:leftJoystick toNode:stickMan forTimeDelta:deltaTime];\r\n}\r\n<\/pre>\n<p>Xcode segnaler\u00e0 un errore perch\u00e9 il metodo applyJoystick:toNode:forTimeDelta non \u00e8 stato dichiarato, diamogli quindi retta ed aggiungiamolo subito:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n-(void)applyJoystick:(SneakyJoystick *)aJoystick toNode:(CCNode*)tempNode forTimeDelta:(float)deltaTime\r\n{\r\n    CGPoint scaledVelocity = ccpMult(aJoystick.velocity, 350.0f);\r\n    CGPoint newPosition = ccp(tempNode.position.x + scaledVelocity.x * deltaTime,tempNode.position.y + scaledVelocity.y * deltaTime);\r\n    [tempNode setPosition:newPosition];\r\n}\r\n<\/pre>\n<p>In questo modo modifichiamo la posizione del nostro personaggino in funzione della posizione del joystick e del tempo intercorso dall&#8217;ultimo aggiornamento.<br \/>\n<strong>Nota:<\/strong> scaledVelocity serve per aumentare o diminuire la velocit\u00e0 con cui si sposta il personaggio, provate ad inserire valori diversi e analizzate quello che succede.<\/p>\n<p>Ok, ci siamo! Proviamo a compilare il programma e, se avete seguito tutto per bene fino a qui, potrete anche voi godervi finalmente il vostro bellissimo &#8220;omino nero volante&#8221;.<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-05.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-05.png\" alt=\"primo-videogioco-cocos2d-joystick-05\" title=\"primo-videogioco-cocos2d-joystick-05\" width=\"550\" height=\"293\" class=\"aligncenter size-full wp-image-9233\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-05.png 744w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2012\/07\/primo-videogioco-cocos2d-joystick-05-300x159.png 300w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<h4>Conclusioni<\/h4>\n<p>La lezione di oggi \u00e8 stata veramente lunga e impegnativa, abbiamo affrontato gli argomenti principali di cocos2d come le scene e i layer e abbiamo imparato ad usare la classe SneakyJoystick per fornire un joystick ai nostri videogame. Nella prossima lezione vedremo come gestire al meglio le sprite.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nelle due precedenti lezioni del nostro corso di programmazione videogame con cocos2d abbiamo analizzato le principali classi&#8230;<\/p>\n","protected":false},"author":53,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1119],"tags":[1151,1150,1149,1153,1152,1148],"class_list":["post-9214","post","type-post","status-publish","format-standard","hentry","category-corso-programmazione-videogiochi","tag-corso-cocos2d-italiano","tag-creare-videogiochi-iphone","tag-joystick-cocos2d","tag-layer-cocos2d","tag-scene-cocos2d","tag-sneakyjoystick"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/9214","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=9214"}],"version-history":[{"count":24,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/9214\/revisions"}],"predecessor-version":[{"id":9249,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/9214\/revisions\/9249"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=9214"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=9214"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=9214"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}