Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411512 Posts in 69376 Topics- by 58431 Members - Latest Member: Bohdan_Zoshchenko

April 27, 2024, 06:39:52 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityTownhallForum IssuesArchived subforums (read only)TutorialsScala for Games II: Hello world
Pages: [1]
Print
Author Topic: Scala for Games II: Hello world  (Read 4873 times)
Krux
Level 2
**



View Profile
« on: April 04, 2011, 09:53:06 AM »

This tutorial assumes you are interested to make games with scala. It will cover all steps you need to compile a project.

Everything you need to install is Simple Build Tool (sbt). With sbt you build your projects, solve dependencies, and do many more stuff. How to install sbt you can read here. This is everything you need to install, everything else is managed by sbt. Even downloading the scala compiler is done by sbt. For code editing notepad will be sufficient, yet.

now create a folder somewhere on your computer, and open that folder in a terminal. If you have done everything right in the first step, typing sbt will start sbt and you will be prompted if you want to Create a project. Now you have to enter some project specific details. Name Organisation and Version does not really matter it is only for you, but scala version and sbt version shound not be changed (just hit enter). Now the download of many dependencies starts. After it has finished you should have new folders, and in the terminal you are now in the interactive sbt shell. The most important command you can type here is run. It compiles and runs your project. To test this, you can create a new source file Main.scala in src/main/scala with the following content:
Code:
object Main{
  def main(args:Array[String]){
    println("Hallo Welt")
  }
}
This is just a Hello world program. BTW ~run will automatically compile and run your code every time you save your sourcecode.

For our project we can use the LWJGL project plugin. Create a file plugin.scala in project/plugin (folder needs to be created) with the following content

Code:
import sbt._

class Plugin(info: ProjectInfo) extends PluginDefinition(info) {
  val lwjglVersion = "com.github.philcali" % "sbt-lwjgl-plugin" % "2.0.4"
}
this is the plugin definition file. It sets the dependencies to all deeded plugin. If you want to use more plugins for your project, you will have to define them in this file.

Now we also need our project definition, create a file project.scala in project/build (folder needs to be created) with the following content

Code:
import sbt._

class Project(info: ProjectInfo) extends LWJGLProject(info)
This is our project definition. there is no project specific configuration yet, because everything we need to run a LWJGL project is inherited by LWJGLProject.

in our sbt terminal we now need to do the folloing two commands

reload reloads project definition
update downloads dependencies

now everything is ready to write an LWJGL project. If you are interested how this lwjgl project definition looks like, you can see it in project/plugins/src_managed/sbt-lwjgl-plugin-2.0.4/LWJGLProject.scala. There are also project defitiontions of Slick and JMonkey projects, to use them your project definition would look like:
Code:
class Project(info: ProjectInfo) extends LWJGLProject(info) with JMonkey
or
Code:
class Project(info: ProjectInfo) extends LWJGLProject(info) with Slick2D

to make the home project a little bit more interesting I have created a simple template project that can then be modified into any other project, it is a little bit more than the classic rotating triangle (IKJL for controls). just override your main scala source with:

Code:
import org.lwjgl._
import opengl.{Display,GL11,DisplayMode}
import GL11._
import input._
import math._

object Main{
  val GAME_TITLE = "My Game"
  val FRAMERATE = 60
  val width = 640
  val height = 480

  // init needs to be called before display list of player can be created
  init
  
  var finished = false

  def main(args:Array[String]){
    while(!finished){
      Display.update
      
      logic
      render

      Display.sync(FRAMERATE)
    }
  }

  def init{
    println("init Display")
    Display.setTitle(GAME_TITLE)
    Display.setVSyncEnabled(true)
    Display.setDisplayMode(new DisplayMode(width,height))
    Display.create

    println("init gl")
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING)
    glEnable(GL_LIGHT0)
    adjustcam
  }

  def adjustcam{
    val v = width.toFloat / height.toFloat
    
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity
    glFrustum(-v,v,-1,1,1,100)
    glMatrixMode(GL_MODELVIEW)
  }

  def cleanup{
    Display.destroy
  }

  def logic{
    import Keyboard._

    if(isKeyDown(KEY_ESCAPE))
      finished = true
    if(Display.isCloseRequested)
      finished = true
    
    Player.update
    Camera.update
    // this rotates our camera around the center
  }

  def renderGrid(size : Int){
      // this creates the nice looking background.
    glDisable(GL_LIGHTING)
    glBegin(GL_LINES)
    for(i <- -size to size){
      glVertex2i(i,-size)
      glVertex2i(i, size)
      glVertex2i(-size,i)
      glVertex2i( size,i)
    }
    glEnd
    glEnable(GL_LIGHTING)
  }

  def render{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    Camera.apply
    Player.draw
    
    //without background, motion is not visible
    // a green grid is nice and retro
    glColor3f(0,1,0)
    renderGrid(1000)
  }
}

