Crea un braccio robotico usando la cinematica in avanti

Forward Kinematics (FK) è un algoritmo di posizionamento. Non è così complicato come sembra se lo associ a una sequenza di azioni dal punto di vista dell'operatore dell'escavatore. A partire dal nodo più vicino, l'operatore configura l'orientamento di ciascun nodo nella speranza che lo scoop raggiunga la posizione desiderata. Spesso, diversi tentativi vengono fatti prima di raggiungere il successo. FK è un algoritmo per eseguire tale compito. In questo tutorial, tenteremo di implementare FK e applicarlo su un escavatore da una vista laterale 2D. Avendo capito questo algoritmo, si può facilmente adattarlo ad un ambiente 3D. Godere!


Passaggio 1: Flusso delle esercitazioni

Questo tutorial assumerà la seguente sequenza:

  • Spiegazione per il background matematico di FK.
  • La mplementazione codificata verrà eseguita in un file in base al flusso sequenziale.
  • Successivamente, classe orientata agli oggetti sviluppata per implementare l'algoritmo FK.
  • Dimostrazione della classe FK utilizzata in un progetto.
  • Grafica applicata alla dimostrazione.

Passaggio 2: catena

Prima di tutto, dobbiamo capire il concetto di una catena. Una catena astrae l'ordine gerarchico dei nodi. Esiste un nodo radice, l'ordine più alto della catena, a cui tutti gli altri nodi sono uniti. Il nodo che si connette alla radice è il primo livello figlio. Il nodo che si collega al bambino di primo livello è il bambino di secondo livello.

La relazione gerarchica è semplificata di seguito:

root> node1> node2> node3> node4> node5?

L'animazione flash sopra mostra la parent (gerarchia più alta) alle relazioni child (lower in hierarchia), dove ogni freccia punta a un nodo figlio.


Passaggio 3: frecce

Ognuno di questi nodi è collegato a quelli adiacenti da un vincolo. Definirò questi vincoli come "frecce". Arrow sono vettori. Hanno una lunghezza (meglio conosciuta come grandezza) e un angolo che ne descrive l'orientamento. In questa esercitazione, queste frecce puntano dal nodo genitore al nodo figlio. Ad esempio, node1 è unito a root da arrow1. Arrow1 sta puntando da root a node1.

Le frecce seguono anche un ordine gerarchico perché tentano di unirsi a una catena gerarchica di nodi. Questa relazione gerarchica è semplificata come di seguito:

arrow1> arrow2> arrow3> arrow4> arrow5?

Allora, dov'è la freccia0? Bene, root è il più alto nella gerarchia. Nessuna freccia indica che non c'è effettivamente una freccia0.



Step 4: Delta Rotation

La regolazione della rotazione delle frecce è la cosa più importante nell'algoritmo FK. Qui, ruoteremo una freccia per angolo delta. Se ruotiamo la freccia1, la posizione di node1 si aggiornerà. Ma non è tutto.

Nell'algoritmo FK, la cinematica attraversa la gerarchia dalla più alta alla più bassa. Supponiamo che la nostra catena abbia 6 nodi, uniti da 5 frecce. Se la rotazione delta è applicata alla freccia1, quindi la freccia2 alla freccia5 devono essere ruotate anche dall'angolo delta. Ho messo in evidenza le frecce che sono influenzate dal cambiamento.

arrow1 > arrow2 > arrow3 > arrow4 > arrow5

Se viene applicata la rotazione delta sulla freccia3, vengono influenzate solo la freccia4 e la freccia5.

arrow1>arrow2> arrow3 > arrow4 > arrow5

Per ogni freccia interessata, sarà interessata anche la posizione del nodo associato. Quindi node4 e node5 aggiorneranno le loro posizioni.

Nel file SWF sopra, fare clic sulle frecce per vedere l'ondulazione cinematica sui nodi (frecce più scure).


Passaggio 5: avviare il progetto

Lauch FlashDevelop e avvia un nuovo progetto. Aggiungi un "MileStone1.as" nel tuo progetto.






Passaggio 6: una catena di due nodi: due elementi grafici

