Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - Realizzazione di uno script
Forum - C# / VB.NET - Realizzazione di uno script

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
Thejuster (Member)
Guru^2


Messaggi: 1704
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 10:55
Martedì, 24/05/2016
Buongiorno ragazzi, chiedo aiuto per riuscire a capire come far funzionare
egregiamente un mio metodo.

In Mire Engine ho realizzato questo script di esempio per i futuri scripter del motore.

Codice sorgente - presumibilmente C# / VB.NET

  1. --> #########################################################
  2. --> # MIRE ENGINE Script -  Dialog Example                  #
  3. --> #########################################################
  4. --> # Questo script mostra come creare dinamicamente        #
  5. --> # In discorso a dialighi tramite script                 #
  6. --> # Tutta via richiede un piccolo accorgimento            #
  7. --> # Per poter gestire i tasti, richiede che quando        #
  8. --> # Viene interpellato il metodo Update gli sia passato   #
  9. --> # Tra parentesi il gestore dei tasti ovvero key         #
  10. --> #########################################################
  11. --> # BY: MakigItali Dev Team                              #
  12. --> #########################################################
  13.  
  14.  
  15.  
  16. Dialog_Example =
  17. {
  18. dialogs = false,
  19. dialog_count = 0,
  20. dialog_max = 0,
  21. keystate = ""
  22. }
  23.  
  24.  
  25. function Dialog_Example.Update(key)
  26.  
  27. ----------------------------------------------------
  28. -- # Chiamata dell'evento Example
  29. ----------------------------------------------------
  30.    
  31.     -- Se premo F1 apri il dialogo
  32.     if key == "f1" then
  33.         Dialog_Example.dialogs = true
  34.         System_Audio.Accept()
  35.     end
  36.    
  37.  
  38.     -- Se il dialogo è attivo richiamo l'evento
  39.     if Dialog_Example.dialogs == true then
  40.  
  41.         Dialog_Example.Show()
  42.  
  43.     end
  44.  
  45.    
  46. -------------------------------------------------------
  47.  
  48.  
  49.  
  50. end
  51.  
  52.  
  53.  
  54. function Dialog_Example.Show()
  55. ----------------------------------------------------
  56. -- # Prova di un dialogo
  57. ----------------------------------------------------
  58.  
  59.     -- Gestore dei tasti
  60.     Dialog_Example.keystate = Keyboard_State.Get_Key()
  61.    
  62.  
  63.    
  64.     --Se il dialogo è attivato, mostra il messaggio
  65.     if Dialog_Example.dialogs == true then
  66.    
  67.         if Dialog_Example.dialog_count == 0 then          
  68.             Window.Dialog("Benvenuto Giocatore\nQuesto e' un dialogo di esempio")
  69.             --call_event("event_0") --> Richiamo un evento dal database
  70.         end
  71.        
  72.        
  73.         if Dialog_Example.dialog_count == 1 then
  74.             Window.Dialog("Questo script di esempio illustra come creare dialoghi\nManualmente da script")
  75.         end
  76.        
  77.         if Dialog_Example.dialog_count == 2 then
  78.             Window.Dialog("Puoi trovare questo esempio nella cartella Script/Example/Dialog_Example.lua")
  79.         end
  80.        
  81.         if Dialog_Example.dialog_count == 3 then
  82.            
  83.         Window.Dialog("Per disattivare questo script\nVai in Scene_Game.lua e commenta o elimina la riga contenente:\nDialog_Example.Update(key)")
  84.         end
  85.        
  86.        
  87.     end
  88.    
  89.    
  90.  
  91.     -- Quando premo ENTER mostra il successivo dialogo
  92.     if Dialog_Example.keystate == "enter" then
  93.         System_Audio.Cursor()
  94.         Dialog_Example.dialog_count = Dialog_Example.dialog_count + 1
  95.     end
  96.  
  97.    
  98.    
  99.     -- Quando i dialoghi sono terminati, disattiva il dialogo
  100.     if Dialog_Example.dialog_count == 4 then
  101.         Dialog_Example.dialogs = false -- Disattivo il Dialogo
  102.         Dialog_Example.dialog_count = 0 --Resetto il conteggio
  103.         System_Audio.Cancel()
  104.     end
  105.  
  106.  
  107.    
  108.    
  109.  end




