consultarcanvas2

canvas2  时间:2021-05-20  阅读:()
PROGRAMACINDEJUEGOSPARAMVILESCONJ2ME0000PROGRAMACINDEJUEGOSPARAMVILESCONJ2MEPROGRAMACINDEJUEGOSPARAMVILESCONJ2ME1111ProgramacióndejuegosparamóvilesconJ2MEAlbertoGarcíaSerranowww.
agserrano.
comEstaobraestábajounalicenciaAttribution-NonCommercial-NoDerivs2.
5deCreativeCommons.
Paraverunacopiadeestalicencia,visitehttp://creativecommons.
org/licenses/by-nc-nd/2.
5/oenvieunacartaaCreativeCommons,559NathanAbbottWay,Stanford,California94305,USA.
PROGRAMACINDEJUEGOSPARAMVILESCONJ2ME2222ndice.
Introducción4BreveintroducciónallenguajeJava.
6J2ME.
6EllenguajeJava7Variablesytiposdedatos7Clasesyobjetos.
10ClasesyobjetosenJava.
10Herencia.
13Polimorfismo14Estructurasdecontrol.
14Estructurasdedatos17NuestroprimerMIDlet.
19CompilandoelprimerMIDlet19DesarrollodeMIDlets.
22AnatomíadeunMIDlet.
23Lainterfazdeusuariodealtonivel.
25CómofuncionaunMIDlet26Elementosdelainterfazdeusuario.
28LaclaseAlert.
29LaclaseList.
30LaclaseTextBox31LaclaseForm.
32LaclaseStringItem34LaclaseImageItem.
34LaclaseTextField.
35LaclaseDateField.
36LaclaseChoiceGroup.
36LaclaseGauge.
37Lainterfazgráficadebajonivel.
40PrimitivasGráficas.
43Colores.
43Primitivas.
44Texto.
45Imágenes.
46Sprites48Controldesprites.
49UnUniversoentumóvil.
57Animandonuestroavión57Lecturadelteclado.
57Threads58ElGameLoop.
59Movimientodelavión.
61Construyendoelmapadeljuego.
63Scrolling.
64Enemigos,disparosyexplosiones.
70Tiposdeinteligencia70Comportamientosymáquinasdeestado.
72Enemigos.
73Disparosyexplosiones.
76Sonido79Sonidos.
79PROGRAMACINDEJUEGOSPARAMVILESCONJ2ME3333Música.
80ElAPIdejuegosdeMIDP2.
84GameCanvas84Layer.
88TiledLayer.
89LayerManager.
91Sprite.
93Almacenamiento.
RMS99TrabajandoconRMS99AbrirycerrarunrecordStore99Aadirregistros.
100Leerregistros100Borrarregistros100Recorriendoregistros.
100Comunicaciones104CódigoFuentedeM1945.
108Recursos.
122Bibliografía.
122Java.
122J2ME.
122Enlaces.
122J2ME.
122Programacióndevideojuegos1234444Introducciónosteléfonosmóvilessonyaparteesencialennuestraformadevida.
Cadadíasonmáslosusuariosdeestosterminales,ycadavezmáspequeos.
Hastaahora,noshanacompaadoatodaspartesynoshanpermitidocomunicarnosconcualquierotroterminal,yaseafijoomóvil.
Aunquelacomunicacióntelefónicaporvozeselprincipalusodeestosterminales,prontosehandesarrolladonuevasformasdecomunicaciónyotrascapacidadesentornoanuestrospequeosteléfonos.
Elprimero,yquizásmáslucrativohastalafecha,fueelusodelamensajeríaSMS(ShortMessageService).
Nuestrospequeosterminalesnospermitenenviarmensajescortosdetexto(hastauntamaode160caracteres)quesonenviadosdesdeelterminalalcentroservidordemensajescortosoSMSC(ShortMessageServiceCentre),queasuvezseencargadehacerllegarelmensajealmóvildestinatario.
Mástarde,aparecieronlosterminalescapacesdenavegarporInternet,perolaslimitacionesdelapantallaydelostecladoshacíaninviablesuusoconpáginaswebnormales.
AsínaciólatecnologíaWAP,quenospermitennavegarporpáginasespecialescreadasenWMLenlugardeenHTML.
Sinembargo,laslimitacionesdeestemedio,yquizástambiénporelelevadoprecioylabajavelocidaddelservicio,hanhechoquelatecnologíaWAPnosehayaextendidotantocomosuhermanamayor,laWEB.
Parapaliarlasbajasvelocidades-sincontarconlabajafiabilidad-delatecnologíaGSMparalatransmisióndedatos,apareciólatecnologíaGPRS(GeneralPacketRadioService).
GPRSnosofreceunareddetransferenciadedatossinhilosaunavelocidadaceptable,tantoesasí,queahorasepuedeenviargrandespaquetesdeinformación,comofotografías,música,einclusovideo.
Apartirdeaquí,sehacepatentelanecesidaddeunanuevageneracióndemóvilescapacesdereproducirmúsicasmáscomplejasymostrargráficosyfotografíasencolor.
Alavezqueaparecenestosmóvilesenelmercado,apareceelnuevoserviciodemensajescortosllamadoMMS(MultimediaMessageService).
GraciasaMMS,ademásdetexto,podemosenviarfotografías,sonidos,gráficos,etc.
Peroaúnestabaporllegarlaverdaderarevolución.
SunMycrosystemsdaunpasoadelantedentrodesutecnologíaJava,ynospresentaJ2ME(Java2MicroEdition):unentornodeproducciónparapequeosdispositivosquepermitelaejecucióndeprogramascreadosenJava.
Unadelasprincipalescapacidadesqueaadeestatecnologíaanuestrosterminaleseslaposibilidaddedescargaryejecutarjuegosconunacalidadrazonable.
Hoy,nuestrosteléfonosmóvilescorrenauténticossistemasoperativos.
ElmásconocidoquizásesSymbian,queeselcorazóndegrancantidaddemóviles,comolosNokia,Sony-Ericsson,Motorolayotros.
EstelibrotratasobrecomoprogramarjuegosparaestosdispositivosutilizandoJ2ME.
LaprimeraversióndelaespecificaciónMIDP(MovileInformationDeviceProfile),definíalosrequerimientosmínimosparapoderejecutarprogramasJ2ME,sinembargo,ofrecíanpocaayudaalahoradecrearjuegos,porloquehabíaquerecurriralibreríaspropiasdecadafabricante,haciendonecesariocreardiferentesversionesdeunjuegoparacadafabricante.
Laversión2.
0.
subsanadealgunamaneraesteproblema,ynosofreceunaAPImuchomásadecuadaparalaprogramacióndejuegos.
Decualquierforma,siemprequeusemoslascaracterísticasnuevasdelasegundaversión,seindicaráconvenientemente.
NoquisieraterminarsinagradeceraAriFeldman(http://www.
arifeldman.
com/)susgráficosconlicenciaGPL,quesehanutilizadoparaL5555realizareljuegoM1945.
Esperoquedisfrutesconestelibro.
Encualquiercasopuedecontactarconelautorenladirecciónj2me@agserrano.
com.
6666BreveintroducciónallenguajeJava.
nestecapítuloquieropresentarte,deformageneral,J2MEyencuadrarladentrodelatecnologíaJava.
TambiénvamosahacerunabreveintroducciónallenguajeJava,almenosensusaspectosbásicosparapoderadentrartesinproblemasenlaprogramaciónconJ2ME.
J2MECuandoSundecidiólanzarsunuevostandardJava,llamadoJava2,creótresdiferentesentornosparadesarrolloyejecucióndeaplicaciones.
EstosfueronJ2SE,J2EEyJ2ME.
J2SE(Java2StandardEdition)es,pordecirlodealgunamanera,labasedelatecnologíaJava.
Permiteeldesarrollodeapplets(aplicacionesqueseejecutanenunnavegadorweb)yaplicacionesindependientes(standalone).
J2SEeselherederodirectodelJavainicial(antesdeJava2).
J2EE(Java2EnterpriseEdition)estábasadoenJ2SE,peroaadeunaseriedecaracterísticasnecesariasenentornosempresariales,relativosaredes,accesoadatosyentrada/salidaquerequierenmayorcapacidaddeproceso,almacenamientoymemoria.
Ladecisióndesepararlosesdebidaaquenotodasestascaracterísticassonnecesariasparaeldesarrollodeaplicacionesstandard.
AligualqueJ2EEcubreunasnecesidadesmásampliasqueJ2SE,sehacepatentelanecesidaddeunsubconjuntodeJ2SEparaentornosmáslimitados.
LarespuestadeSunesJ2ME(Java2MicroEdition).
J2MEsebasaenlosconceptosdeconfiguraciónyperfil.
Unaconfiguracióndescribelascaracterísticasmínimasencuantoalaconfiguraciónhardwareysoftware.
LaconfiguraciónqueusaJ2MEeslaCLDC(ConnectedLimitedDeviceConfiguration).
ConcretamenteCLDCdefine:-CuálessonlascaracterísticasdellenguajeJavaincluidas.
-QuéfuncionalidadseráincluidaenlamáquinavirtualJava.
-LasAPIsnecesariasparaeldesarrollodeaplicacionesenmóviles.
-LosrequerimientosHardwaredelosdispositivos.
Debidoalaslimitacionesdelhardwareenelquecorrerálamáquinavirtual,algunasdelascaracterísticasdellenguajeJavahansidorecortadas.
Enconcreto,sehaomitidoelsoportedeoperacionesmatemáticasenpuntoflotante,yporlotanto,lostiposdedatosquemanejanestadeinformación.
Laotragrandiferenciaesquelamáquinavirtualtampocodarásoportealmétodofinalize()encargadodeeliminarlosobjetosdelamemoria.
Tambiénselimitaelnúmerodeexcepcionesdisponiblesparaelcontroldeerrores.
CAPTULO1E7777J2MEestáformadoporlaconfiguraciónCLDCyporelperfilMID(conocidoporMIDPoMIDProfile).
CLDCesunaespecificacióngeneralparaunamplioabanicodedispositivos,quevandesdePDAsateléfonosmóvilesyotros.
Unperfildefinelascaracterísticasdeldispositivodeformamásespecifica.
MIDP(MobileInformationDeviceProfile)definelasAPIsycaracterísticashardwareysoftwarenecesariasparaelcasoconcretodelosteléfonomóviles.
Lascaracterísticasconcretasdelaversión1.
0y2.
0deMIDPpuedenserconsultadasenlapáginawebdeSun(http://java.
sun.
com/j2me/).
EllenguajeJavaEllenguajeJavaesunlenguajecompletamenteorientadoaobjetos.
TodoenJavaesunobjeto.
DuranteelrestodelcapítulovamosaverlascaracterísticasgeneralesdellenguajeJava(sólolasnecesariasenJ2ME),loquenospermitiráentrarenelsiguientecapítuloconlabasenecesariaparaempezaraprogramarMIDlets.
UnMIDletesunprogramacapazdecorrerenundispositivomóvil.
Elnombreguardaciertasimilitud(nocasual)conlosprogramascapacesdecorrerenunnavegador(applets).
SiquieresampliarconocimientossobreellenguajeJava,puedesconsultarlabibliografíaenlosapéndicesdeestelibro.
VariablesytiposdedatosLasvariablesnospermitenalmacenarinformaciónytalcomoindicasupropionombre,puedenvariaralolargodelaejecucióndelprograma.
Unavariablesedefineapartirdeunnombreyuntipo.
Elnombredeunavariablepuedesercualquiera,aunqueconvieneutilizarnombresclarosyrelacionadosconelcometidodelavariable.
Sólohemosdetenerencuentaalgunasreglasenlosnombresdevariables:-Nopuedencontenerespaciosenblanco.
-Dosvariablesnopuedentenerelmismonombre.
-NopodemosutilizarpalabrasreservadasdeJava.
LosprogramadoresenJavasuelenseguirunaseriedeconvencionesalahoradenombrarlasvariables.
Estofacilitalalecturadecódigodeterceros.
-Lasvariablescomienzanconunaletraminúscula.
-Silavariableestácompuestapordosomáspalabras,lasegunda(ylassiguientestambién)comienzanporletramayúscula.
PorejemplonumeroDeVidas.
-Losnombresdelasclasescomienzanporletramayúscula.
Lasvariablestienenasociadasuntipo.
Eltipodelavariabledefinequédatoescapazdealmacenar.
LostiposdedatosválidosenJavasonlossiguientes:-byte.
Ochobits.
-short.
Númeroenterode16bits.
-int.
Númeroenterode32bits.
-long.
Númeroenterode64bits.
-float.
Númeroenpuntoflotantede32bits.
-double.
Númeroenpuntoflotantede64bits.
-char.
CarácterASCII.
-boolean.
Valorverdaderoofalso.
8888Hayqueaclararquelostiposfloatydouble,aúnformandopartedelstandardJava,noestándisponiblesenJ2ME.
Antesdepoderutilizarunavariable,hayquedeclararla,esdecir,darleunnombreyuntipo.
Lasiguientelíneadeclaraunavariablellamadavidasdetipoenterode32bits.
intvidas;Unavariableporsímismanoesmuyútil,anoserquepodamosrealizaroperacionesconellas.
Estasoperacionesserealizanpormediodeoperadores.
Haycincotiposdeoperadores.
-Deasignación-Aritméticos-Relaciónales-Lógicos-AniveldebitCuandodeclaramosunavariableéstanocontieneningúnvalor(realmentesi,tieneelvalornull).
Paradarleunvaloralavariableutilizamoseloperadordeasignación=(signodeigualdad).
Así,paraasignarelvalor3alavariablevidas,procedemosdelasiguienteforma.
vidas=3;Observaelpuntoycoma(;)alfinaldelalínea.
EnJavacadainstrucciónacabaconunpuntoycoma.
Tenemosdisponiblesotrosoperadoresdeasignación:a+=ba=a+ba-=ba=a–ba*=ba=a*ba/=ba=a/ba%=ba=a%ba&=ba=a&ba|=ba=a|bLossiguientesoperadoresquevamosaversonlosoperadoresaritméticos.
Haydostipos,losoperadoresunariosylosbinarios.
Losoperadoresaritméticosunariosson++y--.
Puedenirdelanteodetrásdeunavariable,ysumisiónesincrementar(odecrementar)enunaunidadelvalordelavariable.
Sisesitúantraslavariablehablamosdepostincremento(opostdecremento),esdecir,lavariableesincrementada(odecrementada)despuésdehabersehechousodeella.
Siporelcontrariovadelantehablamosdepreincremento(opredecremento),esdecir,primerosemodificasuvalorydespuéssehaceusodelavariable.
Veamosunejemplo:nuevasVidas=++vidas;Enesteejemplo,primeroincrementamoselvalordelavariablevidas,ydespuésseloasignamosalavariablenuevasVidas.
enemigoActual=enemigos--;Aquí,primeroasignamosalavariableenemigoActualelvalordelavariableenemigos,ydespuésdecrementamoselvalordeestaúltimavariable.
Elotrotipodeoperadoresaritméticossonlosbinarios.
9999a+bSumadeayba-bDiferenciadeayba*bProductodeaporba/bDiferenciaentreayba%bRestodeladivisiónentreaybLosoperadoresrelacionalesnospermitencomparardosvariablesovalores.
Unoperadorrelacionaldevuelveunvalordetipoboolean,esdecir,verdadero(true)ofalso(false).
a>btruesiaesmayorqueba=btruesiaesmayoroigualqueba>bDesplazalosbitsdeahacialaderechabvecesa0){vueltas--;}Alaentradadelbucle,lavariablevueltastieneelvalor10.
Mientraselvalordeestavariableseamayorque0,sevaarepetirelbloquedecódigoquecontiene.
Enestecaso,elbloquedecódigoseencargadedecrementarlavariablevuelta,porloquecuandosuvalorlleguea0,novolveráaejecutarse.
Loqueestamoshaciendoessimularunbucleforqueseejecuta10veces.
Elbucledo/whilefuncionadeformasimilaralanterior,perohacelacomprobaciónalasalidadelbucle.
do{sentencias;}while(condición);Elsiguienteejemplo,esigualqueelanterior.
Ladiferenciaentreambosesqueconelbucledo/while,elcódigoseejecutarásiemprealmenosunavez,yaquelacomprobaciónsehacealfinal,mientrasqueconelbuclewhile,esposiblequenuncaseejecuteelcódigointernosinosecumplelacondición.
vueltas=10;do{vueltas--;}while(vueltas>0);VeamosunaúltimaestructurapropiadeJava(noexisteenC)yquenospermiteejecutaruncódigodeformacontrolada.
Concretamentenospermitetomaraccionesespecíficasencasodeerrordeejecuciónenelcódigo.
17171717try{sentencias;}catch(excepción){sentencias;}Sielcódigoincluidoenelprimerbloquedecódigoproducealgúntipodeexcepción,seejecutaráelcódigocontenidoenelsegundobloquedecódigo.
UnaexcepciónesuntipodeerrorqueJavaescapazdecontrolarpordecirlodeunaformasencilla,realmente,unaexcepciónesunobjetodelaclaseException.
Siporejemplo,dentrodelprimerbloquedecódigointentamosleerunarchivo,ynoseencuentraenlacarpetaespecificada,elmétodoencargadodeabrirelarchivolanzaráunaexcepcióndeltipoIOException.
EstructurasdedatosYahemosvistolostiposdedatosquesoportaJava.
Ahoravamosaverunpardeestructurasmuyútiles.
Concretamentelacadenadecaracteresylosarrays.
Unacadenadecaracteresesunasucesióndecaracterescontinuos.
Vanencerradossiempreentrecomillas.
Porejemplo:"EnunlugardeLaMancha.
.
.
"Esunacadenadecaracteres.
Paraalmacenarunacadena,JavadisponedeltipoString.
Stringtexto;Unavezdeclaradalavariable,paraasignarleunvalor,lohacemosdelaformahabitual.
texto="Estoesuntexto";Podemosconcatenardoscadenasutilizandoeloperador+.
Tambiénpodemosconcatenarunacadenayuntipodedatosdistinto.
Laconversiónacadenasehacedeformaautomática.
Stringtexto;intvidas;texto="Vidas:"+vidas;PodemosconocerlalongituddeunavariabledetipoString(realmenteunobjetodetipoString)haciendousodesumétodolenght.
longitud=texto.
lenght();Elotrotipodedatosqueveremosacontinuacióneselarray.
Unarraynospermitealmacenarvarioselementosdeunmismotipobajoelmismonombre.
Imaginaunjuegomultijugadorenelquepuedenparticiparcincojugadoresalavez.
Cadaunollevarásupropiocontadordevidas.
Medianteunarrayde5elementosdetipoentero(int)podemosalmacenarestosdatos.
Ladeclaracióndeunarraysehaceasí.
publicint[]vidas;vidas=newint[5];18181818odirectamente:publicint[]vidas=newint[5];Hemosdeclaradounarraydecincoelementosllamadovidasformadoporcinconúmerosenteros.
Siquisiéramosacceder,porejemplo,altercerelementodelarray,loharíamosdelasiguientemanera.
v=vidas[3];Lavariablevtomaráelvalordeltercerelementodelarray.
Laasignacióndeunvaloresexactamenteigualaladecualquiervariable.
vidas[3]-=1;Elsiguienteejemplomuestraelusodelosarrays.
tmp=0;for(i=1;ix2)&&((y1+h1)>y2)&&((x2+w2)>x1)&&((y2+h2)>y1)){returntrue;}else{returnfalse;}}Setratadecomprobarsielcuadrado(superficie)quecontieneelprimersprite,sesolapaconelcuadradoquecontienealsegundo.
Hayotrométodosmásprecisosquenospermitendetectarcolisiones.
Consisteendividirelspriteenpequeassuperficiesrectangularestalycomomuestralapróximafigura.
Figura5.
5.
UnmétodomáselaboradodedeteccióndecolisionesSepuedeobservarlamayorprecisióndeestemétodo.
Elprocesodedetecciónconsisteencomprobarsihaycolisióndealgunodeloscuadrosdelprimerspriteconalgunodeloscuadradosdelsegundoutilizandolamismacomprobaciónquehemosutilizadoenelprimermétodoparadetectarsisesolapandosrectangulos.
Sedejacomoejercicioallectorlaimplementacióndeestemétododedeteccióndecolisiones.
Acontinuaciónsemuestraellistadocompletodenuestralibrería.
53535353importjavax.
microedition.
midlet.
*;importjavax.
microedition.
lcdui.
*;importjava.
util.
*;importjava.
io.
*;classSprite{privateintposx,posy;privatebooleanactive;privateintframe,nframes;privateImage[]sprites;//constructor.
'nframes'eselnúmerodeframesdelSprite.
publicSprite(intnframes){//ElSpritenoestáactivopordefecto.
active=false;frame=1;this.
nframes=nframes;sprites=newImage[nframes+1];}publicvoidsetX(intx){posx=x;}publicvoidsetY(inty){posy=y;}intgetX(){returnposx;}intgetY(){returnposy;}intgetW(){returnsprites[nframes].
getWidth();}intgetH(){returnsprites[nframes].
getHeight();}publicvoidon(){active=true;}publicvoidoff(){active=false;}publicbooleanisActive(){returnactive;}publicvoidselFrame(intframeno){frame=frameno;}publicintframes(){returnnframes;}//Cargaunarchivotipo.
PNGyloaadealspriteen//elframeindicadopor'frameno'publicvoidaddFrame(intframeno,Stringpath){try{sprites[frameno]=Image.
createImage(path);}catch(IOExceptione){System.
err.
println("Can`tloadtheimage"+pathe.
toString());}}54545454booleancollide(Spritesp){intw1,h1,w2,h2,x1,y1,x2,y2;w1=getW();//anchodelsprite1h1=getH();//alturadelsprite1w2=sp.
getW();//anchodelsprite2h2=sp.
getH();//altodelsprite2x1=getX();//pos.
Xdelsprite1y1=getY();//pos.
Ydelsprite1x2=sp.
getX();//pos.
Xdelsprite2y2=sp.
getY();//pos.
Ydelsprite2if(((x1+w1)>x2)&&((y1+h1)>y2)&&((x2+w2)>x1)&&((y2+h2)>y1)){returntrue;}else{returnfalse;}}//DibujamoselSpritepublicvoiddraw(Graphicsg){g.
drawImage(sprites[frame],posx,posy,Graphics.
HCENTER|Graphics.
VCENTER);}}55555555Veamosunejemploprácticodeusodenuestralibrería.
CreaunnuevoproyectoenKToolBar,yaadeelprogramasiguienteeneldirectorio'src',juntoconlalibreríaSprite.
java.
Porsupuestonecesitarásincluirelgráficohero.
pngeneldirectorio'res'.
EnlossiguientescapítulosvamosabasarnosenestalibreríaparaelcontroldelosSpritesdeljuegoquevamosacrear.
Figura5.
6.
NuestroprimerSprite.
56565656importjavax.
microedition.
midlet.
*;importjavax.
microedition.
lcdui.
*;publicclassSpriteTestextendsMIDletimplementsCommandListener{privateCommandexitCommand,playCommand,endCommand;privateDisplaydisplay;privateSSCanvasscreen;publicSpriteTest(){display=Display.
getDisplay(this);exitCommand=newCommand("Salir",Command.
SCREEN,2);screen=newSSCanvas();screen.
addCommand(exitCommand);screen.
setCommandListener(this);}publicvoidstartApp()throwsMIDletStateChangeException{display.
setCurrent(screen);}publicvoidpauseApp(){}publicvoiddestroyApp(booleanunconditional){}publicvoidcommandAction(Commandc,Displayables){if(c==exitCommand){destroyApp(false);notifyDestroyed();}}}classSSCanvasextendsCanvas{privateSpritemiSprite=newSprite(1);publicSSCanvas(){//CargamoslosspritesmiSprite.
addFrame(1,"/hero.
png");//IniciamoslosSpritesmiSprite.
on();}publicvoidpaint(Graphicsg){//Borrarpantallag.
setColor(255,255,255);g.
fillRect(0,0,getWidth(),getHeight());//situarydibujarspritemiSprite.
setX(50);miSprite.
setY(50);miSprite.
draw(g);}}57575757UnUniversoentumóvil.
horaquehemosdesarrolladounaherramientaparaelcontroldesprites,vamosaaprenderasacarlepartido.
Connuestralibreríaseremoscapacesdemostrarenlapantalladeldispositivotodoloquevaocurriendoeneljuego,perotambiénhemosdesercapacesdeleerlainformacióndesdeeltecladodelmóvilpararesponderalasinstruccionesquedaeljugador.
Tambiénesimportantequeelmovimientodeljuegoseasuaveysuficientementerápido.
Enestecapítuloexaminaremoslascapacidadesdeanimacióndelosmidlets,incluidoelscrolling,asícomolainterfazconelteclado.
AnimandonuestroaviónLecturadeltecladoTodaaplicacióninteractivanecesitaunmedioparacomunicarseconelusuario.
VamosautilizarparaellotresmétodosquenosofrecelaclaseCanvas.
LosmétodoskeyPressed(),keyReleased()ykeyRepeated().
Estosmétodossonllamadoscuandoseproduceuneventorelacionadoconlapulsacióndeunatecla.
keyPressed()esllamadocuandoseproducelapulsacióndeunatecla,ycuandosoltamoslateclaesinvocadoelmétodokeyReleased().
ElmétodokeyRepeated()esinvocadodeformarepetitivacuandodejamosunateclapulsada.
Lostresmétodosrecogencomoparámetrounnúmeroentero,queeselcódigounicodedelateclapulsada.
LaclaseCanvastambiénnosofreceelmétodogetGameAction(),queconvertiráelcódigoaunaconstanteindependientedelfabricantedeldispositivo.
Lasiguientetabla,muestraunalistadeconstantesdecódigosestándar.
KEY_NUM0,KEY_NUM1,KEY_NUM2,KEY_NUM3,KEY_NUM4,KEY_NUM5,KEY_NUM6,KEY_NUM7,KEY_NUM8,KEY_NUM9TeclasnuméricasKEY_POUNDTecla'almohadilla'KEY_STARTeclaasteriscoGAME_A,GAME_B,GAME_C,GAME_DTeclasespecialesdejuegoUPArribaDOWNAbajoLEFTIzquierdaRIGHTDerechaFIREDisparoLosfabricantesdedispositivosmóvilessuelenreservarunasteclasconfuncionesmásomenosprecisasdeformaquetodoslosjuegossecontrolendeformasimilar.
Otros,comoelcasodelNokia7650ofrecenunmini-joystick.
Usandolasconstantesdelatablaanterior,podemosabstraernosdelaspeculiaridadesdecadafabricante.
Porejemplo,enelNokia7650,cuandomovamoseljoystickhaciaarribasegeneraraelcódigoUP.
Vemosunejemplodeuso:publicvoidkeyPressed(intkeyCode){intaction=getGameAction(keyCode);CAPTULO6A58585858switch(action){caseFIRE://Dispararbreak;caseLEFT://Moveralaizquierdabreak;caseRIGHT://Moveraladerechabreak;caseUP://Moverhaciaarribabreak;caseDOWN://Moverhaciaabajobreak;}}PuedeparecerlógicoutilizarkeyRepeated()paracontrolarunspriteenlapantalla,yaquenosinteresaquemientraspulsemosunatecla,estesemantengaenmovimiento.
Enprincipioestaseríalamaneracorrectadehacerlo,peroenlapractica,notodoslosdispositivossoportanlaautorepeticióndeteclas(incluidoelemuladordeSun).
Vamosasolucionarloconelusodelosotrosdosmétodos.
Loquequeremosconseguiresqueenelintervalodetiempoqueeljugadorestápulsandounatecla,semantengalaanimación.
EsteintervalodetiempoesprecisamenteeltranscurridoentrequeseproducelallamadaalmétodokeyPressed()ylallamadaakeyReleased().
Unpocomásabajoveremoscomoseimplementaestatécnica.
ThreadsComenzamosestelibroconunaintroducciónaJava.
Deformaintencionada,ydebidoalovoluminosoqueesellenguajeJava,algunostemasnofueroncubiertos.
Unodeestostemasfueronlosthreads.
Vamosaverlossomeramente,ahoraqueyaestamosalgomásfamiliarizadosconellenguaje,yloutilizaremosennuestrojuego.
Muyprobablementeelsistemaoperativoqueutilizastienecapacidadesdemultiprocesoomultitarea.
Enunsistemadeestetipo,puedesejecutarvariasaplicacionesalmismotiempo.
Acadaunadeestasaplicacioneslasdenominamosprocesos.
Podemosdecirqueelsistemaoperativoescapazdeejecutarmúltiplesprocesossimultáneamente.
Sinembargo,enocasionesesinteresantequedentrodeprocesoselancenunoomássubprocesosdeformasimultánea.
Vamosautilizarunejemploparaaclararelconcepto.
Piensaentunavegadorwebfavorito.
Cuandololanzas,esunprocesomásdentrodelalistadeprocesosqueseestanejecutandoenelsistemaoperativo.
Ahora,supongamosquecargamosenelnavegadorunawebllenadeimágenes,einclusoalgunasdeellasanimadas.
Siobservaselprocesodecarga,verásquenosecargandeformasecuencialunatrasotra,sinoquecomienzanacargarsevariasalavez.
Estoesdebidoaqueelprocesodelnavegadorlanzavariossubprocesos,unoporcadaimagen,queseencargandecargarlas,yensucaso,deanimarlasdeformaindependientealrestodeimágenes.
Cadaunodeestossubprocesossedenominathread(hiloohebraencastellano).
EnJava,unthreadpuedeestarencuatroestadosposibles.
Ejecutándose:Estáejecutándose.
Preparado:Estápreparadoparapasaralestadodeejecución.
Suspendido:Enesperadealgúnevento.
Terminado:Sehafinalizadolaejecución.
59595959LaclasequedasoporteparalosthreadsenJavaesjava.
lang.
Thread.
EntodomomentopodremosteneraccesoalthreadqueestáenejecuciónusandoelmétodoThread.
currentThread().
Paraqueunaclasepuedaserejecutadacomounthreadhadeimplementarlainterfazjava.
lang.
Runnable,enconcreto,elmétodorun().
steeselmétodoqueseejecutarácuandolancemoselthread:publicclassHiloimplementsRunnable{publicvoidrun(){//códigodelthread}}Paraarrancarunthreadusamossumétodostart().
//Creamoselobjeto(queimplementaRunable)HilomiHilo=newHilo();//CreamosunobjetodelaclaseThread//AlquepasamoscomoparámetroalobjetomiHiloThreadmiThread=newThread(miHilo);//ArrancamoselthreadmiThread.
start();Sisólovamosautilizarelthreadunavezynolovamosareutilizar,siemprepodemossimplificarlo.
HilomiHilo=newHilo();newThread(miHilo).
start();LaclaseThreadnosofrecealgunosmétodosmás,perolosmásinteresantessonstop(),quepermitefinalizarunthread,ysleep(inttime),quelodetienedurantelosmilisegundosqueleindiquemoscomoparámetro.
ElGameLoopCuandojugamosaunjuegoparecequetodopasaalavez,enelmismoinstante,sinembargo,sabemosqueunprocesadorsólopuederealizarunaacciónalavez.
Laclaveesrealizarcadaunadelasaccionestanrápidamentecomoseaposibleypasaralasiguiente,deformaquetodassecompletenantesdevisualizarelsiguienteframedeljuego.
El"gameloop"obucledejuegoeselencargadode"dirigir"encadamomentoquetareaseestárealizando.
Enlafigura6.
1.
podemosverunejemplodegameloop,yaunquemásomenostodossonsimilares,notienenporquetenerexactamentelamismaestructura.
Analicemoselejemplo.
Loprimeroquehacemosesleerlosdispositivosdeentradaparaversieljugadorharealizadoalgunaacción.
Sihuboalgunaacciónporpartedeljugador,elsiguientepasoesprocesarla,estoes,actualizarsuposición,disparar,etc.
.
.
,dependiendodequéacciónsea.
Enelsiguientepasorealizamoslalógicadejuego,esdecir,todoaquelloqueformapartedelaacciónyquenoquedabajocontroldeljugador,porejemplo,elmovimientodelosenemigos,cálculodetrayectoriadesusdisparos,comprobacióndecolisionesentrelanaveenemigayladeljugador,etc.
.
.
Fueradelalógicadeljuegoquedanotrastareasquerealizamosenlasiguientefase,comosonactualizarelscrolldefondo(silohubiera),activarsonidos(sifuera60606060necesario),realizartrabajosdesincronización,etc.
.
Yaporúltimo,nosrestavolcartodoalapantallaymostrarelsiguienteframe.
Estafaseesllamada"fasederender".
Normalmente,elgamelooptendráunaspectosimilaralosiguiente:intdone=0;while(!
done){//Leerentrada//Procesarentrada//Lógicadejuego//Otrastareas//Mostrarframe}Antesdequeentremosenelgameloop,tendremosquerealizarmúltiplestareas,comoinicializartodaslasestructurasdedatos,etc.
.
.
Elsiguienteejemploesmuchomásrealista.
Estáimplementadoenunthread.
publicvoidrun(){iniciar();while(true){//ActualizarfondodepantalladoScroll();//ActualizarposicióndeljugadorcomputePlayer();//Actualizarpantallarepaint();serviceRepaints();try{Thread.
sleep(sleepTime);}catch(InterruptedExceptione){System.
out.
println(e.
toString());}}}Loprimeroquehacemosesinicializarelestadodeljuego.
Seguidamenteentramosenelbucleprincipaldeljuegoogamelooppropiamentedicho.
Enestecaso,esunbucleinfinito,peroenunjuegoreal,tendríamosquepodersalirusandounavariablebooleanaqueseactivaraalproducirseladestruccióndenuestroaviónocualquierotroeventoquesupongalasalidadeljuego.
Yadentrodelbucle,loquehacemosesactualizarelfondodepantalla-enlasiguientesecciónentraremosenlosdetallesdeesteproceso-,acontinuación,calculamoslaposicióndenuestroaviónparaposteriormenteforzarunrepintadodelapantallaconunallamadaarepaint()yserviceRepaints().
Porúltimo,utilizamoselmétodosleep()pertenecientealaclaseThreadparaintroducirunpequeoretardo.
Esteretardohabrádeajustarsealavelocidaddeldispositivoenqueejecutemoseljuego.
61616161GameloopLeereventosdeentrada(Joystick,mouse,teclado)Procesarentrada(moverjugador)Lógicadejuego(moverenemigos,procesarcolisiones,etc.
.
.
)Otrastareas(Animarfondo(scroll),sonidos,sincronizartiempo,etc.
.
.
)Visualizarenpantalla(render)Figura6.
1.
GameLoopgenéricoMovimientodelaviónParamovernuestroaviónutilizaremos,comocomentamosenlaseccióndedicadaalalecturadelteclado,losmétodoskeyPressed()ykeyReleased().
Concretamente,loquevamosahaceresutilizardosvariablesparaalmacenarelfactordeincrementoaaplicarenelmovimientodenuestroaviónencadavueltadelbucledeljuego.
EstasvariablessondeltaXydeltaYparaelmovimientohorizontalyvertical,respectivamente.
publicvoidkeyReleased(intkeyCode){intaction=getGameAction(keyCode);switch(action){62626262caseLEFT:deltaX=0;break;caseRIGHT:deltaX=0;break;caseUP:deltaY=0;break;caseDOWN:deltaY=0;break;}}publicvoidkeyPressed(intkeyCode){intaction=getGameAction(keyCode);switch(action){caseLEFT:deltaX=-5;break;caseRIGHT:deltaX=5;break;caseUP:deltaY=-5;break;caseDOWN:deltaY=5;break;}}Cuandopulsamosunatecla,asignamoselvalorcorrespondientealdesplazamientodeseado,porejemplo,siqueremosmoverelaviónaladerecha,elvalorasignadoadeltaXserá5.
Estosignificaqueencadavueltadelgameloop,sumaremos5alaposicióndeavión,esdecir,sedesplazará5píxelesaladerecha.
Cuandosesueltalatecla,inicializamosa0lavariable,esdecir,detenemoselmovimiento.
Lafunciónencargadadecalcularlanuevaposicióndelaviónes,pues,bastantesencilla.
voidcomputePlayer(){//actualizarposicióndelaviónif(hero.
getX()+deltaX>0&&hero.
getX()+deltaX0&&hero.
getY()+deltaY=32){indice_in=0;indice-=xTiles;}if(indice=32){indice_in=0;indice-=xTiles;}if(indice0&&hero.
getX()+deltaX0&&hero.
getY()+deltaY50&&state!
=2){//pasoalestado2(movimientodiagonal)state=2;if((Math.
abs(random.
nextInt())%2)+1==1){deltaX=2;}else{deltaX=-2;}}//movemoslanavesetX(getX()+deltaX);setY(getY()+deltaY);}publicvoidinit(intxhero){deltaY=3;deltaX=0;if(type==1){if(xhero>getX()){deltaX=2;}else{deltaX=-2;}}}//SobrecargadelmétododrawdelaclaseSpritepublicvoiddraw(javax.
microedition.
lcdui.
Graphicsg){selFrame(type);//llamamosalmétodo'draw'delaclasepadre(Sprite)super.
draw(g);}publicEnemy(intnFrames){super(nFrames);}}AlosatributosdelaclaseSpriteaadimoscuatromás.
Elatributotype,indicarácuáleseltipodeenemigo.
Ennuestrocasohaydostipos.
Paramanejaresteatributodotamosanuestra75757575clasedelosmétodosgetType()ysetType()paraconsultaryestablecereltipodelenemigo.
Elatributostatemantendráelestadodelanave.
Lanavedetipo2,esdecirlaquecambiasutrayectoria,tienedosestado.
Enelestado1simplementeavanzaenhorizontal.
Enelestado2sutrayectoriaesdiagonal.
ParamanejarelestadodelosenemigosaadimoslasclasesgetState()ysetState()paraconsultaryestablecerelestadodelosenemigos.
LosdosatributosquenosquedansondeltaXydeltaY,quecontienenlosdesplazamientosenelejehorizontalyverticalrespectivamentequeseproduciráencadavueltadelgameloop.
Alcrearunainstanciadenuestraclase,loprimeroquehemosdehacerenelconstructoresllamaralaclasepadre,queesSprite,parapasarleelparámetroquenecesitaparareservarelnúmerodeframes.
Tambiénparainicializarelsprite.
super(nFrames);Vamostambienasobrecargarelmétododraw()delmétodoSprite.
Enestemétodo,primeroseleccionaremoseltipodeaviónquevamosaponerenlapantallasegúnsutipo,después,llamamosalmétododraw()delaclasepadre.
Nuestroenemigodetipo1debetomarunatrayectoriadependiendodelaposicóndenuestroavión.
Paraello,necesitamosunaformadecomunicarlealanaveenemigadichaposición.
Hemoscreadounmétodollamadoinit()alaquelepasamoscomoparámetrolaposiciónactualdenuestroavión.
EnestemétodoponemoslosatributosdeltaXydeltaYasusvaloresiniciales.
Porúltimonecesitaremosunmétodoqueseencarguederealizarelmovimientodelanave.
EstemétodoesdoMovement().
SufunciónprincipalesactualizarlaposicióndelanaveenemigasegúnlosatributosdeltaXydeltaY.
Tambiéncomprobamoslaposicióndelenemigodetipo1paracambiarsuestadocuandoseanecesario.
YadisponemosdenuestraclaseEnemyparamanejaralosavionesenemigos.
Ennuestrojuegopermitiremosunmáximode6enemigossimultáneosenpantalla(realmentehabrámenos),asíquecreamosunarraydeelementosdetipoEnemy.
Elsiguientepasoesinicializarcadaunodeestosseiselementos.
Vamosacargardosframes,unoparalanavedetipo1yotroparaladetipo2.
Dependiendodeltipodelanave,seleccionaremosunframeuotroantesdedibujarelavión.
privateEnemy[]enemies=newEnemy[7];//Inicializarenemigosfor(i=1;igetHeight())||(enemies[i].
getY()super.
frames())super.
off();}//SobrecargadelmétododrawdelaclaseSpritepublicvoiddraw(javax.
microedition.
lcdui.
Graphicsg){selFrame(state);//llamamosalmétodo'draw'delaclasepadre(Sprite)super.
draw(g);}}Elúnicoatributoqueaadimosesstate,quenosindicaráelestadodelaexplosión.
Enlapráctica,elestadodelaexplosiónvaaserelframeactualdesuanimacióninterna,dehecho,suclasedoMovement()loúnicoquehaceesaumentarelframepararealizarlaanimación.
Lainicializaciónygestióndeexplosionesydisparosesidénticaaladelosavionesenemigos,porloquenovamosaentrarenmuchomásdetalle.
Nosrestacomprobarlascolisionesentrelosspritesdeljuego.
Vamosarealizartrescomprobaciones.
Colisiónhéroe–enemigoColisiónhéroe–disparoColisiónenemigo–disparo78787878Tenencuentaquehay6posiblesenemigosy6posiblesdisparosalavezenpantalla,porloquehayquerealizartodaslascombinacionesposibles.
//Colisiónheroe-enemigofor(i=1;i20)posx-=5;elsemapx+=5;}if((keyStates&RIGHT_PRESSED)!
=0){if(posx20)posy-=5;elsemapy+=5;}if((keyStates&DOWN_PRESSED)!
=0){if(posy80)posx-=5;elsemapx+=5;hero.
setFrame(2);98989898}if((keyStates&RIGHT_PRESSED)!
=0){if(posx20)posy-=5;elsemapy+=5;hero.
setFrame(0);}if((keyStates&DOWN_PRESSED)!
=0){if(posy"+dato);}catch(EOFExceptioneofe){}catch(IOExceptionioe){}}catch(RecordStoreExceptione){}}publicvoidguardaRegistro(RecordStorers,Stringdato){ByteArrayOutputStreambaos=newByteArrayOutputStream();DataOutputStreamos=newDataOutputStream(baos);try{//guadareldatoos.
writeUTF(dato);}catch(IOExceptionioe){}103103103103//extraerelarraydebutesbyte[]b=baos.
toByteArray();//loaadimosalrecordStoretry{rs.
addRecord(b,0,b.
length);}catch(RecordStoreExceptionrse){}}publicvoiddestroyApp(booleanunconditional){}publicvoidstartApp(){}publicvoidpauseApp(){}}104104104104Comunicacionesnteléfonomóvilescapazderealizarconexionesconunservidor.
Estoabreunvastocampodeaplicacionesytambiénmuchasposibilidadesenelcampodelosjuegos.
Unaposibleaplicaciónpuedeserunservidorquealmacenelaspuntuacionesmáximasentretodoslosjugadoresdeunjuego,oinclusolaposibilidaddejuegoonlinecontraotrosjugadores.
EnprincipiounMIDletpuedeestablecerdiversostiposdeconexiones:Sockets,http,https,datagramas,yotras,sinembargo,elstandardsóloobligaalaimplementacióndelprotocolohttp,asíquedependiendodeldispositivodispondremosdeunostiposdeconexionesuotras.
Paramantenerlacompatibilidadesaconsejableutilizarlasbasadasenelprotocolohttpy,porlotanto,limitarnosaestetipodeconexión.
LaclaseConnector,queseencuentraenelpaquetejavax.
microedition.
io,eslabasedelascomunicacionesenlosMIDlets.
Paraabrirunaconexiónutilizamoselmétodoopen()delaclaseConnector.
Connector.
open(Stringconexion);ElparámetroconexióneslaURLalaquequeremosconectar.
ElformatodelaURLeselstandard.
Lossiguientessonformatosválidos.
http://www.
dominio.
comhttp://www.
dominio.
com:8080http://www.
dominio.
com/script.
jspparam1=1¶m2=2UnaformamuyestandarizadadecomunicaciónconunservidoresmediantellamadasascriptsescritosenJSP,PHPocualquierotrolenguajedescript,ypasandolosparámetrosnecesarios,yaseapormétodopostométodoget.
Estescriptprocesarálainformaciónyharáusodeella,porejemplo,almacenándolaenunabasededatos.
Laescrituradescriptsseescapadelámbitodeestelibro,sinembargo,podrásencontrarnumerosaspublicacionessobreeltemaademásdegrancantidaddeinformaciónenInternet.
Ademásdeconexioneshttp,podemosabrirotrostiposdeconexionessiemprequenuestroteléfonomóvillosoporte.
Socketsocket://www.
dominio.
com:8000Datagramasdatagram://www.
dominio.
com:8000Archivosfile:/datos.
txtPuertoscomm:0;baudrate=9600UnavezabiertoelcanaldecomunicaciónpodemosutilizarlosmétodosopenInputStream()yopenOutputStream()delaclaseConnectorparaabrirunacorrientedelecturaoescrituramediantelacual,leeryescribirinformación.
ElmétodoopenInputStream()devuelveunobjetodeltipoInputStream,querepresentaunacorrientedeentradadebytes.
Contienealgunosmétodosquepermitencontrolarlaentradadedatos.
Losmásinteresantesson:CAPTULO11U105105105105intavailable()Númerodebytesdisponiblesenlacorrientedelecturavoidclose()Cierralacorrienteabstractintread()LeeelsiguientebytedelacorrienteDeformasimilar,elmétodoopenOutputStream()devuelveunobjetodetipoOutputStream,querepresentaunacorrientedesalidadebytes.
Losmétodosmásinteresantesson:voidclose()Cierralacorrientevoidflush()Fuerzalasalidadelosbytesalmacenadosenelbuffervoidwrite(byte[]b)abstractvoidwrite(intb)EscribeunbyteounarraydebytesenlacorrientedesalidaNosrestaconocerlaclaseHttpConnection,quegestionaunaconexiónbasadaenelprotocolohttp.
Podemoscrearunaconexióndeestetipomedianteelmétodoopen()delaclaseConnectortalycomoyavimos.
HttpConnectionc=(HttpConnection)Connector.
open(url);Algunosmétodosinteresantessonlossiguientes:StringgetHost()DevuelveelnombredelhostremotointgetPort()DevuelveelpuertodeconexiónStringgetQuery()DevuelvelosparámetrospasadosenlaURLStringgetRequestMethod()DevuelveelmétododepeticiónintgetResponseCode()DevuelveelcódigoderespuestaStringgetResponseMessage()DevuelveelmensajederespuestaStringgetURL()DevuelvelaURLdelaconexiónvoidsetRequestMethod(Stringmethod)Estableceelmétododepetición(GET,POSToHEAD)Parailustrartododuranteelcapítulo,vamosadesarrollarunprogramaqueescapazdeconectarconunserviciowebyobtenerinformación.
Nosconectaremosaunawebdenoticias(weblog)yextraeremoslascabecerasdelasnoticiasparamostrarlasennuestromóvil.
Lawebquevamosautilizareswww.
barrapunto.
com.
106106106106Figura10.
1.
Webdebarrapunto.
comEstawebpermiteaccederalainformaciónenformatoXMLenlaURLhttp://backends.
barrapunto.
com/barrapunto.
xml,queproduceunasalidacomoésta(reproducimosaquíunasólanoticia):TutorialdeSecureShellhttp://barrapunto.
com/article.
plsid=04/01/21/10482222004-01-2110:46:17fernand0ssh-scp-ssh-keygen8536articlestopicseguridad.
pngLostítulosdelasnoticiasestánencerradasentrelasetiquetasy,asíquevamosaextraereltextoqueseencuentreentreambas.
Figura10.
2.
Salidadenuestrolectordenoticias.
111107070707importjava.
io.
*;importjavax.
microedition.
io.
*;importjavax.
microedition.
lcdui.
*;importjavax.
microedition.
midlet.
*;publicclassConexionextendsMIDlet{privateDisplaydisplay;//UrlquevamosaconsultarStringurl="http://backends.
barrapunto.
com/barrapunto.
xml";publicConexion(){display=Display.
getDisplay(this);}publicvoidstartApp(){try{verNoticias(url);}catch(IOExceptione){}}publicvoidpauseApp(){}publicvoiddestroyApp(booleanunconditional){}voidverNoticias(Stringurl)throwsIOException{HttpConnectionc=null;InputStreamis=null;StringBufferb=newStringBuffer();StringBuffersalida=newStringBuffer();TextBoxt=null;try{c=(HttpConnection)Connector.
open(url);c.
setRequestMethod(HttpConnection.
GET);c.
setRequestProperty("IF-Modified-Since","10Nov200017:29:12GMT");c.
setRequestProperty("User-Agent","Profile/MIDP-1.
0Configuration/CLDC-1.
0");c.
setRequestProperty("Content-Language","es-ES");is=c.
openInputStream();intch,i,j;//leerlosdatosdesdelaURLwhile((ch=is.
read())!
=-1){b.
append((char)ch);if(ch=='\n'){if(b.
toString().
indexOf("")>0){i=b.
toString().
indexOf("")+7;j=b.
toString().
indexOf("");salida.
append(b.
toString().
substring(i,j));salida.
append("\n-n");}b.
delete(0,b.
length());}}//mostrarnoticiasenlapantallat=newTextBox("Noticiasenbarrapunto.
com",salida.
toString(),1024,0);}finally{if(is!
=null){is.
close();}if(c!
=null){c.
close();}}display.
setCurrent(t);}}108108108108CódigoFuentedeM1945M1945.
javapackagemygame;importjavax.
microedition.
midlet.
*;importjavax.
microedition.
lcdui.
*;importjava.
util.
*;importjava.
io.
*;publicclassM1945extendsMIDletimplementsCommandListener{privateCommandexitCommand,playCommand,endCommand;privateDisplaydisplay;privateSSCanvasscreen;publicM1945(){display=Display.
getDisplay(this);exitCommand=newCommand("Salir",Command.
SCREEN,2);playCommand=newCommand("Jugar",Command.
CANCEL,2);endCommand=newCommand("Salir",Command.
SCREEN,2);screen=newSSCanvas();screen.
addCommand(playCommand);screen.
addCommand(exitCommand);screen.
setCommandListener(this);}publicvoidstartApp()throwsMIDletStateChangeException{display.
setCurrent(screen);}publicvoidpauseApp(){}publicvoiddestroyApp(booleanunconditional){}publicvoidcommandAction(Commandc,Displayables){if(c==exitCommand){if(screen.
isPlaying()){screen.
quitGame();}else{destroyApp(false);notifyDestroyed();}}if(c==playCommand&&!
screen.
isPlaying()){//Play!
!
!
newThread(screen).
start();}}}classSSCanvasextendsCanvasimplementsRunnable{privateintscore,sleepTime,cicle,lives,shield;privateintindice_in,indice,xTiles,yTiles;privatebooleanplaying,fireOn=false;privatebooleandone;privateintdeltaX,deltaY;privateHerohero=newHero(1);privateEnemy[]enemies=newEnemy[7];privateBullet[]aBullet=newBullet[7];APNDICEA109109109109privateSpriteintro=newSprite(1);privateExplode[]explode=newExplode[7];privateSprite[]tile=newSprite[5];//Mapadeljuegointmap[]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,1,3,1,2,1,1,1,1,1,1,1,1,1,1,4,1,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,4,1,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1,1,3,1,2,1,1,1,1,1,1,1,1,1,1,4,1,1,1,1,1};publicSSCanvas(){//Cargamoslosspriteshero.
addFrame(1,"/hero.
png");intro.
addFrame(1,"/intro.
png");//IniciamoslosSpriteshero.
on();intro.
on();}voidstart(){inti;playing=true;sleepTime=50;hero.
setX(getWidth()/2);hero.
setY(getHeight()-20);deltaX=0;deltaY=0;cicle=0;xTiles=7;yTiles=8;indice=map.
length-(xTiles*yTiles);indice_in=0;score=0;lives=3;shield=0;//Inicializarenemigosfor(i=1;igetHeight())||(enemies[i].
getY()getHeight()/2&&enemies[i].
getY()getHeight())||(aBullet[i].
getY()=32){indice_in=0;indice-=xTiles;}if(indice0)shield--;}voidcomputePlayer(){//actualizarposicióndelaviónif(hero.
getX()+deltaX>0&&hero.
getX()+deltaX0&&hero.
getY()+deltaYx2)&&((y1+h1)>y2)&&((x2+w2)>x1)&&((y2+h2)>y1)){returntrue;}else{returnfalse;}}//DibujamoselSpritepublicvoiddraw(Graphicsg){g.
drawImage(sprites[frame],posx,posy,Graphics.
HCENTER|Graphics.
VCENTER);}}118118118118Enemy.
javapackagemygame;importjava.
util.
*;classEnemyextendsSprite{privateinttype,state,deltaX,deltaY;publicvoidsetState(intstate){this.
state=state;}publicintgetState(intstate){returnstate;}publicvoidsetType(inttype){this.
type=type;}publicintgetType(){returntype;}publicvoiddoMovement(){Randomrandom=newjava.
util.
Random();//Losenemigosdetipo2cambiaransutrayectoria//alalcanzarunaposicióndeterminada(pos.
50)if(type==2&&getY()>50&&state!
=2){//pasoalestado2(movimientodiagonal)state=2;if((Math.
abs(random.
nextInt())%2)+1==1){deltaX=2;}else{deltaX=-2;}}//movemoslanavesetX(getX()+deltaX);setY(getY()+deltaY);}publicvoidinit(intxhero){deltaY=3;deltaX=0;if(type==1){if(xhero>getX()){deltaX=2;}else{deltaX=-2;}}}//SobrecargadelmétododrawdelaclaseSpritepublicvoiddraw(javax.
microedition.
lcdui.
Graphicsg){selFrame(type);//llamamosalmétodo'draw'delaclasepadre(Sprite)super.
draw(g);}publicEnemy(intnFrames){super(nFrames);}}119119119119Bullet.
javapackagemygame;classBulletextendsSprite{privateintowner;publicBullet(intnFrames){super(nFrames);}publicvoidsetOwner(intowner){this.
owner=owner;}publicintgetOwner(){returnowner;}publicvoiddoMovement(){//siowner=1eldisparoesnuestro//sino,esdelenemigoif(owner==1){setY(getY()-6);}else{setY(getY()+6);}}//SobrecargadelmétododrawdelaclaseSpritepublicvoiddraw(javax.
microedition.
lcdui.
Graphicsg){selFrame(owner);//llamamosalmétodo'draw'delaclasepadre(Sprite)super.
draw(g);}}120120120120Explode.
javapackagemygame;classExplodeextendsSprite{privateintstate;publicExplode(intnFrames){super(nFrames);state=1;}publicvoidsetState(intstate){this.
state=state;}publicintgetState(){returnstate;}publicvoiddoMovement(){state++;if(state>super.
frames())super.
off();}//SobrecargadelmétododrawdelaclaseSpritepublicvoiddraw(javax.
microedition.
lcdui.
Graphicsg){selFrame(state);//llamamosalmétodo'draw'delaclasepadre(Sprite)super.
draw(g);}}121121121121Hero.
javapackagemygame;classHeroextendsSprite{privateintstate;publicvoidsetState(intstate){this.
state=state;}publicintgetState(intstate){returnstate;}publicHero(intnFrames){super(nFrames);}}122122122122RecursosBibliografíaJavaJava2.
Manualdeusuarioytutorial.
AgustínFroufe.
Ed.
Ra-MaISBN:84-7897-389-3JuegosenJava.
JoelFan/EricRies/CalinTenitchiEd.
AnayaMultimediaISBN:84-415-0410-5J2MEJ2ME.
Manualdeusuarioytutorial.
Froufe,A/Jorge,P.
Ed.
Ra-MaISBN:8478975977WirelessJavawithJ2ME.
MichaelMorrison.
Ed.
Sams.
ISBN:0-672-32142-4EnlacesJ2MEhttp://java.
sun.
com/j2me/-PáginaprincipaldeSunsobreJ2MEhttp://developers.
sun.
com/techtopics/mobility/midp/reference/techart/index.
html-ArtículossobreJ2MEhttp://developers.
sun.
com/techtopics/mobility/midp/samples/-CódigosJ2MEdeejemploAPNDICEB123123123123http://www.
developer.
com/java/j2me/-NoticiasrelativasaJ2MEhttp://www.
midlet-review.
com/-Páginasobrejuegosparamóvileshttp://www.
palowireless.
com/java/tutorials.
asp-TutorialesyartículossobreJ2MEProgramacióndevideojuegoshttp://www.
flipcode.
com/http://www.
gamedev.
net/http://www.
gamasutra.
com/http://gpp.
netfirms.
com/http://www.
gametutorials.
com/http://www-cs-students.
stanford.
edu/~amitp/gameprog.
html124124124124125125125125ndiceAlfabéticoAaddCommand,27addRecord,100Alert,29algoritmosdebúsqueda,70animación,49array,17CCanvas,25,43ChChoiceGroup,36Cclases,10CLDC,6colisiones,51Command,27commandAction,27Connector,104Control,79createImage,46createPlayer,79Ddatagramas,104DateField,36deleteRecord,100destroyApp,24Disparos,76Displayable,25do/while,16drawArc,44drawImage,46drawLine,44drawRect,44drawRoundRect,44drawString,45Eexplosiones,76FfillArc,44fillRect,44fillRoundRect,44for,15Form,32GGameLoop,59GameCanvas,84Gauge,37getDisplay,26getFont,45getGameAction,57getRecord,100Hherencia,13http,104https,104Iif/else,14Image,46ImageItem,34InputStream,104inteligenciaartificial,70JJAD,23JAR,23KkeyPressed,57keyReleased,57keyRepeated,57KToolBar,19KVM,23LLayer,88LayerManager,91lenght,17List,30MManager,79máquinasdeestado,72MIDlet,19MIDP,7Oobjetos,10openInputStream,104openOutputStream,104OutputStream,105PpauseApp,24Player,79playTone,80polimorfismo,14RrecordEnumeration,100RecordEnumeration,100recordStore,99redneuronal,70RMS,99SScreen,25Scrolling,64secuencia,80setColor,44126126126126setCommandListener,27setFont,45setGrayScale,44sistemasbasadosenreglas,71Sockets,104sonido,79Sprite,93sprites,48startApp,24String,17StringItem,34switch,15Tteclado,57TextBox,31TextField,35Threads,58TiledLayer,89tiles,63ToneControl,81try,17Wwhile,16

