Fixed merge conflicts
This commit is contained in:
commit
2e50452a22
@ -98,6 +98,12 @@ Vi har også et par andre mer abstrakte ting vi bør tenke på – f.eks. koordi
|
||||
* [IArea](src/inf101/v18/grid/IArea.java) – et rektangulært sett med ILocations. Brukes f.eks. av spillkartet for å lettvint gå gjennom alle cellene/rutene i kartet.
|
||||
* ([IGrid<T>](src/inf101/v18/grid/IGrid.java) og [IMultiGrid<T>](src/inf101/v18/grid/IMultiGrid.java) – IGrid<T> er tilsvarende til den du har brukt i labbene tidligere; IMultiGrid<T> er et grid der hver celle er en liste av T-er. Den blir brukt av spillkartet, men du trenger neppe bruke den selv.)
|
||||
|
||||
UML:
|
||||
<a href="https://retting.ii.uib.no/inf101/inf101.v18/wikis/img/RogueInterface.png">
|
||||
<img src="https://retting.ii.uib.no/inf101/inf101.v18/wikis/img/RogueInterface.png" width="200">
|
||||
</a>
|
||||
|
||||
|
||||
### *(4%)* Deloppgave A1: Tilstand, oppførsel og grensesnitt for objektene
|
||||
*Du vil sikkert finne på lurere svar på spørsmålene etterhvert som du jobber med oppgaven. Det er fint om du lar de opprinnelige svarene stå (det er helt OK om de er totalt feil eller helt på jordet) og heller gjør tilføyelser. Du kan evt. bruke ~~overstryking~~ (putt dobbel tilde rundt teksten, `~~Rabbit.java funker fordi det bor en liten kanin inni datamaskinen~~`) for å markere det du ikke lenger synes er like lurt.*
|
||||
|
||||
@ -145,7 +151,7 @@ Hvis du ser på koden for [Rabbit.java](src/inf101/v18/rogue101/examples/Rabbit.
|
||||
* du kan finne ut hva som ligger i nabofeltet ved hjelp av kartet (`game.getMap()`); f.eks. med metoden `getItems()`.
|
||||
* kaninen har allerede kode for å sjekke gjennom tingene og se om den finner en `Carrot` – du kan kopiere og tilpasse denne
|
||||
* hvis kaninen finner en gulrot kan den gjøre `game.move(...)` og så returnere med en gang
|
||||
** *e)** Kaninens jobb blir litt enklere om den får litt hjelp fra `Game` med å finne ut hvor den kan gå. Implementer metoden `getPossibleMoves()` i `Game`.
|
||||
* **e)** Kaninens jobb blir litt enklere om den får litt hjelp fra `Game` med å finne ut hvor den kan gå. Implementer metoden `getPossibleMoves()` i `Game`.
|
||||
|
||||
#### Bedre gulrøtter
|
||||
|
||||
@ -153,7 +159,7 @@ Prøv også å justere gulrøttene litt ([Carrot](src/inf101/v18/rogue101/exampl
|
||||
|
||||
* **a)** Gulrøttene får helsen satt til -1 når de blir spist – etter helsereglene våre vil de derfor bli fjernet fra kartet. Prøv å sette helsen til 0 i stedet. Hvorfor går det ikke bedre med kaninene selv om gulrøttene nå blir værende på kartet?
|
||||
* **b)** Det hadde kanskje vært praktisk (ihvertfall for kaninene) om gulrøttene vokste seg store og fine igjen etter en stund; for eksempel ved at de “helbreder” ett helsepoeng for hver runde som går – men `Carrot` har ingen `doTurn()` metode slik `Rabbit` har, så den får ikke med seg at rundene går eller at kaninene hopper rundt (rent bortsett fra at det går an å “jukse” ved å regne med / håpe på at `draw()` blir kalt en gang per runde).
|
||||
* Lag en `doTurn()`-metode i `Carrot` som øker `hp` med 1 for hver runde (opp til `getMaxHealth()`).
|
||||
* ~~Lag en `doTurn()`-metode i `Carrot` som øker `hp` med 1 for hver runde (opp til `getMaxHealth()`).~~ (Denne fulgte med fra før.)
|
||||
* Hva skjer, ser det ut til å virke?
|
||||
* Hvis det ikke virker, hva må du eventuelt gjøre for å få `Carrot` til å gjøre noe hver runde?
|
||||
* **c)** Du kan også prøve å la `Game` legge til nye, tilfeldig plasserte gulrøtter av og til:
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user