tiled map case study: rendering with jpanel © allan c. milne v14.12.26

23
tiled Map Case Study: Rendering with JPanel © Allan C. Milne

Upload: cori-cain

Post on 01-Jan-2016

218 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

tiled Map Case Study:Rendering with JPanel

© Allan C. Milne

v14.12.26

Page 2: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

Agenda.

Accessing a JPanel.

Map & tile representation.

Drawing the map.

Using the renderer.

Page 3: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

Where are we now?

• we use a strategy pattern to include rendering behaviour;• the MapRenderer interface;• composition of tiledMap with a concrete

MapRenderer object;• the render() method mechanism.

• We have a concrete rendering class;• ConsoleRenderer.

Page 4: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

Where do we want to be?

• Add more concrete rendering implementations;– different ways of displaying on the console;– using different display technologies.

• In particular, rendering in a windows user interface;– for example, using a JPanel to draw some

representation of the map.

Page 5: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

A problem with JPanel.

• There is only one console and any code can access it;– thus any code writing to the console to

render a map simply uses System.out

• … but a client application’s user interface may have many JPanel objects making it up;– which JPanel object will the map

renderering code draw on?

Page 6: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

Our approach.

• Make the concrete rendering class – implement the MapRenderer interface; and– inherit from JPanel;

• This means that our class can both– act as a concrete rendering class; and– be used as a JPanel within a client’s user

interface.

Page 7: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

class JPanelRenderer extends JPanel implements MapRenderer { @Override public void render (TiledMap aMap) { … … … } // end render method.

@Override protected void paintComponent (Graphics g) { … … … } // end paintcomponent method.

… … …

} // end JPanelRenderer class.

The concrete renderer.

Page 8: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

paintComponent(Graphics g)

• Renders a map by drawing a representation on the JPanel through its supplied Graphics object.

• Called by the panel’s redraw() method when this is called by a client.

• We require to have– a map object to draw; and– a representation to use for the drawing.

Page 9: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

class JPanelRenderer extends JPanel implements MapRenderer { private TiledMap mMap;

@Override public void render (TiledMap aMap) { mMap = aMap; redraw(); } // end render method.

@Override protected void paintComponent (Graphics g) { … … … } // end paintcomponent method.

… … …

} // end JPanelRenderer class.

So we have …

Page 10: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

Constructor method(s).

• Since our rendering class is also a JPanel any constructor methods must reflect the requirements of a JPanel.

• In particular, we can supply the size of the panel in pixels.

• We should also initialize the mMap field.

Page 11: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

• public JPanelRenderer (int aWidth, int aHeight) • { • //TODO validate the arguments are >0 and set to 0 if not.

• setPreferredSize (new Dimension (aWidth, aHeight));

• mMap = null; • } // end constructor method.

A constructor …

Page 12: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

Map and tile representation.

• Consider the panel to be made up of a grid of squares:

– size of grid = size of map;

– Each rid square is drawn in a colour representing the terrain tile type of the corresponding map tile;

– each grid square will have a size (resolution) in pixels.

Page 13: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

• Panel size (in pixels) and therefore shape will be determined by the client and Java layout manager when the JPanel object is created and added to the user interface.

• For a map to be rendered we must have– panel width >= map width; and– panel height >= map height.

• If dimension sizes are equal then the grid squares will be only 1 pixel in size.

• the shape of the grid is defined by the shape of the map and may not fill the panel if it has a different shape.

Map and grid size.

Page 14: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

Map tile colours.

• java.awt.Color can represent colours.• The colour to draw a square on the grid

is determined by the terrain tile type of the corresponding tile on the map.

• Use a switch statement; or

• adopt a similar approach to that used for determining the character to display for a tile in the console renderer.

Page 15: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

TerrainType enumeration.

• Add a private java.awt.Colour attribute.

• Amend the constructor to initialize this attribute with a supplied colour.

• Amend the value definitions to include a specific colour parameter.

• Expose the asColour() method to return the colour attribute for an value.

Page 16: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

Drawing a map.

• paintComponent (Graphics g)– super.paintComponent(g);– for each map tile:

• use g.setColor(…) to set colour;• to draw the square use g.fillRect (

– x-coord of top left corner,– y-coord of top left corner,– x-size,– y-size )

Page 17: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

We know …

• the size of the panel;– getWidth() and getHeight() panel methods.

• the map;– mMap field.

• the size of the map; – height() and width() methods of mMap.

• the colours to use for tiles;– asColour() method of TerrainType.

Page 18: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

Outstanding problems.

• The resolution (pixels per grid square) must be determined.

• the coordinate system of a JPanel is different from that of the map.

Page 19: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

Calculating resolution.• Is panel big enough to represent the map

even at 1 pixel per tile?– If not, then draw a message on the panel and

return.

• Resolution can only be an integer.• Is calculated as the smallest resolution of the

width and height dimensions;– Maintains the square aspect ratio of the grid

elements;– May result in unused areas of the panel if it is a

different shape than the map.

Page 20: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

Coordinate systems.• In the map,

– (0,0) is at the bottom left;– X coordinates go from left to right;– Y coordinates go from bottom to top.

• On the JPanel,– (0,0) is at the top left;– X coordinates go from left to right;– Y coordinates go from top to bottom (but still positive).

• We must apply a transform from map to JPanel coordinates.

Page 21: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

Coordinate transformation.

• Need to transform tile position (xm,ym) on the map to (xp,yp) on the JPanel.

• Requires us to consider– the resolution of the panel grid squares;– the different origin positions;– the different Y coordinate directions.

• xp = xm * resolution

• yp = (map-height * resolution) – ( (ym + 1) * resolution)

Page 22: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

Client usage.

public static void main (…){ final TiledMap map = new TiledMap (…); … … … SwingUtilities.invokeLater(new Runnable() { @Override public void run() { createWindowAndRender (map); } }); … … …} // end main method.

Page 23: tiled Map Case Study: Rendering with JPanel © Allan C. Milne v14.12.26

… and the renderer …

private static final void createWindowAndRender (TiledMap aMap) { JPanelRenderer panelRenderer = new JPanelRenderer(…);

final JFrame frame = new JFrame(“ title "); … … … frame.add (panelRenderer, BorderLayout.CENTER); … … … frame.pack();

aMap.setRenderer (panelRenderer); aMap.render();

} // end createWindowAndRender method.