前の続き。
実際にファイルを読み込めるようにしました。
EnumeratorMはIterVをモナドで包むための型です。
enumReaderはブログの例とは違いますが、一字ずつ読み込むのではなく、BufferReaderを用いて一行づつ読み込むようにしています。
<<<はScalazで定義されており、composeと同じです。
enumと同様に、Doneになるまで処理を繰り返します。
enumFileはファイルをenumReaderに渡す。
bracketにより、closeReaderが確実に行われることが保証されています。
実行例
現在、scalaz.effectsにあるIterateeな入出力関数はこれらと、標準入力からの読み込みだけです。
2011年9月6日火曜日
2011年9月4日日曜日
ScalazでIteratee
Scala会議でLTしてきました。
拙い発表でしたが、まじめに聞いてくれたScala会議参加者の方々には感謝です。
このLTで話せなかったIterateeについて、tanakhさんのブログを参考に書かせていただきます。
Scalazでの実装
ブログを参考に実際に実装してみます。
定義は簡単。
Haskellのコードとあまり変わりがないですね。(ぇ
ストリームはList(El(1), El(2), El(3), EOF())みたいなイメージです。
enum,runの実装。
enumはfoldl(むしろreduce?)そのままで、IterVを関数と初期値にみたたて、Doneの場合でも結果を返すものと思えばいいです。
runは結果を取り出すだけ。初期値に当たるものがない場合があるので、結果はOptionで返します。
Iterateeたち。
これらをストリームに適用し、結果を得ます。curriedとか初めて使った気がします。
型が消えてしまうので、match式のところはwarningがいっぱいです。
この対処法がないのが残念なところ。(あったら教えてください
モナド。
PartialApplyを使おうとして嵌りました。定義のところで使っちゃダメなんですね・・・・
このインスタンスを作ることで、合成(>>=や>|>)を使うことができます。
Haskellと違って、Monadを定義すればFunctorやApplicativeがついてくるのでちょっと楽。
実行例
Haskellのコードそのままに書けるのは感動ですね。
次はIOを実装しようと思います。
拙い発表でしたが、まじめに聞いてくれたScala会議参加者の方々には感謝です。
このLTで話せなかったIterateeについて、tanakhさんのブログを参考に書かせていただきます。
Scalazでの実装
ブログを参考に実際に実装してみます。
定義は簡単。
Haskellのコードとあまり変わりがないですね。(ぇ
ストリームはList(El(1), El(2), El(3), EOF())みたいなイメージです。
enum,runの実装。
enumはfoldl(むしろreduce?)そのままで、IterVを関数と初期値にみたたて、Doneの場合でも結果を返すものと思えばいいです。
runは結果を取り出すだけ。初期値に当たるものがない場合があるので、結果はOptionで返します。
Iterateeたち。
これらをストリームに適用し、結果を得ます。curriedとか初めて使った気がします。
型が消えてしまうので、match式のところはwarningがいっぱいです。
この対処法がないのが残念なところ。(あったら教えてください
モナド。
PartialApplyを使おうとして嵌りました。定義のところで使っちゃダメなんですね・・・・
このインスタンスを作ることで、合成(>>=や>|>)を使うことができます。
Haskellと違って、Monadを定義すればFunctorやApplicativeがついてくるのでちょっと楽。
実行例
Haskellのコードそのままに書けるのは感動ですね。
次はIOを実装しようと思います。
2010年11月19日金曜日
EmacsでScalaプログラミング
1週間ぐらい前ですが、Scalaでの開発はEclipseからEmacsにかえました。
理由は、Eclipseが補完をするときに動作がとても重くなることで、これはちょっとしたストレスになっていました。
そこで、今勉強中のEmacsでScalaの開発ができるプラグインを探したところ、ENSIME という素晴らしいものを見つけました。
ENSIMEの導入は、scala-modeやyasnippet必要なので少し面倒かもしれません。
私は、よりIDE風にするため、ECB(Emacs Code Browser)も使っています。
ENSIMEはEclipseのプラグインよりも動作が軽く、sbtやmavenとの連携も楽にできるのでとてもおすすめです。
理由は、Eclipseが補完をするときに動作がとても重くなることで、これはちょっとしたストレスになっていました。
そこで、今勉強中のEmacsでScalaの開発ができるプラグインを探したところ、ENSIME という素晴らしいものを見つけました。
Emacs+sbt+ENSIME+ECB
ENSIMEの導入は、scala-modeやyasnippet必要なので少し面倒かもしれません。
私は、よりIDE風にするため、ECB(Emacs Code Browser)も使っています。
ENSIMEはEclipseのプラグインよりも動作が軽く、sbtやmavenとの連携も楽にできるのでとてもおすすめです。
2010年11月7日日曜日
コントローラーを使用する
コントローラーを作成、選択するために以下のものを作成しました。
Controller.scala
認識したコントローラーの名前を表示し、選択したラジオボタンのインデックスからコントロラーを作成しています。
ACT3D.initの先頭にController.createを追加し、ACT3D.cleanupにController.destroyを追加します。
実行すると、
このようなウィンドウが表示され、コントローラーを選択できるようになります。
「何も選択しない」を選ぶと、controllerにはダミーが入れられます。
controllerにダミーが入っている場合は、キーボード操作になる予定です。
このプログラムにはSWTが使われていますが、LWJGLが環境依存なので、それに合わせて使っているだけです。
SwingやAWTでも特に問題はないです。
![]()

![]()
Controller.scala
package com.halcat.game
import org.lwjgl.input._
import org.lwjgl.util.input._
import org.eclipse.swt._
import events._
import layout._
import widgets._
object Controller {
private var controller: Controller = _
def create {
Controllers.create
val display = new Display
val shell = new Shell(display, SWT.DIALOG_TRIM)
val count = Controllers.getControllerCount
var index = 0
if (count != 0) {
shell.setLayout(new GridLayout(1, false))
shell.setText("コントローラーの選択")
val label = new Label(shell, SWT.CENTER)
label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER))
label.setText("使用するコントローラーを選択してください。")
label.pack
val group = new Group(shell, SWT.SHADOW_OUT)
group.setLayout(new FillLayout(SWT.VERTICAL))
for (i <- 0 to count) {
val radioButton = new Button(group, SWT.RADIO)
if (i == 0)
radioButton.setSelection(true)
if (i == count)
radioButton.setText("何も選択しない")
else
radioButton.setText(Controllers.getController(i)
.getName)
radioButton.addSelectionListener(new SelectionAdapter {
override def widgetSelected(e: SelectionEvent) {
index = i
}
})
radioButton.pack
}
group.pack
val okButton = new Button(shell, SWT.PUSH)
okButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END))
okButton.setText("OK")
okButton.addSelectionListener(new SelectionAdapter {
override def widgetSelected(e: SelectionEvent) {
shell.dispose
}
})
okButton.pack
shell.pack
shell.open
while (!shell.isDisposed)
if (!display.readAndDispatch)
display.sleep
display.dispose
controller = if (index != count)
Controllers.getController(index)
else
new ControllerAdapter
} else {
controller = new ControllerAdapter
}
}
def destroy = Controllers.destroy
def poll = Controllers.poll
}
認識したコントローラーの名前を表示し、選択したラジオボタンのインデックスからコントロラーを作成しています。
ACT3D.initの先頭にController.createを追加し、ACT3D.cleanupにController.destroyを追加します。
実行すると、
このようなウィンドウが表示され、コントローラーを選択できるようになります。
「何も選択しない」を選ぶと、controllerにはダミーが入れられます。
controllerにダミーが入っている場合は、キーボード操作になる予定です。
このプログラムにはSWTが使われていますが、LWJGLが環境依存なので、それに合わせて使っているだけです。
SwingやAWTでも特に問題はないです。
読み込み中
クリックでキャンセルします
画像が存在しません
2010年10月23日土曜日
オブジェクトの描画
object ACT3D.initに以下を追加
次に、 オブジェクトの描画です。
GLUTオブジェクトを使って簡単に何か描こうと思っていたのですが、LWJGLにはGLUTはない模様・・・
なので、GLUオブジェクトを使って描きます。
object ACT3D
これを実行すると、
こんな感じで、球が描画されます。
今回使っているglFrustumやgluLookAtは、私にはまだ到底説明できないものなので、Googleなどで調べてもらえるとありがたいです。
![]()