Ora per implementare la nostra prima catena FK. Per prima cosa, dobbiamo aggiungere i due sprite sullo stage come variabili di classe. Il nodo radice è un cerchio blu e il primo nodo è un cerchio viola.

 rootNode = new Sprite (); rootNode.graphics.beginFill (0x4499FF); rootNode.graphics.drawCircle (0, 0, 20); rootNode.graphics.endFill (); addChild (rootNode); node1 = new Sprite (); node1.graphics.beginFill (0x772255); node1.graphics.drawCircle (0, 0, 20); node1.graphics.endFill (); addChild (node1);

Passaggio 7: una catena di due nodi: vincoli di freccia

node1 è unito a rootNode tramite vec1, che è un'istanza della classe Vector2D (classe scritta personalizzata). È una variabile di classe. Lo iniziamo e impostiamo la sua grandezza a 60.

 vec1 = new Vector2D (0, 0); vec1.setMagnitude (60);

Passaggio 8: una catena di due nodi: posizionamento

Prima di iniziare ad assegnare agli ascoltatori l'aggiunta di interattività al nostro piccolo programma, dobbiamo impostare la posizione iniziale dei nodi. Prima il rootNode, che è abbastanza ovvio. Il prossimo è node1 (evidenziato) da cui dipende rootNodeLa posizione di.

 // impostazione dei nodi rootNode.x = 150; rootNode.y = 150; node1.x = rootNode.x + vec1.x; node1.y = rootNode.y + vec1.y;

Passaggio 9: una catena di due nodi: listener

Quasi lì. Aggiungiamo un ascoltatore all'evento tastiera. Premendo una chiave arbitraria, vec1 ruota e modifica ulteriormente l'orientamento di node1 riguardo a rootNode.

 stage.addEventListener (KeyboardEvent.KEY_DOWN, move);  move della funzione privata (e: KeyboardEvent): void vec1 = vec1.rotate (Math2.radianOf (10)); node1.x = rootNode.x + vec1.x; node1.y = rootNode.y + vec1.y; 

Di seguito è completato MileStone1. Semplice, giusto?

Fare clic sul file SWF, quindi premere qualsiasi tasto (ripetutamente) per vedere l'effetto.


Passaggio 10: una catena di tre nodi: grafica e freccia

Ora che abbiamo la configurazione di base, lasciamo andare un po 'oltre. Aggiungeremo node2 (anche viola) alla catena esistente. node2 è unito a node1 attraverso vec2, a cui viene data una grandezza di 60

 // un secondo figlio node2 = new Sprite (); node2.graphics.beginFill (0x772255); node2.graphics.drawCircle (0, 0, 20); node2.graphics.endFill (); addChild (nodo 2); vec2 = new Vector2D (0, 0); vec2.setMagnitude (60);

Passo 11: Una catena di tre nodi: posizionamento

Inizializziamo la posizione di node2 in relazione con node1 utilizzando vec2 come un vincolo usando il seguente codice. Ricorda di includere anche lo stesso pezzo di codice nell'ascoltatore della tastiera (riga 64 di MileStone2).

 node2.x = node1.x + vec2.x; node2.y = node1.y + vec2.y;

Ecco il MileStone2 completato:

Ancora una volta, usa la tastiera per vedere l'effetto.


Step 12: Una catena di tre nodi: Uh-oh

Hmm? C'è qualcosa di sbagliato in questa implementazione FK. Vedi, la cinematica non attraversa la catena. Richiama il passaggio 4: Rotazione delta; la cinematica deve decrescere dal livello attuale della gerarchia fino alla fine. Ho evidenziato le linee di codice che fanno questo. Per correggere l'errore logico, è sufficiente incollare la riga 65 su MileStone2. Ho fornito MileStone3 in caso di difficoltà.

 move della funzione privata (e: KeyboardEvent): void vec1 = vec1.rotate (Math2.radianOf (10)); node1.x = rootNode.x + vec1.x; node1.y = rootNode.y + vec1.y; vec2 = vec2.rotate (Math2.radianOf (10)); node2.x = node1.x + vec2.x; node2.y = node1.y + vec2.y; 

Passaggio 13: una catena di tre nodi: più controlli

Successivamente, aggiungiamo flessibilità al nostro controllo. Attualmente controlliamo il posizionamento di node1 e node2. Consente il controllo sul posizionamento di node2 solo.

 move della funzione privata (e: KeyboardEvent): void if (e.keyCode == Keyboard.PAGE_UP) vec1 = vec1.rotate (Math2.radianOf (10)); node1.x = rootNode.x + vec1.x; node1.y = rootNode.y + vec1.y; vec2 = vec2.rotate (Math2.radianOf (10)); node2.x = node1.x + vec2.x; node2.y = node1.y + vec2.y;  else if (e.keyCode == Keyboard.PAGE_DOWN) vec2 = vec2.rotate (Math2.radianOf (10)); node2.x = node1.x + vec2.x; node2.y = node1.y + vec2.y; 

