Android-Developers

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Tuesday, 22 November 2011

Making Android Games that Play Nice

Posted on 06:45 by Unknown

[This post is by Ian Ni-Lewis, a Developer Advocate who devotes most of his time to making Android games more awesome. — Tim Bray]



Making a game on Android is easy. Making a great game for a mobile, multitasking, often multi-core, multi-purpose system like Android is trickier. Even the best developers frequently make mistakes in the way they interact with the Android system and with other applications
 — mistakes that don’t affect the quality of gameplay, but which affect the quality of the user’s experience in other ways.

A truly great Android game knows how to play nice: how to fit seamlessly into the system of apps, services, and UI features that run on Android devices. In this multi-part series of posts, Android Developer Relations engineers who specialize in games explain what it takes to make your game play nice.

I: The Audio Lifecycle (or, why is there music coming from my pants?)

One of the most awesome things about Android is that it can do so much stuff in the background. But when apps aren’t careful about their background behaviors, it can get annoying. Take my own personal pet peeve: game audio that doesn’t know when to quit.

The problem

I’m on the bus to work, passing the time with a great Android game. I’m completely entranced by whatever combination of birds, ropes, and ninjas is popular this week. Suddenly I panic: I’ve almost missed my stop! I leap up, quickly locking my phone as I shove it into a pocket.

I arrive breathless at my first meeting of the day. The boss, perhaps sensing my vulnerability, asks me a tough question. Not tough enough to stump me, though — I’ve got the answer to that right here on my Android phone! I whip out my phone and press the unlock button... and the room dissolves in laughter as a certain well-known game ditty blares out from the device.

The initial embarrassment is bad enough, but what’s this? I can’t even mute the thing! The phone is showing the lock screen and the volume buttons are inactive. My stress level is climbing and it takes me three tries to successfully type in my unlock code. Finally I get the thing unlocked, jam my finger on the home button and breathe a sigh of relief as the music stops. But the damage is done — my boss is glowering and for the rest of the week my co-workers make video game noises whenever they pass my desk.

What went wrong?

It’s a common mistake: the developer of the game assumed that if the game received an onResume() message, it was safe to resume audio. The problem is that onResume() doesn’t necessarily mean your app is visible — only that it’s active. In the case of a locked phone, onResume() is sent as soon as the screen turns on, even though the phone’s display is on the lock screen and the volume buttons aren’t enabled.

Fixing this is trickier than it sounds. Some games wait for onWindowFocusChanged() instead of onResume(), which works pretty well on Gingerbread. But on Honeycomb and higher, onWindowFocusChanged() is sent when certain foreground windows — like, ironically, the volume control display window — take focus. The result is that when the user changes the volume, all of the sound is muted. Not the developer’s original intent!

Waiting for onResume() and onFocusChanged() seems like a possible fix, and it works pretty well in a large number of cases. But even this approach has its Achilles’ heel. If the device falls asleep on its own, or if the user locks the phone and then immediately unlocks it, your app may not receive any focus changed messages at all.

What to do about it

Here’s the easy two-step way to avoid user embarrassment:

  1. Pause the game (and all sound effects) whenever you receive an onPause() message. When gameplay is interrupted — whether because the phone is locked, or the user received a call, or for some other reason — the game should be paused.


  2. After the game is paused, require user input to continue. The biggest mistake most game developers make is to automatically restart gameplay and audio as soon as the user returns to the game. This isn’t just a question of solving the “music over lock screen” issue. Users like to come back to a paused game. It’s no fun to switch back to a game, only to realize you’re about to die because gameplay has resumed before you expected it.


Some game designers don’t like the idea of pausing the background music when the game is paused. If you absolutely must resume music as soon as your game regains focus, then you should do the following:

  1. Pause playback when you receive onPause().


  2. When you receive onResume():

    1. If you have previously received an onFocusChanged(false) message, wait for an onFocusChanged(true) message to arrive before resuming playback.


    2. If you have not previously received an onFocusChanged(false) message, then resume audio immediately.



  3. Test thoroughly!


Fixing audio embarrassments is almost always a quick and easy process. Take the time to do it right, and your users will thank you.

Email ThisBlogThis!Share to XShare to FacebookShare to Pinterest
Posted in Best Practices, Games, Media and Camera | No comments
Newer Post Older Post Home

0 comments:

Post a Comment

Subscribe to: Post Comments (Atom)