object Camera{
  var angle = 0.0f
  var rotation = 0.0f

  def update{
    angle += 2.0f % 360
    rotation += 0.2f
  }

  def apply{
    glLoadIdentity
    glTranslatef(0,0,-20)
    glRotatef(-70,1,0,0)
    glRotatef(rotation,0,0,1)
  }
}

// the player is a singleton, because we only have one player
// if we want to make this game into a multiplayer game, we only need to
// replace object with class, and instanciate some player objects.
object Player
{
  // short form to init three variables
  var x,y,z = 0f

  val vertexData = BufferUtils.createFloatBuffer(18);
  val normalData = BufferUtils.createFloatBuffer(18);
  
  vertexData.put(Array[Float](0,0,0.5f, -0.5f,-0.5f,0, -0.5f, 0.5f,0,  0.5f, 0.5f,0,  0.5f,-0.5f,0, -0.5f,-0.5f,0)).flip
  normalData.put(Array[Float](0,0,   1, -1   ,-1   ,1, -1   , 1   ,1,  1   , 1   ,1,  1   ,-1   ,1, -1   ,-1   ,1)).flip
  
  val displayList = glGenLists(1)
  
  glEnableClientState(GL_VERTEX_ARRAY)
  glEnableClientState(GL_NORMAL_ARRAY)
    
  glVertexPointer(3,0,vertexData)
  glNormalPointer(0,normalData)
    
  glNewList(displayList,GL_COMPILE)
  glDrawArrays(GL_TRIANGLE_FAN,0,6)
  glEndList
  
  glDisableClientState(GL_VERTEX_ARRAY)
  glDisableClientState(GL_NORMAL_ARRAY)

  def update{
    // in scala we can locally import all methods from Keyboard.
    import Keyboard._

    // rx and rx store our keyboard input as direction
    var rx,ry = 0

    // keys are IKJL for up down left right

    if(isKeyDown(KEY_I))
      ry += 1
    if(isKeyDown(KEY_K))
      ry -= 1
    if(isKeyDown(KEY_J))
      rx -= 1
    if(isKeyDown(KEY_L))
      rx += 1
      
    // this makes the direction relative to the camera position
    // it is a simple rotation matrix you may know from linear algebra
    val ax = rx*cos(-Camera.rotation.toRadians)-ry*sin(-Camera.rotation.toRadians)
    val ay = rx*sin(-Camera.rotation.toRadians)+ry*cos(-Camera.rotation.toRadians)

    x += 0.1f*ax.toFloat
    y += 0.1f*ay.toFloat
  }
  
  def draw = {
    glPushMatrix
    glTranslatef(x,y,z)
    glRotatef(Camera.angle, 0, 0, 1.0f)
    glColor3f(1, 0, 0)
    glCallList(displayList)
    glPopMatrix
  }
}


ok, thats all about setting up LWJGL. From here on you can edit your code, compile your project and do whatever you want to do. But for syntax highlighting, you should use one of the supported editors. I am using Gedit, but Jedit does work as well as the cooperative editor gobby. IntelliJ (complete Java IDE) does also work. The good thing is, there is an sbt plugin that generates the IntelliJ project files for you, and a plugin for IntelliJ (use the plugin manager) that lets you use sbt inside of intelliJ.

(any response even negative response is welcome)
« Last Edit: April 06, 2011, 08:04:03 AM by Krux » Logged
vogre
TIGBaby
*


View Profile
« Reply #1 on: April 06, 2011, 03:42:13 AM »

Yeah, I am interested in making games with Scala!

My last attempt at OpenGL programming was at college, using the fixed function pipeline.
For learning a more moder OpenGL style I am trying to convert a C++ OpenGL tutorial to Scala and LWJGL (using sbt as well).
It is stored at https://github.com/vogre/lwjgltut - you're welcome to try.

I've only got the single triangle to render so far, but I'll be working further.

Logged
goshki
Level 4
****



View Profile WWW
« Reply #2 on: April 06, 2011, 04:02:36 AM »

Oh, this is nice. For some time I've wanted to see how Scala does in game-development. It seems such a nicer and more elegant and more powerful language compared to plain Java. I'm definitely gonna give it a try in the near future.
Logged

Krux
Level 2
**



View Profile
« Reply #3 on: April 06, 2011, 07:14:35 AM »

yay feedback  Gentleman maybe we'll see some scala games in the next competition  Giggle
« Last Edit: April 06, 2011, 08:05:37 AM by Krux » Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic