Keroro Posted January 27, 2008 Share Posted January 27, 2008 (edited) Molti di voi conoscono bene il ruby e magari si sentono limitati da rpgmaker xp o il vx o semplicemente vorrebbero creare qualcosa che sia completamente farina del proprio sacco e che magari si discosti molto da un rpg.Vorrei mostrarvi la libreria che uso e che amo tanto (ci programmo in C), della quale esiste da qualche anno un porting funzionante in Ruby PremessaAmmetto che stanotte mi ci sono imbattuto per sbaglio perché cercavo una libreria per scrivere kanji, SDLSKK (sì, sono strano =D ), destino ha voluto fosse ospitata nello stesso sito delle Ruby/SDL.Vorrei però cogliere l'occasione per aprire un nuovo filone di game making in questo sito ;D Ruby/SDLChe cos'è?SDL è una libreria cross-platform che permette di sviluppare facilmente un videogioco offrendo un accesso a basso livello all'audio, tastiera, mouse, joystick, 3d tramite OpenGL e funzioni 2d "veloci".L'implementazione ruby è più lenta (ma anche più semplice!) rispetto a quella C/C++, quindi l'autore del porting ruby consiglia di evitare il 3d mentre per il 2d va benissimo! Come la installo?Io sono culoso e scrivo da linux (ubuntu) per installarla è bastato scriveresudo apt-get install libsdl-ruby1.8I windowsiani trovano le istruzioni ed il download qui: http://www.kmc.gr.jp/~ohai/rubysdl_download.en.htmlCome potete notare quello è il sito ufficiale del porting ruby, era noto che i giapponesi avessero il pallino visto che questo linguaggio l'hanno creato loro ;)Se doveste avere problemi con l'installazione chiedete qui, e spero che qualche ruby windows guru risponderà :D Premessa2Non conosco il ruby come le mie tasche perché non lo uso abitualmente (anzi se vedete nella sezione RGSS sono appena sopra la mezza sega :D), tutto il codice che scriverò sarà quindi evidentemente non ottimizzato, e non ha neanche la pretesa di esserlo visto che la sola pretesa è INSEGNARE qualcosa, sta poi a voi riunire in questo o quel modulo o in quella classe specifica.Utilizzerò il termine funzione piuttosto che metodo, del resto il metodo è una particolare funzione (perché non sono abituato a chiamarle metodi :Ok: ) ConsiglioProgrammate sempre con la documentazione/reference in background in modo programmare senza intoppi, trovate la reference delle Ruby/SDL alla pagina http://www.kmc.gr.jp/~ohai/rubysdl_doc.en.html===== Hello World! =====Il nostro primo programma non farà niente se non aprire una finestra in cui disegnamo qualche scarabocchio ;O;Penso sia necessario anche per notare la fondamentale differenza con le librerie TK.Le librerie TK sono a oggetti, mentre SDL è una libreria procedurale, seppur in Ruby costituita da classi e metodi.Questo vi permette molta libertà nella programmazione, libertà che sfrutto al volo perché non sono ancora ferrato con gli oggetti XD. Innanzitutto dobbiamo includere la libreria quindi nel nostro hello.rb metteremorequire 'sdl'Poi dobbiamo inizializzare la libreria: il sistema SDL è costruito da più "sottosistemi" attivabili a nostro piacimento passandoli come argomento (combinati con l'OR |) alla funzione SDL.init SDL::INIT_AUDIOSDL::INIT_VIDEOSDL::INIT_CDROMSDL::INIT_JOYSTICKPenso siano autoesplicativi, vediamo un po' se indovinate cosa ci serve...Soltanto il sistema video!quindi da bravi amanuensi scriviamoSDL.init( SDL::INIT_VIDEO)NB: devi inizializzare la libreria prima di usare una qualsiasi funzione SDL! Adesso è ora di creare la nostra finestra ma prima un piccolo excursusAlla base di tutto c'è la classe SDL::Surface, essa rappresenta un'area di memoria che funziona come una immagine virtuale:ha una sua larghezza, altezza e profondità (bits per pixel) puoi disegnarci su tramite molti metodi ed in maniera diversa, puoi disegnare pixel o primitive quali linee, rettangoli, cerchi, puoi copiarci una immagine bmp, png, jpeg con o senza alpha channel e definire eventualmente un colore alpha (come rpgmaker 2000)puoi copia incollarla su altre Surface (così come le immagini in paint)Le SDL associano una Surface alla Finestra dell'applicazione ed il giocatore vedrà tutto e soltanto quello che disegnamo dentro questa Surface. Per crearla dobbiamo usare la funzione SDL.setVideoMode( width, height,bpp,flags)Analizziamo gli argomenti:width è la larghezza della finestraheight è l'altezza della finestrabpp sono i bitsperpixelflags (si compongono sempre tramite operatore OR)SDL::SWSURFACE crea la Surface nella Memoria di Sistema, da evitare come la peste (è per i pc senza scheda video)SDL::HWSURFACE crea la Surface nella Memoria Video (ovvero accellerazione hardware!)SDL::FULLSCREEN abilita il fullscreenSDL::SDL_DOUBLEBUF abilita il doppio buffer (RULES!)La funzione restituisce l'istanza della SDL::Surface associata alla Finestra ho creato anche delle variabili (che potete benissimo inglobare in una classe) per semplificare il tutto:width = 640 height = 480 bpp = 32 schermo = SDL.setVideoMode(width,height,bpp,SDL::HWSURFACE|SDL::DOUBLEBUF) nota: il signore tra SDL::HWSURFACE e SDL::DOUBLEBUF è l'operatore OR e si ottiene con la combinazione di tasti SHIFT + \ (quella a sx dell'1) abbiamo creato la nostra finestra e dobbiamo porre particolare attenzione a schermo visto che come ho nerettizzato prima vedremo solo quello che disegneremo dentro questa SDL::Surface!! (ennesima volta che lo scrivo) Modifichiamo qualche parametro estetico così prendete familiarità con le classi#SDL::WM.Caption stringa1, stringa2Imposta il titolo della finestra a stringa1 e il titolo nella icon bar a stringa2Il # indica il commento, lo metto in modo che un eventuale neofita non mi chieda perché non funziona perché ruby non trova stringa1SDL::WM.Caption "Hello World!", "Hello World!"e nascondiamo il mouseSDL::Mouse.hide Ora arriva un passo importante ed un concetto difficile: Controllo degli eventiLa programmazione delle SDL è fatta ad eventi, che significa?La pressione di un tasto genera un evento, il rilascio di un tasto un altro evento, la chiusura della finestra, il movimento del mouse, la pressione ed il rilascio dei tasti del mouse, altri eventi, una caterva di eventi sul joystick e TANTI ALTRI.Che cosa deve fare la nostra applicazione o gioco?Reagire agli eventi, magari :)Come reagire lo decidiamo noi (se preme la freccetta si muove in basso o se premo esc esco dal gioco), ma per reagire bisogna accorgercene!E come ce ne accorgiamo con le SDL/Ruby?Ci sono diversi metodi, per ora ho provato solo il metodo classico (e presente nella controparte C) mentre esiste un metodo ancora più semplice (ma che non ho voglia di vedere come funzioni, per gli interessati nella Ruby/SDL reference la classe è la SDL::Event2)Metodo classico: Uso di SDL::EventPraticamente creiamo questo evento generico che sarà da ricettacolo a tutti gli eventi che si manifestano e che estrarremo, uno alla volta, con il metodo poll, una volta estratto vediamo che tipo di evento si tratta e agiamo di conseguenza Ma non basta!Vogliamo che il gioco continui ad andare fino a quando lo vogliamo noi, quindi ci serve prima di tutto un ciclo quasi infinito, che io abitualmente creo confine = 0 while (fine == 0) #controllo gli eventi #aggiorno il mondo (le variabili) #disegno tutto #flippo il backbuffer end Come vedete metterò tutto il mio programma dentro al while Per uscire basterà porre fine = 1 o brutalmente un break e grazie a Dio (per ora) non serve altro dopo il while per deinizializzare la libreria perché il porting Ruby si deinizializza da solo! Torniamo ad i nostri eventi, questa volta analizziamo in pseudocodice-Finché poll mi restituisce un evento-controllo l'evento, se è tizio faccio questo, se è caio faccio quest'altro Passiamo al codice, vi avverto, per i neofiti (e per me lo è stato) può essere abbastanza spaventoso, il while dentro il while (DEN DEN DEN!)evento = SDL::Event.new #creo l'istanza prima dei while! while (fine == 0) #già inserito #controllo gli eventi while (evento.poll != 0) if (evento.type == SDL::Event::QUIT) then fine = 1 break end if (evento.type == SDL::Event::KEYDOWN) then if (evento.keySym == SDL::Key::Escape) then fine = 1 break end end end #aggiorno il mondo (le variabili) #disegno tutto #flippo il backbuffer end >>>Riprendo la trattazione Come avete visto il metodo type restituisce il tipo di evento che la nostra applicazione ha INTERCETTATOTipi di EventoSDL::Event::ACTIVEEVENT non trovo documentazione in ruby, in c è quando il mouse entra/esce nella finestra dell'applicazione o quando l'applicazione è minimizzata (penso che da minimizzata continui ad andare, se volete frozzare il gioco mettete un flag dopo aver ricevuto questo evento e controllato sia in state == SDL::APPACTIVE, gain = 0 se minimizzata, gain = 1 se ripristinata)SDL::Event::KEYDOWN un qualsiasi tasto premutoSDL::Event::KEYUP un qualsiasi tasto rilasciatoSDL::Event::MOUSEMOTION movimento del mouseSDL::Event::MOUSEBUTTONDOWN pressione di un tasto del mouseSDL::Event::MOUSEBUTTONUP rilascio di un tasto del mouseSDL::Event::JOYAXISMOTION movimento di un asse del joystickSDL::Event::JOYBALLMOTION movimento di palla XD del joystickSDL::Event::JOYHATMOTION movimento dell'hat del joystick (non ho idea di cosa sia ;D)SDL::Event::JOYBUTTONDOWN pressione bottone joystickSDL::Event::JOYBUTTONUP rilascio bottone joystick SDL::Event::QUIT quando si preme alt+f4 o si clicca sulla croce in alto a destraSDL::Event::SYSWMEVENT dipende dal windows manager del sistema (ovvero intercetti chiamate a eventi aggiuntivi, sapete che tutti i wm funzionano a eventi?) (è il modo per implementare il copia incolla, ad esempio), se volete una applicazione crossplatform e non sapete come individuare il sistema di riferimento, ignorateloSDL::Event::VIDEORESIZE se ridimensionano la tua finestra, ma puoi ottenere questo evento solo se metti in setVideoMode la flag SDL::RESIZABLE (e perché in un gioco dovremmo farlo? anzi non ho messo il fullscreen per non essere invadente, lo lascio restringere per distruggermi tutte le proporzioni :D? avrebbe senso soltanto se l'applicazione fosse 3d :) )Come vedete gli eventi di pressione e rilascio sono generici e dobbiamo vedere con altri metodi che tipo di tasto/bottone è stato premuto, per quanto riguarda la tastiera si fa con il metodo keySym che restituisce il codice corrispondente al tasto premuto (per una lista di tasti guardate la reference ;) )Il ruby per quanto riguarda gli eventi è ridondante perché permette diverse vie per controllare l'input, che vedremo nel prossimo tutorial/esempio ;)Come vedete nel codice sopra non ho fatto che dire: se tentano di chiudere la finestra o se premono esc, chiuditi Andiamo avanti, per ora non abbiamo nessuna istanza che si muove o viene aggiornata quindi la parte di aggiorno il mondo la ignoriamo, altrimenti cosa ci andrebbe?Qui non esistono variabili predefinite per la velocità degli oggetti, ogni deltat dovete sommarla voi (e qui si entra in un discorso complicato, l'esecuzione non va alla stessa velocità su tutti i computer, un pentium 2 con scheda video cacca magari impiega 1 secondo per girare il while mentre un computer decente di 5 anni fa con scheda video carina ce ne impiega 0.05) quindi quando ci toccherà muovere un evento prima dovremo calcolare il tempo intercorso tra un while ed un altro e poi incrementare le variabili controllate in proporzione al tempo (ma questa è un'altra storia) Siamo finalmente arrivati alla fine, disegnamo sullo schermo!In teoria qui dovremmo gestire tutte le Surface e riversarle (copiarle) come vogliamo sullo schermo (immagini che fungono da sprite, background ecc...) ma visto che non ne abbiamo possiamo disegnare direttamente sullo schermo!Piuttosto che disegnare qualche funzione malata pixel per pixel preferisco che usiate i molteplici metodi offerti dalle SGE (una parte di Ruby/SDL) (che trovate nella reference nella sezione SDL::Surface)#qualche mio disegnino a caso, volevo fare una faccina schermo.fillRect 0,0,640,480,0xF0F6FA schermo.fillRect 50,50,50,50,0xCACCAA #questo colore mi fa morire XD schermo.drawRect 540,50,50,100,0x215571 #per creare un rettangolo più spesso schermo.drawRect 541,51,48,98,0x215571 #ne disegno due uno dentro l'altro schermo.drawLine 340,100,300,200,0xFF0000 schermo.drawLine 300,200,330,220,0xFF0000 schermo.drawLine 300,200,330,201,0xFF0000 schermo.drawLine 330,220,330,201,0xFF0000 schermo.drawCircle 250,150,40,0x0 schermo.drawFilledCircle 400,150,30,0x000090 schermo.drawFilledCircle 400,150,10,0x0(spiego sotto questa sezione)bisogna poi aggiungere il flip del backbuffer, che cos'è il backbuffer? praticamente piuttosto che scrivere direttamente in faccia al monitor, al monitor sono associate due Surface, una davanti e una dietro. Noi possiamo disegnare e fare quello che ci pare su quella dietro (sul di dietro :Q_) mentre l'utente continuerà a vedere quella avanti, dopo che abbiamo finito di disegnare possiamo versare la faccia di dietro su quella davanti tramite questo semplice comando!#fine schermo.flip end #già scritto, è quello del while (fine == 0) !!!!! Così siamo arrivati alla fine, provate il gioco con ruby hello.rb e vedrete gli scarabocchi che facevo stanotte (belli no?)adesso indaghiamo su quel mucchio di funzioni grafiche e intellegibili che ho usatoMetodi di SDL::SurfacefillRect x,y,width,height,colore crea un rettangolo pieno colorato di dimensioni widthxheight in (x,y)drawRect x,y,width,height,colore crea un rettangolo vuoto ma come sopradrawLine x0,y0,x1,y1,colore disegna una lineadrawCircle x,y,raggio,colore disegna una circonferenzadrawFilledCircle x,y,raggio,colore disegna un cerchioTutte molto isy e sul manuale ne trovate altre ;D Allego il file hello.rb per chi si fosse perso require 'sdl' SDL.init( SDL::INIT_VIDEO) width = 640 height = 480 bpp = 32 fine = 0 schermo = SDL.setVideoMode(width,height,bpp,SDL::HWSURFACE|SDL::DOUBLEBUF) SDL::WM.setCaption "Hello World!","Hello World!" SDL::Mouse.hide evento = SDL::Event.new() while (fine == 0) while (evento.poll != 0) if (evento.type == SDL::Event::QUIT) then fine = 1 break end if (evento.type == SDL::Event::KEYDOWN) then if (evento.keySym == SDL::Key::Escape) then fine = 1 break end end end schermo.fillRect 0,0,640,480,0xF0F6FA schermo.fillRect 50,50,50,50,0xCACCAA schermo.drawRect 540,50,50,100,0x215571 schermo.drawRect 541,51,48,98,0x215571 schermo.drawLine 340,100,300,200,0xFF0000 schermo.drawLine 300,200,330,220,0xFF0000 schermo.drawLine 300,200,330,201,0xFF0000 schermo.drawLine 330,220,330,201,0xFF0000 schermo.drawCircle 250,150,40,0x0 schermo.drawFilledCircle 400,150,30,0x000090 schermo.drawFilledCircle 400,150,10,0x0 schermo.flip end fatemi sapere che ne pensate per domande/approfondimenti nel prossimo tutorial creeremo una istanza che si muoverà con le freccette :) Edited January 27, 2008 by Keroro I Miei Script:Salva Schermata (3 Aprile 2012)Attacco Personalizzabile (2 Aprile 2012)Keyboard Input (Porting) (17 Marzo 2012)Continua... Link to comment Share on other sites More sharing options...
DaD Posted January 27, 2008 Share Posted January 27, 2008 Tempo fai provai a programmare con le tk però lasciai subito perdere perchè erano obbrobriose, le sdl sembrano davvero belle toste, casomai provo a fare qualcosina anche io dopo gli esame :Ok:Cmq sei il solito malato xD TPC Radio Site | Blog | Big-Bughttp://img102.imageshack.us/img102/4332/slackware2userbarok0.gifhttp://img141.imageshack.us/img141/1571/nokappams1cf8.png http://i29.tinypic.com/2vijdlh.jpg Link to comment Share on other sites More sharing options...
ProGM Posted January 27, 2008 Share Posted January 27, 2008 mmm tutto ciò mi ispira, ora provo a fare esperimenti °_° Progetti: http://i.imgur.com/jmLkIqi.pnghttp://i54.tinypic.com/2rh4ojq.pnghttps://github.com/ProGM Crea anche tu il tuo gioco per Game Boy! http://rpg2s.net/gif/SCContest3Oct.gifhttp://www.rpg2s.net/img/fablecontest1st.pnghttp://i43.tinypic.com/1zokd2s.png http://i.imgur.com/BEu6G.gifhttp://i.imgur.com/H1ARhq7.gifhttp://i.imgur.com/Af6ijZN.gifAOT: Associazione Odiamo la Telecom:http://i.imgur.com/aYJs89E.png"4 gattini... 4 stelline... E le 4 paperelle non ci stavano :3"Flame http://i30.tinypic.com/i27ypj.png Link to comment Share on other sites More sharing options...
Keroro Posted January 29, 2008 Author Share Posted January 29, 2008 hanno letto in tanti ma risposto solo in 2 :(per quelli che hanno letto e vogliono fare prove potete giocare con hello.rb modificando le figure da disegnare sopra lo schermo :S.non so se fare un ulteriore tutorial sull'argomento quindi ditemi voi (anche via mp, msn o quello che volete) se lo volete :) I Miei Script:Salva Schermata (3 Aprile 2012)Attacco Personalizzabile (2 Aprile 2012)Keyboard Input (Porting) (17 Marzo 2012)Continua... Link to comment Share on other sites More sharing options...
Black_Dragon Posted January 29, 2008 Share Posted January 29, 2008 Uhm...interessante.Dopo una prova però posso dire che preferisco le direct x in c++. "Fight for honor, fight for your life. Pray to god that our side is right.-Avenged sevenfold M.I.A. http://mypsn.eu.playstation.com/psn/profile/Black_Serian.png Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now