SlideShare a Scribd company logo
1 of 78
Download to read offline
Scala 遊戲開發 101
with LibGDX and RxJava
賴宇宣(@raincolee)
About Me
• 賴宇宣(Raincole)
• Twitter: @raincolee
• raintomorrow.cc
• ludumdare.com/compo/author/raincole/
Agenda
• What am I doing here?
• A small tour of functional reactive programming
in Scala
• What’s a game, from a functional perspective
• Type-safe Entity-Component-System
implementation(bonus)
What Am I Doing Here?
What Am I Doing Here?
• Introducing Scala
!
• 

• 

What Am I Doing Here?
• Introducing Scala
• Promoting LibGDX(hopefully)
• 

• 

What Am I Doing Here?
• Introducing Scala
• Promoting LibGDX(hopefully)
• Sharing my humble opinions about reactive
functional programming
• 

What Am I Doing Here?
• Introducing Scala
• Promoting LibGDX(hopefully)
• Sharing my humble opinions about reactive
functional programming
• It’s not really about game developement

What Am I Doing Here?
• Introducing Scala
• Promoting LibGDX(hopefully)
• Sharing my humble opinions about reactive
functional programming
• It’s not really about game developement

(Yes I lied :))
I’m Not an Evangelist!
I’m Not an Evangelist!
• Scala(or RxScala, or functional programming, or
any other buzzword) is not the holy grail…
!
• 





I’m Not an Evangelist!
• Scala(or RxScala, or functional programming, or
any other buzzword) is not the holy grail…
• Sometimes they’re ugly…
• 





implicit def toGdxArray[T<:AnyRef]!
(iterable: Iterable[T])!
(implicit arg0: ClassTag[T])!
: com.badlogic.gdx.utils.Array[T] = {!
new com.badlogic.gdx.utils.Array[T](iterable.toArray)!
}!
Disclaimer
• Treat snippets here as pseudo-code
!
• 

Disclaimer
• Treat snippets here as pseudo-code
• Design architectures here aren’t very practical.
Don’t try it at home work.
!
LibGDX
LibGDX
• A cross-platform game engine
!
!
• 

LibGDX
• A cross-platform game engine
• Desktop/Android/iOS(robovm)/HTML5(GWT)
!
• 

