Loading
Tobse Fritz
This is a live streamed presentation. You will automatically follow the presenter and see the slide they're currently on.
ITscope GmbH
Java Entwickler
Kotlin Fanboy
Hobby Fotograf
Gaming Nerd
3D Printer
Daddy
Mit ITscope vereinfachen Systemhäuser
Ihre Verkaufsprozesse & IT Beschaffung
WO
WO
WO
WO
2003
Gründung
62
Mitarbeiter
7.800
Aktive Nutzer
420+
Distributoren
3 Mio
Produkte
Fakten
Tech Stack
Hospital
Kathis Kleiner Sattelit
Swing Plus Remake
Hit Klack Remake
Candy Crush Clone
Magic Maze Online Multiplayer
JVM
Win
Mac
Linux
JS
Browser
Native
Android
IOS
JVM
Win
Mac
Linux
JS
Browser
Win
Mac
Linux
Native
Android
IOS
Common
Code
Kotlin
Compiler
LLVM IR
JVM
Win
Mac
Linux
JS
Browser
Win
Mac
Linux
Native
Android
IOS
KorGE
Libs
Common
Code
Kotlin
Compiler
LLVM IR
JVM
Win
Mac
Linux
JS
Browser
Win
Mac
Linux
Native
Android
IOS
KorGE
Libs
Common
Code
expect
expect fun play(file: Sound)
actual
actual
actual
actual
actual
Features
public class Person {
private final String firstName;
private final String lastName;
private final LocalDate birthDay;
public Person(String firstName, String lastName,
LocalDate birthDay) {
this.firstName = firstName;
this.lastName = lastName;
this.birthDay = birthDay;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public LocalDate getBirthDay() {
return birthDay;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(firstName, person.firstName) &&
Objects.equals(lastName, person.lastName) &&
Objects.equals(birthDay, person.birthDay);
}
@Override
public int hashCode() {
return Objects.hash(firstName, lastName, birthDay);
}
@Override
public String toString() {
return "Person{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", birthDay=" + birthDay +
'}';
}
}
data class PersonK(
val firstName: String,
val lastName: String,
val birthDay: LocalDate
)
Java
Kotlin
Prägnanz
public class RectangleJava {
private int x = 0;
private int y = 0;
private int width = 0;
private int height = 0;
public boolean contains(int x, int y) {
var inWidth = (x >= this.x) && (x <= this.x + width);
var inHeight = (y >= this.y) && (y <= this.y + height);
return inWidth && inHeight;
}
}
Java
public class RectangleKotlin {
private val x = 0;
private val y = 0;
private val width = 0;
private val height = 0;
public fun contains(x: Int, y: Int): Boolean {
val inWidth = (x >= this.x) && (x <= this.x + width);
val inHeight = (y >= this.y) && (y <= this.y + height);
return inWidth && inHeight;
}
}
Kotlin
public fun public private fun
new
;
class RectangleKotlinNice {
private val x = 0
private val y = 0
private val width = 0
private val height = 0
fun contains(x: Int, y: Int): Boolean {
val inWidth = x in (x .. this.x + width)
val inHeight = y in (y .. this.y + height)
return inWidth && inHeight
}
}
Kotlin
Features
Prägnant
Sicher
Interoperabel
Optimales Tooling
Frei & OpenSource
Inline Classes
Extensions
Contracts
Operator Overloading
Gradle DSL
Data Classes
Coroutines
The Tree Game
The Tree Game
The Tree Game
Lesson learned
image(backgroundBitmap){
size(gameWidth, gameHeight)
}
image(treeBitmap).centerOnStage()
Image(appleBitmap).addTo(this)
container {
name = "Happy Sun"
circle(radius = 50.0, fill = YELLOW)
circle(radius = 8.0, fill = BLACK).position(60, 20)
circle(radius = 8.0, fill = BLACK).position(24, 20)
circle(radius = 10.0, fill = RED).position(50, 60)
position(50, 50)
}
The Tree Game
private suspend fun hit() {
tween(this::y[gameHeight],
time = 1.seconds, easing = EASE_IN)
tween(this::rotation[Random[-40, 40].degrees],
time = 100.milliseconds, easing = EASE_IN)
}
EASE_IN_ELASTIC EASE_OUT_ELASTIC EASE_OUT_BOUNCE LINEAR EASE_IN EASE_OUT EASE_IN_OUT EASE_OUT_IN EASE_IN_BACK EASE_OUT_BACK
EASE_IN_OUT_BACK EASE_OUT_IN_BACK EASE_IN_OUT_ELASTIC EASE_OUT_IN_ELASTIC EASE_IN_BOUNCE EASE_IN_OUT_BOUNCE EASE_OUT_IN_BOUNCE EASE_IN_QUAD EASE_OUT_QUAD EASE_IN_OUT_QUAD
Lesson learned
The Tree Game
val bus = GlobalBus()
class GameOverEvent()
private fun eatApple() {
if (apples == 0) {
bus.send(GameOverEvent())
}
}
bus.register<GameOverEvent> {
text("Game Over", textSize = 64.0).centerOnStage()
}
private suspend fun hit() {
tween(this::y[gameHeight],
time = 1.seconds, easing = EASE_IN)
tween(this::rotation[Random[-40, 40].degrees],
time = 100.milliseconds, easing = EASE_IN)
}
Game Over
Lesson learned
The Tree Game
class Bird(...){
init {
onClick {
hit()
}
}
class Bird(...){
init {
onCollision(filter = { it is Image}) {
if (it.name == "apple") {
it.removeFromParent()
eatApple()
}
}
}
}
Lesson learned
resourcesVfs["bird.mp3"].readSound().play()
The Tree Game
JS
Browser
runAndroidRelease
runJs
runJvm
runNativeRelease
Native
Android
Native
IOS
Win
Mac
Linux
Native
JVM
Win
Mac
Linux
Tasks > run
iosRunSimulatorDebug
Lesson learned
The Tree Game
Coming soon
🆕
Jetzt mit Hörnchen!
The Tree Game
gamepad.down(0, GameButton.LEFT) {
x -= 40
}
gamepad.down(0, GameButton.RIGHT) {
x += 40
}
gamepad.down(0, GameButton.BUTTON0) {
shoot()
}
keys {
down {
if (it.key == Key.LEFT) {
x -= 20
}
if (it.key == Key.RIGHT) {
x += 20
}
if (it.key == Key.SPACE) {
shoot()
}
}
}
Coming soon
solidRect(50, 50, Colors.RED)
solidRect(50, 50, Colors.RED)
solidRect(50, 50, Colors.RED)
solidRect(600, 100, Colors.WHITE)
solidRect(50, 50, Colors.RED)
.registerBodyWithFixture(type = BodyType.DYNAMIC, density = 2, friction = 0.01)
solidRect(50, 50, Colors.RED)
.registerBodyWithFixture(type = BodyType.DYNAMIC)
solidRect(50, 50, Colors.RED)
.registerBodyWithFixture(type = BodyType.DYNAMIC)
solidRect(600, 100, Colors.WHITE)
.registerBodyWithFixture(
type = BodyType.STATIC,
friction = 0.2
)
solidRect(50, 50, Colors.RED)
.registerBodyWithFixture(type = BodyType.DYNAMIC, density = 2, friction = 0.01)
solidRect(50, 50, Colors.RED)
.registerBodyWithFixture(type = BodyType.DYNAMIC)
solidRect(50, 50, Colors.RED)
.registerBodyWithFixture(type = BodyType.DYNAMIC)
solidRect(600, 100, Colors.WHITE)
.registerBodyWithFixture(
type = BodyType.STATIC,
friction = 0.2
)
onClick {
val pos = it.currentPosLocal
solidRect(50, 50, Colors.RED).position(pos.x, pos.y).rotation(randomAngle())
.registerBodyWithFixture(type = BodyType.DYNAMIC)
}
fun randomAngle(): Angle = Random.nextInt(0, 90).degrees
val container = fixedSizeContainer(width, height)
container.korui {
vertical {
layoutChildrenPadding = 2
horizontal {
preferredWidth = 100.percent
button("HELLO", {
preferredWidth = 70.percent
})
button("WORLD", {
preferredWidth = 30.percent
preferredHeight = 32.pt
})
}
button("TEST")
checkBox("CheckBox", checked = true)
comboBox("test", listOf("test", "demo"))
}
}
DSL
Absolute Positionierung
uiButton(256.0, 32.0) {
text = "Disabled Button"
position(128, 128)
}
val emitter = resourcesVfs["particle2.pex"].readParticleEmitter()
particleEmitter(emitter)
Axiom Verge
Brigador
2016
2015
Edit Worlds
10K
10K
1Mio
100K
need
more?
https://store.steampowered.com/app/379720/DOOM/
Warum ein Spiel programmieren?
https://produktivkeller.com/game-jams
29 - 31 Oktober 2021
https://globalgamejam.org
28 - 30 Januar 2022
28 000 creators
104 Countries
6 000 Games
Warum ein Spiel programmieren?
Warum ein Spiel programmieren?
https://globalgamejam.org/news/poster-showcase-2018-0
git clone https://github.com/korlibs/korge-hello-world
Tools
Werde Teil der ITscope Familie
Werde Teil der ITscope Familie
Java Backend Developer (m/w/d)
Festanstellung, Vollzeit
Informatikstudenten (m/w/d)
Werkstudent, Teilzeit
Werkstudent (m/w/d) im Marketing
Werkstudent, Teilzeit
Werde Teil der ITscope Familie