mobile game framework. stuff you should know… genres paper prototyping mechanics theme/backstory...
TRANSCRIPT
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 LoopInput 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 extendsActivity– 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 AssetManagerAssetManager 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 AudioSetup…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 AudioMediaPlayer 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 GraphicsKeep 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