Utilizzare i tasti Pagina giù e Pagina su per spostare i diversi nodi.

Sì, la rotazione è ancora a senso unico, in senso antiorario. Lo scopo di eseguire i passaggi da 5 a 13 è quello di costruire una solida comprensione dell'algoritmo FK. Ora che è stato creato, portiamo questo ad un altro livello: progettando una classe FKChain che permetta una facile implementazione di FK.


Passaggio 14: Classe FKChain: variabili

FKChain è stato progettato per implementare facilmente FK. Ho progettato la classe con le seguenti variabili e funzioni. Ti condurrò attraverso di loro.

variabili Scopo Tipo di dati
nodi Per contenere i nodi della catena FK Vettore matrice di sprites
frecce Per contenere le frecce che collegano i nodi Vettore matrice di Vector2D
lowerLimits Per mantenere il limite inferiore dell'angolo ammissibile Vettore matrice di Numero
upperLimits Per mantenere il limite superiore dell'angolo ammissibile Vettore matrice di Numero
selectedIndex Per contenere i dati del nodo selezionato corrente Numero intero

Passaggio 15: Classe FKChain: struttura dati

L'associazione dei nodi alle frecce insieme ad altri vincoli è rappresentata dal seguente diagramma.


Nota l'associazione di nodi a frecce, lowerLimits e upperLimits. L'angolo segnato in rosso è vincolato in base alla formula nell'immagine sopra.

Nota anche che ho menzionato nel passaggio 3 che non c'è freccia [0]. Tuttavia, se dovessimo implementare i confini, avremo bisogno freccia [0] essere un vettore orizzontale dove angolo di freccia [1] viene misurato e valutato dai vincoli.


Passaggio 16: Classe FKChain: funzioni

Ora che comprendi i bulloni e le noci della classe FKChain, passiamo a definire le funzioni di FKChain.

funzioni Input / Tipo di dati Scopo
FKChain () nodo principale / folletto Inizia variabili di classe. Imposta il nodo radice nella catena FK
con vincoli rilevanti. Imposta selectedNode al nodo radice.
appendNode () prossimo nodo figlio / folletto Aggiungi un nuovo nodo alla catena insieme ai vincoli pertinenti. Imposta
corrente selezionata. Imposta selectedNode al nuovo nodo.
removeNode () nodo da rimuovere / folletto Rimuovi il nodo di input dalla catena insieme ai vincoli pertinenti.
selectedNode () nodo da manipolare / folletto Imposta il nodo selezionato corrente per eseguire manipolazioni come la regolazione
la sua freccia (magnitudine e angolo) e le limitazioni sull'angolo della freccia.
updateLimits () inferiore, limiti superiori / Numero Imposta nuove limitazioni (limite superiore e inferiore) sulla freccia
angolo del nodo selezionato.
alterMagnitude () grandezza/ Numero Imposta nuova magnitudine sulla freccia del nodo selezionato.
alterAngle () angolo da regolare a / Numero Inserisce l'angolo delta sulla freccia del nodo selezionato.
setPosition () (nessuna) Ripple giù cinematica dalla gerarchia del nodo selezionato alla fine del
catena.

Passaggio 17: Classe FKChain: Proprietà

Ho anche introdotto alcuni getter per facilitare lo sviluppo. Vengono utilizzati durante lo scorrimento dei nodi.

Proprietà Scopo
nodoCorrente Restituisce il nodo selezionato corrente.
bambino Restituisce il figlio del nodo selezionato.
genitore Restituisce il genitore del nodo selezionato.

Passaggio 18: utilizzo di FKChain

