Professional Documents
Culture Documents
Sounds Cargarsonidos Reproducirsonidos Descargarsonidos Music Cargarunamsica Descargarunamsica Navegandoentrepantallasdeljuego Vibracin Cmaras Animacin Manualdebuenasprcticas Separarlalgicadelapresentacin PginasparaDesarrollodeJuegos Solucindeproblemas
IntroduccinalibGDX
LibGDXesunframeworkmultiplataformadedesarrollodejuegosparaWindows,Linuxy Android.EstescritoenJavaconunamezcladeC/C++paradarsoporteyrendimientoatareas relacionadasconelusodelafsicayprocesamientodeaudio. LibGDXpermitegenerarunaaplicacinensuPCyutilizarelmismocdigoenAndroid,deesta maneraelprocesodepruebasydepuracinserealizadeformamsrpidaycmodayaque elPCesmuchomsrpidoqueeldispositivoAndroid. ConLibGDXnosaseguramosdequelamismaaplicacinpuedefuncionarcorrectamenteen diferentesdispositivos. LibGDXestcompuestoporunaseriedecomponentesdeserncomunesatodaslas aplicaciones. MarcodeAplicacin,quemanejarelbucleprincipalyademsestarencargadodelclicode vida,esdecir,loseventosdecreacin,destruccin,pausayresumedelamisma. UncomponentedeGrficosquenospermitirgestionarlarepresentacindeimgenesy objetosgrficosenlapantalla. UncomponentedeAudio,quenosfacilitarelaccesoalossonidosymsicadelaaplicacin. UncomponentededeEntradaySalidaparaleeryescribirlosdiferentesficherosdedatos comoporejemplo,imgenes,archivosdeconfiguracin,sonidos,msica,texturas,... UncomponentedeEntradaquegestionaralaentradaatravsdelteclado,pantallatcilo acelermetro.
Realmente,estosmdulossonslointerfacespblicasqueofrecelalibrera. Lapropiaaplicacinserlaencargadadelagestindelosdiferentesmdulos. Ventajas: Soporte2dfull(bajoyaltonivel) Muchadocumentacin,tutoriales,ejemplosdecdigo ReleasesenformaperidicalaultimafueensetiembreyanteriorenMayo Sepuedeprobarendesktop(antesdesubiramobile) ManejaAudio,input(usuario),fsica,matemtica,archivos MaspoderosoqueAndengine Soporta3d libGDXtedaunaccesomsfcilaBajonivel Posibilidaddetomarunjuegohechoenjavajar2do3dyadaptarloalibgdxparaq funcionenativoenandroid,esohicieronconeljuegoDroidInvaders3d. Desventaja: Elsoportedealtonivelen3destaenconstruccinactualmente Linksdereferencia:
PaginaOficial Wikidelproyecto Blog Foro Juegoen3dyarealizado:DroidInvaders ListadodeEjemplos VideoTutoriales Documentacin
Descargarlalibrera
Paradescargarlalibreradebemosiralawebdelamisma:http://libgdx.badlogicgames.com/
Aladerechapulsamosendownloadydelasdosversionesdelalibreraquenosaparecen, seleccionamoslaversinNightlyBuild.
TraspulsarenDownloadyaslonosquedadescargarlaltimaversindelalibrera.
CrearunproyectoJAVAnuevo
AunqueelobjetivofinalesqueeljuegofuncionesobreAndroid,trabajaremosconunproyecto JAVAqueunavezterminadoseportaraAndroid.
Nosquedaraelproyectodeestaforma:
ParaellohacemosclickderechosobreelproyectoyenelmencontextualBuildPath> ConfigureBuildPath...trasloquesenosmuestralosiguiente:
Enestaventanadesplegamosgdx.jarytalcomoseveenlaimagenseleccionamosJavadoc location.UnavezhechoestopulsamossobreEdit...
todoloqueocurraeneljuego. Paraelloclickderechosobresrc>New>Class.
Unavezcreadalaclaseprincipaldelproyecto,crearemoselpuntodeentradaparalaejecucin delaaplicacinJAVA.Unaclasequenospermitirlanzareljuego.
Paraellocreamosunaclasequecontengaelmtodomain:
Nosquedaraelproyectodelasiguienteforma:
ParapoderlanzareljuegoaadimosenlaclaseDemo1Desktoptenemosqueaadirlo siguiente: newJoglApplication(newDemo1Game(),"Demo1",320,480,false) Losparmetrosindicanlosiguiente: newDemo1Game().InstanciadelaclasequeimplementaGame "Demo1".Queeselttulodelaaplicacin. 320.Anchoenpxeles. 480.Altoenpxeles. false.ParaindicarquenoqueremosutilizarOpenGLS2.0enestecaso.Porloqueseutilizar el1.1 Unavezhechoestoyatenemosunjuegoquenohacenadayquepodemoslanzarcomo aplicacinJAVA. ParalanzarlotenemosquehacerclickderechoenelproyectoyRunAs>JavaApplication Unavezhechoestonossaldrunaventanaparaseleccionarelpuntodeentradadela aplicacinqueennuestroejemploesDemo1Desktop.java
Elresultadodelaejecucinserunapantallanegraconlaresolucinindicada.
PortarelproyectoJAVAaunproyectoAndroid
AhoracrearemoselproyectoparacompilarloenAndroid.Paraefectospracticosusareun ejemploqueyoyatena.HechoenescritoriollamadoHolaLibgdx.
12.Referenciamoslaslibrerascopiadas.Clickderechoalproyecto/buildpath/configurebuild path...
13.Antesdecerraresapantallaanterioriralapestaaprojectyadjuntarlelareferenciaal proyectodeescritorio.
12.ModificarlaActivityprincipal"HolaLibGdxActivity"paraquenoextiendadeActivitysinode AndroidApplication.(crt+shift+o)pararesolverlosimportsnecesarios. package c o m . l i b g d x . h o l a l i b g d x import a n d r o i d . o s . B u n d l e import c o m . b a d l o g i c . g d x . b a c k e n d s . a n d r o i d . A n d r o i d A p p l i c a t i o n import c o m . l i b g d x . h o l a l i b g x . H o l a L i b g d x public class H o l a L i b G d x A c t i v i t y extends A n d r o i d A p p l i c a t i o n { /**Calledwhentheactivityisfirstcreated.*/ @Override public void o n C r e a t e ( B u n d l e s a v e d I n s t a n c e S t a t e ) {
super. o n C r e a t e ( s a v e d I n s t a n c e S t a t e ) / / A c a i n i c i a l i z a m o s a l a p p d e e s c r i t o r i o . i n i t i a l i z e ( new H o l a L i b g d x ( ) , false) } }
Deberaquedarnosas. 13.Loejecutamosenelemulador.
Desbloqueamoseldispositivoenelemulador.
CiclodevidadeunaaplicacinlibGDX
Esteapartadodescribecmoseestructuraunaaplicacinlibgdx. LAAPLICACION Eselprincipalpuntodeentradaparacualquieraplicacinlibgdx.LainterfazApplication determinalaplataformaylosgraficosdefondoquesernutilizadosporlaaplicacin.Lainterfaz tambinproporcionalosmtodosparaaccederagrficos,audio,archivosdeentraday mdulosdeE/S.TambindaaccesoaunmdulodeLoggingelcualfuncionaentodaslas plataformas. LibGDXescompatibleactualmentecondosbackendsdeaplicacionesdeescritorio(lwjgly JOGL)yotraparaAndroid. ParacrearunaaplicacinlibGDX,sehadeimplementarlainterfazApplicationListener primero. APPLICATIONLISTENER ApplicationListenereselresponsabledelainicializacindelaaplicacin,laactualizacindel estadodeljuego(esdecir,lalgicadeljuego),renderizacindelaimagen,pausadodeljuego, guardarelestadoylaliberacindelosrecursosalsalirdelaaplicacin. Estambinellugardondeloseventosdelciclodevidasonmanejados.Cadaaplicacin/juego, sinimportarelbackendy/oplataformadedestinotendrqueimplementarlainterfaz ApplicationListener.Laimplementacinesexactamentelamismaparatodaslasplataformas. Portanto,ApplicationesresponsabledelcircuitodejuegoyApplicationListeneresellugar dondeseimplementalalgicadeljuego. LaimplementacindelainterfazApplicationListener
Loseventosquesondesencadenadosporlosenlaaplicacindelciclodevidatalcomose describe: create():Sellamaunavezcuandosecrealaaplicacin. resize(intwidth,intheight):Sellamaaestemtodocadavezquelapantalladeljuego cambiasutamaoyeljuegonoestenelestadodepausa.Tambinselellamaslounavez justodespusdelmtodocreate().Losparmetrossonlanuevaanchurayalturadelapantalla. render():Mtodollamadoporelbucledeljuegodelaaplicacincadavezqueserenderiza.La actualizacindeljuegotambintienelugaraquantesdelarepresentacinreal. pause():Elmtododepausase llamajustoantesquesedestruyalaaplicacin.EnAndroidse llamacuandoelbotndeiniciosepresionaohayaunallamadaentrante.Enelescritoriose llamajustoantesdedispose()alsalirdelaaplicacin.Esunbuenlugarparaguardarelestado deljuegoenAndroid,yaquenosegarantizaqueseareanudado. resume():EstemtodoesllamadosloenAndroid,cuandolaaplicacinrecibeelfoco.Enel escritorioestemtodonoserllamadonunca. dispose():Selellamacuandolaaplicacinsedestruye.Esprecedidoporunapausa().
Ciclodevidadeunaaplicacion
Losmtodosantesmencionadossonprovocadosporlaaplicacindurantesuciclodevida. ElsiguientediagramamuestralasdiferentesfasesporlasquepasaunaaplicacinlibGDX:
Grficos
ElmdulodegrficosesunresumendelacomunicacinconelGPUyproporcionamtodosde convenienciaparaobtenerlasinstanciasdeOpenGLES.Seencargadetodoelcdigo repetitivonecesariosparahacerseconelejemplodeOpenGLyseocupadetodaslas implementacionesproporcionadasporelfabricante. Dependiendodelhardwaresubyacente,loscontenedorespuedenseropuedennoestar disponible. Elmdulodegrficostambinproporcionamtodosparagenerarmapasdepixelsytexturas. EnelsiguientecdigopodemosvercmoobtenerunainstanciadelaAPIOpenGL1.0:
GL10 gl = Gdx.graphics.getGL10 ();
TexturaseInterpolacin
Textureesuna"imagen"enlamemoriadelchipgrfico(lasimgenesendiscosecargarnen estazonadememoria).EnOpenGLelanchoyaltodeunatexturatienequeserpotenciade2 (...32,64,128,256,512,1024,etc).Aunqueenlosejemplossedefinenlatexturacuadrada,no tieneporquseras.Puedestenerunatexturade128x32,32x256,etc. Porejemplo,elHTCG1soportacomomucho,unatexturade1024x1024(Aunquepuedestener msdeunatexturaalavez).Intentarutilizartexturasmsgrandesenestedispositivo provocarnerroreseneljuego.Larecomendacinesquenopasesdelvalor1024para establecerelanchooaltodetustexturas. UnparmetromuyimportantequehayqueindicaralahoradecrearunobjetoTextureesun valorTextureOptionsqueindicarqumtodoseutilizarpararedimensionarlasimgenes quetenemosdentrodelatextura.(Paranocomplicarlascosas,dejaremosesaexplicacin).
AmpliadaconNEAREST:
AmpliadaconBILINEAR:
queteaparezcan"halos"querodeanlosbordesdelasmismas.Aquesdondeentraenjuegola tcnica"premultipliedalpha",lacualcorrigeeseproblema.Intentaevitarutilizar"premultiplied alpha"amenosqueveascosasrarasenlosbordesdetusimgenes,comosobrasohalos resplandecientesquenodeberanestar. Siquieresunainterpolacinbilineal,estableces: TextureOptions.BILINEAR Siquieresunainterpolacinbilinealcon"premultipliedalpha",estableces: TextureOptions.BILINEAR_PREMULTIPLYALPHA LomismoocurresiquieresinterpolacinNEARESTconosin"premultipliedalpha".Escosa tuyaexplorarlosvaloresquepuedeselegirdeTextureOptions. Parafinalizar,decirqueTextureOptions.DEFAULT= TextureOptions.NEAREST_PREMULTIPLYALPHA
TextureRegion
Defineunrearectangulardeunatextura.Elsistemadecoordenadasutilizadotienesuorigen enlaesquinasuperiorizquierdaconelejexapuntandohacialaderechayelejeyapuntando haciaabajo. LastextureRegionsonempleadasparacrearnuevasimagenes(otambinllamadosactoresde tipoimagen)asociadasaunreadeunatextura. Tienevariasopcionesparaconstruirunobjetodeestaclase,sonlossiguientes:
T e x t u r e R e g i o n ( )
Construyeunaregionsintextutanicoordenadasdefinidas.Sepodrandefinirdespuesempleando losmtodosdelaclase.
T e x t u r e R e g i o n ( T e x t u r e t e x t u r e )
Construyeunaregiondetamaoespecificadoenlatextura.
T e x t u r e R e g i o n ( T e x t u r e t e x t u r e , f l o a t u , f l o a t v , f l o a t u 2 , f l o a t v 2 )
T e x t u r e R e g i o n ( T e x t u r e t e x t u r e , i n t w i d t h , i n t h e i g h t )
Construyeunareginconconlascoordenadasdelatexturayelanchoyaltoespecificado.
T e x t u r e R e g i o n ( T e x t u r e t e x t u r e , i n t x , i n t y , i n t w i d t h , i n t h e i g h t )
Defineunateturaespecificandoelpunto(x,y)deorigenyeltamaodelarea(ancho,alto)
T e x t u r e R e g i o n ( T e x t u r e R e g i o n r e g i o n )
Construyeunareginconlamismatexturaycoordenadasquelareginpasadacomoparmetro.
T e x t u r e R e g i o n ( T e x t u r e R e g i o n r e g i o n , i n t x , i n t y , i n t w i d t h , i n t h e i g h t )
Construyeunareginconlamismatexturaycoordenadasquelareginpasadacomoparmetro.
UnejemplodeseleccindeunreaconTextureRegioneselsiguiente
TextureRegion texture = new TextureRegion(new Texture( Gdx.files.internal("data/jugador.png")), 0, 0, 40, 40);
TexturePacker
EmpaquetaimagenesenunTextureAtlas.
Empaquetarimgenesautomaticamente
Sedeberimportarlalibreria:gdxtools.jar ElcdigoparaejecutarelTexturePacker: Settingssettings=newSettings() settings.padding=2 settings.maxHeight=1024 settings.maxWidth=1024 settings.incremental=true TexturePacker.process(settings,"images","data") Sedebertenerenelproyectounacarpetaimages,conlasimagenesaprocesar.Elproceso generarlacarpetadataconelpackrealizado.
Cargadeimgenesempaquetadas
AsiserecuperanlastexturasdeuntextureAtlasGeneradoporunpacker. publicstaticAtlasRegionbackground atlas=newTextureAtlas(Gdx.files.internal("data/pack")) background=atlas.findRegion("background")
Dibujarimgenesenpantalla
CreamoslaclaseAssetparaalmacenarlosrecursosdeimagenes. */ publicclassAssets{ /**Contieneelpaquetedetexturas.*/ publicstaticTextureAtlasatlas /**Regionesdentrodelaimagendetexturaempaquetada*/ publicstaticAtlasRegionbackground publicstaticAtlasRegionsoundoff publicstaticAtlasRegionsoundon publicstaticAtlasRegionstart publicstaticAtlasRegiontitle
} publicstaticvoiddispose(){ atlas.dispose() }
@Override publicvoidcreate(){ } @Override publicvoiddispose(){ batcher.dispose() } @Override publicvoidpause(){ } @Override publicvoidrender(){ GL10gl=Gdx.graphics.getGL10()//referenciaaOpenGL1.0 gl.glClearColor(0,1,0,1) gl.glClear(GL10.GL_COLOR_BUFFER_BIT) guiCam=newOrthographicCamera(10,15) //definiciondenuestrapropiamedidadeljuego guiCam.position.set(10f/2,15f/2,0) //Dondeestaramirandolacamara batcher=newSpriteBatch() //crearsolamenteunbatcherporpantallayeliminarlocuandonoseuse
guiCam.update() batcher.setProjectionMatrix(guiCam.combined) //DibujandoelBackground batcher.disableBlending() //seeliminagraficamentelatransparenciayaqueesunfondo batcher.begin() batcher.draw(Assets.background,0,0,10,15) batcher.end() //DibujandoelementosenpantallaactivamoselBlending batcher.enableBlending() batcher.begin() batcher.draw(Assets.title,1,8,8,6) batcher.draw(Assets.start,2,5,6,1) batcher.draw(Assets.soundon,2,3,6,1) batcher.end() } @Override publicvoidresize(intarg0,intarg1){ } @Override publicvoidresume(){ } }
Entrada
Elmdulodeentradapermitecapturarlosdiversasformasdeentradadecada plataforma.Permitesaberdelestadodecadatecla,lapantallatctilyelacelermetro. Enelescritoriolapantallatctilsesustituyeporelratn,mientrasqueelacelermetrono estdisponible. Enelfragmentodecdigosiguienteseobtieneeltouchactualdecoordenadassihayun touchdelcelular(odelratnenelescritorio): if(Gdx.input.isTouched()){ System.out.println("deentradaseprodujoenx="+x+",y="+y) } Demanerasimilaratodoslosmediosdeentradapuedenserconsultadosymanipulados.
Detectarpulsacionesenlapantallatctil
SedebedifinirunVector,unareaficticiadondesecaptareleventodepulsacindeldedo. UsamostambienelobjetodeOrthographicCamera,paraconvertirlospixelesennuestra medidaenmetros.LuegopreguntamossielbotonquecreamosBoundingBoxtieneuntouch. Yescribimoselcdigoparamanejareseevento.
Audio
LibGDXcuentaconunmdulodeaudioqueofrecedostiposderecursos:Elsonidoyla msica. AmbostipossoportanelformatoWAV,MP3yOGG.Tambinofreceaccesoalhardwarede sonido. Ladiferenciaentreelsonidoylamsicaesqueelsonidosealmacenaenmemoriayseusa cadavezquesequierereproduciralgunodeellos,mientrasquelamsicasonstreamsde sonidoqueestnalmacenadosenficherosyalosqueseaccedecadavezquesequiere reproduciralgo. Elsiguientefragmentodecdigoreproduceunficherodemsicadesdeeldiscoconelvolumen alamitad:
Sounds
Soundesunaclasedestinadaalareproduccindeunefectodesonido.Lonormalescargarel sonidodesdeunarchivoamemoriayluegoreproducirloatravsdelmtodoSound.play().Los sonidossongeneralmentecortos,llegandoadurarunospocossegundosyaquealser cargadosenmemoriapuedenllegaraocupardemasiado,incidiendodirectamenteenel rendimiento. Cuandoyanovayamosausarmsesesonidosernecesariollamaralmtodo Sound.dispose()paraliberarmemoriaeneldispositivo.
Cargarsonidos
LosArchivosparalosefectosdesonidolospondremosdentrodeunacarpetallamadadata ParacargarenmemoriaunefectodesonidotanslosernecesariodefinirlocomotipoSound yllamaralmtodoGdx.audio.newSoundpasandocomoparmetroelficherodentrodel directoriodata. Elsiguientefragmentodecdigocargaunsonidoenmemoria. Soundexplosion explosion=Gdx.audio.newSound(Gdx.files.internal("data/explosion.ogg")) Puestoqueelsonidoserunacosaqueslosecargarunavezdurantetodalavidadela aplicacin,haremoslallamadaanewSoundennuestromtododestinadoalacargadedatos.
Reproducirsonidos
Parareproducirunsonidopreviamentecargadoenmemoriatanslosernecesariohaceruna llamadaalmtodoplaydelsonidopasandocomoparmetrounvalorentre0y1que representarelvolumen. explosion.play(1)
Descargarsonidos
Unavezquenoqueramoshacerusodelsonidosernecesariodescargarlodememoriayaque enlosdispositivosmviles,lamemoriaRAMsiguesiendounelementomuyprecidado. Paradescargardememoriaunsonidotanslosernecesariollamaralmtododisposedel objeto.Estopodemoshacerloennuestroapartadodestinadoaladescargadedatosobienen elmtododisposedelaaplicacin,comoyahemosvistoenelapartadodeciclodevidadela aplicacin. explosion.dispose()
Music
Musiceslaclasedelibgdxparacargararchivosdesonidoennuestrosjuegosderivadelaclase Disposableconstadelossiguientesmtodos: play()Comienzaalacancin,enelelcasodeestarpausadalareanudadondese quedoyenelcasodequesehubieraparadolacomienzadesdeelprincipio. pause()Pausalacancin,silacancinnohaempezadoaunoestayahafinalizado, estemtodoesignoradoalllamarlo. stop()Paralacancin.Lasiguientevezquesellamealmtodoplay()lacancin comenzardesdeelprincipio. isPlaying()Funcinquedevuelveunbooleano,indicandosiesverdadonoquela cancinestasonando. setLopping()Admitecomoparmetrounbooleanoparaindicarsiseactivalafuncin loopenlacancin,estafuncinactivalarepeticinindefinidadelamsica,detalforma quesisellamaalprocedimientoindicandotrue,lacancinserepiteindefinidamente hastaquelaparemosohastaquedesactivemoselloop. isLopping()Funcinquedevuelveunbooleano,indicandosiesverdadonoquela cancinestasonando. setVolume()Varaelvolumendelsonido,admiteporparmetros(01),conun0se poneensilencioycon1seponeelvolumenalmximo. getPosition()Funcinquedevuelveunfloatconlaposicindelacancinen milisegundos dispose()Eseldestructordelaclase.Esmuyconvenientellamarlocuandonosea necesarialamusicayaqueconsumememoriadeldisposivo LibgdxsoportalosformatosMP3,OGGyWAV.EsconvenienteusarOggencasitodoslos casos. Sinecesitamscontrolsobreeldispositivodeaudio,puedeutilizarelAudioDeviceyclases Audiorecorderquetambinseobtienedelainterfazdeaudio.Estasclasespermitenala salidadelasmuestrasdePCMparaeldispositivofsicodeaudio,ascomomuestrasPCM registrodeunmicrfonoconectado.
Cargarunamsica
Lasmsicassepuedenalmacenardeformainternaenelproyectoqueestamosdesarrollando oenunarutafija(porejemploparaponercomomsicaunsonidostandarddelsistema) ParacargarunamsicaenmemoriadebemosinstanciarunobjetodelaclaseMusicpasandole comoparmetrounpunteroalficherodeltipoFileHandlenativodejava,delasiguienteforma: Musicmusic=Gdx.audio.newMusic(Gdx.files.getFileHandle("data/8.12.mp3",FileType.Internal))
Enesteejemplolacancin8.12.mp3estaguardadadentrodelacarpetadelproyectodata,por loqueeltipodearchivoleindicamosqueesinterno.FileType.Internal.Enelcasodenopoder abrirelarchivosegeneraunaexcepcinGdxRuntimeException LostiposposiblesdeficherossonlosnativosdeJavadetipoFile.FileType,estosson: ExternalPathrelativoalaraizdelalmacenamientoSDdeandroid. InternalPathrelativoalarutadelaaplicacionandroidodichodeotromodorelativoal directorioraizdelaaplicacincreada. ClasspathElpathdelficheroestaenunarutarelativaalaraizdelClashpath AbsoluteElpathestaindicadodeformaabsoluta,indicandoelfilesystemquelo contiene.
Reproducirunamsica
Parareproducirunamsicacomohemosmencionadoantesbastaconllamaralmetodoplay() desdeelobjetoinstanciadodetipoMusic. Vamosaverlomasclaramenteconunpequeoejemplodecomodejarunamsica reproducindoseenunbucleinfinito dondelamsicaesunarchivomp3almacenadoenunacarpetaquehemosllamadodata Musicmusic=Gdx.audio.newMusic(Gdx.files.getFileHandle("data/8.12.mp3",FileType.Internal)) music.setLooping(true) music.play()
Descargarunamsica
Unavezquenoqueramoshacerusodelsonidosernecesariodescargarlodememoria. Paradescargardememoriaunsonidotanslosernecesariollamaralmtododisposedel objeto.Estopodemoshacerloennuestroapartadodestinadoaladescargadedatosobienen elmtododisposedelaaplicacin,comoyahemosvistoenelapartadodeciclodevidadela aplicacin. Enelcasodequelamsicaestuvieraenunbuclelolgicoespararlaantesdeeliminarlapor seguirunasecuencialgica,yenparteporestticadelaprogramacin,estossehace llamandoalmtodostop,portantoelordenseria: music.stop() music.dispose()
Navegandoentrepantallasdeljuego
Vibracin
Paraagregarlealjuegodelarkanoid(eldelvideotutorial)quevibrealchocarlabarritaconla paredizquierdapormodificamoselmtodorender()delaclaseGameScreen. try{ Gdx.input.vibrate(200) System.out.println("vibra") }catch(Exceptione){ System.out.println(e) }
Cmaras
OrthographicCameraguiCam guiCam=newOrthographicCamera(10,15)//definiciondenuestrapropiamedidadeljuego
10x15metros:Estoesporquedividmoslos320x480pixelesenbloquesde32px. guiCam.position.set(10f/2,15f/2,0)//Dondeestaramirandolacamara
Animacin
Crearemosunpersonajedeunpersonajeyharemosunaanimacin,esdecir,quecamine comosiseestuvieramoviendo.
Aquseveelejemplodeunhombrecorriendo.Laimagensepuedevercomounamatrizdeimgeneslas cualessevanarecorrercondosciclosysevanapasarporimagenaunvector. Cuandosecrealaanimation,selepasaporparametrolavelocidadconlaquesemueveelframeyelvector deimgenes. PorltimocuandoseinvocaalspriteBatch.draw()seleindicaelvectorquecontienelasimgenes,la posicindeXydeYendondesequierendibujarlasmismas.
UsaremoslasiguienteImagencomosecuencia:
Copiaremosestaimagen,enlacarpeta/imagendelproyecto Creamosunaclasequeimplementescreenanimacin:
publicclassAnimationScreenimplementsScreen{ Gamegame staticfinalfloatWORLD_WIDTH=5 staticfinalfloatWORLD_HEIGHT=3.3f privatestaticfinalintFRAME_COLS=6//#1 privatestaticfinalintFRAME_ROWS=5//#2 OrthographicCameraguiCam SpriteBatchbatcher AnimationwalkAnimation//#3 TexturewalkSheet//#4 TextureRegion[]walkFrames//#5 SpriteBatchspriteBatch//#6 TextureRegioncurrentFrame//#7 floatpositionX=1 floatstateTime//#8 Inicializamosenelconstructorloreferentealaanimacin: publicAnimationScreen(Gamegame){ this.game=game batcher=newSpriteBatch() guiCam=newOrthographicCamera(WORLD_WIDTH,WORLD_HEIGHT) guiCam.position.set(WORLD_WIDTH/2,WORLD_HEIGHT/2,0)
walkSheet=newTexture(Gdx.files.internal("images/man.png"))//#9 TextureRegion[][]tmp=TextureRegion.split(walkSheet, walkSheet.getWidth()/FRAME_COLS,walkSheet.getHeight() /FRAME_ROWS)//#10 walkFrames=newTextureRegion[FRAME_COLS*FRAME_ROWS] intindex=0 for(inti=0i<FRAME_ROWSi++){ for(intj=0j<FRAME_COLSj++){ walkFrames[index++]=tmp[i][j] } } walkAnimation=newAnimation(0.025f,walkFrames)//#11
spriteBatch=newSpriteBatch()//#12 stateTime=0f//#13 }
Sinecesitanelcdigofuentecompletodeesteejemplo:javi10823@gmail.com
Manualdebuenasprcticas
TODO:Introduccinacosasparasermseficientesylimpiosescribiendocdigo. Paraserlimpiosyeficientesescribiendocdigoesimportantetenerencuentavariascosas comocreacionesdemtodosparasimplificarelcdigo,nohacercondicionesmuylargaso muchosbuclesanidados,estossonsoloalgunosejemplos,ahoraexplicareunpocomas extensoalgunosdelospuntosmencionadosanteriormente. Definirvariablesalprincipiodelaclase/mtodo,deestaformasetieneunaccesorpidoaesa variableysabemosdeunsimplevistazoqueatributostiene. Respetarlasreglasdenomenclaturadeloslenguajestalescomolossiguientes: Losnombresdelasvariablescomienzanconletrasminsculas,yencasodecontener variaspalabrasselepondrmaysculaalaprimeraletradecadapalabraapartirdelasegunda palabra. Losnombresdelosmtodosseescribirnenminsculasiguiendolamismareglaque elnombradodelasvariables.Porlogeneral,elnombredeestossuelenserverbos. Lasvariablesfinalesseescribirnintegramenteenmayscula,separando,sifuera necesario,diferentespalabraspormediodelcarcterguinbajo_ Elnombredelospaquetesserealizarintegramenteenminscula,aunquecontenga variaspalabras. Elnombredelasclasescomenzarconlaprimeraletraenmaysculaylassiguientes enminscula.Encasodecontenervariaspalabrasselasdistingirponiendomaysculala primeraletradecadapalabra. Tabularelcdigoparaunamayorcompresindelmismo.Enjava,adiferenciadeotros lenguajesdeprogramacincomopuedeserpython,noesnecesarioquelaslineasdecdigo estntabuladasparaperteneceraunmtodo/funcin/claseyaqueparaestoseutilizanlas llaves,perodeestaformasehaceelcdigomslegible. Realizarunestudioquerelacioneeltiempodeprocesamientovsalmacenamiento.En ocasionesunalistapuedeestarmuybienparaalmacenardatos,perounarraytieneunacceso inmediatoaldatocontenido. Sivesqueprogramandoescribesvariasveceslomismo,creacionesdeobjetoquevaranmuy poco,comprobacindeunobjeto,cambiarunobjeto,lomasprobableesquepuedascambiarlo porunafuncinounmtodo.Porejemplo: Crearuncasillerode10x10,estoimplicadibujarocrear100casillas,escribiras 100veces: batcher.draw(casilla,posX,posY,1,1)
Yestonoeseficiente,peropodrasdibujarlocon: for(inti=1i<11i++){ for(intj=1j<11j++){ batcher.draw(casilla,i,j,1,1)} } } Usarswitchcasesivesquecomparaslomismodentrodemuchosif,teniendoen cuentaqueuncasesolocompruebaintegeryenumerados. Antesdecrearunmtodocomprobarquenoexisteya,oparecido,paraquepuedas modificarlo,siemprequealmodificarlonohayanadadependiendodeel. Usarvariosforanidadoshacequeelprogramaseralenticemucho,yaquepodemos encontrarnosconrecorridosconmuchoselementosylosrecorretodosporloqueralentiza muchoynoeseficiente,estonosueleaparecermuchoperohayquetenercuidadoalahorade meterforwhileodo,unodentrodeotrosyaquepuededarproblemas Otradelascosasquehayquetenerencuentaalahoradeprogramaresserlimpioyno escribircomosenosvanocurriendolascosasydejarloas,yaquesidespusalguienquiere usarnuestroocdigoosimplementesabercomofuncionaleseraimposible,poresocuando estemosprogramandohayqueintentardejarlineassimples,oexplicarconcomentarioscuando veamosquealgopuedequenoseentienda. Loquetambinayudaraalahoradelalimpiezaydelaclaridadseranlaclases,lomas importanteenelcasodelaprogramacinorientadaaobjetos.Siemprequevallasautilizarun objetoquevayaatenermasdeunapropiedadseutilizanclases.Algunosejemplos: Pelotaenunespacio:Ademsdesunombretendrunxeyindicandosuposicin. Personaje:Ademsdesunombrepuedetenersuposicinindicadaconxey,un inventarioguardadoenunarray,ocualquiercosa. Enestosyenmuchosmaslacreacindeunaclaseeslomejor,cuandoveasqueestas creandodosvariablesparaguardarinformacinsobreunobjetodentrodeunaclase seguramentepodrsinstanciareseobjetodesdeotraclaseyseramasclaroqueponiendo tantosatributos.
Separarlalgicadelapresentacin
Conlgicanosreferimosatodaslascomprobaciones,modificacionesocreacionesquese hacenantesderenderizar,yaqueelprocesoderenderizadosoloyaeslentosimetestambin todalalogicaaraqueeljuegosealento,porestoesrecomendablehacerloenunaclaseaparte. Parahacerlapartelgicabastaconcrearunclaseapartedelrenderizadodondecomprobemos loquehagafaltaantesdepintarenpantalla.Porejemplo: Cambiarlavelocidaddeunapelotaalchocarconunapared: //Choqueenparedizquierda if(ball.position.x0.25<1){ ball.position.x=1+0.25f ball.direction.x=ball.VELOCITY } Comprobarelvalordeunacasillaparapintarladeuncolordiferente: publicAtlasRegioncasilla(intx,inty){ switch(matriz[x][y]){ case0:returnAssets.casillaGbreak case1:returnAssets.casillaBbreak case2:returnAssets.casillaRbreak case3:returnAssets.barcobreak default:returnAssets.barco2 break } } Actualizarvaloresdelasvariables. Enresumentodoloquenoseadibujarenpantallaydebaejecutarsesiempresehadeponer fueradelrenderizado,peroteniendoencuentaqueelrenderlodebellamar,sihicieramosla partelogicaenunaclasellamadaWorlddeberiaquedaralgoparecidoaesto: publicclassWorld{ //atributosinternos //constructor publicWorld(){
initialize()//metodointerno,abajocreado. } //inicializarvariablesolimpiar publicvoidinitialize(){ } //actualizacion publicvoidupdate(){ //aquideberirtodoloqueformapartedelalgicaparaelrenderizadodela pantalla,teniendoencuentaquehayquellamarlodesdeelrender,queseelpuedepasarlos parmetrosquesenecesiten } } PuedehaberdistintosWorld,ypuedeusarseenlaspantallasquesenecesiten,notieneporque sersolodeuna. ParausarelWorldhayquellamarlodesdeelrender,peroantestienequehaberunobjeto desdeelquellamarlo,queseracreadoenlaclasedelapantalla,aquiunejemplo: publicclassGameScreenimplementsScreen{ Worldworld //Atributos publicGameScreen(){ this.world=newWorld()//estollamaalcontructor,quealavezllamaalinizialite. //inicializaciondeatributos. } @Override publicvoiddispose(){ } @Override
publicvoidhide(){ } @Override publicvoidpause(){ } @Override publicvoidrender(floatdelta){//deltaeseltiempotranscurridodesdelaultimallamada porsilalogicalonecesita. World.update()//aquiactualizamoslalogicadeljuego. //Pintarimgenes. } @Override publicvoidresize(intwidth,intheight){ } @Override publicvoidresume(){ } @Override publicvoidshow(){ } }
PginasparaDesarrollodeJuegos
DescargarSonidos
http://www.mysoundfx.com/
Musicaparadarambienteatujuego
http://pro.jamendo.com/es/
TutorialcreacinSpritesAnimadasdesdecero
http://ilovepixel.net/tutorial.html
2dGameArtForProgrammers
http://2dgameartforprogrammers.blogspot.com/
CrearunpersonajeparaAnimacin
http://2dgameartforprogrammers.blogspot.com/2011/10/creatinggamecharacter.html
Caras
http://2dgameartforprogrammers.blogspot.com/2011/11/creatingbasicface.html
Fondos http://2dgameartforprogrammers.blogspot.com/2011/10/morefunwithgradients.html
Solucindeproblemas
TODO:Sedescribenlosproblemasquemspuedenaparecerjuntoconsussoluciones.