LibGDX
• A cross-platform game engine
• Desktop/Android/iOS(robovm)/HTML5(GWT)
• You can use any JVM-based language
• (except HTML5, casue GWT compiles Java
directely)
More on LibGDX
• Basic Structure
!
!
!
class MyGame extends Game {!
override def create() {!
// initialize!
}!
!
override def render() {!
val delta = Gdx.graphics.getDeltaTime!
// updateGame(delta)!
// renderGame()!
}!
}!
More on LibGDX
• Render
!
!
!
spriteBatch.begin()!
val texture = new TextureRegion(!
! new Texture(Gdx.files.internal(“images/bg.png"))!
)!
spriteBatch.draw(texture, 0, 0}!
spriteBatch.end()!
More on LibGDX
• Input
!
!
!
Gdx.input.setInputProcessor(new InputAdapter {!
override def touchDown(screenX: Int, screenY: Int,!
pointer: Int, button: Int): Boolean = {!
// handle touch down!
true!
}!
!
override def touchUp(screenX: Int, screenY: Int,!
pointer: Int, button: Int): Boolean = {!
// handle touch up!
true!
}!
})!
More on LibGDX
• Load assets with different resolutions
!
!
!
val resolutions = List(new Resolution(320, 480, "320x480"),!
new Resolution(640, 1136, "640x1136"))!
val resolver = new ResolutionFileResolver(!
! ! ! ! ! ! new InternalFileHandleResolver(), resolutions)!
val manager = new AssetManager()!
manager.setLoader(classOf[Texture], new TextureLoader(resolver))!
manager.load("images/bg.png", classOf[Texture])!
// will load "images/640x1136/bg.png" on iPhone5!
More on LibGDX
• Call native code through Java
!
!
!
new IOSApplication(new Retinol(), config) {!
@Override!
public void log (String tag, String message) {!
Foundation.log("[info] " + tag + ": " + message);!
}!
};!
Small Tour of Functional Reactive
Programming in Scala
Small Tour of Functional Reactive
Programming in Scala
!
!
!
!
Small Tour of Functional Reactive
Programming in Scala
• The “Better Java”
!
!
!
Small Tour of Functional Reactive
Programming in Scala
• The “Better Java”
!
!
!
class Vector2 {!
private float x;!
private float y;!
public Vector2(float x, float y) {!
this.x = x;!
this.y = y;!
}!
public int getX() { return x; }!
public int getY() { return y; }!
}!
Small Tour of Functional Reactive
Programming in Scala
• The “Better Java”
!
!
!
case class Vector2(x: Float, y: Float)!
Small Tour of Functional Reactive
Programming in Scala
• The “Better Java”
!
!
• If there is a missing ID, get ready to watch the world burn

idList.stream().map(id -> dict.get(id).contains(name))!
Small Tour of Functional Reactive
Programming in Scala
• The “Better Java”
!
!
• If there is a missing ID, get ready to watch the world burn

… later!
idList.stream().map(id -> dict.get(id).contains(name))!
Small Tour of Functional Reactive
Programming in Scala
• The “Better Java”
!
!
• 

idList.flatMap(dict.get(_))!
Small Tour of Functional Reactive
Programming in Scala
• The “Better Java”
!
!
• Thus, Scala is not just for “lambda expression”.

idList.flatMap(dict.get(_))!
Small Tour of Functional Reactive
Programming in Scala
Small Tour of Functional Reactive
Programming in Scala
Small Tour of Functional Reactive
Programming in Scala
• 











Small Tour of Functional Reactive
Programming in Scala
• “Purely functional” language = Stateless.
!
!
!
Small Tour of Functional Reactive
Programming in Scala
• “Purely functional” language = Stateless.
• Scala is not pure, fortunately.
!
!
Small Tour of Functional Reactive
Programming in Scala
• “Purely functional” language = Stateless.
• Scala is not pure, fortunately?
!
!
list.foldLeft(List[Int]()) {!
(accu, elem) => f(elem) :: accu!
}!
for(elem <- list)!
newList = newList :+ elem!
Small Tour of Functional Reactive
Programming in Scala
• But it’s definitely a bad idea to pass mutable
non-singleton objects all around.
• Code like this really makes me cringe:







(from Unity)
GameObject.Find("Hand");!
Small Tour of Functional Reactive
Programming in Scala
• Thinking “what if I have to explicitly pass every
single dependeny through constructor” makes
me write better OOP code.
• More on this later.
Small Tour of Functional Reactive
Programming in Scala
Small Tour of Functional Reactive
Programming in Scala
Small Tour of Functional Reactive
Programming in Scala
• A way to implement Observer Pattern.
• An Observable is an event source. When a
new event occurs, it notifis all its Observers.
!
!
Small Tour of Functional Reactive
Programming in Scala
• A way to implement Observer Pattern.
• An Observable is an event source. When a
new event occurs, it notifis all its Observers.
!
!
val numbers = Observable.from(List(1,2,3,4))!
numbers.subscribe(n => println(n))!
Small Tour of Functional Reactive
Programming in Scala
• A way to implement Observer Pattern.
• An Observable is an event source. When a
new event occurs, it notifis all its Observers.
!
!
• Why bother?
val numbers = Observable.from(List(1,2,3,4))!
numbers.subscribe(n => println(n))!
Small Tour of Functional Reactive
Programming in Scala
• java.util.Observable isn’t good enough:
• No type parameter
• No composition
• No scheduling
Small Tour of Functional Reactive
Programming in Scala
• Type parameter
!
!
!
• util.Observable can only pass Object …
Observable.from(List(1,2,3))!
.map(_.toString)!
// Observable[String]!
Small Tour of Functional Reactive
Programming in Scala
• Composition
!
!
• The game loop should wait the assets to get
loaded.
val tickEventRx = ...!
val assetLoadingEventRx = ...!
val processor = GameProcessor(tickEventRx)!
Small Tour of Functional Reactive
Programming in Scala
• Composition
!
!
• Naturally dependency injection = better OO!

// The main game loop starts once all assets are loaded!
val newTickRx = tickRx awaitComplete assetLoadingRx!
val processor = GameProcessor(newTickRx)!
Small Tour of Functional Reactive
Programming in Scala
• Composition
!
!
• 

def awaitComplete[U](that: Observable[U]): Observable[T] = {!
var completed = false!
that.subscribe(!
t => {},!
e => e.printStackTrace(),!
() => completed = true!
)!
observable.filter(t => completed)!
}!
Small Tour of Functional Reactive
Programming in Scala
• Scheduling
!
!
!
• It’s easy to integrate with other libraries cause
we can control when an Observable emits.
val TickScheduler: Scheduler = new rx.Scheduler {!
override def createWorker: rx.Scheduler.Worker = new TimerWorker!
}!
class TimerWorker extends rx.Scheduler.Worker {!
override def schedule(…): Subscription = {!
Timer.schedule(task, delaySeconds.toFloat)!
}!
}
What’s a Game, from a
Functional Perspective
• Game = Simulation with Inputs
!
!
What’s a Game, from a
Functional Perspective
• Simulation = apply a function repeatively
!
!
finalWorld = update(update(...update(world)...))!
update(world) = world of next tick
What’s a Game, from a
Functional Perspective
• Simulation = apply a function per frame
!
!
def onFrame(delta) {!
world = update(world, delta)!
render(world)!
}!
What’s a Game, from a
Functional Perspective
• Simulation = apply a function per frame
!
!
tickEventRx.subscribe(tickEvent =>!
world = update(world, tickEvent.delta)!
render(world)!
)!
What’s a Game, from a
Functional Perspective
• Wait a second! Inputs are events too!
!
!
touchDownEventRx.subscribe(touchDownEvent =>!
world = birdFlyUp(world)!
)!
What’s a Game, from a
Functional Perspective
• For example:
!
!
!
val touchSubject = Subject[TouchEvent]()!
!
gdxInput.setInputProcessor(new InputAdapter {!
override def touchDown(screenX: Int, screenY: Int,!
pointer: Int, button: Int): Boolean = {!
touchSubject.onNext(TouchDownEvent(screenX, screenY, pointer, button))!
true!
}!
})!
!
InputEventRxs(!
touchEventRx = touchSubject!
)!
What’s a Game, from a
Functional Perspective
• Now we have a consistent way to render images
& update objects & handle player
input(including network input)
!
!
class Processor(rxA, rxB...) {!
rxA.subscribe({!
world = foo(world)!
sideEffectA()!
})!
rxB.subscribe({!
world = foo(world)!
sideEffectB()!
})!
}!
What’s a Game, from a
Functional Perspective
• Now we have a consistent way to render images
& update objects & handle player
input(including network input)
!
!
class Processor(rxA, rxB...) {!
rxA.subscribe({!
world = foo(world)!
sideEffectA()!
})!
rxB.subscribe({!
world = foo(world)!
sideEffectB()!
})!
}!
What’s a Game, from a
Functional Perspective
• Necessary Evil…?
!
!
!
What’s a Game, from a
Functional Perspective
• The middle way!
!
!
!
trait Procedure!
trait SideEffect extends (World => Unit) with Procedure!
trait Transformation extends (World => World) with Procedure!
object Processor {!
def apply(rxA, rxB...): Observable[Procedure] {!
Observable.from(!
List(rxA.map(...),!
rxB.map(...)...)!
).flatten!
}!
}!
!
Observable.from(processorA, processorB...).flatten!
What’s a Game, from a
Functional Perspective
!
• Now we can decide the execution order, log the
procedures, combine similar side-effects, etc…
!
Yet Another Entity-
Component-System
• What’s Entity-Component-System(ECS)?
!
!
Type-Safe Another Entity-
Component-System
• What’s Entity-Component-System(ECS)?
• There are so many different implementations…
!
Type-Safe Another Entity-
Component-System
• Traditional ECS
• World has Iterable[Entity] and Iterable[System]
• Entity has Iterable[Component]
• In every frame:
Type-Safe Another Entity-
Component-System
world.systems.foreach(_.update(delta))!
class RenderSystem {!
def update(delta: Float) {!
val entities = world.entities.filter(e =>!
e.hasComponent(classOf[Transform]) &&!
e.hasComponent(classOf[RigidBody])!
)!
val sortedEntities = entities.sortBy(e =>!
e.getComponent(classOf[Transform]).position.z!
)!
sortedEntities.foreach(e =>!
val transform = e.getComponent(classOf[Transform])!
val texture = e.getComponent(classOf[Texture])!
draw(texture, transform.position.x, transform.position.y)!
)!
}!
}!
Type-Safe Another Entity-
Component-System
!
!
!
world.systems.foreach(_.update(delta))!
class PhysicSystem {!
def update(delta: Float) {!
val entities = world.entities.filter(e =>!
e.hasComponent(classOf[Transform]) && !
e.hasComponent(classOf[RigidBody])!
)!
entities.foreach(e =>!
entities.foreach(e2 =>!
if(collide(e, e2)) {!
e.onCollision(e2)!
e2.onCollision(e)!
}!
)!
)!
}!
}!
Type-Safe Another Entity-
Component-System
• Two questions:
• getComponent may return null.
• How to represent the dependencies between
components? e.g. Rigidbody requires
Transform.
Type-Safe Another Entity-
Component-System
• getComponent may return null
• We can make it return Option[Component]
instead of Component
• However it still leads unnecessary pattern
matching and collection traversal…
Type-Safe Another Entity-
Component-System
• Dependencies between components
• Unity has @RequireComponent, which is
bascially a macro…
• Is there an easier way?
Type-Safe Another Entity-
Component-System
• Cake Pattern!
!
!
!
Type-Safe Another Entity-
Component-System
• Cake Pattern!
!
!
!
trait TransformComponent {!
val transform: Transform!
}!
!
case class Transform(position: Vector2,!
scale: Vector2 = new Vector2(1, 1),!
rotation: Float = 0) {!
}!
Type-Safe Another Entity-
Component-System
• Cake Pattern!
!
!
!
trait BirdControlComponent { this: TransformComponent =>!
val birdControl: BirdControl!
}!
!
case class BirdControl(velocity: Vector2)!
Type-Safe Another Entity-
Component-System
• Cake Pattern!
!
!
!
class ControlSystem {!
def update(delta: Float) {!
val entities = world.entities.collect {!
case e: BirdControlComponent with TransformComponent => e!
}!
entities.foreach(e =>!
applyVelocity(e.birdControl.velocity, e.transform)!
)!
}!
}!
Type-Safe Another Entity-
Component-System
!
• Cake Pattern solved both problems: type safety
and dependency management.
• 

Type-Safe Another Entity-
Component-System
!
• Cake Pattern solved both problems: type safety
and dependency management.
• Downside: we can no longer dynamically add/
remove components into/from an entity.
Question?
Thank you!

More Related Content

What's hot

Networks and Types - the Future of Akka @ ScalaDays NYC 2018
Networks and Types - the Future of Akka @ ScalaDays NYC 2018Networks and Types - the Future of Akka @ ScalaDays NYC 2018
Networks and Types - the Future of Akka @ ScalaDays NYC 2018Konrad Malawski
 
Introducing Scala to your Ruby/Java Shop : My experiences at IGN
Introducing Scala to your Ruby/Java Shop : My experiences at IGNIntroducing Scala to your Ruby/Java Shop : My experiences at IGN
Introducing Scala to your Ruby/Java Shop : My experiences at IGNManish Pandit
 
Solid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaSolid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaKazuhiro Sera
 
FunctionalConf '16 Robert Virding Erlang Ecosystem
FunctionalConf '16 Robert Virding Erlang EcosystemFunctionalConf '16 Robert Virding Erlang Ecosystem
FunctionalConf '16 Robert Virding Erlang EcosystemRobert Virding
 
Functional Programming in Clojure
Functional Programming in ClojureFunctional Programming in Clojure
Functional Programming in ClojureTroy Miles
 
ITSubbotik - как скрестить ежа с ужом или подводные камни внедрения функциона...
ITSubbotik - как скрестить ежа с ужом или подводные камни внедрения функциона...ITSubbotik - как скрестить ежа с ужом или подводные камни внедрения функциона...
ITSubbotik - как скрестить ежа с ужом или подводные камни внедрения функциона...Vyacheslav Lapin
 
RSpec on Rails Tutorial
RSpec on Rails TutorialRSpec on Rails Tutorial
RSpec on Rails TutorialWen-Tien Chang
 
Reactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysReactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysManuel Bernhardt
 
Scala scripting-slides
Scala scripting-slidesScala scripting-slides
Scala scripting-slidesDaniel Sebban
 
RxJS Animations Talk - 2017
RxJS Animations Talk - 2017RxJS Animations Talk - 2017
RxJS Animations Talk - 2017Ben Lesh
 
とりあえず使うScalaz
とりあえず使うScalazとりあえず使うScalaz
とりあえず使うScalazShuya Tsukamoto
 
Speaking Scala: Refactoring for Fun and Profit (Workshop)
Speaking Scala: Refactoring for Fun and Profit (Workshop)Speaking Scala: Refactoring for Fun and Profit (Workshop)
Speaking Scala: Refactoring for Fun and Profit (Workshop)Tomer Gabel
 
Debugging Spark: Scala and Python - Super Happy Fun Times @ Data Day Texas 2018
Debugging Spark:  Scala and Python - Super Happy Fun Times @ Data Day Texas 2018Debugging Spark:  Scala and Python - Super Happy Fun Times @ Data Day Texas 2018
Debugging Spark: Scala and Python - Super Happy Fun Times @ Data Day Texas 2018Holden Karau
 
Scala elegant and exotic part 1
Scala  elegant and exotic part 1Scala  elegant and exotic part 1
Scala elegant and exotic part 1VulcanMinds
 
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsFresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsKonrad Malawski
 
Building Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with ScalaBuilding Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with ScalaWO Community
 
Introduction to Akka - Atlanta Java Users Group
Introduction to Akka - Atlanta Java Users GroupIntroduction to Akka - Atlanta Java Users Group
Introduction to Akka - Atlanta Java Users GroupRoy Russo
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghStuart Roebuck
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignLightbend
 

What's hot (20)

Scala Introduction
Scala IntroductionScala Introduction
Scala Introduction
 
Networks and Types - the Future of Akka @ ScalaDays NYC 2018
Networks and Types - the Future of Akka @ ScalaDays NYC 2018Networks and Types - the Future of Akka @ ScalaDays NYC 2018
Networks and Types - the Future of Akka @ ScalaDays NYC 2018
 
Introducing Scala to your Ruby/Java Shop : My experiences at IGN
Introducing Scala to your Ruby/Java Shop : My experiences at IGNIntroducing Scala to your Ruby/Java Shop : My experiences at IGN
Introducing Scala to your Ruby/Java Shop : My experiences at IGN
 
Solid And Sustainable Development in Scala
Solid And Sustainable Development in ScalaSolid And Sustainable Development in Scala
Solid And Sustainable Development in Scala
 
FunctionalConf '16 Robert Virding Erlang Ecosystem
FunctionalConf '16 Robert Virding Erlang EcosystemFunctionalConf '16 Robert Virding Erlang Ecosystem
FunctionalConf '16 Robert Virding Erlang Ecosystem
 
Functional Programming in Clojure
Functional Programming in ClojureFunctional Programming in Clojure
Functional Programming in Clojure
 
ITSubbotik - как скрестить ежа с ужом или подводные камни внедрения функциона...
ITSubbotik - как скрестить ежа с ужом или подводные камни внедрения функциона...ITSubbotik - как скрестить ежа с ужом или подводные камни внедрения функциона...
ITSubbotik - как скрестить ежа с ужом или подводные камни внедрения функциона...
 
RSpec on Rails Tutorial
RSpec on Rails TutorialRSpec on Rails Tutorial
RSpec on Rails Tutorial
 
Reactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDaysReactive Web-Applications @ LambdaDays
Reactive Web-Applications @ LambdaDays
 
Scala scripting-slides
Scala scripting-slidesScala scripting-slides
Scala scripting-slides
 
RxJS Animations Talk - 2017
RxJS Animations Talk - 2017RxJS Animations Talk - 2017
RxJS Animations Talk - 2017
 
とりあえず使うScalaz
とりあえず使うScalazとりあえず使うScalaz
とりあえず使うScalaz
 
Speaking Scala: Refactoring for Fun and Profit (Workshop)
Speaking Scala: Refactoring for Fun and Profit (Workshop)Speaking Scala: Refactoring for Fun and Profit (Workshop)
Speaking Scala: Refactoring for Fun and Profit (Workshop)
 
Debugging Spark: Scala and Python - Super Happy Fun Times @ Data Day Texas 2018
Debugging Spark:  Scala and Python - Super Happy Fun Times @ Data Day Texas 2018Debugging Spark:  Scala and Python - Super Happy Fun Times @ Data Day Texas 2018
Debugging Spark: Scala and Python - Super Happy Fun Times @ Data Day Texas 2018
 
Scala elegant and exotic part 1
Scala  elegant and exotic part 1Scala  elegant and exotic part 1
Scala elegant and exotic part 1
 
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka StreamsFresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
 
Building Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with ScalaBuilding Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with Scala
 
Introduction to Akka - Atlanta Java Users Group
Introduction to Akka - Atlanta Java Users GroupIntroduction to Akka - Atlanta Java Users Group
Introduction to Akka - Atlanta Java Users Group
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
Akka and the Zen of Reactive System Design
Akka and the Zen of Reactive System DesignAkka and the Zen of Reactive System Design
Akka and the Zen of Reactive System Design
 

Viewers also liked

Dinara sadyrbek kyzy
Dinara sadyrbek kyzyDinara sadyrbek kyzy
Dinara sadyrbek kyzyBakytbek Uulu
 
Almazbek kyzy guliza
Almazbek kyzy gulizaAlmazbek kyzy guliza
Almazbek kyzy gulizaBakytbek Uulu
 
Iklan tbbk dg32 tahun 2014
Iklan tbbk dg32 tahun 2014Iklan tbbk dg32 tahun 2014
Iklan tbbk dg32 tahun 2014Arun Narayanan
 
那些IOI教我的事以及沒教的事 (高中資訊科教師增能研討會 2014)
那些IOI教我的事以及沒教的事 (高中資訊科教師增能研討會 2014)那些IOI教我的事以及沒教的事 (高中資訊科教師增能研討會 2014)
那些IOI教我的事以及沒教的事 (高中資訊科教師增能研討會 2014)宇宣 賴
 
97340085 bộ-chuyển-nguồn-tự-động
97340085 bộ-chuyển-nguồn-tự-động97340085 bộ-chuyển-nguồn-tự-động
97340085 bộ-chuyển-nguồn-tự-độngDương Thế Tính
 
Management of Hip Dislocations
Management of Hip DislocationsManagement of Hip Dislocations
Management of Hip Dislocationsahmedashourful
 
24687200 event-marketing-project
24687200 event-marketing-project24687200 event-marketing-project
24687200 event-marketing-projectyashwant434
 
Lab diag nephrotic synd 2003
Lab diag nephrotic synd 2003Lab diag nephrotic synd 2003
Lab diag nephrotic synd 2003Ravi Jain
 
semen analysis
semen analysissemen analysis
semen analysisRavi Jain
 
Dr ravi lipid profile
Dr ravi lipid profileDr ravi lipid profile
Dr ravi lipid profileRavi Jain
 

Viewers also liked (15)

Ainaz turdumatova
Ainaz turdumatovaAinaz turdumatova
Ainaz turdumatova
 
Oydinoi bahridinova
Oydinoi bahridinovaOydinoi bahridinova
Oydinoi bahridinova
 
Asan bentuk
Asan bentukAsan bentuk
Asan bentuk
 
Dinara sadyrbek kyzy
Dinara sadyrbek kyzyDinara sadyrbek kyzy
Dinara sadyrbek kyzy
 
Almazbek kyzy guliza
Almazbek kyzy gulizaAlmazbek kyzy guliza
Almazbek kyzy guliza
 
Iklan tbbk dg32 tahun 2014
Iklan tbbk dg32 tahun 2014Iklan tbbk dg32 tahun 2014
Iklan tbbk dg32 tahun 2014
 
那些IOI教我的事以及沒教的事 (高中資訊科教師增能研討會 2014)
那些IOI教我的事以及沒教的事 (高中資訊科教師增能研討會 2014)那些IOI教我的事以及沒教的事 (高中資訊科教師增能研討會 2014)
那些IOI教我的事以及沒教的事 (高中資訊科教師增能研討會 2014)
 
97340085 bộ-chuyển-nguồn-tự-động
97340085 bộ-chuyển-nguồn-tự-động97340085 bộ-chuyển-nguồn-tự-động
97340085 bộ-chuyển-nguồn-tự-động
 
Kertas kerja projek prs
Kertas kerja projek prsKertas kerja projek prs
Kertas kerja projek prs
 
Management of Hip Dislocations
Management of Hip DislocationsManagement of Hip Dislocations
Management of Hip Dislocations
 
24687200 event-marketing-project
24687200 event-marketing-project24687200 event-marketing-project
24687200 event-marketing-project
 
Lab diag nephrotic synd 2003
Lab diag nephrotic synd 2003Lab diag nephrotic synd 2003
Lab diag nephrotic synd 2003
 
semen analysis
semen analysissemen analysis
semen analysis
 
Dr ravi lipid profile
Dr ravi lipid profileDr ravi lipid profile
Dr ravi lipid profile
 
Esr
EsrEsr
Esr
 

Similar to Coscup

Solid and Sustainable Development in Scala
Solid and Sustainable Development in ScalaSolid and Sustainable Development in Scala
Solid and Sustainable Development in Scalascalaconfjp
 
楽々Scalaプログラミング
楽々Scalaプログラミング楽々Scalaプログラミング
楽々ScalaプログラミングTomoharu ASAMI
 
Incremental Development with Lisp: Building a Game and a Website
Incremental Development with Lisp: Building a Game and a WebsiteIncremental Development with Lisp: Building a Game and a Website
Incremental Development with Lisp: Building a Game and a WebsiteJames Long
 
Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript EngineKris Mok
 
Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?Mario Camou Riveroll
 
The State of Managed Runtimes 2013, by Attila Szegedi
The State of Managed Runtimes 2013, by Attila SzegediThe State of Managed Runtimes 2013, by Attila Szegedi
The State of Managed Runtimes 2013, by Attila SzegediZeroTurnaround
 
RxSwiftを用いたアプリ開発の実践
RxSwiftを用いたアプリ開発の実践RxSwiftを用いたアプリ開発の実践
RxSwiftを用いたアプリ開発の実践GOMI NINGEN
 
The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)jeffz
 
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)jeffz
 
