Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • cagnion/mp2_anahita_et_constance_2
1 result
Show changes
Showing
with 0 additions and 1963 deletions
package ch.epfl.cs107.play.engine.actor;
import ch.epfl.cs107.play.engine.actor.Entity;
import ch.epfl.cs107.play.engine.actor.ImageGraphics;
import ch.epfl.cs107.play.areagame.area.Area;
import ch.epfl.cs107.play.io.ResourcePath;
import ch.epfl.cs107.play.math.DiscreteCoordinates;
import ch.epfl.cs107.play.math.RegionOfInterest;
import ch.epfl.cs107.play.math.Vector;
import ch.epfl.cs107.play.window.Canvas;
public class Background extends Entity {
/// Sprite of the actor
private final ImageGraphics sprite;
/**
* Default Background Constructor
* by default the Background image is using the area title as file name
* @param area (Area): ownerArea. Not null
*/
public Background(Area area) {
super(DiscreteCoordinates.ORIGIN.toVector());
sprite = new ImageGraphics(ResourcePath.getBackground(area.getTitle()), area.getWidth(), area.getHeight(), null, Vector.ZERO, 1.0f, -Float.MAX_VALUE);
sprite.setParent(this);
}
/**
* Default Background Constructor
* by default the Background image is using the area title as file name
* @param area (Area): ownerArea. Not null
*/
public Background(Area area, String title) {
super(DiscreteCoordinates.ORIGIN.toVector());
sprite = new ImageGraphics(ResourcePath.getBackground(title), area.getWidth(), area.getHeight(), null, Vector.ZERO, 1.0f, -Float.MAX_VALUE);
sprite.setParent(this);
}
/**
* Extended Background Constructor
* by default the Background image is using the area title as file name
* @param area (Area): ownerArea. Not null
* @param region (RegionOfInterest): region of interest in the image for the background, may be null
*/
public Background(Area area, RegionOfInterest region) {
super(DiscreteCoordinates.ORIGIN.toVector());
sprite = new ImageGraphics(ResourcePath.getBackground(area.getTitle()), area.getWidth(), area.getHeight(), region, Vector.ZERO, 1.0f, -Float.MAX_VALUE);
sprite.setParent(this);
}
/**
* Extended Background Constructor
* @param area (Area): ownerArea. Not null
* @param region (RegionOfInterest): region of interest in the image for the background, may be null
* @param name (String): Background file name (i.e only the name, with neither path, nor file extension). Not null
*/
public Background(Area area, RegionOfInterest region, String name) {
super(DiscreteCoordinates.ORIGIN.toVector());
sprite = new ImageGraphics(ResourcePath.getBackground(name), area.getWidth(), area.getHeight(), region, Vector.ZERO, 1.0f, -Float.MAX_VALUE);
sprite.setParent(this);
}
/**
* Alternative Background Constructor
* @param name (String): Background file name (i.e only the name, with neither path, nor file extension). Not null
* @param width (int): of the desired background
* @param height (int): of the desired background
* @param region (RegionOfInterest): region of interest in the image for the background. May be null
*/
public Background(String name, int width, int height, RegionOfInterest region) {
super(DiscreteCoordinates.ORIGIN.toVector());
sprite = new ImageGraphics(ResourcePath.getBackground(name), width, height, region, Vector.ZERO, 1.0f, -Float.MAX_VALUE);
sprite.setParent(this);
}
/// Background implements Graphics
@Override
public void draw(Canvas canvas) {
sprite.draw(canvas);
}
}
package ch.epfl.cs107.play.engine.actor;
import ch.epfl.cs107.play.engine.Updatable;
import ch.epfl.cs107.play.engine.actor.Graphics;
import ch.epfl.cs107.play.engine.actor.ImageGraphics;
import ch.epfl.cs107.play.engine.actor.TextGraphics;
import ch.epfl.cs107.play.io.*;
import ch.epfl.cs107.play.math.TextAlign;
import ch.epfl.cs107.play.math.Transform;
import ch.epfl.cs107.play.math.Vector;
import ch.epfl.cs107.play.window.Canvas;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.awt.*;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayDeque;
import java.util.Queue;
/**
* XML Dialog
* Shou
*/
public final class Dialog implements Updatable, Graphics {
private final Queue<String> dialog = new ArrayDeque<>();
/// Static variables for positioning the text and the dialog window
private static final float FONT_SIZE = 0.6f;
/// Number max of char per line of text
private static final int MAX_LINE_SIZE = 35;
private static final String BACKGROUND_NAME = "dialog";
/// Sprite and text graphics line
private final ImageGraphics sprite;
private final TextGraphics[] lines;
private boolean isCompleted = false;
public Dialog(String path){
final float height = 13f / 4;
final float width = 13f;
final Vector firstLineAnchor = new Vector(0.5f, height - FONT_SIZE);
final Vector secondLineAnchor = new Vector(0.5f, height - 2.5f * FONT_SIZE);
final Vector thirdLineAnchor = new Vector(0.5f, height - 4 * FONT_SIZE);
sprite = new ImageGraphics(ResourcePath.getSprite(BACKGROUND_NAME), width, height, null, Vector.ZERO, 1.0f, 3000);
lines = new TextGraphics[3];
lines[0] = new TextGraphics("", FONT_SIZE, Color.BLACK, null, 0.0f, false, false, firstLineAnchor, TextAlign.Horizontal.LEFT, TextAlign.Vertical.MIDDLE, 1.0f, 3001);
lines[1] = new TextGraphics("", FONT_SIZE, Color.BLACK, null, 0.0f, false, false, secondLineAnchor, TextAlign.Horizontal.LEFT, TextAlign.Vertical.MIDDLE, 1.0f, 3001);
lines[2] = new TextGraphics("", FONT_SIZE, Color.BLACK, null, 0.0f, false, false, thirdLineAnchor, TextAlign.Horizontal.LEFT, TextAlign.Vertical.MIDDLE, 1.0f, 3001);
initialize(new ResourceFileSystem(DefaultFileSystem.INSTANCE), ResourcePath.getDialog(path));
update(0); // HR : Update to the first text
}
private void initialize(FileSystem fs, String fileName){
try(var input = fs.read(fileName)) {
// Set up the document builder
var db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
// Change the entity resolver
db.setEntityResolver((publicId, systemId) -> new InputSource(new StringReader("")));
// Parse the xml document
var doc = db.parse(input);
//optional, but recommended
//read this - http://stackoverflow.com/questions/13786607/normalization-in-dom-parsing-with-java-how-does-it-work
doc.getDocumentElement().normalize();
// Fetch all the string resources forming the dialog
var nList = doc.getElementsByTagName("string");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
var id = eElement.getAttribute("id");
var value = eElement.getTextContent();
if (!value.isBlank() && id.isBlank()){
dialog.add(value);
} else if (value.isBlank() && !id.isBlank()) {
} else if (value.isBlank() && id.isBlank()){
throw new IllegalStateException("Cannot configure the dialog, either give the value or the id to a string resource");
} else {
throw new IllegalStateException("Cannot configure the dialog, either give the value or the id to a string resource, not both");
}
}
}
} catch (IOException e) {
// Empty on purpose, will return null as an error
System.out.printf("Dialog File : %s not found", fileName);
} catch (SAXException | ParserConfigurationException e) {
e.printStackTrace();
}
}
@Override
public void update(float deltaTime) {
int cursor;
cursor = 0;
var text = dialog.poll();
// HR : If this dialog completes, do not update since there is nothing to update
if (text == null) {
isCompleted = true;
return;
}
int lengthToPush = text.length()-cursor;
// For each line
for(int i = 0; i<3; i++){
// If some text still need to be pushed : fill the next line
if(lengthToPush <= 0) {
lines[i].setText("");
}
else if(lengthToPush <= MAX_LINE_SIZE) {
lines[i].setText(text.substring(cursor));
cursor += lengthToPush;
}
else{
int maxSize = MAX_LINE_SIZE;
String toConcat = "";
if(i == 2){
maxSize -= 4;
toConcat += " ...";
}
String sub = text.substring(cursor, cursor+maxSize+1);
int last = sub.lastIndexOf(' ');
if(last == -1){
System.out.println("Error: You get a Word longer than " + MAX_LINE_SIZE);
}
lines[i].setText(sub.substring(0, last)+toConcat);
cursor = cursor+last+1;
}
lengthToPush = text.length()-cursor;
}
}
@Override
public void draw(Canvas canvas) {
// Compute width, height and anchor
float width = canvas.getTransform().getX().getX();
float height = canvas.getTransform().getY().getY();
float ratio = canvas.getWidth()/(float)canvas.getHeight();
if(ratio > 1)
height = width / ratio;
else
width = height * ratio;
final Transform transform = Transform.I.translated(canvas.getPosition().sub(width/2, height/2));
sprite.setRelativeTransform(transform);
sprite.setWidth(width);
sprite.setHeight(height/4);
sprite.draw(canvas);
lines[0].setAnchor(new Vector(0.5f, height/4 - FONT_SIZE));
lines[1].setAnchor(new Vector(0.5f, height/4 - 2.5f * FONT_SIZE));
lines[2].setAnchor(new Vector(0.5f, height/4 - 4 * FONT_SIZE));
for(int i = 0; i < 3; i++){
lines[i].setRelativeTransform(transform);
lines[i].draw(canvas);
}
}
public boolean isCompleted(){
return isCompleted;
}
}
package ch.epfl.cs107.play.engine.actor;
public interface Draggable {
/** @return (boolean): true if this is able to be drag */
boolean canDrag();
/** @return (boolean): true if this is dragging */
boolean isDragging();
/** @return (boolean): true if this wants to be dropped */
boolean wantsDropInteraction();
/** acknowledge that a drop do happened */
void acknowledgeDrop();
}
package ch.epfl.cs107.play.engine.actor;
public interface Droppable {
/** @return (boolean): true if this is able to interact with a drop */
boolean canDrop();
/**
* Interaction of a dropping
* @param draggable the object that is dropped
*/
void receiveDropFrom(Draggable draggable);
}
package ch.epfl.cs107.play.engine.actor;
import ch.epfl.cs107.play.engine.actor.Actor;
import ch.epfl.cs107.play.math.Transform;
import ch.epfl.cs107.play.math.Vector;
/**
* Basic Entity are simply actor and represented by a current exact position and its corresponding transform
*/
public abstract class Entity implements Actor {
/// Exact Position as a floating vector
private Vector currentPosition;
/// Corresponding transformation
private Transform transform;
/**
* Default Entity constructor
* @param position (Coordinate): Initial position of the entity. Not null
*/
public Entity(Vector position) {
if (position == null )
throw new NullPointerException();
this.currentPosition = position;
}
/**
* Update the current position (i.e. after motion)
* after position change, the transform need to be updated to. Hence set it to null
* @param v (Vector): The new Position. Not null
*/
protected void setCurrentPosition(Vector v){
this.currentPosition = v;
transform = null;
}
/// Entity implements Positionable
@Override
public Transform getTransform() {
// Compute the transform only when needed
if (transform == null) {
float x = currentPosition.x;
float y = currentPosition.y;
transform = new Transform(
1, 0, x,
0, 1, y
);
}
return transform;
}
@Override
public Vector getPosition(){
return currentPosition;
}
@Override
public Vector getVelocity() {
return Vector.ZERO;
}
}
package ch.epfl.cs107.play.engine.actor;
import ch.epfl.cs107.play.engine.actor.Entity;
import ch.epfl.cs107.play.engine.actor.ImageGraphics;
import ch.epfl.cs107.play.areagame.area.Area;
import ch.epfl.cs107.play.io.ResourcePath;
import ch.epfl.cs107.play.math.DiscreteCoordinates;
import ch.epfl.cs107.play.math.RegionOfInterest;
import ch.epfl.cs107.play.math.Vector;
import ch.epfl.cs107.play.window.Canvas;
public class Foreground extends Entity {
/// Sprite of the actor
private final ImageGraphics sprite;
/**
* Default Foreground Constructor
* by default the Background image is using the area title as file name
* @param area (Area): ownerArea. Not null
*/
public Foreground(Area area) {
super(DiscreteCoordinates.ORIGIN.toVector());
sprite = new ImageGraphics(ResourcePath.getForeground(area.getTitle()), area.getWidth(), area.getHeight(), null, Vector.ZERO, 1.0f, 1000);
sprite.setParent(this);
}
/**
* Extended Foreground Constructor
* by default the Background image is using the area title as file name
* @param area (Area): ownerArea. Not null
* @param region (RegionOfInterest): region of interest in the image for the foreground, may be null
*/
public Foreground(Area area, RegionOfInterest region) {
super(DiscreteCoordinates.ORIGIN.toVector());
sprite = new ImageGraphics(ResourcePath.getForeground(area.getTitle()), area.getWidth(), area.getHeight(), region, Vector.ZERO, 1.0f, 1000);
sprite.setParent(this);
}
/**
* Extended Foreground Constructor
* @param area (Area): ownerArea. Not null
* @param region (RegionOfInterest): region of interest in the image for the foreground, may be null
* @param name (String): Background file name (i.e only the name, with neither path, nor file extension). Not null
*/
public Foreground(Area area, RegionOfInterest region, String name) {
super(DiscreteCoordinates.ORIGIN.toVector());
sprite = new ImageGraphics(ResourcePath.getForeground(name), area.getWidth(), area.getHeight(), region, Vector.ZERO, 1.0f, 1000);
sprite.setParent(this);
}
/**
* Alternative Foreground Constructor
* @param name (String): Background file name (i.e only the name, with neither path, nor file extension). Not null
* @param width (int): of the desired foreground
* @param height (int): of the desired foreground
* @param region (RegionOfInterest): region of interest in the image for the foreground, may be null
*/
public Foreground(String name, int width, int height, RegionOfInterest region) {
super(DiscreteCoordinates.ORIGIN.toVector());
sprite = new ImageGraphics(ResourcePath.getForeground(name), width, height, region, Vector.ZERO, 1.0f, 1000);
sprite.setParent(this);
}
/// Foreground implements Graphics
@Override
public void draw(Canvas canvas) {
sprite.draw(canvas);
}
}
package ch.epfl.cs107.play.engine.actor;
import ch.epfl.cs107.play.window.Canvas;
/**
* Represents a drawable element.
*/
public interface Graphics {
/**
* Renders itself on specified canvas.
* @param canvas target, not null
*/
void draw(Canvas canvas);
}
package ch.epfl.cs107.play.engine.actor;
import ch.epfl.cs107.play.math.Vector;
import ch.epfl.cs107.play.window.Canvas;
/**
* GraphicEntity useful to link a single Specific Graphic type to a space point
*/
public class GraphicsEntity extends Entity{
private final Graphics graphics;
/**
* Default GraphicsEntity constructor
* Notice: it is private
* @param position (Vector): Initial position of the entity. Not null
* @param graphics (Graphics): graphics to display at position. Not null
*/
private GraphicsEntity(Vector position, Graphics graphics) {
super(position);
this.graphics = graphics;
}
/**
* Alternative GraphicsEntity Constructor
* @param position (Vector): initial Position. Not null
* @param graphics (ImageGraphics): graphics to display at position. Not null
*/
public GraphicsEntity(Vector position, ImageGraphics graphics) {
this(position, (Graphics) graphics);
graphics.setParent(this);
}
/**
* Alternative GraphicsEntity Constructor
* @param position (Vector): initial Position. Not null
* @param graphics (TextGraphics): graphics to display at position. Not null
*/
public GraphicsEntity(Vector position, TextGraphics graphics) {
this(position, (Graphics) graphics);
graphics.setParent(this);
}
/**
* Alternative GraphicsEntity Constructor
* @param position (Vector): initial Position. Not null
* @param graphics (ShapeGraphics): graphics to display at position. Not null
*/
public GraphicsEntity(Vector position, ShapeGraphics graphics) {
this(position, (Graphics) graphics);
graphics.setParent(this);
}
/** @return (Graphics): The graphics of the entity*/
public Graphics getGraphics() {
return graphics;
}
/**
* Set the current position. Make public the protected method of super class
* @param position (Vector): new Position. Not null
*/
public void setCurrentPosition(Vector position){
super.setCurrentPosition(position);
}
/// GraphicsEntity implements drawable
@Override
public void draw(Canvas canvas) {
if(graphics!= null) {
graphics.draw(canvas);
}
}
}
package ch.epfl.cs107.play.engine.actor;
import ch.epfl.cs107.play.engine.actor.Entity;
import ch.epfl.cs107.play.areagame.area.Area;
import ch.epfl.cs107.play.math.DiscreteCoordinates;
import ch.epfl.cs107.play.math.shape.Polyline;
import ch.epfl.cs107.play.math.Vector;
import ch.epfl.cs107.play.window.Canvas;
import java.util.ArrayList;
import java.util.List;
/**
* Grid Overlay entity
* Draw a grid on the DiscreteCoordinate Lines:
* Assume a coordinate system which is graduated every unit (0, 1, 2, ...)
* Assume a grid overlay with unit square
*/
public class Grid extends Entity {
/// Whole grid lines
private final Polyline gridLine;
/// Border of the grid
private final Polyline border;
/**
* Default Grid Constructor
* @param width (int): of the desired grid
* @param height (int): of the desired grid
*/
public Grid(int width, int height){
super(DiscreteCoordinates.ORIGIN.toVector());
final List<Vector> points = new ArrayList<>();
// Add all vertical lines as a snake from top left to top/bottom right
for(int c = 1; c < width; c++) {
points.add(new Vector(c, (c%2)*height));
points.add(new Vector(c, ((c+1)%2)*height));
}
// Reach the right in the margin
points.add(new Vector(width, (width%2)*height));
// Add all horizontal lines as a snake
for(int r = 1; r < height; r++) {
points.add(new Vector((r%2)*width, r));
points.add(new Vector(((r+1)%2)*width, r));
}
// Convert the point into a opened poly line
gridLine = new Polyline(false, points);
border = new Polyline(true, 0,0,0, height, width, height, width, 0);
}
public Grid(Area area) {
this(area.getWidth(), area.getHeight());
}
/// Grid implements Graphics
@Override
public void draw(Canvas canvas) {
canvas.drawShape(gridLine, getTransform(), null, java.awt.Color.GRAY, 0.05f, 0.5f, 10000);
canvas.drawShape(border, getTransform(), null, java.awt.Color.GRAY, 0.05f, 1, 10000);
}
}
package ch.epfl.cs107.play.engine.actor;
import ch.epfl.cs107.play.math.Node;
import ch.epfl.cs107.play.math.RegionOfInterest;
import ch.epfl.cs107.play.math.Transform;
import ch.epfl.cs107.play.math.Vector;
import ch.epfl.cs107.play.window.Canvas;
import ch.epfl.cs107.play.window.Image;
/**
* Contains information to render a single image, which can be attached to any positionable.
*/
public class ImageGraphics extends Node implements Graphics {
/// Region of interest as a rectangle in the image
private final RegionOfInterest roi;
/// Image name
private String name;
/// Image dimension
private float width, height;
/// Anchor of the image (i.e. if the origin of the image is not the origin of the parent)
private Vector anchor;
/// Transparency of the image. Between 0 (invisible) amd 1 (opaque)
private float alpha;
/// Depth used as render priority. It is the third axis. See it as altitude : lower values are drawn first
private float depth;
///
private final boolean removeBackground;
/**
* Creates a new image graphics.
* @param name (String): image name, may be null
* @param width (float): actual image width, before transformation
* @param height (float): actual image height, before transformation
* @param roi (RegionOfInterest): region of interest as a rectangle in the image
* @param anchor (Vector): image anchor, not null
* @param alpha (float): transparency, between 0 (invisible) and 1 (opaque)
* @param depth (float): render priority, lower-values drawn first
* @param removeBackground (boolean): indicate if we need to remove the uniform color background before using this image
*/
public ImageGraphics(String name, float width, float height, RegionOfInterest roi, Vector anchor, float alpha, float depth, boolean removeBackground) {
this.name = name;
this.width = width;
this.height = height;
this.roi = roi;
this.anchor = anchor;
this.alpha = alpha;
this.depth = depth;
this.removeBackground = removeBackground;
}
/**
* Creates a new image graphics.
* @param name (String): image name, may be null
* @param width (float): actual image width, before transformation
* @param height (float): actual image height, before transformation
* @param roi (RegionOfInterest): region of interest as a rectangle in the image
* @param anchor (Vector): image anchor, not null
* @param alpha (float): transparency, between 0 (invisible) and 1 (opaque)
* @param depth (float): render priority, lower-values drawn first
*/
public ImageGraphics(String name, float width, float height, RegionOfInterest roi, Vector anchor, float alpha, float depth) {
this(name, width, height, roi, anchor, alpha, depth, false);
}
/**
* Creates a new image graphics.
* @param name (String): image name, may be null
* @param width (float): actual image width, before transformation
* @param height (float): actual image height, before transformation
* @param roi (RegionOfInterest): region of interest as a rectangle in the image
* @param anchor (Vector): image anchor, not null
*/
public ImageGraphics(String name, float width, float height, RegionOfInterest roi, Vector anchor) {
this(name, width, height, roi, anchor, 1.0f, 0.0f, false);
}
/**
* Creates a new image graphics.
* Creates a new image graphics.
* @param name (String): image name, may be null
* @param width (float): actual image width, before transformation
* @param height (float): actual image height, before transformation
* @param roi (RegionOfInterest): region of interest as a rectangle in the image
*/
public ImageGraphics(String name, float width, float height, RegionOfInterest roi) {
this(name, width, height, roi, Vector.ZERO);
}
/**
* Creates a new image graphics.
* @param name (String): image name, may be null
* @param width (float): actual image width, before transformation
* @param height (float): actual image height, before transformation
* @param roi (RegionOfInterest): region of interest as a rectangle in the image
* @param removeBackground (boolean): indicate if we need to remove the uniform color background before using this image
*/
public ImageGraphics(String name, float width, float height, RegionOfInterest roi, boolean removeBackground) {
this(name, width, height, roi, Vector.ZERO, 1.0f, 0.0f, removeBackground);
}
/**
* Creates a new image graphics.
* @param name (String): image name, may be null
* @param width (float): actual image width, before transformation
* @param height (float): actual image height, before transformation
*/
public ImageGraphics(String name, float width, float height) {
this(name, width, height, null, Vector.ZERO);
}
/**
* Sets image name.
* @param name (String): new image name, may be null
*/
public void setName(String name) {
this.name = name;
}
/** @return (String): image name, may be null */
public String getName() {
return name;
}
/**
* Sets actual image width, before transformation.
* @param width (float): image width
*/
public void setWidth(float width) {
this.width = width;
}
/** @return (float): actual image width, before transformation */
public float getWidth() {
return width;
}
/**
* Sets actual image height, before transformation.
* @param height (float): image height
*/
public void setHeight(float height) {
this.height = height;
}
/** @return (float): actual image height, before transformation */
public float getHeight() {
return height;
}
/**
* Sets image anchor location, i.e. where is the center of the image.
* @param anchor (Vector): image anchor, not null
*/
public void setAnchor(Vector anchor) {
this.anchor = anchor;
}
/** @return (Vector): image anchor, not null */
public Vector getAnchor() {
return anchor;
}
/**
* Sets transparency.
* @param alpha (float): transparency, between 0 (invisible) and 1 (opaque)
*/
public void setAlpha(float alpha) {
this.alpha = alpha;
}
/** @return (float): transparency, between 0 (invisible) and 1 (opaque) */
public float getAlpha() {
return alpha;
}
/**
* Sets rendering depth.
* @param depth (float): render priority, lower-values drawn first
*/
public void setDepth(float depth) {
this.depth = depth;
}
/** @return (float): render priority, lower-values drawn first */
public float getDepth() {
return depth;
}
@Override
public void draw(Canvas canvas) {
if (name == null)
return;
Image image = canvas.getImage(name, roi, removeBackground);
Transform transform = Transform.I.scaled(width, height).translated(anchor.x, anchor.y).transformed(getTransform());
canvas.drawImage(image, transform, alpha, depth);
}
}
package ch.epfl.cs107.play.engine.actor;
import ch.epfl.cs107.play.areagame.actor.AreaEntity;
import ch.epfl.cs107.play.engine.Updatable;
import ch.epfl.cs107.play.math.Orientation;
import ch.epfl.cs107.play.math.Positionable;
import ch.epfl.cs107.play.math.Vector;
import ch.epfl.cs107.play.math.RegionOfInterest;
import ch.epfl.cs107.play.window.Canvas;
public class OrientedAnimation implements Updatable, Graphics {
private final Animation[] animations;
private final AreaEntity parent;
@Deprecated
private Animation current;
public OrientedAnimation(Animation[] animations, AreaEntity parent) {
this.animations = animations;
this.parent = parent;
this.current = null;
}
public OrientedAnimation(String name, int duration, AreaEntity parent, Vector anchor) {
this(name, duration, parent, anchor,
new Orientation[]{Orientation.DOWN, Orientation.RIGHT, Orientation.UP, Orientation.LEFT},
4, 1, 2, 16, 32);
}
/**
*
* @param name (String): the name of the image
* @param nbFrames (int): number of frames in each row
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param anchor (Vector) : image anchor, not null
* @param regionWidth (int): width of frame (number of pixels in the image)
* @param regionHeight (int): height of frame (number of pixels in the image)
* @param order (Orientation[]): order of the frames in the image
* @param repeat (boolean : true if the animation must be repeated
*
*/
public OrientedAnimation(String name, int duration, AreaEntity parent, Vector anchor,
Orientation[] order, int nbFrames, int width, int height, int regionWidth, int regionHeight, boolean repeat) {
final Sprite[][] sprites = Sprite.extractSprites(name, nbFrames, width, height, parent, regionWidth, regionHeight, anchor, order);
this.animations = Animation.createAnimations(duration, sprites,repeat);
this.parent = parent;
this.current = null;
}
public OrientedAnimation(String name, int duration, AreaEntity parent, Vector anchor,
Orientation[] order, int nbFrames, int width, int height, int regionWidth, int regionHeight) {
this(name, duration, parent, anchor, order, nbFrames, width, height, regionWidth, regionHeight, false);
}
@Override
public void update(float deltaTime) {
current().update(deltaTime);
}
private Animation current() {
if (current != null) {
return current;
}
return animations[parent.getOrientation().ordinal()];
}
@Override
public void draw(Canvas canvas) {
current().draw(canvas);
}
public void reset() {
for (Animation animation : animations) {
animation.reset();
}
}
@Deprecated
public void orientate(Orientation orientation) {
current = animations[orientation.ordinal()];
}
public boolean isCompleted() {
return current().isCompleted();
}
}
package ch.epfl.cs107.play.engine.actor;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import ch.epfl.cs107.play.engine.actor.Entity;
import ch.epfl.cs107.play.math.DiscreteCoordinates;
import ch.epfl.cs107.play.math.Orientation;
import ch.epfl.cs107.play.math.shape.Polyline;
import ch.epfl.cs107.play.math.Vector;
import ch.epfl.cs107.play.window.Canvas;
/**
* Path Overlay entity
* Draw a path on the DiscreteCoordinate Lines:
*/
public class Path extends Entity {
private final Polyline pathLine;
/**
* Default Path Constructor
* @param start (Vector): the origin of the path
* @param path (Queue): the successive orientation of the path
*/
public Path(Vector start, Queue<Orientation> path){
super(DiscreteCoordinates.ORIGIN.toVector());
final List<Vector> points = new ArrayList<>();
Vector prevPoint = start.add(new Vector(0.5f, 0.5f));
points.add(prevPoint);
while(!path.isEmpty()) {
Vector newPoint = prevPoint.add(path.poll().toVector());
points.add(newPoint);
prevPoint = newPoint;
}
// Convert the point into a opened poly line
if(points.size() >= 2)
pathLine = new Polyline(points);
else
pathLine = null;
}
/// Path implements Graphics
@Override
public void draw(Canvas canvas) {
if(pathLine != null)
canvas.drawShape(pathLine, getTransform(), null, java.awt.Color.RED, 0.2f, 1f, 10000);
}
}
package ch.epfl.cs107.play.engine.actor;
import ch.epfl.cs107.play.math.Orientation;
import ch.epfl.cs107.play.math.Positionable;
import ch.epfl.cs107.play.math.RegionOfInterest;
import ch.epfl.cs107.play.math.Vector;
import ch.epfl.cs107.play.window.Canvas;
public class RPGSprite extends Sprite {
private final float depthCorrection;
/**
* Creates a new Sprite.
* @param name (String): image name, may be null
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param roi (RegionOfInterest): region of interest into the image as a rectangle in the image. May be null
* @param anchor (Vector): image anchor, not null
* @param alpha (float): transparency, between 0 (invisible) and 1 (opaque)
* @param depthCorrection (float): correction of the deepness defined by the parent position if exists
*/
public RPGSprite(String name, float width, float height, Positionable parent, RegionOfInterest roi, Vector anchor, float alpha, float depthCorrection) {
super(name, width, height, parent, roi, anchor, alpha, -parent.getPosition().y+depthCorrection);
this.depthCorrection = depthCorrection;
}
/**
* Creates a new image graphics.
* @param name (String): image name, not null
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param roi (RegionOfInterest): region of interest into the image as a rectangle in the image. May be null
* @param anchor (Vector): image anchor, not null
*/
public RPGSprite(String name, float width, float height, Positionable parent, RegionOfInterest roi, Vector anchor) {
super(name, width, height, parent, roi, anchor);
this.depthCorrection = 0;
}
/**
* Creates a new image graphics.
* @param name (String): image name, not null
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param roi (RegionOfInterest): region of interest into the image as a rectangle in the image. May be null
*/
public RPGSprite(String name, float width, float height, Positionable parent, RegionOfInterest roi) {
super(name, width, height, parent, roi);
this.depthCorrection = 0;
}
/**
* Creates a new image graphics.
* @param name (String): image name, not null
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
*/
public RPGSprite(String name, float width, float height, Positionable parent) {
super(name, width, height, parent);
this.depthCorrection = 0;
}
@Override
public void draw(Canvas canvas) {
if(getParent() != null){
setDepth(-getParent().getPosition().y+depthCorrection);
}
super.draw(canvas);
}
//Utilities to extract sprites
/**
* Extracts from an image the sprites corresponding to a given orientation
* the returned array has 4 entry (one per orientation)
* the content of each entry is an array of sprites corresponding to the given orientation
* (the entry indexed by Orientation.dir.ordinal() is the array of sprites corresponding
* to the orientation Orientation.dir).
* @param name (String): the name of the image
* @param nbFrames (int): number of frames in each row
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param anchor (Vector) : image anchor, not null
* @param regionWidth (int): width of frame (number of pixels in the image)
* @param regionHeight (int): height of frame (number of pixels in the image)
* @param order (Orientation[]): order of the frames in the image
*
*
* @return an array of 4 Sprite[] (one Sprite[] per orientation)
*/
public static Sprite[][] extractSprites(String name, int nbFrames, float width, float height, Positionable parent, int regionWidth, int regionHeight, Vector anchor, Orientation[] order){
Sprite[][] sprites = new Sprite[4][nbFrames];
for(int i = 0; i < nbFrames; i++){
int j = 0;
sprites[order[0].ordinal()][i] = new RPGSprite(name, width, height, parent, new RegionOfInterest(i*regionWidth, regionHeight*j++, regionWidth, regionHeight), anchor);
sprites[order[1].ordinal()][i] = new RPGSprite(name, width, height, parent, new RegionOfInterest(i*regionWidth, regionHeight*j++, regionWidth, regionHeight), anchor);
sprites[order[2].ordinal()][i] = new RPGSprite(name, width, height, parent, new RegionOfInterest(i*regionWidth, regionHeight*j++, regionWidth, regionHeight), anchor);
sprites[order[3].ordinal()][i] = new RPGSprite(name, width, height, parent, new RegionOfInterest(i*regionWidth, regionHeight*j, regionWidth, regionHeight), anchor);
}
return sprites;
}
/**
* Extracts from an image the sprites corresponding to a given orientation
* the returned array has 4 entry (one per orientation)
* the content of each entry is an array of sprites corresponding to the given orientation
* (the entry indexed by Orientation.dir.ordinal() is the array of sprites corresponding
* to the orientation Orientation.dir).
* @param name (String): the name of the image
* @param nbFrames (int): number of frames in each row
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param regionWidth (int): width of frame (number of pixels in the image)
* @param regionHeight (int): height of frame (number of pixels in the image)
* @param order (Orientation[]): order of the frames in the image
*
*
* @return an array of 4 Sprite[] (one Sprite[] per orientation)
*/
public static Sprite[][] extractSprites(String name, int nbFrames, float width, float height, Positionable parent, int regionWidth, int regionHeight, Orientation[] order){
return extractSprites(name, nbFrames, width, height, parent, regionWidth, regionHeight, Vector.ZERO, order);
}
/**
* Extracts from an image the sprites
* @param name (String): the name of the image
* @param nbFrames (int): number of frames in each row
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param anchor (Vector) : image anchor, not null
* @param regionWidth (int): width of frame (number of pixels in the image)
* @param regionHeight (int): height of frame (number of pixels in the image)
*
*
* @return an array of Sprite
*/
public static Sprite[] extractSprites(String name, int nbFrames, float width, float height, Positionable parent, Vector anchor, int regionWidth, int regionHeight){
Sprite[] sprites = new Sprite[nbFrames];
for(int i = 0; i < nbFrames; i++){
sprites[i] = new RPGSprite(name, width, height, parent, new RegionOfInterest(i*regionWidth, 0, regionWidth, regionHeight), anchor);
}
return sprites;
}
/**
* Extracts from an image the sprites
* @param name (String): the name of the image
* @param nbFrames (int): number of frames in each row
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param regionWidth (int): width of frame (number of pixels in the image)
* @param regionHeight (int): height of frame (number of pixels in the image)
*
*
* @return an array of Sprite
*/
public static Sprite[] extractSprites(String name, int nbFrames, float width, float height, Positionable parent, int regionWidth, int regionHeight){
return extractSprites(name, nbFrames, width, height, parent, Vector.ZERO, regionWidth, regionHeight);
}
}
package ch.epfl.cs107.play.engine.actor;
import ch.epfl.cs107.play.math.Node;
import ch.epfl.cs107.play.math.shape.Shape;
import ch.epfl.cs107.play.window.Canvas;
import java.awt.Color;
/**
* Contains information to render a single shape, which can be attached to any positionable.
*/
public class ShapeGraphics extends Node implements Graphics {
private Shape shape;
private Color fillColor;
private Color outlineColor;
private float thickness;
private float alpha;
private float depth;
/**
* Creates a new shape graphics.
* @param shape (Shape): shape, may be null
* @param fillColor (Color): fill color, may be null
* @param outlineColor (Color): outline color, may be null
* @param thickness (float): outline thickness
* @param alpha (float): transparency, between 0 (invisible) and 1 (opaque)
* @param depth (float): render priority, lower-values drawn first
*/
public ShapeGraphics(Shape shape, Color fillColor, Color outlineColor, float thickness, float alpha, float depth) {
this.shape = shape;
this.fillColor = fillColor;
this.outlineColor = outlineColor;
this.thickness = thickness;
this.alpha = alpha;
this.depth = depth;
}
/**
* Creates a new shape graphics.
* @param shape (Shape): shape, may be null
* @param fillColor (Color): fill color, may be null
* @param outlineColor (Color): outline color, may be null
* @param thickness (float): outline thickness
*/
public ShapeGraphics(Shape shape, Color fillColor, Color outlineColor, float thickness) {
this(shape, fillColor, outlineColor, thickness, 1.0f, 0.0f);
}
/**
* Sets shape.
* @param shape (Shape): new shape, may be null
*/
public void setShape(Shape shape) {
this.shape = shape;
}
/** @return (Shape): current shape, may be null */
public Shape getShape() {
return shape;
}
/**
* Sets fill color.
* @param fillColor (Color): color, may be null
*/
public void setFillColor(Color fillColor) {
this.fillColor = fillColor;
}
/** @return (Color): fill color, may be null */
public Color getFillColor() {
return fillColor;
}
/**
* Sets outline color.
* @param outlineColor (Color): color, may be null
*/
public void setOutlineColor(Color outlineColor) {
this.outlineColor = outlineColor;
}
/** @return (Color): outline color, may be null */
public Color getOutlineColor() {
return outlineColor;
}
/**
* Sets outline thickness.
* @param thickness (float): outline thickness
*/
public void setThickness(float thickness) {
this.thickness = thickness;
}
/** @return (float): outline thickness */
public float getThickness() {
return thickness;
}
/**
* Sets transparency.
* @param alpha (float): transparency, between 0 (invisible) and 1 (opaque)
*/
public void setAlpha(float alpha) {
this.alpha = alpha;
}
/** @return (float): transparency, between 0 (invisible) and 1 (opaque) */
public float getAlpha() {
return alpha;
}
/**
* Sets rendering depth.
* @param depth (float): render priority, lower-values drawn first
*/
public void setDepth(float depth) {
this.depth = depth;
}
/** @return (float): render priority, lower-values drawn first */
public float getDepth() {
return depth;
}
@Override
public void draw(Canvas canvas) {
canvas.drawShape(shape, getTransform(), fillColor, outlineColor, thickness, alpha, depth);
}
}
package ch.epfl.cs107.play.engine.actor;
import ch.epfl.cs107.play.engine.actor.Acoustics;
import ch.epfl.cs107.play.window.Audio;
import ch.epfl.cs107.play.window.Sound;
public class SoundAcoustics implements Acoustics {
/// Image name
private final String name;
/// volume float value in percent : 0.0f no volume, 1.0f full volume
private final float volume;
/// Boolean flags : loop and stopOtherOnStart
private final boolean randomFirstStart, fadeIn, loop, stopOthersOnStart;
/// Should be played flag: set it true when you want to start the sound
/// - use shouldBeStarted() method
private boolean shouldBeStarted;
/**
* Default sound Acoustics constructor
* @param name (String): name of the sound without path and extension. May be bull
* @param volume (float): 0.0f no sound, 1.0f full audio
* @param fadeIn (boolean): indicate if the song fade in until reaching its max volume
* @param randomFirstStart (boolean): indicate if the first start is random in the sound
* @param loop (boolean): indicate if the sound must loop on self ending
* @param stopOthersOnStart (boolean): indicate if all other sound are stopped on given sound's start
*/
public SoundAcoustics(String name, float volume, boolean fadeIn, boolean randomFirstStart, boolean loop, boolean stopOthersOnStart) {
this.name = name;
this.volume = volume;
this.fadeIn = fadeIn;
this.randomFirstStart = randomFirstStart;
this.loop = loop;
this.stopOthersOnStart = stopOthersOnStart;
this.shouldBeStarted = false;
}
/**
* Alternative sound Acoustics constructor
* @param name (String): name of the sound without path and extension. May be null
*/
public SoundAcoustics(String name) {
this(name, 1.0f, false,false,false, false);
}
/** Set the "should be started" flag to true*/
public void shouldBeStarted(){
this.shouldBeStarted = true;
}
/// SoundAcoustics implements Acoustics
@Override
public void bip(Audio audio) {
if (shouldBeStarted && audio.isSoundSupported()) {
Sound sound = audio.getSound(name);
audio.playSound(sound, randomFirstStart, volume, fadeIn, loop, stopOthersOnStart);
shouldBeStarted = false;
}
}
/// SoundAcoustics propose static tool
/**
* Stop all sounds from given audio context by sending a null sound that stop others on starts
* @param audio (Audio): given audio context. Not null
*/
public static void stopAllSounds(Audio audio){
audio.playSound(null, false, 0.0f, false,false, true);
}
}
\ No newline at end of file
package ch.epfl.cs107.play.engine.actor;
import ch.epfl.cs107.play.io.ResourcePath;
import ch.epfl.cs107.play.math.Orientation;
import ch.epfl.cs107.play.math.Positionable;
import ch.epfl.cs107.play.math.RegionOfInterest;
import ch.epfl.cs107.play.math.Vector;
public class Sprite extends ImageGraphics {
/**
* Creates a new Sprite.
* @param name (String): image name, may be null
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param roi (RegionOfInterest): region of interest into the image as a rectangle in the image. May be null
* @param anchor (Vector): image anchor, not null
* @param alpha (float): transparency, between 0 (invisible) and 1 (opaque)
* @param depth (float): render priority, lower-values drawn first
*/
public Sprite(String name, float width, float height, Positionable parent, RegionOfInterest roi, Vector anchor, float alpha, float depth) {
super(ResourcePath.getSprite(name), width, height, roi, anchor, alpha, depth);
setParent(parent);
}
/**
* Creates a new image graphics.
* @param name (String): image name, not null
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param roi (RegionOfInterest): region of interest into the image as a rectangle in the image. May be null
* @param anchor (Vector): image anchor, not null
*/
public Sprite(String name, float width, float height, Positionable parent, RegionOfInterest roi, Vector anchor) {
super(ResourcePath.getSprite(name), width, height, roi, anchor, 1.0f, 0);
setParent(parent);
}
/**
* Creates a new image graphics.
* @param name (String): image name, not null
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param roi (RegionOfInterest): region of interest into the image as a rectangle in the image. May be null
*/
public Sprite(String name, float width, float height, Positionable parent, RegionOfInterest roi) {
super(ResourcePath.getSprite(name), width, height, roi, Vector.ZERO, 1.0f, 0);
setParent(parent);
}
/**
* Creates a new image graphics.
* @param name (String): image name, not null
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
*/
public Sprite(String name, float width, float height, Positionable parent) {
super(ResourcePath.getSprite(name), width, height, null, Vector.ZERO, 1.0f, 0);
setParent(parent);
}
//Utilities to extract sprites
/**
* Extracts from an image the sprites corresponding to a given orientation
* the returned array has 4 entry (one per orientation)
* the content of each entry is an array of sprites corresponding to the given orientation
* (the entry indexed by Orientation.dir.ordinal() is the array of sprites corresponding
* to the orientation Orientation.dir).
* @param name (String): the name of the image
* @param nbFrames (int): number of frames in each row
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param anchor (Vector) : image anchor, not null
* @param regionWidth (int): width of frame (number of pixels in the image)
* @param regionHeight (int): height of frame (number of pixels in the image)
* @param order (Orientation[]): order of the frames in the image
*
*
* @return an array of 4 Sprite[] (one Sprite[] per orientation)
*/
public static Sprite[][] extractSprites(String name, int nbFrames, float width, float height, Positionable parent, int regionWidth, int regionHeight, Vector anchor, Orientation[] order){
Sprite[][] sprites = new Sprite[4][nbFrames];
for(int i = 0; i < nbFrames; i++){
int j = 0;
sprites[order[0].ordinal()][i] = new Sprite(name, width, height, parent, new RegionOfInterest(i*regionWidth, regionHeight*j++, regionWidth, regionHeight), anchor);
sprites[order[1].ordinal()][i] = new Sprite(name, width, height, parent, new RegionOfInterest(i*regionWidth, regionHeight*j++, regionWidth, regionHeight), anchor);
sprites[order[2].ordinal()][i] = new Sprite(name, width, height, parent, new RegionOfInterest(i*regionWidth, regionHeight*j++, regionWidth, regionHeight), anchor);
sprites[order[3].ordinal()][i] = new Sprite(name, width, height, parent, new RegionOfInterest(i*regionWidth, regionHeight*j, regionWidth, regionHeight), anchor);
}
return sprites;
}
/**
* Extracts from an image the sprites corresponding to a given orientation
* the returned array has 4 entry (one per orientation)
* the content of each entry is an array of sprites corresponding to the given orientation
* (the entry indexed by Orientation.dir.ordinal() is the array of sprites corresponding
* to the orientation Orientation.dir).
* @param name (String): the name of the image
* @param nbFrames (int): number of frames in each row
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param regionWidth (int): width of frame (number of pixels in the image)
* @param regionHeight (int): height of frame (number of pixels in the image)
* @param order (Orientation[]): order of the frames in the image
*
*
* @return an array of 4 Sprite[] (one Sprite[] per orientation)
*/
public static Sprite[][] extractSprites(String name, int nbFrames, float width, float height, Positionable parent, int regionWidth, int regionHeight, Orientation[] order){
return extractSprites(name, nbFrames, width, height, parent, regionWidth, regionHeight, Vector.ZERO, order);
}
/**
* Extracts from an image the sprites
* @param name (String): the name of the image
* @param nbFrames (int): number of frames in each row
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param anchor (Vector) : image anchor, not null
* @param regionWidth (int): width of frame (number of pixels in the image)
* @param regionHeight (int): height of frame (number of pixels in the image)
*
*
* @return an array of Sprite
*/
public static Sprite[] extractSprites(String name, int nbFrames, float width, float height, Positionable parent, Vector anchor, int regionWidth, int regionHeight){
Sprite[] sprites = new Sprite[nbFrames];
for(int i = 0; i < nbFrames; i++){
sprites[i] = new Sprite(name, width, height, parent, new RegionOfInterest(i*regionWidth, 0, regionWidth, regionHeight), anchor);
}
return sprites;
}
/**
* Extracts from an image the sprites
* @param name (String): the name of the image
* @param nbFrames (int): number of frames in each row
* @param width (int): actual image width, before transformation
* @param height (int): actual image height, before transformation
* @param parent (Positionable): parent of this, not null
* @param regionWidth (int): width of frame (number of pixels in the image)
* @param regionHeight (int): height of frame (number of pixels in the image)
*
*
* @return an array of Sprite
*/
public static Sprite[] extractSprites(String name, int nbFrames, float width, float height, Positionable parent, int regionWidth, int regionHeight){
return extractSprites(name, nbFrames, width, height, parent, Vector.ZERO, regionWidth, regionHeight);
}
}
package ch.epfl.cs107.play.io;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.NoSuchFileException;
/**
* Empty implementation of file system.
*/
public enum DefaultFileSystem implements FileSystem {
INSTANCE;
@Override
public InputStream read(String name) throws IOException {
throw new NoSuchFileException(name);
}
@Override
public OutputStream write(String name) throws IOException {
throw new NoSuchFileException(name);
}
}