Game APIs and Basic ADK APIs

advertisement
Mobile Game Framework
Stuff You Should Know…
•
•
•
•
Genres
Paper Prototyping
Mechanics
Theme/Backstory
• Don’t Code!
General Game API
• Window/scene management
• Input
• File I/O
– Playback recording (event logging)
– Audio
• Graphics
• General game framework/loop (w/ timing)
Window Management
• Handle basic Android OS events
– Create
– Pause
– Resume
Input
• Polling
– Code asks, “what is the current state?”
– Info lost between polling
• Event-based
– Queue of events stored
• Touch down, drag/move, up
• Key down, up
Input Polling
•
•
•
•
•
•
•
isKeyPressed(keyCode)
isTouchDown(id)
getTouchX(id)
getTouchY(id)
getAccelX()
getAccelY()
getAccelZ()
Event-based Input
• getKeyEvents()
– Returns List<KeyEvent>
• getTouchEvents()
– Returns List<TouchEvent>
File I/O
• Manage Java InputStream and OutputStream
instances
• Load/use assets (audio, graphics, etc.)
• Save data (state, high score, settings)
Audio Assets
• Music
– Ambient/background
– Streamed (open stream and play)
– Play, pause, stop, looping (bool), volume (float)
• Sound
–
–
–
–
Shorter
Typically event-driven
Load entirely in memory
Play
• Dispose when not needed
Graphics
• Handle typical APIs like color, pixel maps,
compression, double buffering, and alpha
compositing
• Load/store imgs
• Framebuffer
–
–
–
–
–
Clear
DrawSprite
Primitives
Swap
Height/width
Game Loop
Input input = new Input();
Graphics graphics = new Graphics();
Audio audio = new Audio();
Screen currentScreen = new MainMenu();
Float lastFrameTime = currentTime();
while (!userQuit() ) {
float deltaTime = currentTime() – lastFrameTime;
lastFrameTime = currentTime();
currentScreen.updateState(input, deltaTime);
currentScreen.present(graphics, audio, deltaTime);
}
cleanupResources();
Frame Rate Management
vs
Java/ADK Specifics
XML and the Manifest
Best Practices
• Utilize latest SDKs but be compatible back to
1.5
• Install to SD whenever possible
• Single main activity that handles all events
– Debatable relative to general Android App dev
• Portrait or landscape (or both?)
• Access SD
• Obtain a wake lock (keep from sleeping)
Defining Multi-Resolution Assets
• Handle difference devices
– ldpi=36x36
– mdpi=48x48
– hdpi=72x72
– xhdpi=96x96
• /res/drawable/ic_launcher.png
– Same as mdpi
– For Android 1.5 compatibility
Core Android Activity Events
• Create
– Set up window/UI
• Resume
– (Re)start game loop
• Pause
– Pause game loop
– Check isFinishing
• Save state
Test Your Understanding
• LogCat (debugging event list)
– Utilize debugging view in Eclipse
• Define new class that extends
Activity
– Override
• onCreate
• onResume
• onPause
– Check isFinishing()
Handling Touch Events
• setOnTouchListener(this)
• onTouch(view, event)
– Handle types of touch events
– switch(event.getAction())
• MotionEvent.ACTION_DOWN
• MotionEvent.ACTION_UP
• …
– event.getX()
• Multitouch involves handling array of touch data
Handling Key Events
• setOnKeyListener(this)
• onKey(view, keyCode, event)
– Handle KeyEvent.ACTION_DOWN
– Handle KeyEvent.ACTION_UP
Accelerometer Input
• Check if accelerometer present on device
– getSensorList(Sensor.TYPE_ACCELEROMETER)
• Register activity as listener to accelerometer events
– registerListener(this, accel, m.SENSOR_DELAY_GAME)
• onSensorChanged(event)
– event.values[0] <- x
– event.values[1] <- y
– event.values[2] <- z
• Deal with orientation by axis swapping
Asset File I/O
• assets/ folder quite useful via AssetManager
AssetManager am = getAssets();
InputStream is = am.open(filename);
…
is.close();
External/SD Access
• Use <uses-permissions> in manifest
• Check if external storage exists
– Environment.getExternalStorageState();
• Get directory root
– Environment.getExternalStorageDirectory();
• Utilize standard Java file I/O APIs
• Beware: complete SD access to read/write!
Shared Preferences
• Stores key-value pairs
p = getPreferences(Context.MODE_PRIVATE);
e = p.edit();
e.putString(key, value);
e.putInt(key, value);
e.commit();
String s = p.getString(key, null);
int i = p.getInt(key, 0);
Sound Effect Audio
Setup…
setVolumeControlStream(AudioManager.STREA_MUSIC);
soundPool = new SoundPool(max, AudioManager.STREAM_MUSIC, 0);
Get file descriptor and id:
d = assetManager.openFd(“soundEffect.ogg”);
int id =soundPool.load(d, 1);
Then play…
soundPool.play(id, left, right, 0, loop, playback);
Finally…
soundPool.unload(id);
Streaming Audio
MediaPlayer mp = new MediaPlayer();
AssetFileDescriptor afd = am.openFd(“ambient.ogg”);
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
mp.prepare();
mp.start();
…
mp.setVolume(left, right);
mp.pause();
mp.stop();
mp.setLooping(bool);
Handle when completed:
mp.isPlaying()
mp.setOnCompletionListener(listener);
mp.release();
Well-Lit Graphics
Keep screen completely on with wake lock…
• Setup
– <uses-permission> in manifest
• onCreate
– PowerManager pm =
(PowerManager)context.getSystemService(Context.POWER_SERVICE);
– WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK,
"My Lock");
• onResume
– wl.acquire();
• onPause
– wl.release();
Full Screen Graphics
• Remove the title bars
• Get full resolution for graphics/display
• In onCreate:
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
NOTE: do this before setting the content view of activity!
FPS++
• Heretofore, the application only refreshes/draws itself
in response to events
• This is good given battery considerations
• But we can increase the FPS/draw rate
• Inherit from View
• Define onDraw(Canvas) method
• Invoke ‘invalidate’ at the end of onDraw
• Don’t forget to set the content view to a new instance
of this derived class
The Limitless Possibilities of Canvas
• Canvas (parameter to onDraw) provides a wealth
of options
–
–
–
–
–
–
getWidth();
getHeight();
drawPoint(x,y,paint);
drawLine(x1,y1,x2,y2,paint);
drawRect(x1,y1,x2,y2,paint);
drawCircle(x,y,radius,paint);
• Paint
– setARGB(a,r,g,b);
– setColor(0xaarrggbb);
Drawing Bitmaps/Sprites
• Bitmap
– InputStream is = assetManager.open(file);
– Bitmap bmp = BitmapFactory.decodeStream(is);
– getWidth();
– getHeight();
– When done, bmp.recycle();
• Drawing the Bitmap
– canvas.drawBitmap(bmp, x, y, paint);
– canvas.drawBitmap(bmp, srcRect, dstRect, paint);
Drawing Text
• Fonts are placed in the assets/ directory
• Then loaded
– Typeface font =
Typeface.createFromAsset(context.getAssets(),
fontFileName);
• Set the paint instance
– paint.setTypeFace(font);
– paint.setTextSize(x);
– paint.setTextAlign(Paint.Align.LEFT|CENTER|RIGHT);
• Draw using canvas
– canvas.drawText(string, x, y, paint);
Problem with onDraw/invalidate
•
•
•
•
•
This presumes nothing else in the game runs
UI dominates
View vs SurfaceView
We want to have a thread running to do rendering
Create new class that inherits SurfaceView
– Maintain thread
– Implement run, pause methods
• To draw
– Canvas c = holder.lockCanvas();
– c.draw…
– holder.unlockCanvasAndPost(c);
SurfaceView Subclass
Using SurfaceView Subclass
Download