Questo script funziona benissimo, ma sto trovando problemi nel ricrearlo dinamicamente.
Vi spiego.

Nel programma, c'è la gestione degli eventi.
Dove si può creare un evento che successivamente genererà uno script.

Questa screen illustra come viene parsato il codice lua
ed illustrato in una listbox.

http://www.makerando.com/forum/uploads/imgs/pre_1463995611 ...



L'idea che mi è venuta, e stata quella di creare un nuovo metodo nell'sdk
anziché interpellare uno script in lua.


Il metodo che realizzato è questo

Codice sorgente - presumibilmente C++

  1. /// <summary>
  2.         /// Mostra un messaggio di gioco
  3.         /// </summary>
  4.         /// <param name="text">testo del messaggio</param>
  5.         ///
  6.  
  7. //Test
  8. bool dialogo_letto = false;
  9.        
  10.         public void Dialog(string text)
  11.         {
  12.  
  13.           Ciclo:
  14.  
  15.                 //Se il dialogo è normale
  16.                 if (MsgType == _msgtype.Normal)
  17.                 {
  18.                     if (MsgPosition == _msgposition.Down)
  19.                     {
  20.                         system_window(0, graphics.PreferredBackBufferHeight - 150, graphics.PreferredBackBufferWidth, 150);
  21.                     }
  22.  
  23.                     if (MsgPosition == _msgposition.Middle)
  24.                     {
  25.                         system_window(0, graphics.PreferredBackBufferHeight / 3, graphics.PreferredBackBufferWidth, 150);
  26.                     }
  27.  
  28.                     if (MsgPosition == _msgposition.Up)
  29.                     {
  30.                         system_window(0, 0, graphics.PreferredBackBufferWidth, 150);
  31.  
  32.                     }
  33.  
  34.                 }
  35.  
  36.                 if (MsgPosition == _msgposition.Down)
  37.                 {
  38.                     draw_text(10, graphics.PreferredBackBufferHeight - 140, text);
  39.                 }
  40.  
  41.  
  42.                 if (MsgPosition == _msgposition.Middle)
  43.                 {
  44.                     draw_text(10, graphics.PreferredBackBufferHeight / 3 + 10, text);
  45.                 }
  46.  
  47.  
  48.                 if (MsgPosition == _msgposition.Up)
  49.                 {
  50.                     draw_text(10, 10, text);
  51.                 }
  52.          
  53.          if(Input.Keyboard.IsKeyDown(Keys.Enter))
  54.          {
  55.  
  56.             //Se premo invio, il dialogo è stato letto
  57.            dialogo_letto = true;
  58.                
  59.           }
  60.          
  61.      
  62.       if(!dialogo_letto)
  63.       {
  64.          goto Ciclo;
  65.        }
  66.  
  67.  
  68.  
  69.         }




Il problema principale è che il motore viene congelato.
Non mostrando il testo cosa molto strana.

E successivamente mi dà un errore al Draw.
Perché quando la scena passa in mano agli script, gli viene passato anche il controllo del Draw.

Avete un idea su come potrei fare un qualcosa del genere?

L'obiettivo sarebbe di trasformare tutto quello script in LUA in alto
in una sola chiamata.

esempio:

Dialog("Hello World")

Poi quando si preme enter, il programma riprende il suo funzionamento corretto.




PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1452
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 17:11
Martedì, 24/05/2016
Se non vuoi che il motore si "blocchi" devi usare i thread.

Comunque non ho capito cosa vuoi fare....

Ultima modifica effettuata da TheDarkJuster il 24/05/2016 alle 17:12
PM Quote
Avatar
Thejuster (Member)
Guru^2


Messaggi: 1704
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 20:29
Martedì, 24/05/2016
Hai perfettamente ragione scusami,
sono stato poco chiaro.
(Purtroppo ormai mi conoscete è un mio vizio descrivere problemi velocemente)

Lo spiego in maniera più dettagliata.

Nell'editor di livelli, l'utente ha la possibilità sia di scriptare che di creare eventi.
Gli eventi sono in pratica frammenti di codice inline.

ovvero in una sola righa, esegue un comando

guardando questa screen di prima te ne accorgi di ciò che dico

http://www.makerando.com/forum/uploads/imgs/pre_1463995611 ...