Scala Native: Ahead of Time
Scala Native: Ahead of TimeScala Native: Ahead of Time
Scala Native: Ahead of TimeNadav Wiener
 
Scala clojure techday_2011
Scala clojure techday_2011Scala clojure techday_2011
Scala clojure techday_2011Thadeu Russo
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsLeonardo Borges
 
System insight without Interference
System insight without InterferenceSystem insight without Interference
System insight without InterferenceTony Tam
 
Introduction to functional programming (In Arabic)
Introduction to functional programming (In Arabic)Introduction to functional programming (In Arabic)
Introduction to functional programming (In Arabic)Omar Abdelhafith
 
The Inclusive Web: hands-on with HTML5 and jQuery
The Inclusive Web: hands-on with HTML5 and jQueryThe Inclusive Web: hands-on with HTML5 and jQuery
The Inclusive Web: hands-on with HTML5 and jQuerycolinbdclark
 

Similar to Coscup (20)

Solid and Sustainable Development in Scala
Solid and Sustainable Development in ScalaSolid and Sustainable Development in Scala
Solid and Sustainable Development in Scala
 
楽々Scalaプログラミング
楽々Scalaプログラミング楽々Scalaプログラミング
楽々Scalaプログラミング
 
Incremental Development with Lisp: Building a Game and a Website
Incremental Development with Lisp: Building a Game and a WebsiteIncremental Development with Lisp: Building a Game and a Website
Incremental Development with Lisp: Building a Game and a Website
 
Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript Engine
 
Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?
 
