04 J2ME LowLevelIU

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 58

J2ME LOW LEVEL IU Session 4

Trinh Thi Van Anh PTIT 1-2013

Objectives
Canvas Key Events Geometry& Text Images Game API

Session 4/ 2 of 22

Hierarchy of Low Level UI

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

Canvas is a subclass of Displayable Creating Canvas:

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

Canvas Width and Height

Event Handling: The low-level interface, consisting of key codes, game actions and pointer events. Commands:

addCommand(Command) isShown() removeCommand(Command) setCommandListener(CommandListener)


Session 4/ 8 of 22

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

keyPressed(int keyCode) When a key is pressed down

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

Key Codes Game Actions (keycode & translate)

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)

drawRect(int x, int y, int width, int height)

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

Drawing Color and Style

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

Text Font (font)

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:

Font titleFont = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD|Font.STYLE_ITALIC, Font.SIZE_LARGE); g.setFont(titleFont); g.drawString( gTest h, 0, 0, Graphics.TOP|Graphics.LEFT);


Session 4/ 22 of 22

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

Default: Top Left= 0 / 0 Visible area can be moved through translate()


Protected void paint(Graphics g){ //g.translate(50, 50); g.setColor(128, 128, 128); g.fillRect(0, 0, getWidth(), getHeight()); g.setStrokeStyle(Graphics.SOLID); g.setColor(255, 0, 0); g.drawLine(0, 0, getWidth(), getHeight()); g.drawLine(0, getHeight(), getWidth(), 0); g.setColor(0,0, 0); g.drawString("HelloWorld", 0, 0, Graphics.TOP|Graphics.HCENTER);}
Session 4/ 24 of 22

Images

Image-class saves picture, independent of the display Variants:

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 Example (slide)

Load and display the image


Image im= Image.createImage(/title.png); protected void paint (Graphics g){ g.drawImage(im, 0, 0, Graphics.TOP|Graphics.LEFT);}

Created dynamically during runtime (Mutable )


Class ImageDemoCanvas extends Canvas { private Image mutableImg; Public ImageDemoCanvas(){ mutableImg= Image.createImage(10,10); mutableImg.getGraphics().fillArc(0,0,10,10,0,360)}}

Session 4/ 26 of 22

Game API

Game API GameCanvas Sprite Layer and TiledLayer LayerManager

Session 4/ 27 of 22

Games using a Canvas (gameusingcanvas)

Session 4/ 28 of 22

The MIDP UI structure

Session 4/ 29 of 22

Canvas vs. GameCanvas

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

(Both new features are optional in the GameCanvas!)


Session 4/ 30 of 22

Suited for games

GameCanvasConstruction

Key Event delivery

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.

Full screen (also available for Canvas)

Call setFullScreenMode(bool) for (de)activating full screen mode


Session 4/ 31 of 22

Games using a GameCanvas


public void MyGameCanvas extends GameCanvas implements Runnable{ public MyGameCanvas() { super(true); setFullScreenMode(true);// Use full screen mode for the game } public void startGame() { Thread t = new Thread(this); t.start(); } // Start the game loop in its own thread public void run() { Graphics g = getGraphics();

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

Game Actions (gamecanvas)

Session 4/ 36 of 22

Utility Classes for Graphics

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

Custom anchor point

Define reference point:


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:

Query sprite position:


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

Set frame to display

mySprite.setFrame(intsequenceIndex);

Session 4/ 43 of 22

Animation Frame Sequence (sprite & animation)

For continuous animations:


int[] frameSequence= {0, 1, 2, 1}; mySprite.setFrameSequence(frameSequence); ... mySprite.nextFrame(); mySprite.prevFrame();

Wraps automatically

Session 4/ 44 of 22

Transformations

Possible in 90-steps, no smooth rotation

mySprite.setTransform(int transform);

Session 4/ 45 of 22

Collision

Checking for collision between a Sprite and ...


another Sprite an Image a TiledLayer

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

Pixel Collision (collision)

Checks for overlapping, non-transparent pixels

if (mySprite.collidesWith(yourSprite, true)) { ... }

Considerably more expensive than rectangle check

Session 4/ 48 of 22

TiledLayer

For displaying background graphics Made of repeating elements (=tiles)

Create variety of backgrounds with less space Square bitmap Arranged in tile maps

What is a tile?

Session 4/ 49 of 22

How does it work?

Original image (contains all tiles):

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

Set Tile MapSingle cell:


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

Animated Tiles (animatedTile & animatedSwitch)

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);

Paints all layers with a single call to LayerManager.paint(Graphics g, intx, inty)

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

Positioning Layers (scrolling)

Session 4/ 57 of 22

Case study 3

To design and implement a game on J2ME system

Session 4/ 58 of 22

You might also like