Mercurial > hg > ristipolku
view game/Piece.java @ 54:cc7943cd7f2d
Moar work.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 23 Feb 2011 19:54:48 +0200 |
parents | 79185dababf2 |
children | cde170f2f980 |
line wrap: on
line source
/* * Ristipolku * (C) Copyright 2011 Matti 'ccr' Hämäläinen <ccr@tnsp.org> */ package game; import java.awt.*; import java.awt.geom.*; import java.util.*; import java.math.*; public class Piece { public enum RotateDir { LEFT, RIGHT } static final int numConnections = 8; static final float maxTime = 50.0f; int currRotation; int[] connections; boolean[] states; PieceType type, prevType; boolean rotationChanged, rotationActive, typeChanged, typeActive, stateChanged, stateActive; float currAngle, newAngle, rotationTime, typeTime, rotationSpeed; float throbTime; Interpolate lerpRotation; public Piece(PieceType ptype) { // Initialize connections = new int[numConnections]; states = new boolean[numConnections]; type = ptype; rotationChanged = false; rotationActive = false; currRotation = 0; currAngle = 0; typeChanged = false; typeActive = false; throbTime = 0; // Initialize connections between endpoints of the paths inside the piece for (int i = 0; i < numConnections; i++) connections[i] = -1; // Randomize connections in the piece Random rnd = new Random(); for (int i = 0; i < numConnections; i++) { while (connections[i] < 0) { int tmp = rnd.nextInt(numConnections); if (tmp != i && connections[tmp] < 0) { connections[i] = tmp; connections[tmp] = i; } } } } public Piece() { this(PieceType.NONE); } public void setType(PieceType ptype) { typeChanged = (prevType != ptype); prevType = type; type = ptype; } public void clearStates() { for (int i = 0; i < numConnections; i++) states[i] = false; stateChanged = true; } public int getRotatedPoint(int in) { int point = (in - (currRotation * 2)) % 8; if (point < 0) point = 8 + point; return point; } public int getAntiRotatedPoint(int in) { int point = (in + (currRotation * 2)) % 8; if (point < 0) point = 8 + point; return point; } public int getMatchingPoint(int point) { switch (point) { case 0: return 5; case 1: return 4; case 2: return 7; case 3: return 6; case 4: return 1; case 5: return 0; case 6: return 3; case 7: return 2; } return -1; } public void setConnectionState(int point, boolean state) { states[point] = state; states[connections[point]] = state; stateChanged = true; } public int getConnection(int point) { return connections[point]; } public void rotate(RotateDir dir) { // Only normal if (type != PieceType.LOCKED && type != PieceType.ACTIVE) return; currRotation = (currRotation + (dir == RotateDir.RIGHT ? 1 : -1)) % 4; newAngle = (float) ((currRotation * Math.PI) / 2.0f); lerpRotation = new Interpolate(newAngle, currAngle, maxTime); rotationChanged = true; } public Point2D getPointCoords(float x, float y, float dim, int index) { float ox = 0, oy = 0; float step = dim / 10; switch (index) { // Normal line starting and ending points case 0: ox = 3.0f; oy = 0.4f; break; case 1: ox = 7.0f; oy = 0.4f; break; case 2: ox = 9.6f; oy = 3.0f; break; case 3: ox = 9.6f; oy = 7.0f; break; case 4: ox = 7.0f; oy = 9.6f; break; case 5: ox = 3.0f; oy = 9.6f; break; case 6: ox = 0.4f; oy = 7.0f; break; case 7: ox = 0.4f; oy = 3.0f; break; // Matching control points for each point above (+8) case 8: ox = 3.0f; oy = 2.5f; break; case 9: ox = 7.0f; oy = 2.5f; break; case 10: ox = 7.5f; oy = 3.0f; break; case 11: ox = 7.5f; oy = 7.0f; break; case 12: ox = 7.0f; oy = 7.5f; break; case 13: ox = 3.0f; oy = 7.5f; break; case 14: ox = 2.5f; oy = 7.0f; break; case 15: ox = 2.5f; oy = 3.0f; break; } return new Point2D.Float(x + ox * step, y + oy * step); } public PieceType getType() { return type; } public void animate(float time) { if (rotationChanged) { rotationTime = time; rotationActive = true; rotationChanged = false; rotationSpeed = 0.5f; } if (typeChanged && type == PieceType.LOCKED) { rotationSpeed = 1.0f; } if (rotationActive) { float t = (time - rotationTime) * rotationSpeed; if (t < maxTime) currAngle = lerpRotation.getValue(t); else { currAngle = newAngle; rotationActive = false; } } if (typeChanged) { typeTime = time; typeActive = true; typeChanged = false; } if (typeActive) { } if (stateChanged) { } throbTime = (time % 100) / 100.0f; } public void paint(Graphics2D g, float x, float y, float dim) { // Transform drawing by current angle g.rotate(currAngle, x + dim / 2.0f, y + dim / 2.0f); // Color piece by type switch (type) { case LOCKED: g.setPaint(Color.green); break; case ACTIVE: g.setPaint(Color.red); break; case START: g.setPaint(Color.orange); break; } g.fill(new RoundRectangle2D.Float(x, y, dim, dim, dim / 10, dim / 10)); // Start pieces (center piece) do not have border, etc. if (type == PieceType.START) return; // Active piece has a throbbing "ghost" border if (type == PieceType.ACTIVE) { float offs1 = throbTime * 10.0f, offs2 = throbTime * 20.0f; g.setPaint(new Color(0.0f, 0.0f, 0.0f, (float) (1.0f - throbTime) )); g.setStroke(new BasicStroke(2.0f + throbTime * 2.0f)); g.draw(new RoundRectangle2D.Float( x - offs1, y - offs1, dim + offs2, dim + offs2, dim / 10, dim / 10)); } // Draw the connections g.setStroke(new BasicStroke(5.0f)); CubicCurve2D c = new CubicCurve2D.Float(); boolean[] drawn = new boolean[numConnections]; for (int i = 0; i < numConnections; i++) if (!drawn[i]) { Point2D start, cp1, cp2, end; boolean isActive = states[i] || states[connections[i]]; g.setPaint(isActive ? Color.white : Color.black); start = getPointCoords(x, y, dim, i); end = getPointCoords(x, y, dim, connections[i]); cp1 = getPointCoords(x, y, dim, i + 8); cp2 = getPointCoords(x, y, dim, connections[i] + 8); c.setCurve(start, cp1, cp2, end); g.draw(c); // Mark connection drawn, so we don't overdraw drawn[i] = true; drawn[connections[i]] = true; } // Draw piece border g.setPaint(Color.black); g.setStroke(new BasicStroke(5.0f)); g.draw(new RoundRectangle2D.Float(x, y, dim, dim, dim / 10, dim / 10)); } }