making paper
spaceships, timers, and some other things
Hello
Matthew Lim
Jefferson Lee
okay wait, so what was PaperCraft again?
Overview
Loops
Game Loops
Most games work like this, on a per-frame basis:
Draw game
Evaluate next game state
Receive input
Game Loops
How we did it on Android:
Main thread
Draw game
Background thread
Evaluate next game state
Receive input
Game Loops
Set up the TimerTask:
TimerTask frameTask;
int enemyIntervalTicker;
…
public void initFrameTask() {
frameTask = new TimerTask() {
@Override
public void run() {
// this fires every 1/60th of a second...
// 60 ticks = 1 second
// 30 ticks = 1/2 second
synchronized(frameLock) {
// update game logic
if (enemyIntervalTicker++ == 60) {
spawnEnemy();
enemyIntervalTicker = 0;
}
removeOffscreenEnemies();
}
postInvalidate(); // trigger onDraw()
}
};
}
Timer Management
@Override
public void onResume() { // schedule the task
super.onResume();
if (frameTimer == null) {
frameTimer = new Timer();
}
if (frameTask == null) {
initFrameTask();
} else {
frameTask.cancel();
frameTask = null;
initFrameTask();
}
frameTimer.schedule(frameTask, 0, 16);
}
@Override
public void onPause() { // stop the task
super.onPause();
if (frameTimer != null) {
frameTimer.cancel();
frameTimer.purge();
}
if (frameTask != null) {
frameTask.cancel();
frameTask = null;
frameTimer = null;
}
}
Drawing
Drawing with the Canvas API
Two main methods we used to draw everything in the game:
@Override onDraw(Canvas canvas) {
//Shape Drawing
Path path = new Path();
path.moveTo(0,0);
path.lineTo(10,0);
path.lineTo(10,10);
path.lineTo(0,10);
path.close();
canvas.drawPath(path, pathPaint);
//Bitmap Drawing
Bitmap bitmap = generateBitmap();
canvas.drawBitmap(bitmap, transMatrix, null);
}
Drawing Shapes
You might draw a simple shape like this:
private int tWidth, tHeight; //dimension values. could be dynamic
private int posX, posY; //values coming from user input
private Paint paint; //paint object to draw the path
private Path trianglePath = new Path();
…
@Override onDraw(Canvas canvas) {
//make a triangle shape with a path
trianglePath.reset();
trianglePath.moveTo(0,0);
trianglePath.lineTo(tWidth, tHeight/2);
trianglePath.lineTo(0, tHeight);
trianglePath.close();
//draw shape!
canvas.drawPath(path, paint);
}
Drawing Bitmaps
Matrix matrix;
Rect srcRect;
Rect destRect;
@Override
public void onDraw(Canvas canvas) {
// draw w/ x & y offset
canvas.drawBitmap(left, top, bitmap, null);
…
// draw using source/dest rectangles (automatic scaling)
canvas.drawBitmap(bitmap, srcRect, destRect, null);
…
// draw using a matrix (scale/rotate/translate)
matrix.reset();
matrix.setTranslate(tX, tY);
matrix.postRotate(rotAngle,
bitmap.getWidth()/2, bitmap.getHeight()/2);
canvas.drawBitmap(bitmap, matrix, null);
}
Not as many options here:
�
Creating Offscreen Bitmaps
public static Bitmap makeCircleEnemy(int enemyRadius, int blurRadius) {
//create a bitmap to draw on
Bitmap bitmap = Bitmap.createBitmap(enemyRadius*2, enemyRadius*2, Bitmap.Config.ARGB_8888);
//place the bitmap in a canvas to draw on it
Canvas canvas = new Canvas(bitmap);
//create a path to draw the shape
Path enemyPath = new Path();
enemyPath.addCircle(enemyRadius, enemyRadius, enemyRadius, Path.Direction.CW);
enemyPath.close();
canvas.drawPath(enemyPath, enemyPaint);
//bitmap now contains the circle
return bitmap;
}
Animation
Animation
Using Animators:
Using a TimerTask:
Demo
thanks!
MakingPaper repo:
github.com/matthewlim/MakingPaper
PaperCraft:
androidexperiments.com/experiment/papercraft
@matthewylim
@kimchibooty