Popular Posts

  • Bring Your Apps into the Classroom, with Google Play for Education
    Posted by Shazia Makhdumi, Head of Strategic EDU Partnerships, Google Play team Google Play for Education has officially launched . It’s an ...
  • A Faster Emulator with Better Hardware Support
    [This post is by Xavier Ducrohet and Reto Meier of the Android engineering team. — Tim Bray.] The Android emulator is a key tool for Android...
  • Powering Chrome to Phone with Android Cloud to Device Messaging
    [This post is by Dave Burke, who's an Engineering Manager 80% of the time. — Tim Bray] Android Cloud to Device Messaging (C2DM) was lau...
  • Android 1.5 is here!
    I've got some good news today: the Android 1.5 SDK, release 1 is ready! Grab it from the download page . For an overview of the new Andr...
  • Memory Analysis for Android Applications
    [This post is by Patrick Dubroy, an Android engineer who writes about programming, usability, and interaction on his personal blog . — Tim B...
  • Preview of Google TV Add-on for the Android SDK
    [This post is by Ambarish Kenghe, who’s a Product Manager for Google TV — Tim Bray] At Google I/O , we announced that Android Market is comi...
  • Android SDK Tools, Revision 20
    [This post is by Xavier Ducrohet , Tech Lead for the Android developer tools] Along with the preview of the Android 4.1 (Jelly Bean) platfo...
  • RenderScript Intrinsics
    Posted by R. Jason Sams , Android RenderScript Tech Lead RenderScript has a very powerful ability called Intrinsics . Intrinsics are built-...
  • In-App Billing on Android Market: Ready for Testing
    [This post is by Eric Chu, Android Developer Ecosystem. —Dirk Dougherty] Back in January we announced our plan to introduce Android Market ...
  • Twitter for Android: A closer look at Android’s evolving UI patterns
    [This post is by Chris Nesladek, Interaction Designer, Richard Fulcher, Interaction Designer, and Virgil Dobjanschi, Software Engineer — Ti...

Categories

  • accessibility
  • Action Bar
  • Administration
  • Android
  • Android 1.5
  • Android 1.6
  • Android 2.0
  • Android 2.1
  • Android 2.2
  • Android 2.3
  • Android 2.3.3
  • Android 3.0
  • Android 3.2
  • Android 4.0
  • Android 4.2
  • Android 4.3
  • Android 4.4
  • Android Design
  • Android Developer Challenge
  • Android Developer Phone
  • Android Market
  • Android SDK
  • Android Studio
  • Animation and Graphics
  • Announcements
  • App Components
  • App Resources
  • Apps
  • Audio
  • Authentication
  • Best Practices
  • Boston
  • Code Day
  • Connectivity
  • Content Provider
  • Cool Stuff
  • Dashboard
  • Daydream
  • Debugging
  • Developer Console
  • Developer Days
  • Developer Labs
  • Developer profiles
  • Developer Story
  • Education
  • Games
  • GCM
  • Gestures
  • Google Analytics
  • Google Cloud Messaging
  • Google Cloud Platform
  • Google I/O
  • Google Play
  • Google Play game services
  • Google Play services
  • Google Services
  • Google Wallet
  • Google+
  • Guidelines
  • How-to
  • Image Processing
  • IME
  • In-app Billing
  • Input methods
  • Intents
  • io2010
  • IO2013
  • JNI
  • Layout
  • Localization
  • Location
  • Location and Sensors
  • London
  • Maps
  • Media and Camera
  • Mountain View
  • Munich
  • NDK
  • Open source
  • OpenGL ES
  • Optimization
  • Performance
  • Photo Sphere
  • Promo Graphics
  • Quality
  • Quick Search Box
  • Renderscript
  • Resources
  • RTL
  • Sample code
  • SDK Tools
  • SDK updates
  • Security
  • Sensors
  • Speech Input
  • Support Library
  • Survey
  • Tablets
  • Tel Aviv
  • Telephony
  • Testing
  • Text and Input
  • Text-to-Speech
  • Tools
  • Touch
  • User Interface
  • User Support
  • WebView
  • Widgets

Blog Archive

  • ►  2013 (45)
    • ►  November (2)
    • ►  October (7)
    • ►  September (2)
    • ►  August (5)
    • ►  July (5)
    • ►  June (4)
    • ►  May (9)
    • ►  April (3)
    • ►  March (2)
    • ►  February (3)
    • ►  January (3)
  • ►  2012 (43)
    • ►  December (5)
    • ►  November (3)
    • ►  October (3)
    • ►  September (1)
    • ►  August (1)
    • ►  July (2)
    • ►  June (5)
    • ►  May (1)
    • ►  April (5)
    • ►  March (6)
    • ►  February (5)
    • ►  January (6)
  • ▼  2011 (67)
    • ►  December (7)
    • ▼  November (7)
      • Games Coming to Android Market in Korea
      • Making Android Games that Play Nice
      • Updated NDK for Android 4.0
      • New Layout Widgets: Space and GridLayout
      • More Android Developer Labs in Asia
      • JNI Local Reference Changes in ICS
      • Android 4.0 Graphics and Animations
    • ►  October (5)
    • ►  September (5)
    • ►  August (3)
    • ►  July (7)
    • ►  June (3)
    • ►  May (5)
    • ►  April (6)
    • ►  March (8)
    • ►  February (7)
    • ►  January (4)
  • ►  2010 (72)
    • ►  December (8)
    • ►  November (3)
    • ►  October (4)
    • ►  September (8)
    • ►  August (6)
    • ►  July (9)
    • ►  June (11)
    • ►  May (11)
    • ►  April (2)
    • ►  March (3)
    • ►  February (2)
    • ►  January (5)
  • ►  2009 (63)
    • ►  December (7)
    • ►  November (5)
    • ►  October (5)
    • ►  September (8)
    • ►  August (2)
    • ►  July (1)
    • ►  June (2)
    • ►  May (5)
    • ►  April (12)
    • ►  March (5)
    • ►  February (8)
    • ►  January (3)
  • ►  2008 (40)
    • ►  December (3)
    • ►  November (1)
    • ►  October (4)
    • ►  September (6)
    • ►  August (4)
    • ►  June (1)
    • ►  May (5)
    • ►  April (4)
    • ►  March (5)
    • ►  February (2)
    • ►  January (5)
  • ►  2007 (8)
    • ►  December (3)
    • ►  November (5)
Powered by Blogger.

About Me

Unknown
View my complete profile