Ora abbiamo una panoramica di FKChain, diamo un'occhiata alla sua applicazione e ai suoi meccanismi interni. Nel tuo progetto, crea una classe TestChain. Chiameremo un metodo di disegno per disegnare tutto ciò che è richiesto sprites sul nostro palco Ci sono complessivamente cinque sprite e una parentesi per indicare il nodo selezionato corrente.

 public function draw (): void b0 = new Sprite (); b0.graphics.beginFill (0); b0.graphics.drawCircle (0, 0, 15); b0.graphics.endFill (); addChild (b0); b1 = new Sprite (); b1.graphics.beginFill (0); b1.graphics.drawRect (-80, -10, 80, 20); b1.graphics.endFill (); addChild (b1); b2 = new Sprite (); b2.graphics.beginFill (0); b2.graphics.drawRect (-40, -10, 40, 20); b2.graphics.endFill (); addChild (b2); b3 = new Sprite (); b3.graphics.beginFill (0); b3.graphics.drawRect (-40, -10, 40, 20); b3.graphics.endFill (); addChild (b3); b4 = new Sprite (); b4.graphics.beginFill (0); b4.graphics.drawRect (-40, -10, 40, 20); b4.graphics.endFill (); addChild (b4); target = new Sprite (); target.graphics.lineStyle (3, 0xFF0000); target.graphics.moveTo (-15, -10); target.graphics.lineTo (-15, -15); target.graphics.lineTo (-10, -15); target.graphics.moveTo (15, -10); target.graphics.lineTo (15, -15); target.graphics.lineTo (10, -15); target.graphics.moveTo (15, 10); target.graphics.lineTo (15, 15); target.graphics.lineTo (10, 15); target.graphics.moveTo (-15, 10); target.graphics.lineTo (-15, 15); target.graphics.lineTo (-10, 15); addChild (target); 

Passaggio 19: avviare FKChain

 funzione pubblica initChain (): void c = new FKChain (b0); c.appendNode (b1); c.alterMagnitude (120); c.updateLimits (Math2.radianOf (-90), Math2.radianOf (45)); c.appendNode (b2); c.updateLimits (Math2.radianOf (-45), Math2.radianOf (90)); c.appendNode (b3); c.updateLimits (Math2.radianOf (0), Math2.radianOf (90)); c.appendNode (b4); // aggiorna la posizione di tutti i nodi b0.x = 250; b0.y = 300; c.selectNode (b1); c.setPosition (); // Posiziona il target sul nodo root inizialmente target.x = c.currentNode.x; target.y = c.currentNode.y; 

Innanzitutto, dobbiamo istanziare la classe FKChain chiamando il suo costruttore. Fornire un nodo radice nel costruttore. Un ulteriore esame della funzione di costruzione mostra due operazioni principali della funzione. Il primo è l'istanziazione di nodi, frecce, upperLimits e lowerLimits. I dati vengono forniti in queste variabili successivamente.

Si noti che il nodo radice ha una freccia associata. Non l'ho mostrato esplicitamente frecce sono sempre un membro in meno di nodi. Tuttavia, accettalo per ora come spiegherò sul suo utilizzo nelle sezioni successive. Le altre linee evidenziate sono solo riempitivi per garantire un facile indirizzamento sui vincoli. Infine, imposta il nodo attualmente selezionato su radice per ulteriore manipolazione.

 funzione pubblica FKChain (node0: Sprite) // istanza variabili nodi = nuovo vettore.; frecce = nuovo vettore.; upperLimits = new Vector.; lowerLimits = new Vector.; // introduce il nodo root nodes.push (node0); arrows.push (new Vector2D (1, 0)); lowerLimits.push (0); upperLimits.push (0); selectNode (node0); 

Passaggio 20: Aggiunta di nodi a FKChain

Dopo l'avvio, possiamo iniziare ad accodare i nodi all'istanza di FKChain. La creazione della freccia è astratta dagli utenti. Ho evidenziato la magnitudine iniziale e la limitazione dell'angolo di piega (entro -90 < angle < 90). These constraints are easily customised.

 funzione pubblica appendNode (node: Sprite): void nodes.push (node); var newArrow: Vector2D = new Vector2D (0, 0); newArrow.setMagnitude (60); arrows.push (newArrow); lowerLimits.push (Math2.radianOf (-90)); upperLimits.push (Math2.radianOf (90)); selectNode (nodo); 

Passaggio 21: riposizionamento dei nodi in FKChain

 // aggiorna la posizione di tutti i nodi b0.x = 250; b0.y = 300; c.selectNode (b0); c.setPosition (); // Posiziona il target sul nodo root inizialmente target.x = c.currentNode.x; target.y = c.currentNode.y;

