$ sbt run
Created
November 15, 2011 12:37
-
-
Save alphaneet/1366985 to your computer and use it in GitHub Desktop.
processing で scala の並列コレクションを試そうと思ったらヌルポだったでござるの巻 つhttp://d.hatena.ne.jp/alpha_neet/20111115/1321363672
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
resolvers += "processing Maven Repository" at "https://github.com/alphaneet-debu/maven/raw/master" | |
libraryDependencies += "processing" %% "core" % "1.5.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object Par extends processing.core.PApplet { | |
applet => | |
import processing.core.{ | |
PImage, | |
PGraphics, | |
PVector | |
} | |
import processing.core.PConstants.{ | |
P2D, | |
JAVA2D, | |
HSB, | |
ARGB, | |
CENTER | |
} | |
val AngdebTable = List.range(0, 360, 15) | |
class AngdebTable(conv: Double => Double) { | |
val data: Map[Int, Float] = AngdebTable map { | |
angdeg => | |
angdeg -> conv(math.toRadians(angdeg)).toFloat | |
} toMap | |
def apply(angdeg: Int): Float = data(angdeg) | |
} | |
val cos = new AngdebTable(math.cos) | |
val sin = new AngdebTable(math.sin) | |
lazy val halfWidth = (width >> 1) | |
lazy val halfHeight = (height >> 1) | |
lazy val ballImages: List[PImage] = List.range(0, 256) map { | |
createCircle(16, 16, _) | |
} | |
lazy val player = new Player(createCircle(24, 24, 255)) | |
val balls = scala.collection.mutable.ArrayBuffer[Ball]() | |
class Character(val img: PImage) { | |
val pos = new PVector() | |
val vec = new PVector() | |
var speed = 0.0f | |
val halfWidth = img.width >> 1 | |
val halfHeight= img.height >> 1 | |
def move() { | |
pos.x += vec.x * speed | |
pos.y += vec.y * speed | |
} | |
def image() = applet.image(img, pos.x, pos.y) | |
} | |
class Ball extends Character(ballImages(random(ballImages.size).toInt)) { | |
balls += this | |
override def move() { | |
if (pos.x > applet.width) vec.x = math.abs(vec.x) * -1 | |
if (pos.x < 0) vec.x = math.abs(vec.x) | |
if (pos.y > applet.height) vec.y = math.abs(vec.y) * -1 | |
if (pos.y < 0) vec.y = math.abs(vec.y) | |
super.move() | |
} | |
} | |
class Player(img: PImage) extends Character(img) { | |
player => | |
var shotCt = 0 | |
override def move() { | |
vec.x = applet.mouseX | |
vec.y = applet.mouseY | |
if (pos.dist(vec) <= speed) return | |
vec.sub(pos) | |
vec.normalize() | |
super.move() | |
} | |
def shot() { | |
if ((shotCt % 2) == 0) { | |
AngdebTable foreach { | |
angdeg => | |
new Ball { | |
pos.x = player.pos.x | |
pos.y = player.pos.y | |
speed = random(4.0f) + 2.0f | |
val tmp = new PVector(applet.mouseX, applet.mouseY) | |
tmp.sub(pos) | |
tmp.normalize() | |
vec.x = tmp.x * cos(angdeg) - tmp.y * sin(angdeg) | |
vec.y = tmp.x * sin(angdeg) + tmp.y * cos(angdeg) | |
pos.x += vec.x * (halfWidth + player.halfWidth) | |
pos.y += vec.y * (halfHeight + player.halfHeight) | |
} | |
} | |
} | |
shotCt += 1 | |
} | |
} | |
override def setup() { | |
size(1024, 768, P2D) | |
colorMode(HSB, 255) | |
frameRate(60) | |
imageMode(CENTER) | |
player.pos.x = applet.halfWidth | |
player.pos.y = applet.halfHeight | |
player.speed = 3.0f | |
} | |
object Log { | |
val INTERVAL = 200 | |
val DIV = 10 | |
var nowBallSize = 0 | |
def nextBallSize = nowBallSize + INTERVAL | |
def addBallSize(inteval: Int = INTERVAL) = nowBallSize += INTERVAL | |
} | |
case class LogElement(frameRate: Int, size: Int) | |
val log = new scala.collection.mutable.ArrayBuffer[LogElement] { | |
override def clear() { | |
super.clear() | |
Log.nowBallSize = 0 | |
} | |
} | |
def generateRubyScriptForGruff() { | |
import java.io._ | |
var script = | |
""" | |
require 'rubygems' | |
require 'gruff' | |
g = Gruff::Line.new | |
g.title = 'Processing FrameRate Test' | |
g.minimum_value = 30 | |
g.maximum_value = 60 | |
g.data('without collection#par', [<data>], 'red') | |
g.labels = {<label>} | |
g.write('processing_framerate_test.png') | |
""" | |
val ct = if (log.size > Log.DIV) log.size / Log.DIV else 1 | |
script = script.replace("<data>", log.map(_.frameRate).mkString(", ")) | |
script = script.replace( | |
"<label>", | |
(0 until log.size by ct) map { | |
index => | |
"%d => '%d'".format(index, log(index).size) | |
} mkString(", ") | |
) | |
val date = "%tY%<tm%<td%<tH%<tM%<tS" format new java.util.Date | |
save("screenshot" + date + ".png") | |
log.clear() | |
balls.clear() | |
val writer = new OutputStreamWriter(new FileOutputStream("gruff.rb")) | |
writer.write(script) | |
writer.close() | |
} | |
override def draw() { | |
background(0) | |
player.move() | |
player.image() | |
player.shot() | |
balls foreach { | |
c => | |
c.move() | |
c.image() | |
} | |
val fRate = frameRate.toInt | |
if (balls.size >= Log.nextBallSize) { | |
println("frameRate: " + fRate + " balls.size: " + balls.size) | |
log += LogElement(fRate, Log.nextBallSize) | |
Log.addBallSize() | |
} | |
if (fRate < 50 && log.size >= Log.DIV) generateRubyScriptForGruff() | |
} | |
override def mousePressed() = generateRubyScriptForGruff() | |
def hsb(c: Int): (Float, Float, Float) = | |
(g.hue(c), g.saturation(c), g.brightness(c)) | |
def rgb(c: Int): (Float, Float, Float) = | |
(g.red(c), g.green(c), g.blue(c)) | |
def createCircle(size: Int, hue: Int): PImage = createCircle(size, size, hue) | |
def createCircle(width: Int, height: Int, hue: Int): PImage = { | |
val halfW = width >> 1 | |
val halfH = height >> 1 | |
val weight = 2 | |
createAndDrawPImage(width + 1, height + 1) { | |
g => | |
def ellipse(w: Int, h: Int) = g.ellipse(halfW, halfH, w - weight, h - weight) | |
g.colorMode(HSB, 255) | |
g.smooth() | |
g.strokeWeight(weight) | |
g.stroke(hue, 255, 100) | |
g.fill(hue, 255, 255) | |
ellipse(width, height) | |
g.noStroke() | |
val loop = (if (halfW < halfH) halfW else halfH) - weight | |
val s = 255.0f / loop | |
(1 to loop) foreach { | |
x => | |
g.fill(hue, 255 - (x * s), 255) | |
ellipse(width - (x << 1), height - (x << 1)) | |
} | |
} | |
} | |
def createAndDrawPImage(width: Int, height: Int)(draw: PGraphics => Unit): PImage = { | |
val g: PGraphics = createGraphics(width, height, JAVA2D) | |
g.beginDraw() | |
draw(g) | |
g.endDraw() | |
val img = createImage(width, height, ARGB) | |
img.set(0, 0, g) | |
g.dispose | |
img | |
} | |
def main(args: Array[String]) = runSketch() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment