Let's develop a quick game!
Our first game in CosPlay will be a five cute stick-figures dancing Macarena. Each of the five dancers can be turned on and off by pressing his number key 1 through 5 on the keyboard. We'll call this game "ASCII Macarena"
. The goal is to keep the entire game under 100 lines of code but demo some key mechanics of the CosPlay game engine and its gamedev.
The end result should look like this:
Although you can develop with CosPlay in any way you prefer - it's just a simple library after all - for our first game we will be using IntelliJ IDEA. Let's create new SBT project, making sure to select the latest Scala3 SDK.
Once the project is created, open build.sbt
file and add the following lines 8, 9 and 11 to include Maven dependency for the CosPlay game engine. Your edited build.sbt
file should look like this (with whatever the latest Scala3 version):
ThisBuild / version := "0.1.0-SNAPSHOT" ThisBuild / scalaVersion := "3.3.0" lazy val root = (project in file(".")) .settings( name := "macarena", libraryDependencies += "org.cosplayengine" % "cosplay" % "0.9.5" )
To finish configuring our project - first, reload the SBT project and perform two more steps:
resources
folder under src/main
directory. That's where we are going to keep our sound file for Macarena tune. You can download a free *.wav soundtrack for Macarena or any other tune at https://freesound.org, for example. NOTE: if you use different file make sure to change its filename on the line 20 of the game code.AsciiMacarena.scala
in the package org.rowangames
(you can use any other package name - just make sure to change it in the code line 1).Your project view in IDEA should now look like this:
Open AsciiMacarena.scala
we've just created and add the following code:
package com.rowangames import org.cosplay.* import CPColor.* import CPPixel.* import CPKeyboardKey.* import prefabs.images.ani.* import prefabs.scenes.* import prefabs.shaders.* object AsciiMacarena: def main(args: Array[String]): Unit = val BLUE_BLACK = CPColor("0x00000F") val bgPx = ' '&&(BLUE_BLACK, BLUE_BLACK) val dim = CPDim(80, 20) // Dimension for the scenes. // Initialize the engine. CPEngine.init(CPGameInfo(name = "ASCII Macarena", initDim = Option(dim))) val music = CPSound(src = "macarena.wav") // https://freesound.org def sprite( id: String, aniFrames: Seq[CPImage], // Animation key frames. x: Int, y: Int, key: CPKeyboardKey // Keyboard key to toggle this dancer. ): CPSceneObject = // Fade in effect for this sprite. val fiShdr = new CPFadeInShader(true, 1000, bgPx) // Use 1st frame as idle animation & paint the idling dancer. val idleImg = aniFrames.head.skin((px, _, _) => px.withFg(C_GRAY5)) val idleAni = CPAnimation.filmStrip( s"ani-idl-$id", 250, true, false, Seq(idleImg) ) val danceAni = CPAnimation.filmStrip( s"ani-dance-$id", 250, true, false, aniFrames ) new CPAnimationSprite( s"spr-$id", Seq(idleAni, danceAni), x, y, 0, idleAni.getId, // Initial animation. false, // No collision required. Seq(fiShdr)): override def update(ctx: CPSceneObjectContext): Unit = super.update(ctx) ctx.getKbEvent match case Some(evt) => if evt.key == key then // Toggle dancing/idling. if getCurrentAnimation == idleAni then change(danceAni.getId, true, false) else change(idleAni.getId, true, false) case None => () val x = 24 val y = 8 val danceFloor = CPScene("danceFloor", Option(dim), bgPx, sprite("1", CPMacarena1AniImage.trimBg().split(3, 3), x, y, KEY_1), sprite("2", CPMacarena2AniImage.trimBg().split(3, 3), x + 7, y, KEY_2), sprite("3", CPMacarena3AniImage.trimBg().split(3, 4), x + 14, y - 1, KEY_3), sprite("4", CPMacarena4AniImage.trimBg().split(3, 3), x + 21, y, KEY_4), sprite("5", CPMacarena5AniImage.trimBg().split(3, 3), x + 28, y, KEY_5), new CPLabelSprite(24, 12, 0, "[1] [2] [3] [4] [5]", C_DARK_CYAN), CPKeyboardSprite(_.exitGame(), KEY_LO_Q), // Exit the game on 'q' press. new CPOffScreenSprite: // Off-screen sprite to start music auto-play. override def onStart(): Unit = super.onStart() music.loop(1500) ) // Start the game & wait for exit. try CPEngine.startGame( // CosPlay logo scene. new CPFadeShimmerLogoScene( "logo", Option(dim), bgPx, CS_X11_ORANGES ++ CS_X11_BLUES, // Colors to use for shimmer. "danceFloor" // ID of the scene to switch to when logo animation is done. ), danceFloor // Main game scene. ) finally CPEngine.dispose() sys.exit(0)
NOTES:
main(...)
method as entry point for compatibility with Java runtime.80x20
(line 14).danceFloor
) with a set of animated sprites (one for each dancer) - details of the APIs are not important here. Note that we also add a couple of additional sprites to our scene to handle the exit on Q press, showing a text label and start the background soundtrack.danceFloor
scene. To run the game from IntelliJ IDEA make sure you have AsciiMacarena.scala
file open and press Ctrl+Shift+F10. This will start our game in the built-in terminal emulator:
That's it! 👌