Developing multi-platform games with PlayN Java framework
1. Developing multi-platform games
with PlayN Java framework
Joint meeting of Central California Java User Group
and GDG Fresno, 01/08/2015,Bitwise Industries
Presenter: Csaba Toth,
Csaba Technology Services LLC
2. Agenda
• Outlook of the topic and history of PlayN
• Introduction to PlayN, basic concepts
• Technical details
• Triple Play framework
• Showcase of a real-world application
• Thoughts for future
3. Game and UI development in Java
• JavaFX 3D
• LWJGL (Lightweight Java Game Library)
– Open source, exposes OpenGL, OpenAL, OpenCL
– http://www.lwjgl.org/
• PlayN
• + Triple Play
4. PlayN – History
• open source Java software framework
• Apache License
• intended to create multi-platform games
• Motto: “Cross platform game library for N>=5
platforms”
• Started in January 2011named as ForPlay
– Library built on top of GWT
5. PlayN – History
• 2011 Google I/O
• Important person from Google: Lilli Thompson
• In August 2011 the project was forked and rebranded
as PlayN
• Backed up by Google for some years
• Used by Chrome version of Angry Birds
• Google now “abandoned” it, Three Rings gaming studio
put a lot of effort (more about TriplePlay later)
6. Familiar Tools
• Box2D: C++ 2D Physics engine by Erin Catto
• JBox2D: Java port of Box2D
• GWTBox2D: JS port via GWT
7. (GWT – Google Web Toolkit)
• Open source set of tools
• Write JavaScript front-end applications in Java
• Used as a front-end by some Java EE solutions
– (GWT + ExtJS, GXT)
8. (GWT – Google Web Toolkit)
• Advantages
– Removes unused code
– Compile time checking
– Inlines, optimizes
– Obfuscates output
– Adjusted for browser quirks
• Disadvantage: not all Java libraries can be
compiled by GWT, in fact it’s very limited!
9. PlayN – platform
• Java SE - native
• HTML 5 – using GWT
• Flash – not really functional any more AFAIK
• Android – almost native Java
• iOS – using Xamarin framework + Visual Studio
– Upcoming: using RoboVM
10. PlayN platforms
• All Java code you write should be able to be
consumed by GWT compilation and also
Android dexer
11. HTML5
• WebGL
• Canvas2D
• CSS3
• Web Audio API
• Most of the PlayN platform implementations
try to support hardware acceleration
12. Attribution
• A bunch of slide material from Lilli
• Used some material from Michael Twohey,
member of our project and Team Bad Wolf
• Deal-O-Round project (Team Bad Wolf)
15. The Game Loop
• Implement PlayN.Game
public class MyGame implements Game {
public void init() {
// initialize game.
}
public void update (float delta) {
// update world.
}
public void paint (float alpha) {
// render world.
}
}
16. Rendering
// Each device has different screen parameters
// Resize to the available resolution on the current device.
graphics().setSize(
graphics().screenWidth(),
graphics().screenHeight()
);
// Keep the same aspect ratio.
float sx = graphics().screenWidth() / (float) WIDTH;
float sy = graphics().screenHeight() / (float) HEIGHT;
// Fit to the available screen without stretching.
graphics().rootLayer().setScale(Math.min(sx, sy));
20. SurfaceLayer
• Traditional rendering paradigm
• Render multiple images into a single surface
• Clear each frame
// Clear the surface.
surface.clear();
// Draw an image into the surface.
surface.drawImage(myImage, x, y);
// Draw a scaled subsection of the source image into the surface.
surface.drawImage(image, dx, dy, dw, dh, sx, sy, sw, sh);
22. ImageLayer
• Fire and forget image
• Don't need to draw in paint()
• Render images not in scenegraph
• UI, logos, overlays
23. CanvasLayer
• Mirrors much of the HTML5 canvas API
• Procedural circle, rect, line, point, gradient...
• Text rendering
• Slow
canvas.setFillColor(Color.rgb(100, 255, 0));
canvas.fillCircle(x, y, r);
canvas.fillRect(x, y, w, h);
canvas.drawImage(myImage, x, y);
canvas.drawText("Hello text!", x, y);
canvas.drawLine(x0, y0, x1, y1);
24. Layers recap
• 3/4 layer types can draw images
• SurfaceLayer for standard sprite rendering
• GroupLayer for organization
• ImageLayer for static images
• CanvasLayer for procedural drawing
25. Transforms and surfaces
// Like OpenGL push.
surface.save();
surface.translate(p.x, p.y);
surface.rotate(p.r);
surface.scale(p.sx, p.sy);
// Draw something at transformed coordinates!
// Like OpenGL pop.
surface.restore();
26. IO System: Platform Abstractions
• Pointer
– Most general screen event
Works everywhere
• Mouse
– Left, right, mid buttons & wheel
• Touch
– Pressure, size, multitouch
27. IO System
• Input devices
pointer().setListener(new Pointer.Adapter() {
public void onPointerStart(Pointer.Event event) {
// Handle mouse down event.
}
// ...Same pattern for onPointerEnd, onPointerDrag
});
keyboard().setListener(new Keyboard.Adapter() {
public void onKeyDown(Event event) {
// Handle key down event.
}
// ... Same pattern for onKeyUp
});
28. Cross platform input
• Support touch-based zoom where available
import static playn.core.PlayN.platformType;
if (platformType().equals(Platform.Type.ANDROID)) {
touch().setListener(new Touch.Adapter() {
@Override
public void onTouchStart(Event[] touches) {
// Process touch events into a zoom start position.
}
@Override
public void onTouchMove(Event[] touches) {
// Update zoom based on touches.
}
});
}
29. Asset Management
• Abstraction for platform-specific resource fetching
public interface AssetManager {
Image getImage(String path);
Sound getSound(String path);
void getText(String path, ResourceCallback callback);
boolean isDone();
int getPendingRequestCount();
}
30. Loading Images
• Abstraction for platform-specific resource fetching
// Ask the Asset Manager to create a new image.
Image image = assetManager().getImage("myImage.png");
// Specify an onLoaded callback.
image.addCallback(new ResourceCallback() {
public void done(Image image) {
// handle new image.
}
}
// To draw the image that was loaded, render it to a layer.
mySurfaceLayer.surface().drawImage(image, x, y);
31. Asset Watchers
• Make sure everything is loaded before you start the game
AssetWatcher watcher = new AssetWatcher(new Listener() {
public void done() {
startGame();
}
});
// Add assets to check.
watcher.add(image1);
watcher.add(image2);
// ...
// Start the watching now.
watcher.start();
32. Sounds
• Use PlayN.core.Sound() abstraction
• HTML5 version uses Web Audio API via gwt-voices
public interface Sound {
boolean play();
void stop();
void setLooping(boolean looping);
void setVolume(float volume);
boolean isPlaying();
}
assetManager().getSound("mySound.mp3");
33. Storage
• 5MB max due to HTML5 local storage limits
• Strings only (for now)
/** Abstraction for Storage across platforms. */
public interface Storage {
public void setItem(String key, String data);
public void removeItem(String key);
public String getItem(String key);
// Returns true if the Storage data will be persisted across restarts.
public boolean isPersisted();
}
39. Links
• Mike Twohey’s presentation:
https://drive.google.com/file/d/0Bx6U-
HF_yP7qcWdiRXdCdTQyams/view
• Lilli’s presentation:
– http://playn-2011.appspot.com/
• Chris Mohritz presentation, good hands-on lab:
http://www.slideshare.net/ChrisMohritz/building-crossplatform-
games-with-google-playn-14294882
• Where to start:
– https://code.google.com/p/playn/wiki/GettingStarted
– https://developers.google.com/playn
40. We are not done yet at all
• How to draw menus, buttons, texts?
– We can draw texts, but what about buttons and widgets?
• Answer: Triple Play
– https://github.com/threerings/tripleplay
– https://github.com/threerings/playn
– collection of game-related utility classes that can be used with
the PlayN library
– Layouting engine
– Widget set (buttons, labels, sliders, …)
– Formatting
41. What you need
• Eclipse IDE with Android plugins
• Maven build system
• M2E plugin for Eclipse
• Extremely easily scaffold a skeleton with a Maven archetype:
mvn archetype:generate
-DarchetypeGroupId=com.googlecode.playn
-DarchetypeArtifactId=playn-archetype -DarchetypeVersion=1.8
42. Showcase: Deal-O-Round
• Team Bad Wolf was formed for 59
Days of Code
– Csaba Toth, Michael Twohey, Tim
Yopp, Vernon Burt
• Deal-O-Round is a card game
• Uses PlayN framework
• https://dealoround.com
48. Other
• Mp3 music
• Spin
• Timer
• Networking
• Android
• Scoring poker hands
49. Experiences
• PlayN is not as popular as Unity or certain other frameworks,
sometimes hard to get help
• Having the common denominator has restrictions: either you use
the PlayN multi platform APIs, or you have to develop platform
specific code
– OAuth authentication code, networking – won’t go through GWT
compilation phase
• Preferable for 2D games
• Hopefully RoboVM will cause a new momentum
• https://code.google.com/p/playn/w/list
50. Future
• http://www.robovm.com/
• Will provide Java support for iOS (and Android)
• Two developers started it back in 2013
• Oracle featured them and will back them up
• PlayN picks it up too
• Will provide a much straight path to iOS port than
Xamarin/.NET/Visual Studio
• 1.9 PlayN version is under development