Ora la posizione del nodo radice si trova nell'angolo in alto a sinistra dello stage. Sposteremo la posizione di b1 vicino al centro. Quindi dobbiamo riposizionare gli altri nodi in catena e impostare la parentesi di targeting sul nodo attualmente selezionato. Esaminiamo ulteriormente setPosition:

 funzione pubblica setPosition (): void var index: int = Math.max (1, selectedIndex); per (var i: int = index; i < nodes.length; i++)  //set position nodes[i].x = arrows[i].x + nodes[i - 1].x; nodes[i].y = arrows[i].y + nodes[i - 1].y; //set orientation nodes[i].rotation = Math2.degreeOf(arrows[i].getAngle());  

Questa funzione tenta di riposizionare e riorientare tutti i nodi a partire dal nodo attualmente selezionato. Ho impostato un limite all'indice (evidenziato) perché logicamente, mentre eseguiamo il riposizionamento relativo, il nodo radice non è influenzato da nessun genitore. Il nodo più alto nella gerarchia per eseguire il riposizionamento relativo è b1. Non importa se scrivi c.selectNode (B0) o c.selectNode (b1) prima c.setPosition () anche se influenzerà la posizione iniziale della parentesi di tragedia?


Passaggio 22: animazione di FKChain

 funzione pubblica TestChain () this.draw (); this.initChain (); stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDown); 

Ora è tempo di animare la catena. Assegneremo un ascoltatore all'evento tastiera.

 funzione privata keyDown (e: KeyboardEvent): void // scansiona la selezione del nodo if (e.keyCode == Keyboard.SPACE) if (c.currentNode == b4) c.selectNode (b1);  else c.selectNode (c.child);  else if (e.keyCode == Keyboard.UP) c.alterAngle (Math2.radianOf (-1 * step)); c.setPosition ();  else if (e.keyCode == Keyboard.DOWN) c.alterAngle (Math2.radianOf (step)); c.setPosition ();  target.x = c.currentNode.x; target.y = c.currentNode.y; 

Premendo il tasto spazio, la parentesi di mira scorrerà attraverso tutti i nodi, tranne il nodo radice, b0. Premendo il tasto freccia Su si ottiene un angolo delta negativo, -1 * passaggio; mentre il tasto freccia giù darà un angolo delta positivo, passo.

Ecco un esempio di TestChain.

Usa la barra spaziatrice e le frecce Su e Giù per controllarlo. Nota come i vincoli influenzano quanto lontano ogni nodo può "piegarsi".


Passo 23: Vincolo dell'angolo in FKChain

Abbiamo usato alterAngle () nell'ascoltatore. Ora lascia sezionare il funzionamento interno di esso.

 funzione pubblica alterAngle (ang: Number): void var index: int = Math.max (1, selectedIndex); // calc deviation tra la freccia precedente e la freccia corrente deviazione var: Number = arrows [index - 1] .angleBetween (arrows [index]); var future: Number = deviation + ang; // assicura ang entro limiti definiti se (future> upperLimits [index]) ang = upperLimits [index] - deviation;  altro se (futuro < lowerLimits[index])  ang = lowerLimits[index] - deviation;  //update relevant arrows for (var i:int = selectedIndex; i < arrows.length; i++)  arrows[i] = arrows[i].rotate(ang);  

Viene calcolata la deviazione della freccia del nodo corrente da quella del suo genitore, questo è il suo angolo corrente. L'angolo di input viene aggiunto all'angolo corrente per formare l'angolo futuro. Tutto va bene e questo valore dovrebbe essere prodotto. Tuttavia, vogliamo implementare un limite minimo e massimo in modo che l'angolo futuro venga controllato rispetto a questi valori e adeguato di conseguenza. Successivamente, emettiamo il valore per aggiornare tutte le frecce pertinenti.


Passaggio 24: miglioramento dell'effetto Choppy Animation

Potresti notare che l'animazione è irregolare. Si preme il tasto, e si spinge un po '. Possiamo migliorare un po 'mettendo in accelerazione e decelerazione della velocità angolare. Ma richiederà qualche ricablaggio di gestori di eventi. Si noti che il disegnare() e initChain () le funzioni sono riportate dai passi precedenti.

 funzione pubblica TestChain2 () this.draw (); this.initChain (); stage.addEventListener (KeyboardEvent.KEY_DOWN, keyDown); stage.addEventListener (KeyboardEvent.KEY_UP, keyUp); stage.addEventListener (Event.ENTER_FRAME, animato); 

