Thyme: il linguaggio degli script di Algodoo
https://wiki.zum.de/wiki/GadApedia/Thyme_algodoo_english
da mettere in update:
(e)=>{
m = area * density;
vx = vel([0]);
vy = vel([1]);
v = math.sqrt(vx * vx + vy * vy);
v = v * 2;
K = 0.5 * m * v * v;
text = "\n\t x=" + pos([0]) + " m\n\t y=" + pos([1]) + " m\n\t |v|=" + v + " m/s\n\t vx=" + vx + " m/s\n\t vy=" + vy + " m/s" + "\n\tm=" + m + " kg" + "\n\tK=" + K + " J"
}
Timo algodoo ITALIANO
Avvio di Thyme
Ci è stato chiesto di fornire alcune wiki utilizzabili di Timo nel forum Algodoo - Forum11139 .
Questo è un lavoro fatto un po' in fretta, quindi per favore non aspettarti troppo, anche se accoglierò tue richieste di domande specifiche in questo thread del forum.
Innanzitutto,
avvia Algodoo,
crea un oggetto, come un cerchio,
fai clic con il pulsante destro del mouse su di esso,
scegli l'ultima riga (scriptmenu) e il menu degli script si apre:
vedi molte proprietà di quel cerchio
esempio:
posizione pos,
velocità vel
posizione angolare angle
velocità angolare angvel,
color
density
% di energia cinetica restituita al rimbalzo (coeff. elastico) restitution
raggio (radius)
forza attrattività attraction,
coeff. di attrito friction,
indice di rifrazione refractiveIndex,
riflettività reflectiveness,
etc...
Tutti questi valori possono essere cambiati tramite lo SCRIPT !!!
Inoltre, puoi codificare/controllare sotto quali condizioni questi valori devono essere modificati.
Come scrivere uno SCRIPT
Esistono diversi modi per scrivere uno script, ma per semplicità facciamo un esempio solo per il metodo più semplice.
Altri metodi che si ottengono:
usando l'angolo in alto a sinistra del menu di script ,
usando il tasto funzione F10 per aprire la console
ackerando il file .phz. NOTA: i file .phz
si possono rinominare in .zip (lasciare i suffissi dei file visibili in windows) , in questo caso si possono facilmente spacchettare ed editare
lanciando questi .zip con Algodoo funzionano!
qui un viewer online: https://filext.com/file-extension/PHZ
( in questo caso moll.phz)
che (nel mac si trova in Macintosh HD ▸ Users ▸ giovanninicco ▸ Library ▸ Application Support ▸ Algodoo ▸ scenes
Quindi, facciamo un cerchio pulsante (che respira) fuori dal semplice cerchio:
modifichiamo il campo update nel menu di script,
per ruotare i laser: modificare il campo update
(e)=>{ radius = 0.2 + 0.1 * sin(sim.time) }
e inizia la simulazione con un clic sul triangolo verde.
Il cerchio inspira e diventa più grande, quindi espira e diventa più piccolo, quindi il processo si ripete ancora e ancora.
Come ha funzionato? Il tempo trascorso nella simulazione è contenuto nella variabile sim.time e la funzione matematica sin lo converte in un valore alternato uniformemente tra -1 e +1.
Infine, il raggio cambia in questo modo tra 0,1 e 0,3, poiché ho aggiunto l'offset di 0,2 per assicurarmi che il raggio sia sempre positivo.
Esercizio 1: attrarre e respingere
Prova da solo a fare in modo che altri oggetti vengano attratti o respinti dal tuo cerchio. Suggerimento:
disattiva la gravità facendo clic sulla mela rossa,
fissa il cerchio con Fixation (F) (il chiodo )
e aggiungi altri piccoli cerchi.
Aggiungi al tuo script esistente ,un punto e virgola ; (due punti) e
nella riga successiva attraction = sin (sim.time),
quindi l' aggiornamento legge quindi:
(e) => { radius = 0.2 + 0.1 * sin(sim.time); attraction = sin(sim.time) }
Per evitare che le palline fuggano fuori dalla portata, puoi aggiungere alcune barriere intorno alla tua area visibile della scena.
Esercizio2: cambia colore
Prova a cambiare il colore con (attenzione: continua a modificare il campo update
(e)=>{ radius = 0.2 + 0.1 * sin(sim.time); attraction = sin(sim.time); color = [0.5 + 0.5 * sin(sim.time), 0.0, 0.5 - 0.5 * sin(sim.time), 1] }
Come funziona? il colore è costituito da [rosso, verde, blu, visibilità].
parametri di color: [R,G,B,T] cioè rosso, verde, blu, visibilità (nota: un buon metodo per far diventare invisibile qualcosa)
Se la visibilità è 0, è traslucida, qui è sempre 1.
Il valore verde rimane sempre 0, ma rosso e blu variano rispettivamente da 0 a 1 e da 1 a 0.
Attenzione ai punto e virgola alla fine di ogni istruzione.
Se dando invido anziché andare a capo si chiude la finestrella, allora mettere il punto e virgola e NON ANDARE A CAPO ma scrivere tutto di seguito
Interagire con uno script
onClick è attivato se l'utente lo fa scorrere con il mouse.
questo comando applicato ad un oggetto, quando LO si clicca, lo fa diventare (per sempre) blu.
onSpawn viene eseguito al processo di creazione dell'intera scena all'avvio, al momento 0.
Questo comando rende nero un oggetto appena si è al momento 0 della simulazione
onDie viene eseguito quando l'oggetto viene eliminato, la sua ultima azione, come un testamento, l'ultima volontà.
onCollide ogni volta che un altro oggetto colpisce questo oggetto.
creo un oggetto che si muove di moto browniano:
(e)=>{
vel=[rand.normal,rand.normal]
}
Lo clono un po' di volte
Ne prendo uno lo modifico di colore nero e dico che quando tocca un altro lui diventa blu e l'altro diventa nero
(nota: il comportamento dell'altro non sarà modificato)
Gli eventi (e) che coinvolgono due enti come, esempi,o una collisione hanno la seguente struttura:
per accedere ai valori dovrai fare
e.this.property per ottenere la proprietà dello stesso oggetto in cui viene eseguito lo script e
e.other.property per ottenere quelli del partner di interazione.
(e)=>{
e.this.color = [0, 0, 1];
e.other.color = [1, 1, 1]
}
download the code
Azioni in differita: come far partire un oggetto o modificarne le caratteristiche in tempi o luoghi diversi:
Annerire e far partire dopo 5 secondi:
codice per partenza posticipata di un razzo
(e)=>{
t0 = 3;
t = sim.time;
v = 0.5;
a = 3;
({t < t0}) ? {
color = [1, 1, 1]
} : {
color = [0, 0, 0];
pos = [0, 0.5 + v * (t - t0) + 0.5 * a * (t - t0) * (t - t0)]
}
}
onHitByLaser quando un laser colpisce l'oggetto.
----------
Fai le cose su ogni passaggio della simulazione
Penso che ci siano diversi passaggi di simulazione fino a quando non si verifica un aggiornamento dell'immagine. quindi se vuoi assicurarti di eseguire lo script ad ogni piccolo passaggio, usa poststep.
Le tue variabili e funzioni
Questi sono particolarmente utili per controllare e stabilire relazioni e reazioni, che non sono integrate. Le troverai nel 99% dei modelli di algodoo che usano il timo.
scene.my. namespace
Per rendere variabili, che hanno lo stesso valore in tutti gli oggetti della scena, è necessario renderle "globali". Dichiararli una volta dopo aver premuto F10 per accedere alla console digitando ad esempio
sence.my.a3
e se vuoi prenderne il valore, ad es. per la forza di un truster, allora nel thruster-script scrivi nella sezione postscript del thruster
(e)=>{ force = scene.my.a3 }
Se hai un altro propulsore da qualche altra parte e vuoi avere la doppia forza del tuo primo propulsore, puoi entrare nel suo poscritto
(e) => { force = 2 * scene.my.a3 }
Non solo le variabili possono essere dichiarate ma anche le funzioni, come viene fatto nella sezione "Loop per i = da 1 a 10 do ... end" di seguito.
variabili e funzioni locali
Perché ha senso che gli oggetti abbiano le loro variabili, invece di usare solo scene.my ....? Per capirlo, descriverò in dettaglio una funzionalità, dove questo è molto utile: pensa a un paraurti nel flipper, come nella scena di Xray 86013. Dovrebbe spingere via la palla, che la colpisce, quindi la sua restituzione deve essere 2.5, quindi scappa con una velocità 2,5 volte maggiore dopo averlo colpito. Ma il paraurti ha bisogno di un certo tempo (diciamo: 0,5 secondi) per ricaricare la sua potenza fino a quando non è pronto per il prossimo utilizzo, e mentre sta caricando, non dovrebbe urtare duramente, ma deve solo riflettere, quindi la sua restituzione deve essere 1,0 in quel Astuccio. Quindi la struttura logica sarebbe:
il paraurti è pronto per urtare? Se sì, allora {restituzione = 2.5; } In caso contrario, {restitution = 1.0}
Il tempo, in cui si è verificato l'ultimo bump, deve essere salvato, quindi puoi confrontarlo con il tempo reale "sim.time" in modo da impostare la variabile locale _timer = sim.time in caso di bump. Nota che c'è un "trattino basso", un "_" all'inizio di questa variabile, che lo rende permanente anche se finisci l'intera scena e la ricarichi in seguito. Per decidere ora se il paraurti è pronto, basta confrontare il tempo effettivo con il _timer +0.5 come in
sim.time> _timer + 0,5
e se è vero, fai il bernoccolo, altrimenti no. Fin qui tutto bene ... potresti fare tutto questo anche con una variabile globale scene.my.timer. MA, e qui arriva l'utilità delle variabili locali nella sua massima estensione: non desideri un solo paraurti nella tua scena, ma 8 paraurti. Quindi, dopo aver codificato lo script per il paraurti originale, si desidera copiare l'intero oggetto paraurti e crearne solo 7 copie. Ma nota che ogni paraurti ha bisogno del suo tempo di ricarica ora, proprio come nella vita reale. Quindi se lo fai con variabili globali, devi cambiare in ogni bumper il nome delle variabili, ad esempio scene.my.timer2 per il secondo paraurti, scene.my.timer3 per il terzo paraurti, ecc. Ecc. Ad ogni utilizzo di la variabile. Funzionerebbe anche questo, ma è MOLTO FUNZIONANTE. Invece, se usi invece la variabile locale _timer, puoi semplicemente copiare e incollare e non è necessario modificare alcuno script, i diversi paraurti avranno quindi tutte le diverse variabili locali disponibili con valori diversi allo stesso tempo automaticamente! Lo script completo per questo tempo di ricarica del paraurti è elencato di seguito nella sezione "Strutture di controllo".
Non solo le variabili possono essere locali, ma anche funzioni, che è stato utilizzato nella scena noonans 124016, dove ha dichiarato
_abs: = (x) => {x <0? {-1.0 * x}: {x}}
avere f (x) = | x | = abs (x) disponibile nel suo copione a cerniera dove lo usava più spesso, per ottenere numeri positivi.
Distruggi un oggetto
Se imposti la densità di un oggetto su NaN (Not a Number), svanisce! Questo non è un codice pulito, poiché non libererà lo spazio di archiviazione, ma funzionerà e non distruggerai e creerai più di 1000 oggetti, non dovrai preoccuparti affatto dello spazio di archiviazione. Il codice pulito verrà descritto nei metodi sofisticati di entityByGeomID.
Crea un nuovo oggetto
Se si inserisce
(e) => {Scene.addCircle ({radius: = 0.02; vel: = [2, 2]})}
nella sezione poststep, questo creerà già un gruppo infinito di cerchi, che si diffondono dall'origine e si spostano verso la direzione in alto a destra. Poiché non viene specificato alcun colore, avranno tutti colori piacevoli.
Anche altre geometrie possono essere create in questo modo. Kilinich crea una fontana d'acqua codificando il post come
sim.tick% 2 == 0? { v: = scene.addbox ({ pos: = [0, 1]; vel: = [0, 30]; size: = [0.3, 1]; angle: = rand.normal / 50 }); v.liquify }: {}
e ho aggiunto un killer-plain, quindi non ci sarà troppa acqua, poiché troppa acqua sta rallentando la scena.
Strutture di controllo
se condizione, allora ... altro ...
La struttura per questo è
{} ? {}: {}
più precisamente
{Condizione}? {fai questo se vero} :{altrimenti fai questo}
Non ci deve essere un comando nel blocco allora o nel blocco else; se non si deve fare nulla, lasciarlo vuoto.
Come condizione puoi persino usare una variabile vera o falsa, correggimi se sbaglio qui.
Un esempio: cambia il colore del cerchio in blu, se è sul lato destro (la posizione x è maggiore di 0), altrimenti lo imposta in rosso.
La regione nera dietro l' aggiornamento dovrebbe essere:
(e) => { {Pos (0)> = 0} {color = [0,0,1,1]}: {color = [1,0,0,1]} }
Un esempio di come liquefare un oggetto se la sua altezza è superiore a 3, puoi vedere nella spiegazione della liquefazione sotto.
L'esempio del paraurti Xrays (vedere la sezione "Variabili e funzioni locali" sopra) è qui:
sim.time> _timer + 0.5? { restitution = 2.5; _timer = sim.time }: { restituzione = 1.0 }
I cicli per i = da 1 a 10 do ... end
Per il ciclo per l'intero n1, n2 con n1 <n2 Kilinich ha creato un bel script che legge
scene.my.xFor = (n1, n2, code) => { n2> n1? { m: = (n1 + n2) / 2; scene.my.xFor (n1, m, code); scene.my.xPer (m + 1, n2, code) }: {code (n1)} }
Quindi apri la console con F10, copia il codice sopra, inseriscilo nella console, premi invio e poi esegui anche nella console
scene.my.xfor (0,5, (i) => {print (i)})
che quindi stampa i numeri da 0 a 5 nella console.
Ma puoi anche usarlo per la creazione molto accurata di cose su determinate proprietà, ad esempio se vuoi avere 50 laser paralleli, puoi semplicemente farlo
scene.my.xfor (0,49, (i) => {scene.addlaserpen ({pos = [0.0,0.1 * i]})})
Si può dare loro il colore e la direzione definiti, ecc. Ma l'ho saltato per semplicità, quindi il loro colore verrà fuori in modo casuale.
Liquifica un oggetto
Se un oggetto colpisce il tuo cerchio, l'altro oggetto dovrebbe essere liquefatto. Questo viene fatto dal piccolo script: tra parentesi graffe di onCollide nel menu di script, digitare: e.other.liquify in modo che la regione nera dietro onCollide legga ora:
(e) => { e.other.liquify }
È anche piacevole liquefare un oggetto, se soddisfa una certa condizione, come se l'altezza sopra il pavimento sia maggiore di 3, si trasformerà in pioggia. La regione nera dietro l' aggiornamento dovrebbe essere:
(e) => { {E.this.pos (1)> = 3} {} e.this.liquify:? {} }
Qui, usiamo il fatto che pos (0) è il valore x della posizione e pos (1) il valore y della posizione.
Usando il laser
Se un oggetto, colpito da un laser, deve trasformare il suo colore nel colore del laser, quindi inserirlo nel menu di script del laser nella sezione "onLaserHit"
e.geom.color = e.this.color
causa e.geom rimane per il geomentry "hit", e e.this è per il laser stesso.
Al contrario: se vuoi che il laser diventi del colore dell'oggetto che il laser ha colpito per ultimo, quindi inseriscilo nel menu di script del laser
e.this.color = e.geom.color
Per evitare che il laser colpisca più volte o un oggetto lontano, impostare il suo raggio d'azione su un determinato valore, ad esempio su 1.
Usando il mouse
app.mousePos(0) per la x della posizione del mouse
app.mousePos(1) per la y della posizione del mouse
mouse_left pulsante sinistro
mouse_middle
mouse_right
mouse_wheel_up
mouse_wheel_down
Hack the .phz
Il file .phz è solo un file zip rinominato. Quindi rinominalo in .zip e sarai in grado di decomprimerlo con un normale programma di decompressione. Dopo aver decompresso, vedrai alcune delle sue risorse, come trame usate e causa la sua sceneggiatura con l'estensione .phn, probabilmente chiamata scene.phn, così come il thumb.png e checksums.txt.
Per aprire scene.phn per modificarlo, prima creane una copia e rinominalo in scene.txt. Quindi utilizzare un programma gratuito come Notepad ++ per aprire questo file e lavorarci sopra. Al termine del tuo lavoro, ti consiglio di salvarlo con un nuovo nome, dì myscene.phn e fai doppio clic su di esso, in modo che venga aperto con algodoo.
Salva quindi di nuovo questa scena di algodoo e avrai la tua scena modificata completamente funzionante.
Metodi sofisticati
entityByGeomID
Scrivi su file, leggi da file
System.WriteToFile ("myfile.txt, variabile +"; \ n ")
scriverà (aggiungi!) il valore della variabile in un file di testo esistente e restituirà il valore "true" se funzionava e se non funzionava (ad esempio se non esiste un file di questo tipo) allora "false".
Dove si trova il file? Sul mio PC è dentro
Bibliotheken \ Dokumente \ Algodoo in inglese probabilmente \ libraries \ documenti \ algodoo che è una cartella che viene creata da algodoo stesso, ogni volta che viene installata. Ad esempio, nella sua sottodirectory si trova la cartella "scene" in cui di solito vengono memorizzate le scene create dall'utente.
System.ReadWholeFile e string.Split devono essere commentati anche in seguito.
textureMatrix
Se vuoi mettere in un quadrato una trama, come "_pasted_0034.png", apri lo scriptmenu e nella casella nera sotto "trama" inserisci il nome dell'immagine con l'estensione del file e con le virgolette. Finora, abbastanza facile. Ma non è un argomento facile, se vuoi cambiare la dimensione di una trama in un rettangolo o in un cerchio. L'ho provato per qualche ora, fino a quando non ho ottenuto dei buoni risultati, come nella scena 85564.
esempio per trame ridimensionate
dove ho usato
textureMatrix = [1 / size (0), 0, 0.5, 0, 1 / size (1), 0.5, 0, 0, 1]
nello script di aggiornamento.
puoi persino eseguire un video di immagini in sequenza usando la trama, come ho fatto in "video di texture2" (scena 122754). Puoi anche tagliare l'oggetto a pezzi, il video rimane ancora attivo, il che è meraviglioso da vedere!
Una vera modalità di gioco
Per eseguire missioni e raggiungere obiettivi o allegria, è fondamentale che le condizioni delle scene non vengano distrutte o ingannate.
Il trucco di homieeee è implementare uno script in un oggetto, che diventa invisibile intangibile (collideset = 0) e che imposta in modo permanente sim.running = true e App.GUI.playMode = true Se si desidera selezionare lo strumento di trascinamento con un una certa forza massima, in modo che l'utente possa trascinare solo cose mobili con il mouse, quindi
Tools.DragTool.strength = 100000; Tools.DragTool.maxForce = 10000; Tools.DragTool.SelectTool;
potrebbe essere aggiunto a questo oggetto-script.
Algodoo Mod System
È possibile contattare i programmi in esecuzione all'esterno con l'aiuto dei comandi di lettura e scrittura su file. Ogni volta che viene scritto qualcosa di nuovo, un programma esterno lo controlla ed esegue alcune azioni all'esterno, restituendo un file modificato, che viene poi letto da algodoo e che può eseguire algodoo-azioni!
Una prima bella applicazione è quella di riprodurre musica e suoni ogni volta che si scontrano oggetti con una determinata sceneggiatura.
In questo modo puoi creare i tuoi strumenti.
Vedi il forum per ulteriori dettagli.
Elenco di variabili evento
Questo elenco è stato scoperto da FRA32 e pubblicato sull'Algodoo-Forum.
Poststep: float dt - Il tempo trascorso dall'ultimo fotogramma della scena
Aggiornamento: float dt - Il tempo trascorso dall'ultimo aggiornamento;
OnCollide: array normal: L'array normale di collisione pos: Il suono float del punto di collisione Guadagno: Appare in scala con la forza di impatto della collisione.
onClick: array pos: posizione del cursore int clickCount: quanti clic si sono verificati in breve successione bool gestita: ancora incerto su questo
OnKey: bool premuto: True quando è stato premuto un tasto, false quando è stato rilasciato stringa keyCode: il nome della chiave trattenuta string keyChar: il simbolo di testo creato dalla chiave (se non esiste alcun simbolo, ovvero i tasti freccia, questo valore non esiste o) bool gestito: incerto su questo
OnLaserHit: array normal: normal of hit surface array pos: Point of hit
OnHitByLaser: identico a sopra
OnDie: nessun valore aggiuntivo
OnSpawn: nessun valore aggiuntivo
(e.this, e.other, e.geom ed e.laser sono esclusi)
http://www.algodoo.com/forum/viewtopic.php?f=13&t=83&sid=405aa3eb4ee574555278f376d6b0688f