![]()
GL11.glClearColor(0, 0, 0, 0) GL11.glEnable(GL11.GL_DEPTH_TEST) GL11.glViewport(0, 0, width, height) GL11.glMatrixMode(GL11.GL_PROJECTION) GL11.glLoadIdentity GL11.glFrustum(-halfWidth, halfWidth, -halfHeight, halfHeight, 100, 10000)
次に、 オブジェクトの描画です。
GLUTオブジェクトを使って簡単に何か描こうと思っていたのですが、LWJGLにはGLUTはない模様・・・
なので、GLUオブジェクトを使って描きます。
object ACT3D
@throws(classOf[LWJGLException])
def run {
val sphere = new Sphere
sphere.setDrawStyle(GLU.GLU_LINE)
while (running) {
Display.update
if (Display.isCloseRequested) {
running = false
} else {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT)
GL11.glMatrixMode(GL11.GL_MODELVIEW)
GL11.glLoadIdentity
GLU.gluLookAt(0, 150, 50, 0, 0, 0, 0, 1, 0)
GL11.glColor3f(1, 1, 1)
sphere.draw(50, 10, 10)
Display.swapBuffers
Display.sync(fps)
}
}
}
これを実行すると、
こんな感じで、球が描画されます。
今回使っているglFrustumやgluLookAtは、私にはまだ到底説明できないものなので、Googleなどで調べてもらえるとありがたいです。
読み込み中
クリックでキャンセルします
画像が存在しません
2010年10月10日日曜日
ディスプレイの表示
まずは、ディスプレイの設定と作成です。
object ACT3D
setDisplayModeのところですが、利用可能なディスプレイモードから指定した横幅、縦幅のディスプレイモードを取得し、それを設定をしています。
ディスプレイモードの設定以外はやらなくても動きます。垂直同期は有効にするとちらつきがなくなるそうです。
次にディスプレイの更新をします。
object ACT3D
これでクローズがリクエストされるまで指定のFPSでディスプレイが更新されます。
最後に後処理です。ACT3Dのcleanupにこの一行を加えます。
これでディスプレイが表示できるはずです。
実行するときの注意ですが、VM引数に-Djava.library.path="ネイティブライブラリへのパス"を忘れないようにしましょう。
次回は、ディスプレイに何か表示しようと思います。
object ACT3D
@throws(classOf[LWJGLException])
def init {
val mode = Display.getAvailableDisplayModes.find(m => m.getWidth == width && m.getHeight == height) match {
case Some(m) => m
case None => {
println("ウィンドウサイズが正しくありません。")
throw new Exception
}
}
Display.setDisplayMode(mode)
Display.setTitle(title)
Display.setVSyncEnabled(true)
Display.setSwapInterval(1)
Display.create
}
setDisplayModeのところですが、利用可能なディスプレイモードから指定した横幅、縦幅のディスプレイモードを取得し、それを設定をしています。
ディスプレイモードの設定以外はやらなくても動きます。垂直同期は有効にするとちらつきがなくなるそうです。
次にディスプレイの更新をします。
object ACT3D
@throws(classOf[LWJGLException])
def run {
while (running) {
Display.update
if (Display.isCloseRequested) {
running = false
} else {
Display.sync(fps)
}
}
}
これでクローズがリクエストされるまで指定のFPSでディスプレイが更新されます。
最後に後処理です。ACT3Dのcleanupにこの一行を加えます。
Display.destroy
これでディスプレイが表示できるはずです。
実行するときの注意ですが、VM引数に-Djava.library.path="ネイティブライブラリへのパス"を忘れないようにしましょう。
次回は、ディスプレイに何か表示しようと思います。
2010年10月9日土曜日
LWJGLについてと、プログラムの基本的な流れ
このゲームはLWJGLというライブラリを使います。
このライブラリの説明を見ると、
「LWJGLはOpenGL、OpenALなどのクロスプラットフォームライブラリのラッパーや、ゲームコントローラーを扱うライブラリを提供しています。」
といった感じですが、正直なところ、OpenGLのような低次元ライブラリでプログラムを組むのは大変だと思います。
私がこのライブラリを選んだのは、プログラミングの勉強のためなので、冗長な処理を書きたくないというのであれば、他のライブラリをお勧めします。
さて、前置きはこのくらいにしておいてプログラムを書き始めましょう。
こんな感じでしょうか?
initで初期化して、runで実行、最後にcleanupで後処理をして終了。
これが、このプログラムの基本的な流れになります。
このあと、initの中でいろいろなものを設定して、runの中にゲームループを作っていくのですが、とりあえず今回はここまでです。
次回はディスプレイの表示をしようと思います。
このライブラリの説明を見ると、
「LWJGLはOpenGL、OpenALなどのクロスプラットフォームライブラリのラッパーや、ゲームコントローラーを扱うライブラリを提供しています。」
といった感じですが、正直なところ、OpenGLのような低次元ライブラリでプログラムを組むのは大変だと思います。
私がこのライブラリを選んだのは、プログラミングの勉強のためなので、冗長な処理を書きたくないというのであれば、他のライブラリをお勧めします。
さて、前置きはこのくらいにしておいてプログラムを書き始めましょう。
package com.halcat.game.act3d
object ACT3D {
def init {
}
def run {
}
def cleanup {
}
def main(args: Array[String]) {
try {
init
run
} catch {
case e => {
e.printStackTrace
exit(1)
}
}
finally {
cleanup
}
exit(0)
}
}
こんな感じでしょうか?
initで初期化して、runで実行、最後にcleanupで後処理をして終了。
これが、このプログラムの基本的な流れになります。
このあと、initの中でいろいろなものを設定して、runの中にゲームループを作っていくのですが、とりあえず今回はここまでです。
次回はディスプレイの表示をしようと思います。
登録:
投稿 (Atom)