Passo 25: Gestori di eventi della tastiera

Premendo i tasti direzionali, le bandierine verranno alternate vero. Rilasciando queste chiavi, i loro flag associati verranno alternati falso. Questi flag verranno catturati e valutati per ulteriori operazioni da parte di un onEnterFrame gestore di eventi.

 funzione privata keyDown (e: KeyboardEvent): void // scansiona la selezione del nodo if (e.keyCode == Keyboard.SPACE) if (c.currentNode == b4) c.selectNode (b0);  else c.selectNode (c.child);  else if (e.keyCode == Keyboard.UP) upFlag = true;  else if (e.keyCode == Keyboard.DOWN) downFlag = true;  else if (e.keyCode == Keyboard.LEFT) leftFlag = true;  else if (e.keyCode == Keyboard.RIGHT) rightFlag = true;  private function keyUp (e: KeyboardEvent): void if (e.keyCode == Keyboard.UP) upFlag = false;  else if (e.keyCode == Keyboard.DOWN) downFlag = false;  else if (e.keyCode == Keyboard.LEFT) leftFlag = false;  else if (e.keyCode == Keyboard.RIGHT) rightFlag = false; 

Passaggio 26: Variabili cinematiche

Di seguito sono riportate le variabili utilizzate per l'animazione della cinematica:

 private var angVelo: Number = 0; // current angular velocity private var maxVelo: Number = 5; // impostazione di un limite su velocità angolare private var angAcc: Number = 0.2; // incremento incrementale su velocità angolare private var angDec: Number = 0.8; // decay moltiplicatore su velocity angolare var var privato: Number = 5; // passi direzionali quando si sposta l'intera catena

Passaggio 27: Gestore eventi EnterFrame

Catturando le bandiere dall'evento tastiera, possiamo ulteriormente manipolare la cinematica della catena.

 funzione privata animate (e: Event): void // sposta l'intera catena if (c.currentNode == b0) if (upFlag) b0.y - = step else if (downFlag) b0.y + = passaggio if (leftFlag) b0.x - = step else if (rightFlag) b0.x + = step // regolazione dell'angolo else if (upFlag) angVelo - = angAcc; // impostazione limite su velocità angolare angVelo = Math.max (-1 * maxVelo, angVelo);  else if (downFlag) angVelo + = angAcc; // impostazione limite su velocità angolare angVelo = Math.min (maxVelo, angVelo);  else // decelera quando vengono rilasciate le chiavi angVelo * = angDec // imposta il valore sulla freccia del nodo selezionato. c.alterAngle (Math2.radianOf (angVelo));  // aggiorna la posizione c.setPosition (); target.x = c.currentNode.x; target.y = c.currentNode.y; 

Si noti che esiste una gestione leggermente diversa del nodo radice. Mentre viene selezionato, sposteremo l'intera catena su, giù, a sinistra oa destra. Mentre altri bambini vengono selezionati, noi pompiamo in velocità angolare, angVelo, su o giù all'interno della velocità minima e massima. Se le chiavi vengono rilasciate (quindi, tutte le bandiere vengono girate falso), la velocità attuale decelera. Per chiarire ulteriormente questo frammento sopra, leggi il mio post sulla cinematica lineare per avere un'idea del codice sopra.

Di seguito è riportato un esempio del lavoro finito:

Ancora una volta, usa la barra spaziatrice e i tasti freccia su e giù; questa volta, nota quanto è scorrevole il movimento.


Passaggio 28: preparazione delle risorse in Flash IDE

Ora che il lavoro di base per la base di codice è terminato, ci concentreremo sui lavori di cosmesi sul nostro progetto. Non sono un artista molto bravo, quindi sopporto il disegno del mio escavatore.

La grafica che ho disegnato viene convertita in MovieClip. Una cosa da tenere a mente è che il punto di registrazione della grafica deve essere posizionato verso la fine del segmento per le braccia e lo scoop. Ho evidenziato i punti di registrazione con un cerchio rosso per tutte le mie risorse negli screenshot qui sotto.





Ho chiamato questi MovieClip sopra Radice, ARM1, ARM2, e Notizia in anticipo rispettivamente