The State of Managed Runtimes 2013, by Attila Szegedi
The State of Managed Runtimes 2013, by Attila SzegediThe State of Managed Runtimes 2013, by Attila Szegedi
The State of Managed Runtimes 2013, by Attila Szegedi
 
Osd ctw spark
Osd ctw sparkOsd ctw spark
Osd ctw spark
 
RxSwiftを用いたアプリ開発の実践
RxSwiftを用いたアプリ開発の実践RxSwiftを用いたアプリ開発の実践
RxSwiftを用いたアプリ開発の実践
 
Wider than rails
Wider than railsWider than rails
Wider than rails
 
The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)The Evolution of Async-Programming (SD 2.0, JavaScript)
The Evolution of Async-Programming (SD 2.0, JavaScript)
 
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)The Evolution of Async-Programming on .NET Platform (.Net China, C#)
The Evolution of Async-Programming on .NET Platform (.Net China, C#)
 
Scala Native: Ahead of Time
Scala Native: Ahead of TimeScala Native: Ahead of Time
Scala Native: Ahead of Time
 
Scala clojure techday_2011
Scala clojure techday_2011Scala clojure techday_2011
Scala clojure techday_2011
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
 
4. Interaction
4. Interaction4. Interaction
4. Interaction
 
ELAG Workshop version 1
ELAG Workshop version 1ELAG Workshop version 1
ELAG Workshop version 1
 
System insight without Interference
System insight without InterferenceSystem insight without Interference
System insight without Interference
 
JS Essence
JS EssenceJS Essence
JS Essence
 
Introduction to functional programming (In Arabic)
Introduction to functional programming (In Arabic)Introduction to functional programming (In Arabic)
Introduction to functional programming (In Arabic)
 
The Inclusive Web: hands-on with HTML5 and jQuery
The Inclusive Web: hands-on with HTML5 and jQueryThe Inclusive Web: hands-on with HTML5 and jQuery
The Inclusive Web: hands-on with HTML5 and jQuery
 

Coscup

  • 1. Scala 遊戲開發 101 with LibGDX and RxJava 賴宇宣(@raincolee)
  • 2. About Me • 賴宇宣(Raincole) • Twitter: @raincolee • raintomorrow.cc • ludumdare.com/compo/author/raincole/
  • 3. Agenda • What am I doing here? • A small tour of functional reactive programming in Scala • What’s a game, from a functional perspective • Type-safe Entity-Component-System implementation(bonus)
  • 4. What Am I Doing Here?
  • 5. What Am I Doing Here? • Introducing Scala ! • 
 • 

  • 6. What Am I Doing Here? • Introducing Scala • Promoting LibGDX(hopefully) • 
 • 

  • 7. What Am I Doing Here? • Introducing Scala • Promoting LibGDX(hopefully) • Sharing my humble opinions about reactive functional programming • 

  • 8. What Am I Doing Here? • Introducing Scala • Promoting LibGDX(hopefully) • Sharing my humble opinions about reactive functional programming • It’s not really about game developement

  • 9. What Am I Doing Here? • Introducing Scala • Promoting LibGDX(hopefully) • Sharing my humble opinions about reactive functional programming • It’s not really about game developement
 (Yes I lied :))
  • 10. I’m Not an Evangelist!
  • 11. I’m Not an Evangelist! • Scala(or RxScala, or functional programming, or any other buzzword) is not the holy grail… ! • 
 
 

  • 12. I’m Not an Evangelist! • Scala(or RxScala, or functional programming, or any other buzzword) is not the holy grail… • Sometimes they’re ugly… • 
 
 
 implicit def toGdxArray[T<:AnyRef]! (iterable: Iterable[T])! (implicit arg0: ClassTag[T])! : com.badlogic.gdx.utils.Array[T] = {! new com.badlogic.gdx.utils.Array[T](iterable.toArray)! }!
  • 13. Disclaimer • Treat snippets here as pseudo-code ! • 

  • 14. Disclaimer • Treat snippets here as pseudo-code • Design architectures here aren’t very practical. Don’t try it at home work. !
  • 16. LibGDX • A cross-platform game engine ! ! • 

  • 17. LibGDX • A cross-platform game engine • Desktop/Android/iOS(robovm)/HTML5(GWT) ! • 

  • 18. LibGDX • A cross-platform game engine • Desktop/Android/iOS(robovm)/HTML5(GWT) • You can use any JVM-based language • (except HTML5, casue GWT compiles Java directely)
  • 19. More on LibGDX • Basic Structure ! ! ! class MyGame extends Game {! override def create() {! // initialize! }! ! override def render() {! val delta = Gdx.graphics.getDeltaTime! // updateGame(delta)! // renderGame()! }! }!
  • 20. More on LibGDX • Render ! ! ! spriteBatch.begin()! val texture = new TextureRegion(! ! new Texture(Gdx.files.internal(“images/bg.png"))! )! spriteBatch.draw(texture, 0, 0}! spriteBatch.end()!
  • 21. More on LibGDX • Input ! ! ! Gdx.input.setInputProcessor(new InputAdapter {! override def touchDown(screenX: Int, screenY: Int,! pointer: Int, button: Int): Boolean = {! // handle touch down! true! }! ! override def touchUp(screenX: Int, screenY: Int,! pointer: Int, button: Int): Boolean = {! // handle touch up! true! }! })!
  • 22. More on LibGDX • Load assets with different resolutions ! ! ! val resolutions = List(new Resolution(320, 480, "320x480"),! new Resolution(640, 1136, "640x1136"))! val resolver = new ResolutionFileResolver(! ! ! ! ! ! ! new InternalFileHandleResolver(), resolutions)! val manager = new AssetManager()! manager.setLoader(classOf[Texture], new TextureLoader(resolver))! manager.load("images/bg.png", classOf[Texture])! // will load "images/640x1136/bg.png" on iPhone5!
  • 23. More on LibGDX • Call native code through Java ! ! ! new IOSApplication(new Retinol(), config) {! @Override! public void log (String tag, String message) {! Foundation.log("[info] " + tag + ": " + message);! }! };!
  • 24. Small Tour of Functional Reactive Programming in Scala
  • 25. Small Tour of Functional Reactive Programming in Scala ! ! ! !
  • 26. Small Tour of Functional Reactive Programming in Scala • The “Better Java” ! ! !
  • 27. Small Tour of Functional Reactive Programming in Scala • The “Better Java” ! ! ! class Vector2 {! private float x;! private float y;! public Vector2(float x, float y) {! this.x = x;! this.y = y;! }! public int getX() { return x; }! public int getY() { return y; }! }!
  • 28. Small Tour of Functional Reactive Programming in Scala • The “Better Java” ! ! ! case class Vector2(x: Float, y: Float)!
  • 29. Small Tour of Functional Reactive Programming in Scala • The “Better Java” ! ! • If there is a missing ID, get ready to watch the world burn
 idList.stream().map(id -> dict.get(id).contains(name))!
  • 30. Small Tour of Functional Reactive Programming in Scala • The “Better Java” ! ! • If there is a missing ID, get ready to watch the world burn
 … later! idList.stream().map(id -> dict.get(id).contains(name))!
  • 31. Small Tour of Functional Reactive Programming in Scala • The “Better Java” ! ! • 
 idList.flatMap(dict.get(_))!
  • 32. Small Tour of Functional Reactive Programming in Scala • The “Better Java” ! ! • Thus, Scala is not just for “lambda expression”.
 idList.flatMap(dict.get(_))!
  • 33. Small Tour of Functional Reactive Programming in Scala
  • 34. Small Tour of Functional Reactive Programming in Scala
  • 35. Small Tour of Functional Reactive Programming in Scala • 
 
 
 
 
 

  • 36. Small Tour of Functional Reactive Programming in Scala • “Purely functional” language = Stateless. ! ! !
  • 37. Small Tour of Functional Reactive Programming in Scala • “Purely functional” language = Stateless. • Scala is not pure, fortunately. ! !
  • 38. Small Tour of Functional Reactive Programming in Scala • “Purely functional” language = Stateless. • Scala is not pure, fortunately? ! ! list.foldLeft(List[Int]()) {! (accu, elem) => f(elem) :: accu! }! for(elem <- list)! newList = newList :+ elem!
  • 39. Small Tour of Functional Reactive Programming in Scala • But it’s definitely a bad idea to pass mutable non-singleton objects all around. • Code like this really makes me cringe:
 
 
 
 (from Unity) GameObject.Find("Hand");!
  • 40. Small Tour of Functional Reactive Programming in Scala • Thinking “what if I have to explicitly pass every single dependeny through constructor” makes me write better OOP code. • More on this later.
  • 41. Small Tour of Functional Reactive Programming in Scala
  • 42. Small Tour of Functional Reactive Programming in Scala
  • 43. Small Tour of Functional Reactive Programming in Scala • A way to implement Observer Pattern. • An Observable is an event source. When a new event occurs, it notifis all its Observers. ! !
  • 44. Small Tour of Functional Reactive Programming in Scala • A way to implement Observer Pattern. • An Observable is an event source. When a new event occurs, it notifis all its Observers. ! ! val numbers = Observable.from(List(1,2,3,4))! numbers.subscribe(n => println(n))!
  • 45. Small Tour of Functional Reactive Programming in Scala • A way to implement Observer Pattern. • An Observable is an event source. When a new event occurs, it notifis all its Observers. ! ! • Why bother? val numbers = Observable.from(List(1,2,3,4))! numbers.subscribe(n => println(n))!
  • 46. Small Tour of Functional Reactive Programming in Scala • java.util.Observable isn’t good enough: • No type parameter • No composition • No scheduling
  • 47. Small Tour of Functional Reactive Programming in Scala • Type parameter ! ! ! • util.Observable can only pass Object … Observable.from(List(1,2,3))! .map(_.toString)! // Observable[String]!
  • 48. Small Tour of Functional Reactive Programming in Scala • Composition ! ! • The game loop should wait the assets to get loaded. val tickEventRx = ...! val assetLoadingEventRx = ...! val processor = GameProcessor(tickEventRx)!
  • 49. Small Tour of Functional Reactive Programming in Scala • Composition ! ! • Naturally dependency injection = better OO!
 // The main game loop starts once all assets are loaded! val newTickRx = tickRx awaitComplete assetLoadingRx! val processor = GameProcessor(newTickRx)!
  • 50. Small Tour of Functional Reactive Programming in Scala • Composition ! ! • 
 def awaitComplete[U](that: Observable[U]): Observable[T] = {! var completed = false! that.subscribe(! t => {},! e => e.printStackTrace(),! () => completed = true! )! observable.filter(t => completed)! }!
  • 51. Small Tour of Functional Reactive Programming in Scala • Scheduling ! ! ! • It’s easy to integrate with other libraries cause we can control when an Observable emits. val TickScheduler: Scheduler = new rx.Scheduler {! override def createWorker: rx.Scheduler.Worker = new TimerWorker! }! class TimerWorker extends rx.Scheduler.Worker {! override def schedule(…): Subscription = {! Timer.schedule(task, delaySeconds.toFloat)! }! }
  • 52. What’s a Game, from a Functional Perspective • Game = Simulation with Inputs ! !
  • 53. What’s a Game, from a Functional Perspective • Simulation = apply a function repeatively ! ! finalWorld = update(update(...update(world)...))! update(world) = world of next tick
  • 54. What’s a Game, from a Functional Perspective • Simulation = apply a function per frame ! ! def onFrame(delta) {! world = update(world, delta)! render(world)! }!
  • 55. What’s a Game, from a Functional Perspective • Simulation = apply a function per frame ! ! tickEventRx.subscribe(tickEvent =>! world = update(world, tickEvent.delta)! render(world)! )!
  • 56. What’s a Game, from a Functional Perspective • Wait a second! Inputs are events too! ! ! touchDownEventRx.subscribe(touchDownEvent =>! world = birdFlyUp(world)! )!
  • 57. What’s a Game, from a Functional Perspective • For example: ! ! ! val touchSubject = Subject[TouchEvent]()! ! gdxInput.setInputProcessor(new InputAdapter {! override def touchDown(screenX: Int, screenY: Int,! pointer: Int, button: Int): Boolean = {! touchSubject.onNext(TouchDownEvent(screenX, screenY, pointer, button))! true! }! })! ! InputEventRxs(! touchEventRx = touchSubject! )!
  • 58. What’s a Game, from a Functional Perspective • Now we have a consistent way to render images & update objects & handle player input(including network input) ! ! class Processor(rxA, rxB...) {! rxA.subscribe({! world = foo(world)! sideEffectA()! })! rxB.subscribe({! world = foo(world)! sideEffectB()! })! }!
  • 59. What’s a Game, from a Functional Perspective • Now we have a consistent way to render images & update objects & handle player input(including network input) ! ! class Processor(rxA, rxB...) {! rxA.subscribe({! world = foo(world)! sideEffectA()! })! rxB.subscribe({! world = foo(world)! sideEffectB()! })! }!
  • 60. What’s a Game, from a Functional Perspective • Necessary Evil…? ! ! !
  • 61. What’s a Game, from a Functional Perspective • The middle way! ! ! ! trait Procedure! trait SideEffect extends (World => Unit) with Procedure! trait Transformation extends (World => World) with Procedure! object Processor {! def apply(rxA, rxB...): Observable[Procedure] {! Observable.from(! List(rxA.map(...),! rxB.map(...)...)! ).flatten! }! }! ! Observable.from(processorA, processorB...).flatten!
  • 62. What’s a Game, from a Functional Perspective ! • Now we can decide the execution order, log the procedures, combine similar side-effects, etc… !
  • 63. Yet Another Entity- Component-System • What’s Entity-Component-System(ECS)? ! !
  • 64. Type-Safe Another Entity- Component-System • What’s Entity-Component-System(ECS)? • There are so many different implementations… !
  • 65. Type-Safe Another Entity- Component-System • Traditional ECS • World has Iterable[Entity] and Iterable[System] • Entity has Iterable[Component] • In every frame:
  • 66. Type-Safe Another Entity- Component-System world.systems.foreach(_.update(delta))! class RenderSystem {! def update(delta: Float) {! val entities = world.entities.filter(e =>! e.hasComponent(classOf[Transform]) &&! e.hasComponent(classOf[RigidBody])! )! val sortedEntities = entities.sortBy(e =>! e.getComponent(classOf[Transform]).position.z! )! sortedEntities.foreach(e =>! val transform = e.getComponent(classOf[Transform])! val texture = e.getComponent(classOf[Texture])! draw(texture, transform.position.x, transform.position.y)! )! }! }!
  • 67. Type-Safe Another Entity- Component-System ! ! ! world.systems.foreach(_.update(delta))! class PhysicSystem {! def update(delta: Float) {! val entities = world.entities.filter(e =>! e.hasComponent(classOf[Transform]) && ! e.hasComponent(classOf[RigidBody])! )! entities.foreach(e =>! entities.foreach(e2 =>! if(collide(e, e2)) {! e.onCollision(e2)! e2.onCollision(e)! }! )! )! }! }!
  • 68. Type-Safe Another Entity- Component-System • Two questions: • getComponent may return null. • How to represent the dependencies between components? e.g. Rigidbody requires Transform.
  • 69. Type-Safe Another Entity- Component-System • getComponent may return null • We can make it return Option[Component] instead of Component • However it still leads unnecessary pattern matching and collection traversal…
  • 70. Type-Safe Another Entity- Component-System • Dependencies between components • Unity has @RequireComponent, which is bascially a macro… • Is there an easier way?
  • 72. Type-Safe Another Entity- Component-System • Cake Pattern! ! ! ! trait TransformComponent {! val transform: Transform! }! ! case class Transform(position: Vector2,! scale: Vector2 = new Vector2(1, 1),! rotation: Float = 0) {! }!
  • 73. Type-Safe Another Entity- Component-System • Cake Pattern! ! ! ! trait BirdControlComponent { this: TransformComponent =>! val birdControl: BirdControl! }! ! case class BirdControl(velocity: Vector2)!
  • 74. Type-Safe Another Entity- Component-System • Cake Pattern! ! ! ! class ControlSystem {! def update(delta: Float) {! val entities = world.entities.collect {! case e: BirdControlComponent with TransformComponent => e! }! entities.foreach(e =>! applyVelocity(e.birdControl.velocity, e.transform)! )! }! }!
  • 75. Type-Safe Another Entity- Component-System ! • Cake Pattern solved both problems: type safety and dependency management. • 

  • 76. Type-Safe Another Entity- Component-System ! • Cake Pattern solved both problems: type safety and dependency management. • Downside: we can no longer dynamically add/ remove components into/from an entity.