調子にのってScalaでゲーム作成

...してみてないけど,ここのサンプルコードScalaに焼き直して,ちょっと自機とか追加してみたよ。あと,しんさん(id:shin)の指摘通りSTICK()使ってみたス。


この星が流れるだけのって,学生んときI/O別冊の8086アセンブラ本読んで組んだことあるけど,自機の追加までできんかったな。それが,こうも簡単にできるとは。わはは,オレは当時のオレを超えたぞ。:-D
#ライブラリのおかげって事を棚に上げるヤツ。


とりあえず,組んだコード晒しておきます。こうですか?わかりません。><
#Groovyと違って,Scalaはさっぱりわからねぇ。

import java.awt.event.KeyEvent
import java.awt.{Font, Color}
import java.io.File
import javax.imageio.ImageIO

import shinsan.shingl3.ShinGL3OpenGL._
import shinsan.shingl3.ShinGL3Input._
import shinsan.shingl3.ShinGL3SE._
import shinsan.shingl3.ShinGL3BGM._
import shinsan.shingl3.ShinGL3Math._


object Game {
  implicit def formatString(s:String) = new FormatString(s)

  val starmax = 200
  var starx, stary, stars = new Array[Int](starmax)
  var starc = new Array[Color](starmax)
  val font = new Font("monospace", Font.BOLD, 32)

  def main(arg:Array[String]) {
    val icon = ImageIO.read(new File("icon.png"))
    SETSCREEN("サンプル", icon, 320, 240)
    START(new Init(), new MainLoop(), 60)
  }

  class Init extends Runnable {
    def run {
      val rndx, rndy, rnds, rndc = new java.util.Random()
      for (i <- 0 until starmax) {
        starx(i) = rndx.nextInt(320)
        stary(i) = rndx.nextInt(240)
        stars(i) = if (i < 30) 0 else rnds.nextInt(3) + 1
        starc(i) = if (i < 30) Color.darkGray
                   else rndc.nextInt(3) match {
                     case 0 => Color.GREEN
                     case 1 => Color.RED
                     case 2 => Color.YELLOW
                   }
      }
    }
  }

  class MainLoop extends Runnable {
    var myshipx = 144

    def run {
      WIPE(Color.BLACK)
      for(i <- 0 until starmax) {
        FILL(starx(i), stary(i), 1, 1, starc(i), AlphaMode.NORMAL)
        starx(i) = STICK(0) match {
          case 4 => if (starx(i) > 320) -1 else starx(i) + stars(i)
          case 6 => if (starx(i) < -1) 320 else starx(i) - stars(i)
          case _ => starx(i)
        }
        stary(i) = if (stary(i) > 240) -1
                   else STICK(0) match {
                     case 8 => stary(i) + stars(i) * 2
                     case _ => stary(i) + stars(i)
                   }
      }
      myshipx = STICK(0) match {
        case 4 => if (myshipx < 1) 0 else myshipx - 1
        case 6 => if (myshipx > 303) 304 else myshipx + 1
        case _ => myshipx
      }
      PRINT(myshipx, 200, font, Color.GREEN, "凸")
      PRINT(220, 230, font, Color.WHITE, "%dfps" % GETFPS())
      if (INPUT(KeyEvent.VK_ESCAPE)) EXIT(0)
    }
  }
}

class FormatString(str:String) {
  def %(args:Any*) = {
    String.format(str, args.map(_.asInstanceOf[AnyRef]):_*)
  }
}


でもって画面はこんなの。うーん,割り込みのこと考えないとゲームはこんなに簡単なのか。毎回,WIPEしてるのにちらつきやしない。
#って,CPUクロックがGHzオーバーな世の中で何を時代錯誤的な事を言っているのか...。


密かにScalaGString相当のものがないのが不満だったけど,こちらに良いサンプルがあったので,ありがたく使わせてもらいました。
Python風の%をScalaで - みずぴー日記


実際使ってみると理解も早いね,Scala面白かったデス。たしかにパターンマッチは強力だ。implicit conversionは変態すぎてまだわかりません。:-)