Un altro dettaglio è che è necessario premere Ctrl + L per aprire il pannello della libreria ed esportare queste risorse per Actionscript. Fare clic con il tasto destro del mouse, selezionare Concatenamento e inserire i dettagli come mostrato nelle immagini sottostanti.




Passaggio 29: esportazione di asset da Flash IDE

Una volta completate tutte le risorse grafiche, pubblicarle in formato SWC per essere importate correttamente in FlashDevelop. Sto usando Flash CS3. Premi Ctrl + Maiusc + F12 per visualizzare le impostazioni di pubblicazione. Seleziona la scheda Flash e attiva Esporta SWC. Quindi premi Pubblica.



Passaggio 30: Importazione di asset in FlashDevelop

Copia il nuovo file (.swc) nella cartella lib del tuo progetto.


Ora che lo hai nel tuo progetto, devi comunque includere nella libreria. Fai clic con il tasto destro sul tuo file .swc e seleziona "Aggiungi alla libreria".



Passaggio 31: controllare le risorse

Espandi l'elenco come mostrato nell'immagine sottostante per verificare i nomi delle variabili. Ho usato i seguenti nomi ARM1, ARM2, Radice e Notizia in anticipo. Questi sono i nomi di classe associati a tali grafici. Li useremo più tardi.



Passaggio 32: Sostituzione di grafica con risorse

Finalmente arriviamo all'ultima tappa di questo tutorial. Sostituiremo l'esistente disegnare() metodo con questo nuovo, drawAssets ().

 funzione privata drawAssets (): void rootNode = new Root (); arm1 = new Arm1 (); arm2 = new Arm2 (); scoop = new Scoop (); addChild (ARM1); addChild (rootNode); addChild (paletta); addChild (ARM2); target = new Sprite (); target.graphics.lineStyle (3, 0xFF0000); target.graphics.moveTo (-15, -10); target.graphics.lineTo (-15, -15); target.graphics.lineTo (-10, -15); target.graphics.moveTo (15, -10); target.graphics.lineTo (15, -15); target.graphics.lineTo (10, -15); target.graphics.moveTo (15, 10); target.graphics.lineTo (15, 15); target.graphics.lineTo (10, 15); target.graphics.moveTo (-15, 10); target.graphics.lineTo (-15, 15); target.graphics.lineTo (-10, 15); addChild (target); 

Passaggio 33: regolare i vincoli di risorse

In questo momento, se apri la tua applicazione, potresti vedere un gruppo di disegni nell'angolo in alto a sinistra o l'intero braccio e il corpo dell'escavatore allineati in modo divertente. Regolare opportunamente i vincoli di ampiezza e le limitazioni angolari sui join. Ho incluso il mio come di seguito.

 funzione privata initChain (): void c = new FKChain (rootNode); c.appendNode (ARM1); c.alterMagnitude (260); c.updateLimits (Math2.radianOf (-45), Math2.radianOf (45)); c.appendNode (ARM2); c.alterMagnitude (100); c.updateLimits (Math2.radianOf (0), Math2.radianOf (90)); c.appendNode (paletta); c.alterMagnitude (60); c.updateLimits (Math2.radianOf (45), Math2.radianOf (135)); // aggiorna la posizione di tutti i nodi rootNode.x = 250; rootNode.y = 300; c.selectNode (rootNode); c.setPosition (); // Posiziona il target sul nodo root inizialmente target.x = c.currentNode.x; target.y = c.currentNode.y; 

Passaggio 34: spostamento orizzontale

Ulteriori modifiche al controllo da tastiera del nodo radice, ho eliminato il movimento verticale dell'intera catena in modo che l'escavatore (radice) si muova solo in modo orizzontale. Il frammento di seguito è inserito nel Event.ENTER_FRAME gestore

 if (c.currentNode == rootNode) if (leftFlag) rootNode.x - = step else if (rightFlag) rootNode.x + = step

Passo 35: Gioca con il braccio

Ogni singolo adeguamento alla base del codice è fatto. Certo, puoi personalizzarlo come vuoi. Per ora, scorri i nodi usando il tasto Spazio. Per ogni nodo, gioca con i tasti direzionali per vedere l'escavatore che si muove su e giù.


Conclusione

Questo è tutto per questa volta. Spero che il file di classe che ho messo insieme aiuti ad alleggerire la cinematica diretta da qualche parte nella simulazione e nei giochi. Grazie per aver letto e lasciato alcuni commenti se hai trovato un difetto in qualcosa.