guarda quella in basso non quella in alto.
l'utente vedrà la listbox non il codice generato.

esempio:
facendo doppio click sull'elemento  " <> " in fondo
si apre una lista di scelte e appaiono pulsanti che cliccandoci sopra si aprono schermate per configurare un azione

in questo esempio c'è Message: bla bla bla

l'utente inserirà in una textbox il messaggio da visualizzare,
mentre in background viene generato il codice in una sola linea
che sarebbe

Dialog("Testo inserito dall'utente")

mentre l'utente visualizzerà

Message: Testo inserito dall'utente

insomma tutto questo per rendere più user-friendly la cosa.

ora lo script in lua che ho postato prima, e il funzionamento corretto che dovrebbe avere lo script.

però non posso generare quel macello, ho bisogno di fare tutto solo su una righa di codice.
Quindi ho registrato la funzione Dialog("")

che mi và a chiamare quel void in C#

Quello che succede, è che si frezza il programma non mostrato il testo.

Quello che dovrebbe fare,
è mostrare il dialogo che sarebbe questo.

http://s33.postimg.org/lpc1xy2pr/Cattura.jpg

Questo è l'ho ottenuto tramite quello script di sopra.
mentre vorrei usare un semplice void con una sola chiamata per avere tutto questo.




PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1452
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 21:02
Martedì, 24/05/2016
Ok, se quello script funziona, solo quando è inline, e non quando è incluso in una funzione registrata allora:
1) lo script fa riferimento a cose che sono fuori dalla funzione
2) la registrazione non è andata a buon fine

Io credo che il problema sia il numero 1, ma hai qualche modo per assicurarti che non sia il 2?

Comunque:
Codice sorgente - presumibilmente C# / VB.NET

  1. /// <summary>
  2.         /// Mostra un messaggio di gioco
  3.         /// </summary>
  4.         /// <param name="text">testo del messaggio</param>
  5.         ///
  6.  
  7. //Test
  8.         public void Dialog(string text)
  9.         {
  10.                 //Se il dialogo è normale
  11.                 if (MsgType == _msgtype.Normal)
  12.                 {
  13.                     if (MsgPosition == _msgposition.Down)
  14.                     {
  15.                         system_window(0, graphics.PreferredBackBufferHeight - 150, graphics.PreferredBackBufferWidth, 150);
  16.                     }
  17.  
  18.                     if (MsgPosition == _msgposition.Middle)
  19.                     {
  20.                         system_window(0, graphics.PreferredBackBufferHeight / 3, graphics.PreferredBackBufferWidth, 150);
  21.                     }
  22.  
  23.                     if (MsgPosition == _msgposition.Up)
  24.                     {
  25.                         system_window(0, 0, graphics.PreferredBackBufferWidth, 150);
  26.  
  27.                     }
  28.  
  29.                 }
  30.  
  31.                 switch (MsgPosition) {
  32.                     case _msgposition.Down:
  33.                         draw_text(10, graphics.PreferredBackBufferHeight - 140, text);
  34.                         break;
  35.                     case _msgposition.Middle:
  36.                         draw_text(10, graphics.PreferredBackBufferHeight / 3 + 10, text);
  37.                         break
  38.                     default: //_msgposition.Up
  39.                         draw_text(10, 10, text);
  40.                         break
  41.                 }
  42.          
  43.          while (!Input.Keyboard.IsKeyDown(Keys.Enter));
  44. }



consiglio di apportare quei piccoli cambiamenti per:
1) rendere il codice più leggibile e facile da testare
2) sbarazzarsi (elegantemente) di quel flag dialogo_letto
3) evitare goto

Appena riesci dammi ulteriori dettagli :k:

Ultima modifica effettuata da TheDarkJuster il 24/05/2016 alle 21:05
PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 413
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 22:45
Martedì, 24/05/2016
Più che altro riesci  a scrivere dal computer invece che dal telefono? Spezzare le righe andando a capo a metà frase rende molto difficile leggere.

Comunque sembra un problema di context switch tra l'interprete e il programma, è un lua standard quello embeddato nell'engine?

PM Quote
Avatar
Thejuster (Member)
Guru^2


Messaggi: 1704
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 10:20
Mercoledì, 25/05/2016
è il lua 5.1
E' un wrapper.

