/******************************************************************************* * Rhythos Editor is a game editor and project management tool for making RPGs on top of the Rhythos Game system. * * Copyright (C) 2013 David Maletz * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package mrpg.editor; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import javax.swing.JPanel; import javax.swing.Timer; import mrpg.editor.resource.Animation; import mrpg.editor.resource.AnimationSet; import mrpg.world.Direction; import mrpg.world.Tile; import mrpg.world.Tilemap; public class AutoTileEditor extends JPanel implements MouseListener, MouseMotionListener, ActionListener { private static final long serialVersionUID = -2758279297055018804L; private Tilemap tilemap; private final Rectangle rect = new Rectangle(); private int edge=0, tile_size; private Animation ani; private int frame = 0, ct; private Timer timer; public AutoTileEditor(int ts){ tile_size = ts; setPreferredSize(new Dimension(TilesetViewer.TILE_SIZE, TilesetViewer.TILE_SIZE)); addMouseListener(this); addMouseMotionListener(this); } public void setTilemap(Tilemap t){ tilemap = t; repaint(); } public void setAnimation(AnimationSet animation, int aid){ if(aid < 0 || animation == null || aid >= animation.numAnimations()) ani = null; else{ani = animation.getAnimation(aid); ct = ani.speed; if(timer == null) repaint();} } public void actionPerformed(ActionEvent e){ if(ani == null || !isShowing()){timer.stop(); timer = null;} else{ ct--; if(ct == 0){ct = ani.speed; frame++; if(frame >= ani.numFrames()) frame = 0; repaint();} } } public void paint(Graphics g){ if(timer == null && ani != null && ani.numFrames() > 1){ timer = new Timer(83, this); timer.start(); } Graphics2D g2d = (Graphics2D)g; super.paint(g); Graphics2D g2 = (Graphics2D)g.create(); double s = ((double)TilesetViewer.TILE_SIZE)/tile_size; g2.scale(s,s); g2.getClipBounds(rect); g2.clearRect(rect.x, rect.y, rect.width, rect.height); if(tilemap != null){ BufferedImage image = (BufferedImage)tilemap.getTile(0).image; int w = Math.min(rect.x+rect.width, image.getWidth())-rect.x; int h = Math.min(rect.y+rect.height, image.getHeight())-rect.y; if(w > 0 && h > 0){int f = 0; if(ani != null) f = frame*ani.speed; tilemap.getTile(0).paint(g2, ani, f, rect.x, rect.y, rect.x, rect.y, w, h, this); g.getClipBounds(rect); int d = 4, first = (TilesetViewer.TILE_SIZE-(5*d))/2+1; byte walkable = tilemap.getTile(0).info.getWalkable(); AffineTransform t = g2d.getTransform(); g2d.translate(first+d*2-1, first-1); g.setColor((Direction.up(edge))?TilesetEditor.dirSelColor:TilesetEditor.dirColor); if(Direction.up(walkable)) g2d.fillPolygon(TilesetEditor.arrow); else g2d.fillRect(0, 0, d, d); g.setColor(TilesetEditor.dirColorOutline); if(Direction.up(walkable)) g2d.drawPolygon(TilesetEditor.arrow); else g2d.drawRect(0, 0, d, d); g2d.translate(d*2, d*2); g2d.rotate(Math.PI/2, 2, 2); g.setColor((Direction.right(edge))?TilesetEditor.dirSelColor:TilesetEditor.dirColor); if(Direction.right(walkable)) g2d.fillPolygon(TilesetEditor.arrow); else g2d.fillRect(0, 0, d, d); g.setColor(TilesetEditor.dirColorOutline); if(Direction.right(walkable)) g2d.drawPolygon(TilesetEditor.arrow); else g2d.drawRect(0, 0, d, d); g2d.translate(d*2, d*2); g2d.rotate(Math.PI/2, 2, 2); g.setColor((Direction.down(edge))?TilesetEditor.dirSelColor:TilesetEditor.dirColor); if(Direction.down(walkable)) g2d.fillPolygon(TilesetEditor.arrow); else g2d.fillRect(0, 0, d, d); g.setColor(TilesetEditor.dirColorOutline); if(Direction.down(walkable)) g2d.drawPolygon(TilesetEditor.arrow); else g2d.drawRect(0, 0, d, d); g2d.translate(d*2, d*2); g2d.rotate(Math.PI/2, 2, 2); g.setColor((Direction.left(edge))?TilesetEditor.dirSelColor:TilesetEditor.dirColor); if(Direction.left(walkable)) g2d.fillPolygon(TilesetEditor.arrow); else g2d.fillRect(0, 0, d, d); g.setColor(TilesetEditor.dirColorOutline); if(Direction.left(walkable)) g2d.drawPolygon(TilesetEditor.arrow); else g2d.drawRect(0, 0, d, d); g2d.setTransform(t); } } } public void mouseDragged(MouseEvent e) {} public void mouseMoved(MouseEvent e) { int dx = e.getX(), dy = e.getY(); int d = 4, first = (TilesetViewer.TILE_SIZE-(5*d))/2+1; boolean inxc = dx >= first+d && dx <= first+d*3, inyc = dy >= first+d && dy <= first+d*3; int ed = 0; if(inxc && dy < first+d) ed = Direction.UP; if(inxc && dy > first+3*d) ed = Direction.DOWN; if(inyc && dx < first+d) ed = Direction.LEFT; if(inyc && dx > first+3*d) ed = Direction.RIGHT; if(inxc && inyc) ed = Direction.LINEAR; if(ed != edge){edge = ed; repaint();} } public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) { if(tilemap == null) return; if(edge != 0){ Tile.Info info = tilemap.getTile(0).info; info.setWalkable((byte)(info.getWalkable() ^ edge)); repaint(); } } public void mouseReleased(MouseEvent e) {} }