El documento describe los conceptos básicos para programar juegos en J2ME para celulares, incluyendo el uso de Canvas para manejar input, Graphics para dibujar formas, sprites y capas con tiles para objetos animados, y LayerManager para organizar y pintar capas. Explica el bucle principal del juego y técnicas como esperar para completar el tiempo de cada frame.
2. Programación en J2ME
• Canvas permite interpretar el input del usuario
– void keyPressed(int keycode)
– void keyReleased(int keycode)
– void keyRepeated(int keycode)
– int getGameAction(int keycode)
• Posee constantes para comparar
– KEY_NUM0
– KEY_NUM9
– KEY_STAR
– KEY_POUND
– LEFT, RIGHT, UP, DOWN, FIRE
– GAME_A, GAME_B, GAME_C, GAME_D
3. Programación en J2ME (cont.)
• La clase que extienda Canvas tiene que
implementar el método abstracto
Paint(Graphics g)
• En esa función definimos lo que queremos
pintar
• Cada vez que queremos que se refresque la
pantalla, llamamos al método repaint()
5. Programación en J2ME (cont.)
• Game Loop
– Leer Input del usuario
– Simular el mundo (IA, colisiones, etc.)
– Dibujar el resultado
– Esperar para completar el tiempo del frame
• Hasta ahora, todo lo visto se puede
implementar en MIDP1.0
6. Programación en J2ME (cont.)
• Game API
– javax.microedition.lcdui.game.*
• GameCanvas
• Layer
• LayerManager
• Sprite
• TiledLayer
– Sólo disponible desde MIDP2.0
7. Programación en J2ME (cont.)
• GameCanvas
– Extiende a Canvas
– Agrega un buffer fuera de pantalla
– Permite hacer polling a las teclas
– El método getGraphics() retorna el buffer
– Al finalizar de pintar el frame fuera de la
pantalla, se llama a flushGraphics()
– setFullScreenMode(Boolean)
9. Programación en J2ME (cont.)
• Layer
– Base para Sprite y TiledLayer
– void setPosition(int x, int y)
– void setVisible(int x, int y)
– boolean isVisible()
– void move(int dx, int dy)
– int getHeight()
– int getWidth()
– int getX()
– int getY()
10. Programación en J2ME (cont.)
• Sprite
– Extiende Layer agregando animación, detección de
colisión, transformaciones de imagen
– Sprite(Image imagen)
– Sprite(Image imagen, int frameWidth, int frame Height)
– Sprite(Sprite s)
– collidesWith(Image imagen, int x, int y, bool pixelLevel)
– collidesWith(Sprite s, bool pixelLevel)
– collidesWith(TiledLayer t, bool pixelLevel)
– defineCollisionRectangle(int x, int y, int width, int height)
11. Programación en J2ME (cont.)
• Animación del Sprite
– void setFrameSequence(int[] sequence)
• Establece una secuencia a partir de los frames de la
imagen original del sprite
– int getFrameSequenceLength()
• Retorna el número de frames que tiene la secuencia
actual
– int getRawFramesCount()
• Retorna el número de frames que tiene la imagen
original del sprite
12. Programación en J2ME (cont.)
• Animación del Sprite
– void setFrame(int sequenceIndex)
• Selecciona un frame en particular de la secuencia para el
próximo paint del sprite
– void nextFrame()
• Selecciona el siguiente frame en la secuencia
– void prevFrame()
• Selecciona el frame anterior en la secuencia
– int getFrame()
• Retorna el número de frame dentro de la secuencia que está
selecconado actualmente
– void paint(Graphics g)
• Pinta el Sprite. El pixel de referencia es el de arriba a la
izquierda
14. Programación en J2ME (cont.)
• TiledLayer
– TiledLayer(int columns, int rows, Image image, int
tileWidth, int tileHeight)
• Especifica las columnas y filas del fondo, imagen donde estás
los tiles y sus dimensiones
– Void setCell(int col, int row, int tileIndex)
• Pinta en (col, row) con el tile tileIndex (parte de 1, el 0 es
transparente)
– Void fillCells(int col, int row, int numCols, int numRows,
int tileIndex)
• setCell pero en un rectángulo
15. Programación en J2ME (cont.)
• LayerManager
– Sirve para pintar grupos de Layers
– Void append(Layer l)
– Void insert(Layer l, int index)
– Int getSize()
– Void remove(Layer l)
– Void setViewWindow(int x, int y, int width, int height)
– Void paint(Graphics g, int x, int y)
– Layer getLayerAt(int index)
16. Programación en J2ME (cont.)
• Esperar para completar el tiempo del frame
– 15 FPS o menos
– Aprox. 70 milisegundos por frame
elapsed=startTime;
startTime=System.currentTimeMillis();
elapsed=startTime-elapsed;
If(elapsed < MILLISECS_PER_FRAME)
{
thread.sleep(MILLISECS_PER_FRAME-elapsed);
}
Else
{
thread.yield();
}