Upload
mochimedia
View
4.989
Download
1
Tags:
Embed Size (px)
DESCRIPTION
Iain Lobb provides some tips and tricks on how to optimize your 2D Flash games!
Citation preview
Two Dimensions of AwesomeBy Iain Lobb
Two Dimensions of
Awesome.
I don’t have the
awesome.*
I’m looking for the
awesome.
*I’ve found some of it.
First, let’s troll…
The typical Flash game…
• Stickmen!• Arenas!• 20fps!• 550 x 400!
The retro Flash game…• 8-bit pixel art!• 2 frame animations!• Tile grid!• Everything is a square!• Double pixels! You want to see those
pixels, right?• 3rd party engine!
Now let’s see what they’re doing on games
consoles…
Ray Man Origins
Limbo
The 2D awesome…• HD graphics.• 60 frames per second• Smooth scrolling camera. • Multiple layers of parallax.• Uneven, organic terrain.• Expressive character animation.
BunnyMark• 26x37 pixel sprite• 30fps• 640x480
Demo #1BunnyMark - Bitmaps
4000 bunnies
Demo #2BunnyMark - Blitting
6000 bunnies
Demo #3BunnyMark – HTML5 Canvas
2000 bunnies
Bunny Domination!
BunnyLandMark• A more realistic scenario• 30fps• 640x480• 26x37 pixel sprite• Scrolling world• Depth-sorted sprites
Demo #4BunnyLandMark – Bitmaps
22,000 bunnies
Demo #5BunnyLandMark – Blitting
90,000 bunnies!
Now something shocking…
Soylent Green is people!
BunnyMark is a lie.
60 fps
Demo #6BunnyMark – Bitmaps (60fps)
1500 bunnies
Demo #7BunnyMark – Blitting (60fps)
1500 bunnies
HD resolution• Typically Flash game = 640x480• Portal maximum = 800x600• Nitrome = 500x500 pixels• Rayman Origins = 1080p =
1920x1080• 500x500 can fit into 1080p eight
times!
960x720
Demo #8BunnyMark –
Bitmaps (60fps)960 x 720
1000 bunnies
Demo #9BunnyMark –
Blitting (60fps)960 x 720
1000 bunnies
Sprites• 256x148•Digital painting• Scale +/- 50%• Rotation
Introducing PirateMark!
• 60 fps• 960x720• 256x148 sprite• Scaling +/- 50%• Rotation• How many sprites can we have?
Demo #10PirateMark –
Bitmaps (60fps)
…
20 pirates
Demo #11PirateMark –
Bitmaps (30fps)
40 pirates
Demo #12PirateMark –
Blitting (60fps)
15 pirates
Demo #13PirateMark –
Blitting (30fps)
80 pirates
Stage3D
Demo #14PirateMark –
ND2D
20 pirates
Demo #15PirateMark – Genome2D
80 pirates
Demo #16PirateMark –
Starling
100 pirates
Demo #17PirateMark – haXe NME
150 pirates
Demo #18PirateMark –
HTML5 Canvas
0 pirates
100 pirates
He who controls the graphics card
drivers, controls the universe!
Can we support Stage3D and
software rendering?
Can we support 30fps and 60fps?
// Frame-based Euler
function update(){ speedY += gravity; speedX *= drag;
speedY *= drag; x += speedX; y += speedY;}
// Time-based Improved Euler
function update(time:Number){ speedY += gravity * time; speedX *= Math.pow(drag, time); speedY *= Math.pow(drag, time); x += (speedX + oldSpeedX) / 2; y += (speedY + oldSpeedY) / 2; oldSpeedX = speedX; oldSpeedY = speedY;}
Demo #19Improved
Euler
...or fix your time step and interpolate.
Camera and Parallax Scrolling
• A 2D camera is just an X and Y offset.• Subtract the camera position from
each sprite’s world position to get its screen position.
2D Camera
// Simple 2D Camera
for each (var sprite in sprites){ sprite.x = sprite.worldX – cameraX; sprite.y = sprite.worldY – cameraY;}
• By using a container sprite we can make this process even simpler.
• Set the container position to negative the camera position.
• Each sprite will automatically get the correct screen position.
2D Camera
// 2D Camera using container
world.addChild(sprite);
function update(){ world.x = –cameraX; world.y = –cameraY;}
• To enable zooming, we add a second container.
• We move the inner container and scale the outer container.
Zooming
// Zooming 2D Camera
world.addChild(sprite);container.addChild(world);
container.x = stage.stageWidth / 2;container.y = stage.stageHeight / 2;
function update(){ world.x = –cameraX; world.y = –cameraY; container.scaleX = container.scaleY = zoom;}
Demo #21Zooming Camera
• To enable parallax, we position the inner container to negative the camera position, multiplied by a fraction.
Parallax
// Zooming 2D Camera with parallax
world.addChild(sprite);container.addChild(world);
container.x = stage.stageWidth / 2;container.y = stage.stageHeight / 2;
function update(){ world.x = –cameraX * 0.5; world.y = –cameraY * 0.5; container.scaleX = container.scaleY = zoom;}
Demo #22Parallax Camera
Demo #23Starling Camera
Uneven Terrain
hitTestPoint(x, y, shapeFlag);
Demo #24hitTestPoint
hitTestPoint• Only works +/- 2000 pixels• Lags by one frame if you move the container.• Must be on the stage but doesn’t have to be
visible.• Reduce number of calls using AABB broad
phase.• Same principles can be applied using
getPixel32
Bullet
Arrow
Fast moving bullet
Character
Character
Grenade
Grenade
Grenade
Grenade
Demo #25Projectiles
Collision Detection• Box2D / Nape• Straight lines• Why hitTestPoint?
Level Editor• Position objects• Rotate and scale objects• Draw collision areas• Give instance names for code access• Save, Save As, Undo, Redo, Copy, Paste• Zoom
It’s Flash Professional!
It’s Flash Professional!
It’s Flash Professional!
It’s Flash Professional!
Parsing with ActionScript
• Create instance of level• Loop through children.• Determine type of child using
“is”• If no linkage found, assume
terrain
Gotchas
• Small scroll area – scale down and zoom in
• “Invalid size and position”• Flash CS5 crashes creating large SWCs• Expensive
Character Animation
Timelines leak memory!
Sprite Sheets
• Flash, After Effects, Blender• Great performance• High memory use• Not changeable at runtime
Bones• Not the Bone Tool!• Separate sprites for each body part• Saves memory• Adjustable playback speed• Customizable• Parse timeline – animations are pure
data
Demo #26Bones
Demo #28Alice Gameplay
Final thoughts…