国内云服务器 1核 2G 2M 15元/月 萤光云

标题【萤光云双十二 全场6折 15元/月 续费同价】今天站长给大家推荐一家国内云厂商的双十二活动。萤光云总部位于福建福州,其成立于2002 年。主打高防云服务器产品,主要提供福州、北京、上海 BGP 和香港 CN2 节点。萤光云的高防云服务器自带 50G 防御,适合高防建站、游戏高防等业务。这家厂商本次双十二算是性价比很高了。全线产品6折,上海 BGP 云服务器折扣更大 5.5 折(测试了一下是金...

819云互联 香港 日本 美国 2核4G 18元 8核8G 39元 免费空间 免费CDN 香港 E3 16G 20M 230元/月

819云互联是海外领先的互联网业务平台服务提供商。专注为用户提供低价高性能云计算产品,致力于云计算应用的易用性开发,并引导云计算在国内普及。目前平台研发以及运营云服务基础设施服务平台(IaaS),面向全球客户提供基于云计算的IT解决方案与客户服务,拥有丰富的海外资源、香港,日本,美国等各国优质的IDC资源。官方网站:https://www.819yun.com香港特价物理服务器:地区CPU内存带宽...

快云科技:香港沙田CN2云服务器低至29元/月起;美国高防弹性云/洛杉矶CUVIP低至33.6元/月起

快云科技怎么样?快云科技是一家成立于2020年的新起国内主机商,资质齐全 持有IDC ICP ISP等正规商家。云服务器网(yuntue.com)小编之前已经介绍过很多快云科技的香港及美国云服务器了,这次再介绍一下新的优惠方案。目前,香港云沙田CN2云服务器低至29元/月起;美国超防弹性云/洛杉矶CUVIP低至33.6元/月起。快云科技的云主机架构采用KVM虚拟化技术,全盘SSD硬盘,RAID10...

canvas2为你推荐
ionizationios10深圳市富满电子集团股份有限公司空调iphone支持ipadiphone连不上wifi苹果手机为什么突然连不上家里的wifi?win10445端口windows server2008怎么开放4443端口itunes备份itunes备份是什么重庆电信网速测试如何测量网速css3按钮HTML中,怎么表示一个图片按钮杀毒软件免费下载2013排行榜免费杀毒软件最好的是那个?在那下载
三级域名网站 buyvm 香港主机 轻博客 css样式大全 网站被封 服务器架设 华为4核 腾讯云分析 秒杀汇 adroit 国外免费asp空间 gtt 阿里云官方网站 中国电信网络测速 广州虚拟主机 空间申请 免费稳定空间 apachetomcat 防盗链 更多