LoginSignup
0
0

More than 5 years have passed since last update.

[GroovyとProcessing]まいんくらふと2D?

Posted at

episode10は実行可能なJarの作成だったので飛ばしてepisode11。

マインクラフト2Dっぽいもの。
初期画面では空のブロックが全体に敷き詰められていて1つだけ石ブロックが置いてある。
マウスのクリック、ドラッグで石ブロックに変わる。
キーボードのSでJsonファイルにブロックの状態を保存、Lでロードする。

動画リスト:LWJGLのチュートリアル
動画はココ

DisplayTest.groovy
package episode011

import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import processing.core.PApplet

class DisplayTest extends PApplet {

    def grid

    def void setup() {
        size(640, 480)
        frameRate(60)

        grid = new BlockGrid(this)
        grid.setAt(10, 10, BlockType.STONE)
    }

    def void draw() {
        background(0, 0, 0)

        grid.draw()
    }

    def void keyPressed() {
        switch (key) {
            case 's':
                grid.save(new File('save.json'))
                break
            case 'l':
                grid.load(new File('save.json'))
                break
        }
    }

    def void mouseClicked() {
        setStoneBlock()
    }

    def void mouseDragged() {
        setStoneBlock()
    }

    def setStoneBlock() {
        def gridX = floor(mouseX / World.BLOCK_SIZE)
        def gridY = floor(mouseY / World.BLOCK_SIZE)
        if (gridX >= 0 && gridX < World.BLOCKS_WIDTH
                && gridY >= 0 && gridY < World.BLOCKS_HEIGHT) {
            grid.setAt(gridX, gridY, BlockType.STONE)
        }
    }

    def static void main(args) {
        PApplet.main('episode011.DisplayTest')
    }
}

enum BlockType {
    STONE('stone.png'), AIR('air.png'), GRASS('grass.png'), DIRT('dirt.png')

    def location

    def BlockType(location) {
        this.location = location
    }
}

class Block {
    def type = BlockType.AIR
    def x, y
    def img
    def display

    def Block(display, type, x, y) {
        this.display = display
        this.type = type
        this.x = x
        this.y = y
        this.img = display.loadImage(type.location)
    }

    def draw() {
        display.image(img, x, y)
    }
}

class BlockGrid {
    def Block[][] blocks = new Block[World.BLOCKS_WIDTH][World.BLOCKS_HEIGHT];
    def display

    def BlockGrid(display) {
        this.display = display
        World.BLOCKS_WIDTH.times { x ->
            World.BLOCKS_HEIGHT.times { y ->
                blocks[x][y] = new Block(display, BlockType.AIR, x * World.BLOCK_SIZE, y * World.BLOCK_SIZE)
            }
        }
    }

    def load(loadFile) {
        def list = new JsonSlurper().parse(loadFile.newReader())
        list.each { block ->
            blocks[block.x][block.y] = new Block(
                    display,
                    BlockType.valueOf(block.type),
                    block.x * World.BLOCK_SIZE,
                    block.y * World.BLOCK_SIZE)
        }
    }

    def save(saveFile) {
        def list = []
        World.BLOCKS_WIDTH.times { x ->
            World.BLOCKS_HEIGHT.times { y ->
                list << [
                    x: blocks[x][y].x / World.BLOCK_SIZE,
                    y: blocks[x][y].y / World.BLOCK_SIZE,
                    type: blocks[x][y].type
                ]
            }
        }
        saveFile.write(new JsonBuilder(list).toString())
    }

    def setAt(x , y, type) {
        blocks[x][y] = new Block(display, type, x * World.BLOCK_SIZE, y * World.BLOCK_SIZE)
    }

    def getAt(x , y) {
        blocks[x][y]
    }

    def draw() {
        World.BLOCKS_WIDTH.times { x ->
            World.BLOCKS_HEIGHT.times { y ->
                blocks[x][y].draw()
            }
        }
    }
}

class World {
    public static final int BLOCK_SIZE = 32
    public static final int BLOCKS_WIDTH = 20
    public static final int BLOCKS_HEIGHT = 20
}

grocessingGL011.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0