Professional Documents
Culture Documents
04 J2ME LowLevelIU
04 J2ME LowLevelIU
04 J2ME LowLevelIU
Objectives
Canvas Key Events Geometry& Text Images Game API
Session 4/ 2 of 22
Session 4/ 3 of 22
Introduction
Two key classes make up the low-level API, Canvas and Graphics. Canvas :
it has a specific height and width and is drawn onto to create what the end user will see. Whatever is drawn becomes visible on the display. The canvas class also provides methods for low-level event handling We draw onto a canvas with a Graphics object. This class has methods for drawing lines, arcs, rectangles and text. This class also includes methods to specify color as well as font Session 4/ 4 of 22 preferences.
Graphics:
Canvas class
create a subclass of Canvas, and ask that object be set as the current Displayable. The origin for drawing begins in the upper left corner of the display, location 0,0 x values increase heading to the right, y values increase heading down When drawing a line or shape (arc, rectangle, etc.), the thickness (known as the pen) is always 1 pixel wide
Coordinate System
Session 4/ 5 of 22
The Canvas provides a paint() method similar to the paint() method in J2SE AWT components. Provides developers with methods to Handle game actions, key events, etc. Obtain device capabilities and keyboard mapping The only parameter of the paint() method is a Graphics object. import javax.microedition.lcdui.*;
public class SampleCanvas extends Canvas { public void paint(Graphics g) { // Draw stuff using g. } }
Session 4/ 6 of 22
You CANNOT call the paint() method of Canvas. Instead, you should call the repaint() method of Canvas. The system is notified that a repaint is necessary, and it will call the paint() method. The call of the paint() method is not performed immediately; it may be delayed until the control flow returns from the current event handling method. The system may also collect several repaint requests before paint() is actually called.
Session 4/ 7 of 22
Event Handling: The low-level interface, consisting of key codes, game actions and pointer events. Commands:
Example: (canvas)
public class TestCanvas extends Canvas implements CommandListener{ private Command cmdExit; private CanvasMidlet mid; public TestCanvas(CanvasMidlet mid) { this.mid=mid; cmdExit=new Command("Exit", Command.EXIT, 1); addCommand(cmdExit); setCommandListener(this); }
Session 4/ 9 of 22
protected void paint(Graphics g) { g.setColor(0,0,255); g.fillRect(0,0,this.getWidth(),this.getHeight()); int d = Math.min(this.getHeight(),this.getWidth()); g.setColor(255,255,0); g.fillArc((getWidth()-d)/2,(getHeight()-d)/2,d,d,0,360); } public void commandAction(Command c, Displayable d) { if (c == cmdExit) mid.exitMIDlet(); } }
Session 4/ 10 of 22
public class CanvasMidlet extends MIDlet { TestCanvas cv; public void startApp() { cv=new TestCanvas(this); Display.getDisplay(this).setCurrent(cv); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} public void exitMIDlet(){ destroyApp(true); notifyDestroyed(); }}
Session 4/ 11 of 22
CanvasOverview
Session 4/ 12 of 22
Key Events
keyRepeated(int keyCode)
Called again and again when the key is held down Frequency depends on mobile phone keyReleased(int keyCode) When the key is released
Session 4/ 13 of 22
Key Codes
Session 4/ 14 of 22
Phones: no standardized key layout therefore: game actions - appropriate keys for each phone int getGameAction(int keyCode)
Session 4/ 15 of 22
Graphics (draw)
Graphics-object sent to paint() as a parameter Graphics contains a collection of methods that draw and fill simple shapes. The draw methods include: drawLine(int x1, int y1, int x2, int y2)
Draws a line between the coordinates (x1,y1) and (x2,y2) using the current color and stroke style. Draws the outline of the specified rectangle using the current color and stroke style.
Session 4/ 16 of 22
drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) Draws the outline of the specified rounded corner rectangle using the current color and stroke style. drawString(String str, int x, int y, int anchor) Draws the specified String using the current font and color. drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) Draws the outline of a circular or elliptical arc covering the specified rectangle, using the current color and stroke style.
Session 4/ 17 of 22
drawImage(Image img, int x, int y, int anchor) Draws the specified image by using the anchor point. The fill methods include: fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) Fills a circular or elliptical arc covering the specified rectangle. fillRect(int x, int y, int width, int height) Fills the specified rectangle with the current color. fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) Fills the specified rounded corner rectangle with the current color. fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3) Fills the specified triangle will the current color.
Session 4/ 18 of 22
MIDP provides a setColor() method. setColor(int RGB) Sets the current color to the specified RGB values.
setColor(int red, int green, int blue) Sets the current color to the specified RGB values. the values range from 0 to 255, where 255 means brightest and 0 means darkest. MIDP also provides setGrayScale method to set gray scale value.
Session 4/ 19 of 22
Automatic assignment of nearest displayable colour void paint(Graphics g) { g.setColor(255, 255, 255); // White //Fill the whole background g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(255, 0, 0); // Red g.drawLine(5, 5, 250, 250); g.setColor(0, 255, 0); // green g.drawString("Hello", getWidth() / 2, getHeight() / 2, Graphics.HCENTER|Graphics.BASELINE);}
Session 4/ 20 of 22
Text
Definepositionusinganchorpoints Images: similar, but use Vcenter instead of Baseline g.drawString(Mopius, 0, 0, Graphics.HCENTER|Graphics.BASELINE);
Session 4/ 21 of 22
Choose through Font-object, then assign to Graphicsobj. Request font based on criteria: Face: monospace, proportional, system Style: plain, bold, italic, underlined Size:large, medium, small Example:
Geometry
Define settings
g.setStrokeStyle(Graphics.DOTTED); // orGraphics.SOLID
Example:
Protected void paint(Graphics g) { g.setColor(255, 255, 255); // Draw background g.fillRect(0, 0, getWidth(), getHeight()); g.setStrokeStyle(Graphics.DOTTED); // Draw stroke g.setColor(255, 0, 0); g.drawLine(0, 0, getWidth(), getHeight());}
Session 4/ 23 of 22
Coordinate System
Images
Immutable: not modifiable, e.g. when loaded from files, resource bundles or a network. Examples: logos, sprites, Mutable: modifiable, created by the application Examples: off-screen bitmap for double buffering, dynamically modifiable images, images created by the app at runtime for MIDletfile size reasons
Session 4/ 25 of 22
Image im= Image.createImage(/title.png); protected void paint (Graphics g){ g.drawImage(im, 0, 0, Graphics.TOP|Graphics.LEFT);}
Session 4/ 26 of 22
Game API
Session 4/ 27 of 22
Session 4/ 28 of 22
Session 4/ 29 of 22
Canvas Keys: sent as events, asynchronous processing Drawing: only in paint()-method, own thread Suited for event-based games and applications GameCanvas Keys: query state in the game loop for every iteration Drawing: everywhere, graphics shown when calling flushGraphics() from GameLoop
GameCanvasConstruction
Call constructor of GameCanvas base class in first line of own constructor Requires booleanparameter:
true:if using getKeyStates() to query currently pressed keys. Suppresses key event delivery to keyPressed(), keyRepeated() and keyReleased() increases performance. false: deliver key events to the methods stated above, like for normal Canvas.
Session 4/ 32 of 22
// Main game loop while (true) { int keyStates= getKeyStates(); // ... process key input and update the world ... flushGraphics(); Thread.sleep(20); } } }
Session 4/ 33 of 22
Game Loop
Session 4/ 34 of 22
Polling Input
Session 4/ 35 of 22
Session 4/ 36 of 22
Session 4/ 37 of 22
Layer
Abstract base classifier a visual element Defines paint()-method Properties: Position (upper-left corner) Size Visibility
Session 4/ 38 of 22
Sprite
Pre-rendered 2D figure, usually with transparency, integrated into larger scene Early video gaming Sprite: hardware feature built into graphics subsystem Limited number of sprites on the screen Software-based Sprite in Java ME Drawing Moving, rotating, flipping Animation Collision detection
Session 4/ 39 of 22
Loading
Create using: Image img= Image.createImage(/player.png); Sprite mySprite= new Sprite(img); Default Positions reference sprite at its upper left corner
Session 4/ 40 of 22
Reference Pixel
Relative to un-transformed upper left corner of sprite May be outside of sprite fs bounds mySprite.defineReferencePixel(int x, int y); Reference pixel is located at pos x/y on painter fs coordinate system mySprite.setRefPixelPosition(int x, int y); In the painter fs coordinate system Int x = mySprite.getRefPixelX(); // getRefPixelY()
Session 4/ 41 of 22
Position sprite:
Animation
Several instances of the sprite that are slightly different All frames have the same size Only one frame displayed at the same time Create using: Sprite mySprite= new Sprite(img, intframeWidth, intframeHeight);
Session 4/ 42 of 22
Animation Frames
mySprite.setFrame(intsequenceIndex);
Session 4/ 43 of 22
Wraps automatically
Session 4/ 44 of 22
Transformations
mySprite.setTransform(int transform);
Session 4/ 45 of 22
Collision
Session 4/ 46 of 22
Rectangle Collision
Checks collision based on frame boundary if (mySprite.collidesWith(yourSprite, false)) { ... } Fastand efficient Possible to define collision rectangle size mySprite.defineCollisionRectangle(intx, inty, intwidth, intheight);
Session 4/ 47 of 22
Session 4/ 48 of 22
TiledLayer
Create variety of backgrounds with less space Square bitmap Arranged in tile maps
What is a tile?
Session 4/ 49 of 22
Tile Map:
Session 4/ 50 of 22
The JavaME-Side
Create TiledLayer-Object
TiledLayer myBg= new TiledLayer(int colums, int rows, Image img, int tileWidth, int tileHeight); All tilesin the image have the same size imageWidth= multiple of tileWidth (getCellWidth();) imageHeight= multiple of tileHeight (getCellHeight();) getColumns(); getRows(); myBg.setCell(int col, int row, int tileIndex); tileIndex=0 (empty - transparent cell)
Session 4/ 51 of 22
TiledLayer
private LayerManager layerManager; private TiledLayer tiledBackground; tiledBackground = initBackground(); layerManager = new LayerManager(); layerManager.append(tiledBackground); private TiledLayer initBackground() throws Exception { Image tileImages = Image.createImage("/tiles.png"); TiledLayer tiledLayer = new TiledLayer(8,9,tileImages,32,32); int[] map = { for (int i=0; i < map.length; i++) { 5, 1, 1, 4, 1, 1, 1, 1, int column = i % 8; 5, 1, 3, 1, 1, 3, 1, 1, int row = (i - column) / 8; 5, 1, 2, 1, 1, 2, 1, 1, 5, 1, 2, 3, 1, 2, 1, 1, tiledLayer.setCell(column,row,map[i]); 5, 1, 4, 2, 1, 2, 1, 1, } 5, 1, 1, 4, 1, 2, 1, 1, return tiledLayer; 5, 1, 1, 1, 1, 4, 1, 1, } 5, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, }; Session 4/ 52 of 22
Animating Tiles
Generate animated tile index intanimTileIndex= bgLayer.createAnimatedTile(1); Parameter: Initial static tile index that will be displayed Returns negative index, this can be assigned to cells that should be animated Switch to different tile bgLayer.setAnimatedTile(animTileIndex, 2); Causes static tile 2 to be displayed instead of 1 for all cells that have the animTileIndexas content
Session 4/ 53 of 22
Session 4/ 54 of 22
LayerManager
Manages multiple layers Sprites, TiledLayersand own classes derived from those
append(Layer layer);
remove(Layer layer); insert(Layer layer, int index); paint(Graphics g, int x, int y);
Session 4/ 55 of 22
Example: Layermanager
Manages z-order of layers: iLayerManager= new LayerManager(); iLayerManager.append(iPlayerSprite); iLayerManager.append(iEnemySprite); iLayerManager.append(iBulletSprite); iLayerManager.append(iBgLayer);
Session 4/ 56 of 22
Session 4/ 57 of 22
Case study 3
Session 4/ 58 of 22