blackberry game development challenges
DESCRIPTION
BlackBerry Game Development Challenges. Jeff Bacon, Sr. Smartphone Product Manager Simon Dale, Smartphone Services Team Lead J15. Agenda. Buffering Strategies Parallax Scrolling Case Study: Worms A Space Oddity Optimizing with the JDE Navigation API Deficiencies. Magmic Experience. - PowerPoint PPT PresentationTRANSCRIPT
BlackBerry Game Development Challenges
Jeff Bacon, Sr. Smartphone Product Manager
Simon Dale, Smartphone Services Team Lead
J15
Agenda
• Buffering Strategies• Parallax Scrolling• Case Study: Worms A Space Oddity• Optimizing with the JDE• Navigation• API Deficiencies
Magmic Experience
Original & Licensed IPOver 45 Games
Feature Phones (J2ME/MIDP)BlackBerryFeature Phones (BREW)Windows Mobile
Licensed IP: 60+ TitlesJ2ME/MIDP BlackBerry
BREW Windows Mobile
5+ years of BlackBerry game development
Tiles
110 x Graphics.drawBitmap 11 x Graphics.drawBitmap
Buffering StrategiesWhat do we mean by buffering?
Raging Rivers, Magmic Games
• Why do we need to buffer the screen?
• Customers think big screen == big performance• Meet customer expectations• Optimization is FUN!
Buffering StrategiesMotivations
Bitmap buffer = new Bitmap(screenWidth, screenHeight);
private boolean bufferDirty = true;
private void repaintBuffer() { synchronized (buffer) { // … draw all the static content onto the buffer … bufferDirty = false; }}
public void setBufferDirty() { synchronized (buffer) { bufferDirty = true; }}
Buffering StrategiesFull Screen Image
// OPTION 1: Paint Methodpublic void paint(Graphics g) { if (buffer_is_dirty) { repaintBuffer(); } g.drawBitmap(0, 0, screenWidth, screenHeight, buffer, 0, 0); // … draw all dynamic content …}
Buffering StrategiesFull Screen Image
// OPTION 2: Game Run Loopif (buffer_is_dirty) { repaintBuffer(); }
• Good: guarantee clean paints• Bad: frame rate choppy• Bad: long synchronization in paint
• Good: control when frame rate suffers• Bad: can have dirty paints
Buffering StrategiesFull Screen Image: Working and Live buffers
• Reduces maximum paint time• Low variance in FPS• Risk of stale paints
private void repaintBuffer() { synchronized (workingBuffer) { // … draw all the static content onto the workingBuffer … synchronized (liveBuffer) { Graphics g = liveBuffer.getGraphics(); g.drawBitmap(... workingBuffer ...); } bufferDirty = false; }}public void paint(Graphics g) { synchronized (liveBuffer) { g.drawBitmap(... liveBuffer ...); } // … draw all dynamic content …}
Buffering StrategiesLarger-Than-Full Screen Image
Content Area
Viewport
• Same basic code as Full Screen
• Keep track of viewport co-ordinates
• Offset rendering in drawBitmap with viewport
Call of Duty 3, HandsOn Mobile
int numBuffers = (screenWidth/ bufferWidth) + 1;
Bitmap buffers[] = new Bitmap[numBuffers];private boolean[] bufferIsDirty = new boolean[numBuffers];private int leftBuffer = 0;private int leftOffset = 0;
public synchronized void setBufferDirty(int bufferId) { synchronized (buffers) { bufferIsDirty[bufferId] = true; }}
private void repaintBuffer(int bufferId) { synchronized (buffers) { // … draw all the static content onto the buffer … bufferIsDirty[bufferId] = false; }}
Buffering StrategiesSegmented Buffer
public void paint(Graphics g) { synchronized (buffers) { for (int i = 0; i < numBuffers; i++) { if (bufferIsDirty[i]) { repaintBuffer(i); } } } int currentBuffer = leftBuffer; for (int i = 0; i < numBuffers; i++) { g.drawBitmap(… buffers[currentBuffer % numBuffers] …); ++currentBuffer; } // … draw all dynamic content …}
Buffering StrategiesSegmented Buffer
• Remember to respect the leftOffset• Remember to start at leftBuffer index
Screen AreaScreen Area
• More buffers == smoother scrolling• Less buffers == faster painting when not scrolling
Horizontal Scroller: • buffer height == screen height • width can be varied
(ex. above)
Vertical Scroller:• buffer width == screen width • height can be varied
Indiana Jones and the Kingdom of the Crystal Skull, THQ Wireless
Buffering StrategiesSegmented Buffer, Example
What is parallax scrolling?
New Super Mario Bros., Nintendo, Nintendo DS
Parallax Scrolling
• Avoid tiled backgrounds• Use fewer, larger images• Buffer the background layer(s)• Only paint visible areas
Eagle Eye, Magmic Games
Parallax ScrollingOptimization: Reduce Number of Paints
Case Study: Worms A Space Oddity
Can we Buffer?• Can’t draw to a large Bitmap• Difficult to maintain transparency in a buffer• How do we efficiently deform the world?
Why? • Large level maps (1024x512)• Repainting on every tick• Repainting using Graphics.drawRGB()• Updating all map data for all changes
• Stationary camera: 3-5 fps• Moving camera (viewport): 1-2 fps• Explosion: 0 fps
Case Study: Worms A Space OddityProblem: Very Slow Frame Rate
• Use lookup-tables for trig functions• Faster calculations, less accurate
• Localize painting to the current viewport• Remove some detail
• Decreases production quality• Performance often outweighs detail
• Full Screen buffer• Stationary camera improved dramatically
• Stationary camera: 17 fps• Moving camera (viewport): 8-12 fps• Explosion: 0-3 fps
Case Study: Worms A Space OddityStage 1: Basic Optimizations & Full Screen Buffer
Worms A Space Oddity, THQ Wireless
• Create a world buffer: 1024x512px
• Manipulate ARGB data for transparency• Painting buffer done on load• Allows parallax scrolling• Optimize explosions & bounds checking• Localize small changes
1024px
512
px
• Stationary camera: 12 fps• Moving camera: 12 fps• Explosion: 8-10 fps
Case Study: Worms A Space OddityStage 2: More Optimizations & Segmented Buffer
Worms A Space Oddity, THQ Wireless
• Stationary camera: 14-16 fps• Moving camera: 12-14 fps• Explosion: 8-10 fps
Case Study: Worms A Space OddityStage 3: Double Buffering
• Improve stationary camera frame rate• Paint 1 live buffer vs. 1-4 working buffers• Possible panning improvement• Painting off-screen faster than direct to screen