LoginSignup
0
0

More than 5 years have passed since last update.

[GroovyとProcessing]まいんくらふと2Dのブロック選択を改造

Posted at

選択中のブロックを見えるように改造する
マウスカーソルの重なっているブロック上に選択中のブロックを透過して表示する
あと上下左右キーで透過ブロックが移動する

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

package episode013

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

class DisplayTest extends PApplet {

    def grid
    def selection = BlockType.STONE
    def selector_x = 0
    def selector_y = 0
    def mouseEnabled = true

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

        grid = new BlockGrid(this)
    }

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

        if (mouseEnabled) setSelectorPoint()

        grid.draw()
        drawSelectionBox()
    }

    def void keyPressed() {
        switch (key) {
            case 's':
                grid.save(new File('save.json'))
                break
            case 'l':
                grid.load(new File('save.json'))
                break
            case '1':
                selection = BlockType.STONE
                break
            case '2':
                selection = BlockType.DIRT
                break
            case '3':
                selection = BlockType.GRASS
                break
            case '4':
                selection = BlockType.AIR
                break
            case 'c':
                grid.clear()
                break
        }
        switch (keyCode) {
            case RIGHT:
                mouseEnabled = false
                if (!(selector_x + 1 > World.BLOCKS_WIDTH - 1)) {
                    selector_x += 1;
                }
                break
            case LEFT:
                mouseEnabled = false
                if (!(selector_x - 1 < 0)) {
                    selector_x -= 1;
                }
                break
            case UP:
                mouseEnabled = false
                if (!(selector_y - 1 < 0)) {
                    selector_y -= 1;
                }
                break
            case DOWN:
                mouseEnabled = false
                if (!(selector_y + 1 > World.BLOCKS_HEIGHT - 1)) {
                    selector_y += 1;
                }
                break
        }
    }

    def void mouseClicked() {
        mouseEnabled = true
        setSelectorPoint()
        setBlock()
    }

    def void mouseDragged() {
        mouseEnabled = true
        setSelectorPoint()
        setBlock()
    }

    def setBlock() {
        if (selector_x >= 0 && selector_x < World.BLOCKS_WIDTH
                && selector_y >= 0 && selector_y < World.BLOCKS_HEIGHT) {
            grid.setAt(selector_x, selector_y, selection)
        }
    }

    def setSelectorPoint() {
        selector_x = floor(mouseX / World.BLOCK_SIZE)
        selector_y = floor(mouseY / World.BLOCK_SIZE)
    }

    def drawSelectionBox() {
        if (grid.getAt(selector_x, selector_y).type != BlockType.AIR || selection == BlockType.AIR) {
            // 白い透過ブロックを表示
            noStroke()
            fill(255, 255, 255, 150)
            rect(selector_x * World.BLOCK_SIZE, selector_y * World.BLOCK_SIZE, World.BLOCK_SIZE, World.BLOCK_SIZE)
        } else {
            // 選択しているブロックを透過表示
            tint(255, 200)
            new Block(this, selection, selector_x * World.BLOCK_SIZE, selector_y * World.BLOCK_SIZE).draw()
            noTint()
        }
    }

    def static void main(args) {
        PApplet.main('episode013.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()
            }
        }
    }

    def clear() {
        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)
                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 = 15
}

grocessingGL013.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