[GroovyとProcessing]ポンゲーム（未完成）

ボールを画面端のバーで打ち返すゲーム。
動画内で途中までしか作ってないので同じ所までしか作ってない。

キーボード入力の部分が動画と違ってキーを押してる間とキーを話した時の２つに分けて実装した（せざるを得なかった）

動画リスト：[LWJGLのチュートリアル](http://www.youtube.com/playlist?list=PL19F2453814E0E315)
動画は[ココ](http://www.youtube.com/watch?v=YIIqOEKXWLU)

```groovy:DisplayTest.groovy
package episode009

import groovy.swing.SwingBuilder
import processing.core.PApplet

import javax.swing.*

class DisplayTest extends PApplet {

    def lastFrame

    def bat
    def ball

    def void setup() {
        setUpDisplay()
        setUpEntities()
        setUpTimer()
    }

    def void draw() {
        renderEntities()
        logic(delta)
    }

    def setUpDisplay() {
        frameRate(60)
    }

    def setUpEntities() {
        bat = new Bat(this, 10, height / 2 - 80 / 2, 10, 80)
        ball = new Ball(this, width / 2 - 10 / 2, height / 2 - 10 / 2, 10)
        ball.dx = -0.1
    }

    def setUpTimer() {
        lastFrame = System.currentTimeMillis()
    }

    def renderEntities() {
        background(0, 0, 0)
        ball.draw()
        bat.draw()
    }

    def logic(delta) {
        ball.update(delta)
        bat.update(delta)
        if (ball.x <= bat.x + bat.width
                && ball.x >= bat.x
                && ball.y >= bat.y
                && ball.y <= bat.y + bat.height) {
            ball.dx = 0.3
        }
    }

    def void keyPressed() {
        switch (keyCode) {
            case UP:
                bat.dy = -0.2
                break
            case DOWN:
                bat.dy = 0.2
                break
        }
    }

    def void keyReleased() {
        bat.dy = 0
    }

    def getDelta() {
        def currentTime = System.currentTimeMillis()
        def delta = currentTime - lastFrame
        lastFrame = currentTime
        delta
    }

    def static void main(args) {
        def display = new DisplayTest()
        new SwingBuilder().frame(
                title: 'Episode 9',
                defaultCloseOperation: JFrame.EXIT_ON_CLOSE,
                size: [640, 480], show: true) {
            widget(display)
        }
        display.init()
    }
}

class Entity {
    def x, y, width, height
    def display

    def Entity(display, x, y, width, height) {
        this.display = display
        this.x = x
        this.y = y
        this.width = width
        this.height = height
    }

    def setLocation(x, y) {
        this.x = x
        this.y = y
    }

    def intersects(other) {
        x < other.x && y < other.y && x + width > other.x && y + height > other.y
    }
}

class MovableEntity extends Entity {
    def dx, dy

    def MovableEntity(display, x, y, width, height) {
        super(display, x, y, width, height)
        this.dx = 0
        this.dy = 0
    }

    def update(delta) {
        x += delta * dx
        y += delta * dy
    }
}

class Bat {
    @Delegate MovableEntity entity

    def Bat(display, x, y, width, height) {
        this.entity = new MovableEntity(display, x, y, width, height)
    }

    def draw() {
        def posX = x
        def posY = y
        def boxWidth = width
        def boxHeight = height
        display.with {
            noStroke()
            fill(255, 255, 255)
            rect(posX, posY, boxWidth, boxHeight)
        }
    }
}

class Ball {
    def weight
    @Delegate MovableEntity entity

    def Ball(display, x, y, weight) {
        this.entity = new MovableEntity(display, x, y, weight, weight)
        this.weight = weight
    }

    def draw() {
        def posX = x
        def posY = y
        display.with {
            noSmooth()
            stroke(255, 255, 255)
            strokeWeight(weight)
            point(posX, posY)
        }
    }
}
```

![grocessingGL009.png](https://qiita-image-store.s3.amazonaws.com/0/17179/167c30d7-757f-4d6b-4abf-48216baeabba.png)