package edu.uwsp.cnmt110;
import java.awt.event.*;
import java.util.Timer;
import java.util.TimerTask;
/**
* A demo / sample game that shows the minimum methods necessary.
* DO NOT USE THIS IN YOUR GAME. IT IS SIMPLY PROVIDED AS AN EXAMPLE
*/
public class DemoGame extends Game {
private final int MAX_SPRITES = 500;
private Timer timer;
/**
* Creates an instance of the Game class.
*
* @param width The width of the window
* @param height The height of the window.
*/
public DemoGame(int width, int height) {
super("My Demo", width, height);
displayRandomMessages();
}
@Override
public void getInput(InputEvent[] events, long interval) {
// If user presses 'r', we'll clear all the sprites and start over.
for(InputEvent event: events) {
if (event instanceof KeyEvent) {
switch (((KeyEvent) event).getKeyChar()) {
case 'r':
clearSprites();
initialize();
displayRandomMessages();
break;
case ' ':
initialize();
break;
}
}
else if (event instanceof MouseEvent) {
//((MouseEvent) event).getX();
}
}
}
@Override
public boolean updatePosition(Sprite sprite, long interval) {
if (((sprite.getX() - sprite.getWidth() / 2) < 0) ||
((sprite.getX() + sprite.getWidth() / 2) > getWidth())) {
sprite.bounceX();
}
return false;
}
/**
* Displays random messages to the screen.
* Provides an example of how to use the setMessage() and clearMessage() methods.
*/
private void displayRandomMessages() {
if (timer != null) timer.cancel();
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
int countDown = 3;
@Override
public void run() {
String message = null;
switch(countDown) {
case 0:
message = "GO! GO! GO!";
break;
case 1:
message = "<space> for MORE!";
break;
case 2:
message = "<r> to RESTART!";
break;
case 3:
message = "Keyboard Controls";
break;
default:
timer.cancel();
}
if ((message == null) || (message.isEmpty())) {
clearMessage();
}
else {
setMessage(message);
}
countDown--;
}
}, 0, 1000);
}
@Override
public void initialize() {
// Randomly add sprites to the game / screen
for(int index = 0; index < MAX_SPRITES; index++) {
Sprite sprite = new RandomSprite(getWidth(), getHeight());
addSprite(sprite);
}
}
}
Assignment Code
package edu.uwsp.cnmt110;
import java.awt.*;
/**
* Represents a Sprite that knows how to draw itself to a graphics canvas.
*/
public class DrawableSprite extends Sprite implements IDrawable {
private Color color = Color.WHITE;
private Color textColor = Color.RED;
private String name;
/**
* Creates an instance of the DrawableSprite class.
* @param x The x coordinate in a 2d coordinate space where 0,0 is the upper left.
* @param y The y coordinate in a 2d coordinate space where 0,0 is the upper left.
* @param width The width of the Sprite
* @param height The height of the Sprite
* @param angle The angle along which the Sprite is traveling.
* @param speed The speed or distance moved per second.
*/
public DrawableSprite(int x, int y, int width, int height, float angle, int speed) {
super(x, y, width, height, angle, speed);
}
/**
* Creates an instance of the DrawableSprite class.
* @param sprite An instance of Sprite to wrap or clone.
*/
public DrawableSprite(Sprite sprite) {
this(sprite.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight(), sprite.getAngle(), sprite.getSpeed());
}
/**
* Overlays the specified label onto the sprite.
* @param g The graphics canvas to draw onto.
*/
protected void paintLabel(Graphics g) {
String name = getName();
if ((name != null) && (! name.isEmpty())) {
String label = Float.toString(getAngle());
Font font = new Font("serif", Font.PLAIN, 9);
g.setColor(getTextColor());
g.setFont(font);
FontMetrics metrics = g.getFontMetrics(font);
g.drawString(label, getX() - (metrics.stringWidth(label) / 2),
getY() + (metrics.getHeight() / 2));
}
}
/**
* Draws or renders the information.
* @param g The graphics / canvas to draw to.
*/
@Override
public void paint(Graphics g) {
Rectangle boundingRect = getBoundingRect();
g.setColor(getColor());
g.drawRect(boundingRect.getX1(), boundingRect.getY1(), boundingRect.getWidth(), boundingRect.getHeight());
paintLabel(g);
}
/**
* Retrieves the optional name / label associated with the sprite.
* @return The optional name / label
*/
public String getName() {
return name;
}
/**
* Sets the optional name / label associated with the sprite.
* @param name The optional name / label to set for the Sprite.
* @return The instance of the Sprite so that subsequent calls can be chained together.
*/
public Sprite setName(String name) {
this.name = name;
return(this);
}
/**
* Retrieves the color of the outline for the Sprite.
* @return The current color.
*/
public Color getColor() {
return color;
}
/**
* Sets the color to use for the outline.
* @param color The color of the outline.
* @return The instance of the Sprite so that subsequent calls can be chained together.
*/
public DrawableSprite setColor(Color color) {
this.color = color;
return(this);
}
/**
* Retrieves the color of the text or label for the Sprite.
* @return The current text or label color.
*/
public Color getTextColor() {
return textColor;
}
/**
* Sets the text color to use for the label.
* @param textColor The color of the text
* @return The instance of the Sprite so that subsequent calls can be chained together.
*/
public DrawableSprite setTextColor(Color textColor) {
this.textColor = textColor;
return(this);
}
}
Assignment Code
package edu.uwsp.cnmt110;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Represents a base Game class for implementation of a game with graphics content
* using the java Swing framework.
*/
public abstract class Game extends JFrame implements MouseListener, MouseMotionListener, KeyListener {
private final String MESSAGE_GAME_OVER = "GAME OVER";
private Random random;
private int width;
private int height;
private boolean isRunning = false;
private Screen screen;
private CopyOnWriteArrayList<Sprite> sprites;
private ConcurrentLinkedQueue<InputEvent> events;
private boolean gameover;
private String message;
/**
* Creates an instance of the Game class.
* @param title The title for the window
* @param width The width of the window
* @param height The height of the window.
*/
Game(String title, int width, int height) {
super(title);
this.width = width;
this.height = height;
this.screen = new Screen(this);
this.sprites = new CopyOnWriteArrayList<Sprite>();
this.events = new ConcurrentLinkedQueue<InputEvent>();
this.random = new Random();
getContentPane().add(screen);
setSize(width, height);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
// Register for mouse events
addMouseListener(this);
addMouseMotionListener(this);
// Register for keyboard events
addKeyListener(this);
initialize();
}
/**
* Releases memory and resources when object is being disposed.
*/
protected void finalize() {
removeMouseListener(this);
removeMouseMotionListener(this);
removeKeyListener(this);
}
/**
* Retrieves the user input including both mouse and keyboard.
* @param events The collection of events that have occurred since the last update. The most recent event is at the end of the array.
* @param interval The amount of time that has passed since the last update.
*/
public abstract void getInput(InputEvent[] events, long interval);
/**
* Updates the sprite position based on it's speed.
* @param sprite The sprite who's position needs to be updated.
* @param interval The amount of time that has passed since the last update.
* @return True if the position update was handled by the code. If false, the the sprites move operation is called to automatically update it's position.
*/
public abstract boolean updatePosition(Sprite sprite, long interval);
/**
* Initializes the game sprites and configures the play area.
*/
public abstract void initialize();
/**
* Retrieve a shared / common random generator.
* @return The Random instance.
*/
protected Random getRandom() {
return random;
}
/**
* The actual game / screen.
*/
class Screen extends JPanel {
long frames = 0;
final long started = System.currentTimeMillis();
long lastUpdate = 0;
private Game game;
/**
* Creates an instance of the Screen class.
* @param game The parent game that owns this screen
*/
Screen(Game game) {
this.game = game;
}
/**
* Displays / draws the FPS to the lower corner of the screen.
* @param g The graphics / canvas to draw or paint on.
* @param now The current date/time to use for calculation.
*/
private void overlayStatistics(Graphics g, long now) {
g.setColor(Color.LIGHT_GRAY);
Font font = new Font("dialog", Font.PLAIN, 12);
g.setFont(font);
FontMetrics metrics = g.getFontMetrics(font);
g.drawString(String.format("Statistics: (interval %dms, frames: %d, sprites: %d)",
now - lastUpdate, frames, getSprites().length),
5, getHeight() - metrics.getHeight() / 2);
}
/**
* Displays or overlays the specified message to the center of the screen.
* @param message The message to display.
* @param g The graphics / canvas to draw to.
*/
protected void overlayMessage(Graphics g, String message) {
g.setColor(Color.ORANGE);
Font font = new Font("helvetica", Font.PLAIN | Font.BOLD, 72);
g.setFont(font);
FontMetrics metrics = g.getFontMetrics(font);
int width = metrics.stringWidth(message);
g.drawString(message, getWidth() / 2 - width / 2,
getHeight() / 2);
}
/**
* Draws or renders the information.
* @param g The graphics / canvas to draw to.
*/
@Override
public void paint(Graphics g) {
long now = new Date().getTime();
frames++;
g.setColor(Color.BLACK);
g.fillRect(0, 0, width, height);
for(Sprite sprite: getSprites()) {
if (sprite instanceof IDrawable) {
((IDrawable) sprite).paint(g);
}
}
overlayStatistics(g, now);
if ((message != null) && (! message.isEmpty())) {
overlayMessage(g, message);
}
lastUpdate = now;
}
}
/**
* Indicates if gameplay has ended.
* @return True if ended, false if otherwise.
*/
protected boolean isGameover() {
return(gameover);
}
/**
* Sets / changes the gameover value.
* @param gameover The value to set. Tre if game is ended.
* @return The instance of Game so that subsequent calls can be chained together.
*/
protected Game setGameover(boolean gameover) {
this.gameover = gameover;
message = (gameover) ? MESSAGE_GAME_OVER : null;
return(this);
}
/**
* Sets the message to overlay or display to the screen.
* @param message The message to display.
* @return The instance of Game so that subsequent calls can be chained together.
*/
protected Game setMessage(String message) {
this.message = message;
return(this);
}
/**
* Clears the message
* @return The instance of Game so that subsequent calls can be chained together.
*/
protected Game clearMessage() {
message = null;
return(this);
}
/**
* Retrieves all of the sprites currently in the game.
* @return The enumeration of sprites.
*/
protected Sprite[] getSprites() {
return(sprites.toArray(new Sprite[0]));
}
/**
* Adds the specified Sprite into the existing list of sprites.
* @param sprite The sprite to add.
* @return The instance of Game so that subsequent calls can be chained together.
*/
protected Game addSprite(Sprite sprite) {
if (sprite != null) {
sprites.add(sprite);
}
return(this);
}
/**
* Adds the specified Sprite into the existing list of sprites.
* @param sprite The sprite to add.
* @return True if the specified Sprite was removed, false if otherwise.
*/
protected boolean removeSprite(Sprite sprite) {
if (sprite != null) {
return(sprites.remove(sprite));
}
return(false);
}
/**
* Removes all sprites.
* @return The instance of Game so that subsequent calls can be chained together.
*/
protected Game clearSprites() {
for(Sprite sprite: getSprites()) {
removeSprite(sprite);
}
return(this);
}
/**
* Updates all of the positions for each sprite registered on the game board.
* @param interval The amount of time that has passed since the last update.
*/
private void updatePositions(long interval) {
for(Sprite sprite: sprites) {
if (! updatePosition(sprite, interval)) {
sprite.move(interval);
}
}
}
/**
* Starts the execution of the game. This is a blocking call.
*/
public void start() {
if (! isRunning) {
isRunning = true;
long started = System.currentTimeMillis();
long last = started;
while(isRunning) {
long now = System.currentTimeMillis();
try {
long interval = now - last;
// Get input from user
InputEvent[] pendingEvents = new InputEvent[events.size()];
for(int index = 0; index < pendingEvents.length; index++) {
pendingEvents[index] = events.poll();
}
getInput(pendingEvents, interval);
// Calculate updated sprite positions
updatePositions(interval);
// Redraw screen
repaint();
// To avoid 100% CPU utilization, sleep / wait for at least 1ms
Thread.sleep(1);
last = now;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* Stops the execution of the game.
*/
public void stop() {
isRunning = false;
}
/**
* Invoked when the mouse button has been clicked (pressed and released) on a component.
* @param mouseEvent An event which indicates that a mouse action occurred in a component.
*/
@Override
public void mouseClicked(MouseEvent mouseEvent) {
events.add(mouseEvent);
}
/**
* Invoked when a mouse button has been pressed on a component.
* @param mouseEvent An event which indicates that a mouse action occurred in a component.
*/
@Override
public void mousePressed(MouseEvent mouseEvent) {
}
/**
* Invoked when a mouse button has been released on a component.
* @param mouseEvent An event which indicates that a mouse action occurred in a component.
*/
@Override
public void mouseReleased(MouseEvent mouseEvent) {
}
/**
* Invoked when the mouse enters a component.
* @param mouseEvent An event which indicates that a mouse action occurred in a component.
*/
@Override
public void mouseEntered(MouseEvent mouseEvent) {
}
/**
* Invoked when the mouse exits a component.
* @param mouseEvent An event which indicates that a mouse action occurred in a component.
*/
@Override
public void mouseExited(MouseEvent mouseEvent) {
}
/**
* Invoked when a mouse button is pressed on a component and then dragged.
* @param mouseEvent An event which indicates that a mouse action occurred in a component.
*/
@Override
public void mouseDragged(MouseEvent mouseEvent) {
}
/**
* Invoked when the mouse cursor has been moved onto a component but no buttons have been pushed.
* @param mouseEvent An event which indicates that a mouse action occurred in a component.
*/
@Override
public void mouseMoved(MouseEvent mouseEvent) {
events.add(mouseEvent);
}
/**
* Invoked when a key has been typed.
* @param keyEvent An event which indicates that a keystroke occurred in a component.
*/
@Override
public void keyTyped(KeyEvent keyEvent) {
events.add(keyEvent);
}
/**
* Invoked when a key has been pressed.
* @param keyEvent An event which indicates that a keystroke occurred in a component.
*/
@Override
public void keyPressed(KeyEvent keyEvent) {
}
/**
* Invoked when a key has been released.
* @param keyEvent An event which indicates that a keystroke occurred in a component.
*/
@Override
public void keyReleased(KeyEvent keyEvent) {
}
}
Assignment Code
package edu.uwsp.cnmt110;
import java.awt.*;
/**
* Represents an object that can be drawn to a Graphics canvas.
*/
public interface IDrawable {
/**
* Draws the specified item to the Graphics canvas.
* @param g The canvas to draw on.
*/
void paint(Graphics g);
}
Assignment Code
package edu.uwsp.cnmt110;
public class Main {
public static void main(String[] args) {
Game game = new DemoGame(800,600);
game.start();
}
}
Assignment Code
package edu.uwsp.cnmt110;
/**
* Represents a coordinate in a 2D space with an X and Y axis.
*/
public class Point {
private int x;
private int y;
/**
* Creates an instance of the Point class.
* @param x The location on the horizontal axis
* @param y The location on the vertical axis
*/
public Point(int x, int y) {
this.set(x, y);
}
/**
* Creates an instance of the Point class.
* @param point The existing point to use or copy from.
*/
public Point(Point point) {
this(point.getX(), point.getY());
}
/**
* Creates a copy or shallow clone of the object.
* @return A Point
*/
public Point clone() {
return(new Point(getX(), getY()));
}
/**
* Returns the string representation of the Point instance.
* @return The string representation describing the Point.
*/
@Override
public String toString() {
return(String.format("(x:%d,y:%d)", getX(), getY()));
}
/**
* Sets the x and y position for the location.
* @param x The location on the horizontal axis
* @param y The location on the vertical axis
*/
public void set(int x, int y) {
this.x = x;
this.y = y;
}
/**
* Sets the x and y position for the location.
* @param point The point containing the x & y location to set.
*/
public void set(Point point) {
this.set(point.getX(), point.getY());
}
/**
* Retrieves the value for the horizontal axis.
* @return The position on the horizontal axis.
*/
public int getX() {
return x;
}
/**
* Sets or changes the value of the horizontal axis.
* @param x The location on the horizontal axis
* @return The instance of Point so calls can be chained together in succession.
*/
public Point setX(int x) {
this.x = x;
return(this);
}
/**
* Retrieves the value for the vertical axis.
* @return The position on the vertical axis.
*/
public int getY() {
return y;
}
/**
* Sets or changes the value of the vertical axis.
* @param y The location on the vertical axis
* @return The instance of Point so calls can be chained together in succession.
*/
public Point setY(int y) {
this.y = y;
return(this);
}
/**
* Checks for equality of the Point instance with the specified x & y coordinate values.
* @param x The location to compare on the horizontal axis.
* @param y The location to compare on the vertical axis.
* @return True if the coordinates are equal, false if otherwise.
*/
public boolean equals(int x, int y) {
return((getX() == x) &&
(getY() == y));
}
/**
* Checks for equality of the Point instance with the specified x & y coordinate values.
* @param point The location to compare.
* @return True if the coordinates are equal, false if otherwise.
*/
public boolean equals(Point point) {
return(equals(point.getX(), point.getY()));
}
}
Assignment Code
package edu.uwsp.cnmt110;
import java.awt.*;
import java.util.Random;
/**
* Represents a sprite with randomly generated attributes.
* DO NOT USE THIS IN YOUR GAME. IT IS SIMPLY PROVIDED AS AN EXAMPLE
*/
public class RandomSprite extends DrawableSprite {
private final static int MIN_SPRITE_HEIGHT = 5;
private final static int MAX_SPRITE_HEIGHT = 25;
private final static int MIN_SPRITE_WIDTH = 5;
private final static int MAX_SPRITE_WIDTH = 25;
private final static int MIN_SPRITE_SPEED = 2;
private final static int MAX_SPRITE_SPEED = 12;
private static Random random = new Random();
/**
* Creates an instance of a RandomSprite class.
* @param screenWidth The maximum width of the screen.
* @param screenHeight The maximum height of the screen.
*/
public RandomSprite(int screenWidth, int screenHeight) {
super(getRandom().nextInt(screenWidth), getRandom().nextInt(screenHeight),
getRandomWidth(), getRandomHeight(),
getRandom().nextInt(360), getRandomSpeed());
setColor(getRandomColor());
}
/**
* Retrieves a shared Random helper to ensure true randomness.
* @return The configured / shared Random instance.
*/
private static Random getRandom() {
return random;
}
/**
* Generates a random Color
* @return A random color.
*/
private Color getRandomColor() {
return(new Color(getRandom().nextInt(255),
getRandom().nextInt(255),
getRandom().nextInt(255)));
}
/**
* Generates a random number within the specified range.
* @param minimum The minimum value inclusive.
* @param maximum The maximum value inclusive.
* @return The random number.
*/
private static int getRandomValue(int minimum, int maximum) {
int value;
do {
value = getRandom().nextInt(maximum);
} while (value < minimum);
return(value);
}
/**
* Generates a random width of the sprite.
* @return A random width.
*/
private static int getRandomWidth() {
return(getRandomValue(MIN_SPRITE_WIDTH, MAX_SPRITE_WIDTH));
}
/**
* Generates a random height of the sprite.
* @return A random height.
*/
private static int getRandomHeight() {
return(getRandomValue(MIN_SPRITE_HEIGHT, MAX_SPRITE_HEIGHT));
}
/**
* Generates a random speed or distance moved for the sprite.
* @return A random speed.
*/
private static int getRandomSpeed() {
return(getRandomValue(MIN_SPRITE_SPEED, MAX_SPRITE_SPEED));
}
}
Assignment Code
package edu.uwsp.cnmt110;
/**
* Represents a shape containing a height and width
* and four right angles in a 2D coordinate space.
*/
public class Rectangle {
private Point x1y1;
private Point x2y2;
/**
* Creates an instance of the Rectangle class.
* @param x1y1 The upper left point or 2D coordinate for the rectangle.
* @param width The widtt or distance along the X axis
* @param height The height or distance along the Y axis.
*/
public Rectangle(Point x1y1, int width, int height) {
this.x1y1 = x1y1.clone();
this.x2y2 = new Point(x1y1.getX() + width, x1y1.getY() + height);
}
/**
* Creates an instance of the Rectangle class.
* @param x1y1 The upper left point or 2D coordinate position.
* @param x2y2 The lower right point or 2D coordinate position.
*/
public Rectangle(Point x1y1, Point x2y2) {
this.x1y1 = x1y1.clone();
this.x2y2 = x2y2.clone();
}
/**
* Retrieves the upper left corner 2D coordinate position.
* @return The upper left corner.
*/
public Point getX1Y1() {
return(this.x1y1.clone());
}
/**
* Retrieves the lower right corner 2D coordinate position.
* @return The lower right corner.
*/
public Point getX2Y2() {
return(this.x2y2.clone());
}
/**
* Retrieves the horizontal 2D coordinate value from the upper left corner.
* @return The horizontal 2D coordinate from the upper left corner.
*/
public int getX1() {
return(this.getX1Y1().getX());
}
/**
* Retrieves the horizontal 2D coordinate value from the lower right corner.
* @return The horizontal 2D coordinate from the lower right corner.
*/
public int getX2() {
return(this.getX2Y2().getX());
}
/**
* Retrieves the vertical 2D coordinate value from the upper left corner.
* @return The vertical 2D coordinate from the upper left corner.
*/
public int getY1() {
return(this.getX1Y1().getY());
}
/**
* Retrieves the vertical 2D coordinate value from the lower right corner.
* @return The vertical 2D coordinate from the lower right corner.
*/
public int getY2() {
return(this.getX2Y2().getY());
}
/**
* Retrieves the height or distance on the Y access between the top left and lower right corner values.
* @return The height
*/
public int getHeight() {
return (Math.abs(this.getX1Y1().getY() - this.getX2Y2().getY()));
}
/**
* Retrieves the width or distance on the X access between the top left and lower right corner values.
* @return The height
*/
public int getWidth() {
return (Math.abs(this.getX1Y1().getX() - this.getX2Y2().getX()));
}
/**
* Checks for equality of another Rectangle instance.
* @param rectangle The other Rectangle instance to compare.
* @return True if equal, false if otherwise.
*/
public boolean equals(Rectangle rectangle) {
if (rectangle == null) return(false);
return(this.getX1Y1().equals(rectangle.getX1Y1()) &&
this.getX2Y2().equals(rectangle.getX2Y2()));
}
/**
* Returns the default string representation of the Rectangle.
* @return The default string representation.
*/
public String toString() {
return(String.format("[x1y1:%s,x2y2:%s]@%dx%d",
this.getX1Y1().toString(), this.getX2Y2().toString(),
getWidth(), getHeight()));
}
/**
* Makes a shallow clone of copy
* @return A new instance of Rectangle.
*/
public Rectangle clone() {
return(new Rectangle(this.getX1Y1(), this.getX2Y2()));
}
/**
* Checks to see if the specified instance of Rectangle intersect or overlap
* with each other.
* @param rectangle
* @return Tue if they intesect, false if otherwise.
*/
public boolean intersectsWith(Rectangle rectangle) {
int left = Math.max(getX1(), rectangle.getX1());
int right = Math.min(getX2(), rectangle.getX2());
int top = Math.max(getY1(), rectangle.getY1());
int bottom = Math.min(getY2(), rectangle.getY2());
return((left < right) && (bottom > top));
}
}
Assignment Code
package edu.uwsp.cnmt110;
/**
* Represents a sprite for a game.
*/
public abstract class Sprite {
private int directionX = 1;
private int directionY = 1;
private float x;
private float y;
private int width;
private int height;
private float angle;
private int speed;
/**
* Creates an instance of the Sprite class.
* @param x The center position on the horizontal axis.
* @param y The center position on the vertical axis.
* @param width The width of the sprite.
* @param height The height of the sprite.
*/
protected Sprite(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
/**
* Creates an instance of the Sprite class.
* @param location The center position (x & y)
* @param width The width of the sprite.
* @param height The height of the sprite.
*/
protected Sprite(Point location, int width, int height) {
this(location.getX(), location.getY(), width, height);
}
/**
* Creates an instance of the Sprite class.
* @param x The center position on the horizontal axis.
* @param y The center position on the vertical axis.
* @param width The width of the sprite.
* @param height The height of the sprite.
* @param angle The angle or direction that the sprite is moving.
* @param speed The distance that the sprite moves along the specified angle per second.
*/
protected Sprite(int x, int y, int width, int height, float angle, int speed) {
this(new Point(x, y), width, height, angle, speed);
}
/**
* Creates an instance of the Sprite class.
* @param location The center position (x & y)
* @param width The width of the sprite.
* @param height The height of the sprite.
* @param angle The angle or direction that the sprite is moving.
* @param speed The distance that the sprite moves along the specified angle per second.
*/
protected Sprite(Point location, int width, int height, float angle, int speed) {
this(location, width, height);
this.setAngle(angle);
this.speed = speed;
}
/**
* Returns the string representation of the Sprite.
* @return The string representation.
*/
public String toString() {
return(String.format("Sprite[center:%s,size:%dx%d,angle:%.1f,speed:%d)]",
getPosition().toString(), getWidth(), getHeight(), getAngle(), getSpeed()));
}
/**
* Returns the width of the Sprite.
* @return The width in pixels.
*/
public int getWidth() {
return width;
}
/**
* Returns the height of the Sprite.
* @return The height in pixels.
*/
public int getHeight() {
return height;
}
/**
* Returns the angle or direction that the sprite is traveling in a 2D coordinate space.
* @return The angle between 0-359.
*/
public float getAngle() {
return angle;
}
/**
* Sets or changes the angle / direction of the sprite.
* @param angle The angle to set. Accepted values are between 0-359.
* @return The instance of Sprite so subsequent methods can be chained together.
*/
public Sprite setAngle(float angle) {
this.angle = (angle >= 360) ? angle % 360 : angle;
return(this);
}
/**
* Retrieves the current speed or distance that the sprite moves per second.
* @return The speed or distance of the sprite.
*/
public int getSpeed() {
return speed;
}
/**
* Sets or changes the speed or distance the sprite moves per second.
* @param speed The speed or number of pixels moved per second.
* @return The instance of Sprite so subsequent methods can be chained together.
*/
public Sprite setSpeed(int speed) {
this.speed = speed;
return(this);
}
/**
* Returns the center point for the Sprite.
* @return The center point.
*/
public Point getPosition() {
return(new Point(getX(), getY()));
}
/**
* Moves or repositions the sprite to the specified location.
* @param x The new position on the horizontal axis.
* @param y The new position on the veritical axis.
* @return The instance of Sprite so subsequent methods can be chained together.
*/
public Sprite moveTo(int x, int y) {
this.x = x;
this.y = y;
return(this);
}
/**
* Moves or repositions the sprite to the specified location.
* @param point The new location to move to.
* @return The instance of Sprite so subsequent methods can be chained together.
*/
public Sprite moveTo(Point point) {
return(moveTo(point.getX(), point.getY()));
}
/**
* Performs a automatic move or recalculation of the Sprites position based on it's speed and angle.
* @param timeInterval The amount of time in milliseconds that has passed since the last update interval.
* @return The new location of the Sprite.
*/
public Point move(long timeInterval) {
if (timeInterval > 0) {
float distance = getSpeed() / ((float) timeInterval / (60.0f / 1000.0f));
float radianAngle = (float) (getAngle() * Math.PI/180f);
float distanceX = (float) Math.cos(radianAngle) * distance;
float distanceY = (float) Math.sin(radianAngle) * distance;
this.x += (distanceX * directionX);
this.y += (distanceY * directionY);
}
return(new Point(getX(), getY()));
}
/**
* Returns the bounding rectangle that encompasses or outlines the sprite.
* @return The bounding rectangle.
*/
public Rectangle getBoundingRect() {
Point position = getPosition();
return(new Rectangle(new Point(position.getX() - (getWidth() / 2),
position.getY() - (getHeight() /2 )),
getWidth(), getHeight()));
}
/**
* Checks to see if the sprite is colliding or intersecting with the specified sprite.
* @param sprite The sprite to check
* @return True if colliding, false if otherwise.
*/
public boolean collidesWith(Sprite sprite) {
return(this.getBoundingRect().intersectsWith(sprite.getBoundingRect()));
}
/**
* Returns the sprites center location on the horizontal axis.
* @return The position on the x axis.
*/
public int getX() {
return Math.round(this.x);
}
/**
* Returns the sprites center location on the vertical axis.
* @return The position on the y axis.
*/
public int getY() {
return Math.round(this.y);
}
/**
* Changes the direction of the Sprite on the X axis. A simple implementation
* of a reflection or bounce.
* @return The instance of Sprite so subsequent methods can be chained together.
*/
public Sprite bounceX() {
this.directionX *= -1;
return(this);
}
/**
* Changes the direction of the Sprite on the y axis. A simple implementation
* of a reflection or bounce.
* @return The instance of Sprite so subsequent methods can be chained together.
*/
public Sprite bounceY() {
this.directionY *= -1;
return(this);
}
}
Frequently Asked Questions
Is it free to get my assignment evaluated?
Yes. No hidden fees. You pay for the solution only, and all the explanations about how to run it are included in the price. It takes up to 24 hours to get a quote from an expert. In some cases, we can help you faster if an expert is available, but you should always order in advance to avoid the risks. You can place a new order here.
How much does it cost?
The cost depends on many factors: how far away the deadline is, how hard/big the task is, if it is code only or a report, etc. We try to give rough estimates here, but it is just for orientation (in USD):
Regular homework
$20 - $150
Advanced homework
$100 - $300
Group project or a report
$200 - $500
Mid-term or final project
$200 - $800
Live exam help
$100 - $300
Full thesis
$1000 - $3000
How do I pay?
Credit card or PayPal. You don't need to create/have a Payal account in order to pay by a credit card. Paypal offers you "buyer's protection" in case of any issues.
Why do I need to pay in advance?
We have no way to request money after we send you the solution. PayPal works as a middleman, which protects you in case of any disputes, so you should feel safe paying using PayPal.
Do you do essays?
No, unless it is a data analysis essay or report. This is because essays are very personal and it is easy to see when they are written by another person. This is not the case with math and programming.
Why there are no discounts?
It is because we don't want to lie - in such services no discount can be set in advance because we set the price knowing that there is a discount. For example, if we wanted to ask for $100, we could tell that the price is $200 and because you are special, we can do a 50% discount. It is the way all scam websites operate. We set honest prices instead, so there is no need for fake discounts.
Do you do live tutoring?
No, it is simply not how we operate. How often do you meet a great programmer who is also a great speaker? Rarely. It is why we encourage our experts to write down explanations instead of having a live call. It is often enough to get you started - analyzing and running the solutions is a big part of learning.
What happens if I am not satisfied with the solution?
Another expert will review the task, and if your claim is reasonable - we refund the payment and often block the freelancer from our platform. Because we are so harsh with our experts - the ones working with us are very trustworthy to deliver high-quality assignment solutions on time.