Fixed merge conflicts
This commit is contained in:
@ -25,4 +25,14 @@ public interface IPaintLayer {
|
||||
*/
|
||||
void layerToFront();
|
||||
|
||||
/**
|
||||
* @return Width (in pixels) of graphics layer
|
||||
*/
|
||||
double getWidth();
|
||||
|
||||
/**
|
||||
* @return Height (in pixels) of graphics layer
|
||||
*/
|
||||
double getHeight();
|
||||
|
||||
}
|
||||
|
@ -5,13 +5,45 @@ import javafx.scene.paint.Paint;
|
||||
|
||||
public interface IPainter extends IPaintLayer {
|
||||
|
||||
/**
|
||||
* Restore graphics settings previously stored by {@link #save()}.
|
||||
*
|
||||
* @return {@code this}, for sending more draw commands
|
||||
*/
|
||||
IPainter restore();
|
||||
|
||||
/**
|
||||
* Store graphics settings.
|
||||
*
|
||||
* @return {@code this}, for sending more draw commands
|
||||
*/
|
||||
IPainter save();
|
||||
|
||||
/**
|
||||
* Set colour used to drawing and filling.
|
||||
*
|
||||
* @param ink A colour or paint
|
||||
* @return {@code this}, for sending more draw commands
|
||||
*/
|
||||
IPainter setInk(Paint ink);
|
||||
|
||||
/**
|
||||
* Start drawing a shape.
|
||||
*
|
||||
* @return An IShape for sending shape drawing commands
|
||||
*/
|
||||
IShape shape();
|
||||
|
||||
/**
|
||||
* Start drawing with a turtle.
|
||||
*
|
||||
* @return An ITurtle for sending turtle drawing commands
|
||||
*/
|
||||
ITurtle turtle();
|
||||
|
||||
/**
|
||||
* @return Current ink, as set by {@link #setInk(Paint)}
|
||||
*/
|
||||
Paint getInk();
|
||||
|
||||
}
|
@ -2,7 +2,18 @@ package inf101.v18.gfx.gfxmode;
|
||||
|
||||
public interface ITurtle extends IPainter {
|
||||
|
||||
<T> T as(Class<T> class1);
|
||||
/**
|
||||
* This method is used to convert the turtle to an other type, determined by the
|
||||
* class object given as an argument.
|
||||
* <p>
|
||||
* This can be used to access extra functionality not provided by this
|
||||
* interface, such as direct access to the underlying graphics context.
|
||||
*
|
||||
* @param clazz
|
||||
* @return This object or an appropriate closely related object of the given
|
||||
* time; or <code>null</code> if no appropriate object can be found
|
||||
*/
|
||||
<T> T as(Class<T> clazz);
|
||||
|
||||
/**
|
||||
* Move to the given position while drawing a curve
|
||||
@ -236,7 +247,24 @@ public interface ITurtle extends IPainter {
|
||||
*/
|
||||
ITurtle turnTowards(double degrees, double percent);
|
||||
|
||||
double getWidth();
|
||||
/**
|
||||
* Jump (without drawing) to the given relative position.
|
||||
* <p>
|
||||
* The new position will be equal to getPos().move(relPos).
|
||||
*
|
||||
* @param relPos
|
||||
* A position, interpreted relative to current position
|
||||
* @return {@code this}, for sending more draw commands
|
||||
*/
|
||||
ITurtle jump(Point relPos);
|
||||
|
||||
/**
|
||||
* Move to the given relative position while drawing a line
|
||||
* <p>
|
||||
* The new position will be equal to getPos().move(relPos).
|
||||
*
|
||||
* @return {@code this}, for sending more draw commands
|
||||
*/
|
||||
ITurtle draw(Point relPos);
|
||||
|
||||
double getHeight();
|
||||
}
|
@ -92,4 +92,25 @@ public class Point {
|
||||
public String toString() {
|
||||
return String.format("(%.2f,%.2f)", x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply this point by a scale factor.
|
||||
*
|
||||
* @param factor A scale factor
|
||||
* @return A new Point, (getX()*factor, getY()*factor)
|
||||
*/
|
||||
public Point scale(double factor) {
|
||||
return new Point(x*factor, y*factor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find difference between points.
|
||||
* <p>
|
||||
* The returned value will be such that <code>this.move(deltaTo(point)).equals(point)</code>.
|
||||
* @param point Another point
|
||||
* @return A new Point, (point.getX()-getX(), point.getY()-getY())
|
||||
*/
|
||||
public Point deltaTo(Point point) {
|
||||
return new Point(point.x-x, point.y-y);
|
||||
}
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ public class ShapePainter implements IShape {
|
||||
|
||||
@Override
|
||||
public void draw(GraphicsContext context) {
|
||||
if (cmd != null) {
|
||||
if (cmd != null && context != null) {
|
||||
if (fill != null)
|
||||
cmd.fill(context, this);
|
||||
if (stroke != null)
|
||||
@ -238,7 +238,7 @@ public class ShapePainter implements IShape {
|
||||
|
||||
@Override
|
||||
public ShapePainter fill() {
|
||||
if (cmd != null)
|
||||
if (cmd != null && context != null)
|
||||
cmd.fill(context, this);
|
||||
return this;
|
||||
}
|
||||
@ -288,7 +288,7 @@ public class ShapePainter implements IShape {
|
||||
|
||||
@Override
|
||||
public ShapePainter stroke() {
|
||||
if (cmd != null)
|
||||
if (cmd != null && context != null)
|
||||
cmd.stroke(context, this);
|
||||
return this;
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.StrokeLineCap;
|
||||
import javafx.scene.shape.StrokeLineJoin;
|
||||
|
||||
public class TurtlePainter implements IPaintLayer, ITurtle {
|
||||
|
||||
@ -41,12 +43,10 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
|
||||
private final Canvas canvas;
|
||||
private boolean path = false;
|
||||
|
||||
public TurtlePainter(double width, double height, Canvas canvas) {
|
||||
screen = null;
|
||||
if (canvas == null)
|
||||
canvas = new Canvas(width, height);
|
||||
this.canvas = canvas;
|
||||
this.context = canvas.getGraphicsContext2D();
|
||||
public TurtlePainter(double width, double height) {
|
||||
this.screen = null;
|
||||
this.canvas = null;
|
||||
this.context = null;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
stateStack.add(new TurtleState());
|
||||
@ -55,6 +55,8 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
|
||||
}
|
||||
|
||||
public TurtlePainter(Screen screen, Canvas canvas) {
|
||||
if (screen == null || canvas == null)
|
||||
throw new IllegalArgumentException();
|
||||
this.screen = screen;
|
||||
this.canvas = canvas;
|
||||
this.context = canvas.getGraphicsContext2D();
|
||||
@ -63,6 +65,8 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
|
||||
stateStack.add(new TurtleState());
|
||||
state.dir = new Direction(1.0, 0.0);
|
||||
state.pos = new Point(screen.getWidth() / 2, screen.getHeight() / 2);
|
||||
context.setLineJoin(StrokeLineJoin.BEVEL);
|
||||
context.setLineCap(StrokeLineCap.SQUARE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -70,32 +74,37 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
|
||||
public <T> T as(Class<T> clazz) {
|
||||
if (clazz == GraphicsContext.class)
|
||||
return (T) context;
|
||||
if (clazz == getClass())
|
||||
return (T) this;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
context.clearRect(0, 0, getWidth(), getHeight());
|
||||
if (context != null)
|
||||
context.clearRect(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITurtle curveTo(Point to, double startControl, double endAngle, double endControl) {
|
||||
Point c1 = state.pos.move(state.dir, startControl);
|
||||
Point c2 = to.move(Direction.fromDegrees(endAngle + 180), endControl);
|
||||
if (!path) {
|
||||
// context.save();
|
||||
context.setStroke(state.ink);
|
||||
context.setLineWidth(state.penSize);
|
||||
context.beginPath();
|
||||
context.moveTo(state.pos.getX(), state.pos.getY());
|
||||
if (context != null) {
|
||||
if (!path) {
|
||||
// context.save();
|
||||
context.setStroke(state.ink);
|
||||
context.setLineWidth(state.penSize);
|
||||
context.beginPath();
|
||||
context.moveTo(state.pos.getX(), state.pos.getY());
|
||||
}
|
||||
context.bezierCurveTo(c1.getX(), c1.getY(), c2.getX(), c2.getY(), to.getX(), to.getY());
|
||||
}
|
||||
context.bezierCurveTo(c1.getX(), c1.getY(), c2.getX(), c2.getY(), to.getX(), to.getY());
|
||||
state.inDir = state.dir;
|
||||
state.pos = to;
|
||||
state.dir = Direction.fromDegrees(endAngle);
|
||||
|
||||
if (!path) {
|
||||
if (!path && context != null) {
|
||||
context.stroke();
|
||||
// context.restore();
|
||||
}
|
||||
@ -113,6 +122,12 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
|
||||
return drawTo(to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITurtle draw(Point relPos) {
|
||||
Point to = state.pos.move(relPos);
|
||||
return drawTo(to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITurtle drawTo(double x, double y) {
|
||||
Point to = new Point(x, y);
|
||||
@ -121,7 +136,9 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
|
||||
|
||||
@Override
|
||||
public ITurtle drawTo(Point to) {
|
||||
if (path) {
|
||||
if (path && context != null) {
|
||||
context.setStroke(state.ink);
|
||||
context.setLineWidth(state.penSize);
|
||||
context.lineTo(to.getX(), to.getY());
|
||||
} else {
|
||||
line(to);
|
||||
@ -164,6 +181,18 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
|
||||
public ITurtle jump(double dist) {
|
||||
state.inDir = state.dir;
|
||||
state.pos = state.pos.move(state.dir, dist);
|
||||
if (path && context != null)
|
||||
context.moveTo(state.pos.getX(), state.pos.getY());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITurtle jump(Point relPos) {
|
||||
// TODO: state.inDir = state.dir;
|
||||
state.pos = state.pos.move(relPos);
|
||||
if (path && context != null)
|
||||
context.moveTo(state.pos.getX(), state.pos.getY());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -195,11 +224,13 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
|
||||
|
||||
@Override
|
||||
public ITurtle line(Point to) {
|
||||
// context.save();
|
||||
context.setStroke(state.ink);
|
||||
context.setLineWidth(state.penSize);
|
||||
context.strokeLine(state.pos.getX(), state.pos.getY(), to.getX(), to.getY());
|
||||
// context.restore();
|
||||
if (context != null) {
|
||||
// context.save();
|
||||
context.setStroke(state.ink);
|
||||
context.setLineWidth(state.penSize);
|
||||
context.strokeLine(state.pos.getX(), state.pos.getY(), to.getX(), to.getY());
|
||||
// context.restore();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -288,10 +319,55 @@ public class TurtlePainter implements IPaintLayer, ITurtle {
|
||||
|
||||
@Override
|
||||
public ITurtle turtle() {
|
||||
TurtlePainter painter = screen != null ? new TurtlePainter(screen, canvas)
|
||||
: new TurtlePainter(width, height, canvas);
|
||||
TurtlePainter painter = screen != null ? new TurtlePainter(screen, canvas) : new TurtlePainter(width, height);
|
||||
painter.stateStack.set(0, new TurtleState(state));
|
||||
return painter;
|
||||
}
|
||||
|
||||
public ITurtle beginPath() {
|
||||
if (path)
|
||||
throw new IllegalStateException("beginPath() after beginPath()");
|
||||
path = true;
|
||||
if (context != null) {
|
||||
context.setStroke(state.ink);
|
||||
context.beginPath();
|
||||
context.moveTo(state.pos.getX(), state.pos.getY());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ITurtle closePath() {
|
||||
if (!path)
|
||||
throw new IllegalStateException("closePath() without beginPath()");
|
||||
if (context != null)
|
||||
context.closePath();
|
||||
return this;
|
||||
}
|
||||
|
||||
public ITurtle endPath() {
|
||||
if (!path)
|
||||
throw new IllegalStateException("endPath() without beginPath()");
|
||||
path = false;
|
||||
if (context != null)
|
||||
context.stroke();
|
||||
return this;
|
||||
}
|
||||
|
||||
public ITurtle fillPath() {
|
||||
if (!path)
|
||||
throw new IllegalStateException("fillPath() without beginPath()");
|
||||
path = false;
|
||||
if (context != null) {
|
||||
context.save();
|
||||
context.setFill(state.ink);
|
||||
context.fill();
|
||||
context.restore();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Paint getInk() {
|
||||
return state.ink;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@ import java.util.regex.Pattern;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
public class ControlSequences {
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
public static class CsiPattern {
|
||||
public static CsiPattern compile0(String pat, String desc, Consumer<Printer> handler) {
|
||||
CsiPattern csiPattern = new CsiPattern(pat, 0, 0, desc, handler, null, null);
|
||||
@ -73,10 +75,12 @@ public class ControlSequences {
|
||||
String argStr = matcher.groupCount() > 0 ? matcher.group(1) : "";
|
||||
String[] args = argStr.split(";");
|
||||
if (handler0 != null) {
|
||||
if(DEBUG)
|
||||
System.out.println("Handling " + getDescription() + ".");
|
||||
handler0.accept(printer);
|
||||
} else if (handler1 != null) {
|
||||
int arg = args.length > 0 && !args[0].equals("") ? Integer.valueOf(args[0]) : defaultArg;
|
||||
if(DEBUG)
|
||||
System.out.println("Handling " + getDescription() + ": " + arg);
|
||||
handler1.accept(printer, arg);
|
||||
} else if (handlerN != null) {
|
||||
@ -90,7 +94,8 @@ public class ControlSequences {
|
||||
while (argList.size() < numArgs) {
|
||||
argList.add(defaultArg);
|
||||
}
|
||||
System.out.println("Handling " + getDescription() + ": " + argList);
|
||||
if(DEBUG)
|
||||
System.out.println("Handling " + getDescription() + ": " + argList);
|
||||
handlerN.accept(printer, argList);
|
||||
}
|
||||
return true;
|
||||
|
@ -100,13 +100,25 @@ public class Printer implements IPaintLayer {
|
||||
|
||||
private int csiMode = 0;
|
||||
|
||||
private final double width;
|
||||
private final double height;
|
||||
|
||||
public Printer(double width, double height) {
|
||||
this(null, new Canvas(width, height));
|
||||
this.screen = null;
|
||||
this.textPage = null;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
for (int i = 0; i < TextMode.PAGE_HEIGHT_MAX; i++) {
|
||||
lineBuffer.add(new Char[TextMode.LINE_WIDTH_MAX]);
|
||||
}
|
||||
resetFull();
|
||||
}
|
||||
|
||||
public Printer(Screen screen, Canvas page) {
|
||||
this.screen = screen;
|
||||
this.textPage = page;
|
||||
this.width = page.getWidth();
|
||||
this.height = page.getHeight();
|
||||
for (int i = 0; i < TextMode.PAGE_HEIGHT_MAX; i++) {
|
||||
lineBuffer.add(new Char[TextMode.LINE_WIDTH_MAX]);
|
||||
}
|
||||
@ -126,15 +138,17 @@ public class Printer implements IPaintLayer {
|
||||
moveTo(leftMargin, y + 1);
|
||||
break;
|
||||
case "\f":
|
||||
GraphicsContext context = textPage.getGraphicsContext2D();
|
||||
moveTo(leftMargin, topMargin);
|
||||
for (Char[] line : lineBuffer)
|
||||
Arrays.fill(line, null);
|
||||
if(textPage != null) {
|
||||
GraphicsContext context = textPage.getGraphicsContext2D();
|
||||
if (background != null && background != Color.TRANSPARENT) {
|
||||
context.setFill(background);
|
||||
context.fillRect(0.0, 0.0, textPage.getWidth(), textPage.getHeight());
|
||||
} else
|
||||
context.clearRect(0.0, 0.0, textPage.getWidth(), textPage.getHeight());
|
||||
}
|
||||
break;
|
||||
case "\b":
|
||||
moveHoriz(-1);
|
||||
@ -286,7 +300,7 @@ public class Printer implements IPaintLayer {
|
||||
}
|
||||
|
||||
private void drawChar(int x, int y, Char c) {
|
||||
if (c != null) {
|
||||
if (c != null && textPage != null) {
|
||||
GraphicsContext context = textPage.getGraphicsContext2D();
|
||||
|
||||
context.setFill(c.fill);
|
||||
@ -502,6 +516,8 @@ public class Printer implements IPaintLayer {
|
||||
* "ms/char", "mode", "indir", "inv", "fake"); for (int m = -1; m < 8; m++) {
|
||||
* long t0 = System.currentTimeMillis(); int n = 0;
|
||||
*/
|
||||
if(textPage == null)
|
||||
return;
|
||||
GraphicsContext context = textPage.getGraphicsContext2D();
|
||||
|
||||
if (background != null && background != Color.TRANSPARENT) {
|
||||
@ -718,4 +734,14 @@ public class Printer implements IPaintLayer {
|
||||
plot(x, y, (a, b) -> a & ~b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ public class Game implements IGame {
|
||||
|
||||
public Game(String mapString) {
|
||||
printer = new Printer(1280, 720);
|
||||
painter = new TurtlePainter(1280, 720, null);
|
||||
painter = new TurtlePainter(1280, 720);
|
||||
|
||||
addFactory();
|
||||
|
||||
|
Reference in New Issue
Block a user