In pratica ho la libreria del lua nativa, ma con un altra libreria che funge da wrapper per richiamare le funzioni nella libreria nativa.

In pratica questa versione che ho e molto performante rispetto a quelle che girano normalmente nella rete.
è molto più stabile e veloce.

difatti gli script vengono chiamata nell'update quindi puoi immaginare la velocità di chiamata e la risposta immediata dall'interprete.

anche con script complessi riesco ad ottenere un fps molto ma molto stabile e fisso sui 60.
cmq non credo che sia un problema di libreria.

Quando aziono la chiamata
esempio:

Codice sorgente - presumibilmente Plain Text

  1. lua.DoString("Dialog(\"Ciao lumo\")");



il dialogo nell'engine appare e scompare velocissimo.
perché una volata che il metodo viene processato ed eseguito, l'engine continua il suo normale ciclo di renderizzazione.

se creo un ciclo per mostrare continuamente il dialogo, il programma si congela.
Perché esegue direttamente lo script e non il metodo Draw dell'engine.

Il mio motore funziona così:

[ Inizio ] -> [ Main.lua ] ( Configurazioni varie ed importazioni di eventuali sub-class del lua )

[Scene State]
A seconda della scena impostata dall'enumeratore, si può cambiare il flag di rendering.
ed effettuare lo switch tra un Wiewport ed un'altro.

Ogni Viewport inquadra una scena, ed il draw del relativo viewport viene ovviamente cambiato quando serve.
e non fatto girare a vuoto, così ne guadagno di prestazioni.


Il redering generale funziona in questo modo.

Metodo Initialize
1) Decompressione binaria dei file
2) Caricamento a RunTime di Texture estratte dai file binari.
3) Caricamento di Mappe Normali e Diffuse delle sprite.

Metodo Update / Draw
4) Inizio del Rendering
5) Entra in azione il PixelShader
6) Entra in azione lo shader ShadowMap
7) Entra in azione lo shader 2D Deferred Lighting
8) Update del Viewport e renderizzazione della scena di gioco, Player, eventi, collisioni ecc. ecc.
9) Update del lua engine  ( lua.DoString("Scene_Game.Update"); )
    per eseguire eventuali script creati dagli utenti ed interpellati nella Scene_Game.lua globale
    contenuta nella cartella script/

10) Draw del risultato dei script eseguiti dal lua.

Il problema fondamentale è questo.
Se faccio eseguire una sola volta quel void in C# Dialog
appare e scompare velocissimo.

Se provo a fare un qualcosa molto simile ad un ciclo si congela.
Serve una soluzione.

PS: Non ancora ho provato il metodo di DarkJuster.


PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 413
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 17:57
Mercoledì, 25/05/2016
Riesci a capire con il debugger dove si blocca? Potrebbe essere che per qualche motivo non riesce a prendere l'invio da tastiera e quindi rimane bloccato (come è giusto che sia, secondo il codice che hai scritto).
Potrebbe essere ad esempio che il loop che hai messo prenda tutta la CPU e non lasci context switch all'input handler, prova invece che lasciarlo vuoto a metterci dentro uno sleep di qualche centinaio di millisecondi.

PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1452
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 18:09
Mercoledì, 25/05/2016
può anche darsi che con il mio codice risolvi: non ridisegni la stessa cosa migliaia di volte al secondo!
Cosa che ovviamente era un enorme "cattivo comportamento", se non addirittura bug....

PM Quote
Avatar
Thejuster (Member)
Guru^2


Messaggi: 1704
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 19:10
Mercoledì, 25/05/2016
Appena provato.
Anche il metodo di DarkJuster non sembra funzionare.

và in blocco anche con quel metodo.
c'è qualcosa che non quadra..

Con lo sleep ottengo lo stesso risultato. ovviamente si frezza il thread.

però ho notato che solo dopo che ha completato il Thread.Sleep(2000) appare il messaggio.
Eppure è strano. Perché il Thread.Sleep è posto alla fine del void non all'inizio.

Ho provato ad osservare cosa succede con il debbuger con l'evento di DarkJuster.
Il programma rimanere fermo su


return Keyboard.GetState();

e come se il ciclo while bloccasse completamente tutto il processo.



PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo