Thyme: il linguaggio degli script di Algodoo

MANUALI: https://docs.google.com/document/d/17_CPg-QtU3qWp4Q7eD2csOWNFZ4QiGXfBZmCOxFmy4M/edit#heading=h.cgnrloiq2xz5

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

Diese Seite gehört zur GadApedia .

... altro GadApedia-Seiten

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:

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:

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