diff --git a/src/HighScore.txt b/src/HighScore.txt index 2e66562e2705f8e5c5ddccceeecaab861194f30a..147ea53ba1b4b991eb9a128a1231e006722485a3 100644 --- a/src/HighScore.txt +++ b/src/HighScore.txt @@ -1 +1 @@ -49 \ No newline at end of file +158 \ No newline at end of file diff --git a/src/Images1/8ball.png b/src/Images1/8ball.png new file mode 100644 index 0000000000000000000000000000000000000000..86a16f6f593a3626a93b5f8d1e63cee76cf5f2c7 Binary files /dev/null and b/src/Images1/8ball.png differ diff --git a/src/Images1/bomb.png b/src/Images1/bomb.png new file mode 100644 index 0000000000000000000000000000000000000000..d9092e2c0b401a319d2d7775e2bc903b9920ce9a Binary files /dev/null and b/src/Images1/bomb.png differ diff --git a/src/Images1/car.png b/src/Images1/car.png deleted file mode 100644 index 43926969c2db7ec7b03645d3b89ca2318b8ae74a..0000000000000000000000000000000000000000 Binary files a/src/Images1/car.png and /dev/null differ diff --git a/src/Images1/cloud.png b/src/Images1/cloud.png deleted file mode 100644 index 90825a3777dac7549459dc94b2f5fa973657490d..0000000000000000000000000000000000000000 Binary files a/src/Images1/cloud.png and /dev/null differ diff --git a/src/Images1/dinosaur.png b/src/Images1/dinosaur.png deleted file mode 100644 index c8ca237211f03535801067d4b638c1cb2babd6bb..0000000000000000000000000000000000000000 Binary files a/src/Images1/dinosaur.png and /dev/null differ diff --git a/src/Images1/fire_engine.png b/src/Images1/fire_engine.png new file mode 100644 index 0000000000000000000000000000000000000000..0fc5d9fd1edb2d256849a3f11c98b73a393d9421 Binary files /dev/null and b/src/Images1/fire_engine.png differ diff --git a/src/Images1/fly.png b/src/Images1/fly.png deleted file mode 100644 index d967e9553eb7379d5076ae3fc21cf1ca9d2e9bba..0000000000000000000000000000000000000000 Binary files a/src/Images1/fly.png and /dev/null differ diff --git a/src/Images1/h-banana.png b/src/Images1/h-banana.png deleted file mode 100644 index 55598ff54c3c757aec322dffcc0ecb1b477c0dc4..0000000000000000000000000000000000000000 Binary files a/src/Images1/h-banana.png and /dev/null differ diff --git a/src/Images1/heart.png b/src/Images1/heart.png deleted file mode 100644 index 417d80ac9510e8e089b02b121f6bf792f47766f4..0000000000000000000000000000000000000000 Binary files a/src/Images1/heart.png and /dev/null differ diff --git a/src/Images1/helicopter.png b/src/Images1/helicopter.png new file mode 100644 index 0000000000000000000000000000000000000000..2da3f0284df9edac0f115da382168149a3d9a4c5 Binary files /dev/null and b/src/Images1/helicopter.png differ diff --git a/src/Images1/player2_sliding.png b/src/Images1/player2_sliding.png deleted file mode 100644 index f87ac1d9abc8b7348ea582dbc05a762f9d26c34c..0000000000000000000000000000000000000000 Binary files a/src/Images1/player2_sliding.png and /dev/null differ diff --git a/src/Images1/player_sliding.png b/src/Images1/player_sliding.png deleted file mode 100644 index 57476f650e1d481d0c83eee28e6fbb8a315e73f0..0000000000000000000000000000000000000000 Binary files a/src/Images1/player_sliding.png and /dev/null differ diff --git a/src/Images1/runner.png b/src/Images1/runner.png deleted file mode 100644 index 04660d17d9d980bd6c8c4e7a7ecf5156ecbed4e1..0000000000000000000000000000000000000000 Binary files a/src/Images1/runner.png and /dev/null differ diff --git a/src/Images1/smiley.png b/src/Images1/smiley.png deleted file mode 100644 index 78d8e15103c52e570431aaf4a81091a81c439584..0000000000000000000000000000000000000000 Binary files a/src/Images1/smiley.png and /dev/null differ diff --git a/src/Images1/tree.png b/src/Images1/tree.png deleted file mode 100644 index f92878e3f692fac8f738d3b6c63d81844fde9db4..0000000000000000000000000000000000000000 Binary files a/src/Images1/tree.png and /dev/null differ diff --git a/src/Images1/woman-running.png b/src/Images1/woman-running.png deleted file mode 100644 index 84cfab13a42b0d01201adb9af05da4888614fe99..0000000000000000000000000000000000000000 Binary files a/src/Images1/woman-running.png and /dev/null differ diff --git a/src/constants/Constants.java b/src/constants/Constants.java index fb1a9138a056f47d089badd63643a6ef0f70abc0..1182b0f15143a5091031846a8aa47dc67d03c9b1 100644 --- a/src/constants/Constants.java +++ b/src/constants/Constants.java @@ -1,26 +1,11 @@ package constants; -import java.io.FileInputStream; -import java.io.FileNotFoundException; - -import javafx.scene.image.Image; - +/** + * @author oscarwiberg, filipyhde + * Definerar globala konstanter som vi använder återkommande i andra klasser. + */ public interface Constants { - /** - * In this file we define some global constants. - * - * An interface is one way to store variables that are truly constants and not - * subject to change during run time. - * - * Please note that the problem with global variables is that anyone can change - * them whenever. This makes it extremely hard to reason about your code. But - * for constants, this is not a problem since we cannot change them, and - * therefore they stay the same during the entire execution of the program. - */ - /* - * Define the size of the window - */ final int screenWidth = 1000; final int screenHeight = 500; @@ -40,12 +25,21 @@ public interface Constants { //enemies String enemyImg = "src/Images1/lorry.png"; + String enemyImg2 = "src/Images1/fire_engine.png"; String flyingEnemyImg = "src/Images1/saucer.png"; - double enemyWidth = 100; - double enemyHeight = 100; + String flyingEnemyImg2 = "src/Images1/helicopter.png"; + String bombImg = "src/Images1/bomb.png"; + String bombImg2 = "src/Images1/8ball.png"; + double bombWidth = 50; + double bombHeight = 50; + double enemyWidth = 80; + double enemyHeight = 80; // powerups - String lifeImg = "src/Images1/heart2.png"; - String powerImge = "src/Images1/blixt.png"; + String lifeImg = "src/Images1/apple.png"; + String powerImg = "src/Images1/zap.png"; + double powerWidth = 40; + double powerHeight = 40; + } diff --git a/src/main/GameFrame.java b/src/main/GameFrame.java index cd07d05fb3efd6106a6502c7f2d0e42d8793d92b..714617d10cd73e03e577e1b6aa692debf90fa257 100644 --- a/src/main/GameFrame.java +++ b/src/main/GameFrame.java @@ -1,16 +1,15 @@ package main; import javafx.scene.layout.HBox; -import javafx.scene.layout.VBox; import states.GameModel; /** + * @author oscarwiberg, filipyhde * This class Wraps a HBox: A HBox is a second level JavaFX container used * organize contents in the window (Stage/Scene). * * The GameFrame, in this case, has the job of creating the game panel, and * adding it to itself in order for it to show. - * */ public class GameFrame extends HBox { private GamePanel g; diff --git a/src/main/GamePanel.java b/src/main/GamePanel.java index b966fd014f457b5dfa1aa8d518fa290d6f1e4369..008711c4763dd88f60786d02509f727057a22c85 100644 --- a/src/main/GamePanel.java +++ b/src/main/GamePanel.java @@ -1,10 +1,10 @@ package main; import states.GameModel; - import javafx.scene.canvas.Canvas; /** + * @author oscarwiberg, filipyhde * The GamePanel wraps a Canvas * * The main responsibilities of the GamePanel are: diff --git a/src/main/Main.java b/src/main/Main.java index 07ed30ea344cd456d3c4fe6d94c87442cc4a46d0..bdf7150c8be3bc60a5557ffbad2ed422932898fd 100644 --- a/src/main/Main.java +++ b/src/main/Main.java @@ -1,16 +1,13 @@ package main; import states.GameModel; - import constants.Constants; - import javafx.animation.AnimationTimer; import javafx.application.Application; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.input.KeyEvent; import javafx.stage.Stage; -//FFfffffffff /** * This Class is the entry point of the application. * <p> @@ -33,11 +30,6 @@ import javafx.stage.Stage; * @author magni54, alomi60 */ public class Main extends Application { - - private GameModel model; - private Scene gameScene; - private GameFrame frame; - public static void main(String[] args) { launch(args); diff --git a/src/states/Antagonist.java b/src/states/Antagonist.java deleted file mode 100644 index f93d6a72764dd90a54f25c8f54b6240957410b7d..0000000000000000000000000000000000000000 --- a/src/states/Antagonist.java +++ /dev/null @@ -1,59 +0,0 @@ -package states; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; - -import javafx.scene.image.Image; - -public abstract class Antagonist { - - protected double x; - protected double y; - protected Image img; - protected boolean collisionDetected; - - - public Antagonist(String image, double x, double y) { - this.x = x; - this.y = y; - this.collisionDetected = false; - - try { - this.img = new Image(new FileInputStream(image)); - - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - public Antagonist(String image) { - this.collisionDetected = false; - - try { - this.img = new Image(new FileInputStream(image)); - - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - public abstract boolean playerAntagonistCollision(Player player); - - public void setAntagonistX(double pos) { - this.x = pos; - } - - public double getX() { - return x; - } - - public abstract double getY(); - - - public Image getImage() { - return img; - } - -} diff --git a/src/states/Enemy.java b/src/states/Enemy.java index 40c763ca93e9115288ed2a54e445900b51db97d0..c90c308b2a136b0971d10d9e8db93cb13ab8fe71 100644 --- a/src/states/Enemy.java +++ b/src/states/Enemy.java @@ -1,60 +1,22 @@ package states; -import java.io.FileInputStream; +/** + * @author oscarwiberg, filipyhde + * Enemy(groundenemy), gör inte så mycket unikt och använder mest den fördefinierade funktionaliteten som finns objekt classen + * Bomben som flyingenemy är en instan av enemy. + */ +public class Enemy extends Object{ -import java.io.FileNotFoundException; - -import constants.Constants; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; - -public class Enemy extends Antagonist{ - - private double enemyX = -100.00; - private double enemyY = 250.00; - private Image image; - private ImageView enemyView; + - public Enemy(String enemyImg, double x, double y) { - super(enemyImg, x, y); + public Enemy(String enemyImg, double x, double y, double h, double w) { + super(enemyImg, x, y, h, w); } - // if (collided && enemy.getEnemyX() < player.getPlayerX()) { - // collided = false; - // } - - @Override - public boolean playerAntagonistCollision(Player player) { -// boolean hit = false; - - boolean collisionX = player.getPlayerX() < (x + 60.00) && (player.getPlayerX() + 60.00) > x; - - // Check for collision on the y-axis - boolean collisionY = player.getPlayerY() < (y + 45.00) && (player.getPlayerY() + 60.00) > y; - - if (collisionY && collisionX && !collisionDetected) { - player.decreaseLives(); - - collisionDetected = true; - return true; - } - - if (!collisionX) { - collisionDetected = false; - } - - return false; - } - - - @Override - public double getY() { - return y; - } diff --git a/src/states/ExtraLifePowerUp.java b/src/states/ExtraLifePowerUp.java index 01641cf31eea0d1689eed087d03b4f39c3229a2f..094b3177726aa213b71d89da946f4619fab74a86 100644 --- a/src/states/ExtraLifePowerUp.java +++ b/src/states/ExtraLifePowerUp.java @@ -1,16 +1,26 @@ package states; +/** + * @author oscarwiberg, filipyhde + * Usefunktionen är abstract eftersom powerupsen ger olika fördelar, denna återställer spelarens liv, oberoende hur många den har sen innan. + * Du kan därmed aldrig få mer liv än 3 som du startar med. + */ + public class ExtraLifePowerUp extends PowerUp { - ExtraLifePowerUp(String image) { - super(image); - // TODO Auto-generated constructor stub + public ExtraLifePowerUp(String image, double x, double h, double w) { + super(image, x, h, w); } @Override - public void use(Player player) { - // TODO Auto-generated method stub + public void use(Player player, PlayState playState) { + player.resetLives(); + + + } + + } -} + diff --git a/src/states/FlyingEnemy.java b/src/states/FlyingEnemy.java index 1b456bcdb99359741cabd74332cc78e4a9b64b8e..10bc96540e2a679943a802495872fc23820347eb 100644 --- a/src/states/FlyingEnemy.java +++ b/src/states/FlyingEnemy.java @@ -1,107 +1,74 @@ package states; -import java.util.ArrayList; import constants.Constants; import java.util.Random; -import javafx.scene.image.Image; +/** + * @author oscarwiberg, filipyhde + * FlyingEnemy är en klass som extendar object. + * Den flygande enemyn är en enemy som slöpper bomber på player. + * Första bomben släpps på random, därefter tar den in players posiotion fär att försöka släppa på player. + * Går att konfigurera den om man vill att den tar in player xpos efter senaste passeringen eller här och nu(det blir svårare) + * + */ +public class FlyingEnemy extends Object{ -public class FlyingEnemy extends Antagonist{ -// private double enemyX = 800.00; - private ArrayList<Double> enemyY; - private double currY; - private Random rnd = new Random(); + private Random drop; + private int margin = 50; + private double bombDropX; + private boolean bombDropped = false; + public FlyingEnemy(String enemyImg, double x, double y, double h, double w) { + super(enemyImg, x, y, h, w); - public FlyingEnemy(String enemyImg, double x, double y) { - super(enemyImg, x, y); - this.enemyY = new ArrayList<Double>(); - this.enemyY.add(150.0); - this.enemyY.add(180.0); - this.enemyY.add(200.0); - this.enemyY.add(250.0); - // enemyY.add(265.00); - // enemyY.add(265.00); - // enemyY.add(265.00); - // enemyY.add(265.00); + this.drop = new Random(); + this.bombDropX = dropNextBombX(); + } - // double[] enemyY = {250, 200, 150,100}; - // enemyY[0] = 100.0; - // enemyY[1] = 150.0; - // enemyY[2] = 200.0; - // enemyY[3] = 250.0; + + private double dropNextBombX() { + int minX = margin; + int maxX = Constants.screenWidth - margin; + return drop.nextInt(maxX - minX + 1) + minX; } - // System.out.println(weather.get(rnd.nextInt(weather.size()))); - - - -// public boolean playerFlyingEnemyCollision(Player player) { -// boolean hit = false; -// -// if ((enemyX < (player.getPlayerX() + 80.00)) && ((enemyX) > player.getPlayerX())) { //borde vara +80 på enemyx men funkar ej -// // if((player.getPlayerY() + 60.00) >= enemyY) { -// if((player.getPlayerY() + 60.00) >= currY) { -// // if ((enemyY + 80 > (player.getPlayerY())) && ((player.getPlayerY() + 80) > enemyY)) { -// -// hit = true; -// player.decreaseLives(); -// // if (hit && enemyX < player.getPlayerX() + 100) { -// // hit = false; -// // } -// -// } -// -// } -// -// return hit; -// -// // public void setEnemyY() { -// // enemyY = 0.0; -// // -// } - - public FlyingEnemy(String enemyImg) { - super(enemyImg); - this.enemyY = new ArrayList<Double>(); - this.enemyY.add(200.00); //går att stå under - this.enemyY.add(210.00); //behöver ducka - this.enemyY.add(220.00); //behöver ducka - this.enemyY.add(250.00); //behöver hoppa - } - @Override - public boolean playerAntagonistCollision(Player player) { + //om man vill kan man skicka med players x pos på dirren, blir lite svårare då ba + public Enemy dropBomb(Player p, String s) { - boolean collisionX = player.getPlayerX() < (x + 60.00) && (player.getPlayerX() + 60.00) > x; + if (!bombDropped && this.getX() >= bombDropX - 50 && this.getX() <= bombDropX + 50) { + Enemy bomb = new Enemy(s, bombDropX, 50, Constants.bombHeight, Constants.bombWidth); // Drop the bomb at bombDropX + System.out.println("Bomb dropped at: " + bombDropX); - // Check for collision on the y-axis - boolean collisionY = player.getRect() < (currY + 60.00) && (player.getRect() + 60.00) > currY; + bombDropped = true; // Mark that the bomb has been dropped + // Optionally, reset bombDropX to a new random location after dropping the bomb + bombDropX = p.getPlayerX(); + return bomb; + } - if (collisionX && collisionY && !collisionDetected) { - player.decreaseLives(); - collisionDetected = true; - return true; - } - - if (!collisionX) { - collisionDetected = false; - } - + return null; + } - return false; - + public void resetBombDrop() { + bombDropped = false; } - @Override - public double getY() { - currY = enemyY.get(rnd.nextInt(enemyY.size())); - return currY; - } + + + + + + + + + + + + } diff --git a/src/states/GameModel.java b/src/states/GameModel.java index 3632504fc2019a3d6334ee22f5e9033a94ac9a39..ae426e3d120a37d86b05ce5d8f4ce714a72d794c 100644 --- a/src/states/GameModel.java +++ b/src/states/GameModel.java @@ -4,7 +4,8 @@ import javafx.scene.canvas.GraphicsContext; import javafx.scene.input.KeyEvent; /** - * This class represents the current state of the game. + * @author oscarwiberg, filipyhde + * * This class represents the current state of the game. * * This implementation of a state machine keeps a reference to the current state * (see /src/states/GameState). @@ -18,9 +19,7 @@ import javafx.scene.input.KeyEvent; * passing a reference to some other gameState. * * Initial State: MenuState - * */ - public class GameModel { private GameState currentState; diff --git a/src/states/GameState.java b/src/states/GameState.java index cba0ddd627d4898fa1497189881797d744757f2b..a4adc898e974db0bde0a7ac57f6e786fd8f48932 100644 --- a/src/states/GameState.java +++ b/src/states/GameState.java @@ -1,15 +1,12 @@ package states; import javafx.scene.canvas.GraphicsContext; - import javafx.scene.input.KeyEvent; -import javafx.scene.layout.Pane; import javafx.scene.paint.Color; - - import constants.Constants; /** + * @author oscarwiberg, filipyhde * This class represents a state of the game. These states are different views * in the game, which contain their own separate logic. * @@ -29,7 +26,6 @@ import constants.Constants; * To define a valid state, that state has to be derived from this class, and * needs to override the three functions mentioned above. */ - public abstract class GameState { protected GameModel model; diff --git a/src/states/HighScore.java b/src/states/HighScore.java index 98931e969c4f6abb254898de27d6354bb9aa6c2c..e2f7ad9956145d70afa51429e003a4870aa10f3a 100644 --- a/src/states/HighScore.java +++ b/src/states/HighScore.java @@ -1,16 +1,15 @@ package states; -import java.io.BufferedReader; -import java.io.BufferedWriter; import java.io.File; - import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; -import java.util.ArrayList; import java.util.Scanner; +/** + * @author oscarwiberg + * Skriver och läser highscore till textfilen. Om den är tom returneras noll. + */ public class HighScore { diff --git a/src/states/MenuState.java b/src/states/MenuState.java index e32016fb176fc04943f4b6cf1ba1a8f875de2715..edd626d808c8b2b80035785629ec848074db819d 100644 --- a/src/states/MenuState.java +++ b/src/states/MenuState.java @@ -1,52 +1,46 @@ package states; import javafx.scene.canvas.GraphicsContext; - - import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.paint.Color; import javafx.scene.text.Font; -import javafx.scene.text.Text; +import javafx.scene.transform.Rotate; import javafx.scene.image.Image; - import java.io.FileInputStream; import java.io.FileNotFoundException; - import constants.Constants; /** + * @author oscarwiberg, filipyhde * This state represents the menu of the Game The main responsibility of this * class is to allow the user to swap state to the PlayState */ public class MenuState extends GameState { - /* - * The following three variables are just used to show that a change of state - * can be made. The same variables also exist in the PlayState, can you think of - * a way to make this more general and not duplicate variables? - */ + private String informationText; private Color bgColor; private Color fontColor; - // A PlayState, so we can change to the PlayState from the menu. private PlayState playState; - private Image dinosaur; + private Image img1; + private Image img2; private boolean mode1; public MenuState(GameModel model) { super(model); - informationText = "Welcome to the Dino game!\nTo play, press 1 for mode 1 or 2 for mode 2\nEscape to exit game"; + informationText = "Welcome to the Dino game!\nTo play, press:\n1 for mode 1\n2 for mode 2\nEscape to exit game"; bgColor = Color.GREY; fontColor = Color.LIGHTBLUE; - + try { - - dinosaur = new Image(new FileInputStream("src/Images1/dinosaur.png")); + + img1 = new Image(new FileInputStream(Constants.playerImg)); + img2 = new Image(new FileInputStream(Constants.playerImg2)); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } - + } /** @@ -56,14 +50,25 @@ public class MenuState extends GameState { public void draw(GraphicsContext g) { drawBg(g, bgColor); g.setFill(fontColor); - g.setFont(new Font(30)); // Big letters - // Print the information text, centered on the canvas - g.fillText(informationText, Constants.screenWidth/4, Constants.screenHeight / 4); - g.drawImage(dinosaur, Constants.screenWidth/2, Constants.screenHeight/2, 200, 200); - + g.setFont(new Font(30)); + g.fillText(informationText, Constants.screenWidth/3, Constants.screenHeight / 4); + drawRotatedImage(g, img1, 45, 0, 100, 450, 450); + drawRotatedImage(g, img2, -45, Constants.screenWidth - 450, 100, 450, 450); + } + + + private void drawRotatedImage(GraphicsContext g, Image image, double angle, double topLeftX, double topLeftY, double width, double height) { + g.save(); // Save the current graphics context state + rotate(g, angle, topLeftX + width / 2, topLeftY + height / 2); + g.drawImage(image, topLeftX, topLeftY, width, height); + g.restore(); // Restore the graphics context to its original state + } + + private void rotate(GraphicsContext gc, double angle, double px, double py) { + Rotate r = new Rotate(angle, px, py); + gc.setTransform(r.getMxx(), r.getMyx(), r.getMxy(), r.getMyy(), r.getTx(), r.getTy()); } - @Override public void keyPressed(KeyEvent key) { System.out.println("Trycker på " + key.getText() + " i MenuState"); @@ -78,29 +83,28 @@ public class MenuState extends GameState { model.switchState(playState); } else if (key.getCode() == KeyCode.ESCAPE) { System.exit(0); - } - + } } @Override public void update() { // TODO Auto-generated method stub - + } @Override public void activate() { // TODO Auto-generated method stub - + } @Override public void deactivate() { // TODO Auto-generated method stub - + } - + } diff --git a/src/states/Object.java b/src/states/Object.java new file mode 100644 index 0000000000000000000000000000000000000000..de244067e2da382e44e5b66c17932aaad2a449b1 --- /dev/null +++ b/src/states/Object.java @@ -0,0 +1,113 @@ +package states; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import constants.Constants; +import javafx.geometry.Bounds; +import javafx.scene.image.Image; +import javafx.scene.shape.Rectangle; + +/** + * @author oscarwiberg, filipyhde + * Allt som inte är player går egentligen genom denna class för att ärva funktionalitet och variabler. + * + */ +public abstract class Object { + + protected double posX; + protected double posY; + private double height; + private double width; + protected Image img; + + public Object(String image, double x, double y, double h, double w) { + + posY = y; + posX = x; + width = w; + height = h; + + try { + img = new Image(new FileInputStream(image)); + + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public Object(String image, double x, double h, double w) { + posX = x; + width = w; + height = h; + + try { + img = new Image(new FileInputStream(image)); + + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public double getX() { + return posX; + } + + public double getY() { + return posY; + } + + public Image getImage() { + return img; + } + + + public void setX(double posX) { + this.posX = posX; + } + + public void setY(double posY) { + this.posY = posY; + } + + public double getH() { + return height; + } + + public double getW() { + return width; + } + + public boolean playerObjectCollision(Player player) { + boolean hit = false; + + double playerX = player.getPlayerX(); + double playerY = player.getPlayerY(); + + // Define new smaller width and height + double smallerWidth = Constants.playerWidth - 50; // Example: reduced by 20 pixels + double smallerHeight = Constants.playerHeight - 50; // Example: reduced by 20 pixels + + // Calculate new X and Y to center the smaller rectangle around the player's position + double centeredX = playerX + (Constants.playerWidth - smallerWidth) / 2; + double centeredY = playerY + (Constants.playerHeight - smallerHeight) / 2; + + + Bounds playerRect = new Rectangle(centeredX, centeredY, smallerWidth, smallerHeight).getBoundsInParent(); + + + Bounds objectRect = new Rectangle(this.getX(), this.getY(), this.getW(), this.getH()).getBoundsInParent(); + + if (playerRect.intersects(objectRect)) { + hit = true; + } + + return hit; + } + + + + // här kommer de två olika powerupsen avgöra vad som händer när ma ta den, denna klass kallar på kollisionen + +} diff --git a/src/states/PlayState.java b/src/states/PlayState.java index 8f95c702c5697fd62e9234daee7c8f314e98383f..f07c9610638457feb887f4ee7dc041fb2c4ad0fb 100644 --- a/src/states/PlayState.java +++ b/src/states/PlayState.java @@ -1,43 +1,18 @@ package states; import javafx.scene.canvas.GraphicsContext; - -import javafx.scene.image.Image; -import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.paint.Color; -import javafx.scene.shape.Rectangle; import javafx.scene.text.Font; -import javafx.scene.text.Text; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.util.Random; - +import java.util.concurrent.ThreadLocalRandom; import constants.Constants; /** - * This state represents the Playing State of the Game The main responsibility - * of this class is to; - create Game Objects - update Game Objects - draw Game - * Objects Game Objects are for instance; players, enemies, npc's, etc... - * - * The PlayState can also be thought off as a blue print where data is loaded - * into some container from a file or some other type of data storage. - * - * It can also be created by some class responsible for object creation and then - * passed to the PlayState as a parameter. This means all the PlayState has to - * do is receive a list of objects, store them in some container and then for - * every object in that container update and render that object. - * - * This way you can let the user define different Levels based on what - * parameters are passed into the PlayState. + * @author oscarwiberg, filipyhde + * hanterar självaste spelflödet. renderar alla karaktärer och objekt under spelets gång och uppdaterar alla positioner. */ public class PlayState extends GameState { - /* - * The following three variables are just used to show that a change of state - * can be made. The same variables also exist in the MenuState, can you think of - * a way to make this more general and not duplicate variables? - */ + private String informationText; private String livesleft; private String gameOverText; @@ -48,24 +23,25 @@ public class PlayState extends GameState { private Enemy enemy; private boolean collided = false; private boolean up = false; - private boolean down = false; private boolean gameOver = false; - private MenuState menu; private HighScore score = new HighScore(); - private int clearedEnemies; private String scoreText; private ExtraLifePowerUp extraLife; private FlyingEnemy flyingEnemy; - private double tempy; - private Random engen; - private String slidingPlayer; private int movingSpeed = 10; + private Enemy bomb; + private boolean isFlyingEnemyActive = false; + private String currScore; + private double collisionX = -1.00; + private SpeedPowerUp speedUp; + private boolean isPowerUpActive; + private int num; + private String bombImg; + private PowerUp last = null; + private PowerUp pw; + private boolean speedActive; - /* Class only used for testing */ - - // TODO nästa steg, lägg in en flygande enemy för att testa glid funktionen, ändra boundsen på den glidande bilden! - // TODO kanske ta bort att skicka med image när man instansierar player public PlayState(GameModel model, boolean mode) { super(model); @@ -74,8 +50,8 @@ public class PlayState extends GameState { gameOverText = "GAMEOVER\n" + informationText; fontColor = Color.BLACK; scoreText = "Highscore: " + Integer.toString(score.getHighScore()); - // + Integer.toString(score.getHighScore()); - + extraLife = new ExtraLifePowerUp(Constants.lifeImg, 1200.00, Constants.powerHeight, Constants.powerWidth); + speedUp = new SpeedPowerUp(Constants.powerImg, 1200.00, Constants.powerHeight, Constants.powerWidth); if (mode) { mode1(); @@ -83,19 +59,13 @@ public class PlayState extends GameState { mode2(); } - - // menu = new MenuState(model); - } public void mode1() { player = new Player(Constants.playerImg); - slidingPlayer = Constants.slidingPlayerImg; - enemy = new Enemy(Constants.enemyImg, 800.00, 250.00); - extraLife = new ExtraLifePowerUp(Constants.lifeImg); - flyingEnemy = new FlyingEnemy(Constants.flyingEnemyImg); - flyingEnemy.setAntagonistX(800.00); - tempy = flyingEnemy.getY(); + enemy = new Enemy(Constants.enemyImg, 900.00, 270.00, Constants.enemyHeight, Constants.enemyWidth); + flyingEnemy = new FlyingEnemy(Constants.flyingEnemyImg, 900.00, 20.00, Constants.enemyHeight, Constants.enemyWidth); + bombImg = Constants.bombImg; bgColor = Color.ROYALBLUE; lineColor = Color.WHITE; @@ -103,12 +73,9 @@ public class PlayState extends GameState { public void mode2() { player = new Player(Constants.playerImg2); - slidingPlayer = Constants.slidingPlayerImg2; - enemy = new Enemy(Constants.enemyImg, 800.00, 250.00); - extraLife = new ExtraLifePowerUp(Constants.lifeImg); - flyingEnemy = new FlyingEnemy(Constants.flyingEnemyImg); - flyingEnemy.setAntagonistX(800.00); - tempy = flyingEnemy.getY(); + enemy = new Enemy(Constants.enemyImg2, 900.00, 270.00, Constants.enemyHeight, Constants.enemyWidth); + flyingEnemy = new FlyingEnemy(Constants.flyingEnemyImg2, 900.00, 20.00, Constants.enemyHeight, Constants.enemyWidth); + bombImg = Constants.bombImg2; bgColor = Color.BEIGE; lineColor = Color.BLACK; @@ -120,7 +87,20 @@ public class PlayState extends GameState { */ @Override public void draw(GraphicsContext g) { - drawBg(g, bgColor); + drawBackground(g); + drawGameStats(g); + drawPlayer(g); + drawEnemies(g); + drawPowerUps(g); + } + + private void drawPlayer(GraphicsContext g) { + g.drawImage(player.getImage(), player.getPlayerX(), player.getPlayerY(), Constants.playerWidth, Constants.playerHeight); + } + + private void drawGameStats(GraphicsContext g) { + currScore = "Currently: " + Integer.toString(player.getPasses()); + g.setFill(fontColor); g.setFont(new Font(30)); // Big letters @@ -130,78 +110,158 @@ public class PlayState extends GameState { g.fillText(livesleft+player.getLives(), 0, 30); g.fillText(informationText, Constants.screenWidth - 300, 30); g.fillText(scoreText, 0, 60); + g.fillText(currScore, 0, 90); } else { g.fillText(gameOverText, Constants.screenWidth/2, 200); score.saveScore(player.getPasses()); } - + } + private void drawBackground(GraphicsContext g) { + drawBg(g, bgColor); g.setStroke(lineColor); g.setLineWidth(1); g.setLineDashes(2); g.strokeLine(Constants.screenWidth, 350, 0, 350); - - g.drawImage(player.getImage(), player.getPlayerX(), player.getPlayerY(), Constants.playerWidth, Constants.playerHeight); - - - -// Detta block används för att rita ut rectanglarna runt spelare och enemy - g.setStroke(Color.BLACK); // Set the rectangle's border color - g.setLineWidth(2); // Set the border width - g.strokeRect(flyingEnemy.getX(), tempy, Constants.enemyWidth, Constants.enemyHeight); - g.strokeRect(player.getPlayerX(), player.getRect(), Constants.playerWidth, Constants.playerHeight); + } - - - drawEnemy(g); + private void drawPowerUps(GraphicsContext g) { + + if (isPowerUpActive && !speedActive) { - + if (num == 0) { + drawSpeedUp(g); + last = speedUp; + } else { + drawExtraLife(g); + last = extraLife; + } + } } - public void drawEnemy(GraphicsContext g) { - engen = new Random(); + public void drawSpeedUp(GraphicsContext g) { + if(speedUp.getX() < 0 - Constants.playerWidth) { + speedUp.setX(Constants.screenWidth); + isPowerUpActive = false; + } + g.drawImage(speedUp.getImage(), speedUp.getX(), speedUp.getY(), Constants.powerWidth, Constants.powerHeight); + } - // g.drawImage(enemy.getImage(), enemy.getX(), enemy.getY(), Constants.enemyWidth, Constants.enemyHeight); - // if (enemy.getX() < 0 - Constants.enemyWidth) { - // enemy.setAntagonistX(Constants.screenWidth); - // player.updatePasses(1); - // } + public void drawExtraLife(GraphicsContext g) { + if(extraLife.getX() < 0 - Constants.playerWidth) { +// extraLife.setImage(Constants.lifeImg); + extraLife.setX(Constants.screenWidth); + isPowerUpActive = false; + } + g.drawImage(extraLife.getImage(), extraLife.getX(), extraLife.getY(), Constants.powerWidth, Constants.powerHeight); + } + public void drawEnemies(GraphicsContext g) { + + if (!isFlyingEnemyActive) { + drawGroundEnemy(g); + } else { + drawFlyingEnemy(g); + } + + // Render the bomb if it exists + if (bomb != null) { + g.drawImage(bomb.getImage(), bomb.getX(), bomb.getY(), Constants.bombWidth, Constants.bombHeight); + } + } - g.drawImage(flyingEnemy.getImage(), flyingEnemy.getX(), tempy, Constants.enemyWidth, Constants.enemyHeight); + + + private void drawFlyingEnemy(GraphicsContext g) { + g.drawImage(flyingEnemy.getImage(), flyingEnemy.getX(), flyingEnemy.getY(), Constants.enemyWidth, Constants.enemyHeight); + if (flyingEnemy.getX() < 0 - Constants.enemyWidth) { - flyingEnemy.setAntagonistX(Constants.screenWidth); + flyingEnemy.setX(Constants.screenWidth); player.updatePasses(1); - tempy = flyingEnemy.getY(); - - if (player.getPasses() % 5 == 0) { - movingSpeed += 4; + // Reset bomb drop flag to allow the next bomb drop + flyingEnemy.resetBombDrop(); + speedCheck(); + + + + if(getRandom() == 1) { + isFlyingEnemyActive = false; } - } + } } + private void drawGroundEnemy(GraphicsContext g) { + + + g.drawImage(enemy.getImage(), enemy.getX(), enemy.getY(), Constants.enemyWidth, Constants.enemyHeight); + if (enemy.getX() < 0 - Constants.enemyWidth) { + enemy.setX(Constants.screenWidth); + collided = false; + collisionX = -1.00; + player.updatePasses(1); + speedCheck(); + if (player.getPasses() > 4 && getRandom() == 0) { // 50% chance after player hase passed + isFlyingEnemyActive = true; + // Reset position + System.out.println("Stage one activated, flyingenemy added to the mix"); + } + } + } + //TODO om score är större än visst antal --> lotta mellan flying och vanlig, vi kan göra en random med 2 int, ochberoende på vad den blir kan vi rita en //TODO göra en variabel för y positionen som hämtas om vi ritar flygande, för att den ska behålla samma position på hela y axeln + // kör modulo 6, 10, 15 + // dessa returnerar bara samma på nummer som är delbara med 30 + public void speedCheck() { + if (player.getPasses() % 6 == 0) { + movingSpeed += 1; + System.out.println("speed set to: " + Integer.toString(movingSpeed)); + } else if (player.getPasses() > 1 && player.getPasses() % 2 == 0) { //denna bör ändras till något som aldrig klaffar med den ovan + // if (movingSpeed < 100) { + isPowerUpActive = true; +// num = getRandom(); + num = 0; + System.out.println(num); + + // } + } + } + public int getSpeed() { + return movingSpeed; + } + public void setSpeed(int s) { + if (s == 100) { + speedActive = true; + } else { + speedActive = false; + } + movingSpeed = s; + } + + + public int getRandom() { + return ThreadLocalRandom.current().nextInt(2); + } @@ -222,82 +282,120 @@ public class PlayState extends GameState { case UP: // Om spelaren duckar kan den inte hoppa, då ställer sig spelaren upp istället - if (down) { - player.standUp(); - down = false; - } else { - up = true; - } + up = true; break; - case DOWN: - // Spelaren kan inte ducka om den är mitt i ett hopp - if (!up) { - down = true; + case LEFT: + player.moveLeft(movingSpeed); - } break; - default: + case RIGHT: + player.moveRight(movingSpeed); + break; + default: + break; } + } + @Override + public void update() { + if (!gameOver) { + moveEnemies(); + movePowerUps(); + checkGroundCollision(); + checkBombCollision(); + movePlayer(); + } } - @Override - public void update() { - //om enemy position är mindre än player och collide är true kollar den inte collision - // Enemy hoppar 10 snäpp till vänster för varje update - // enemy.setAntagonistX(enemy.getX()-10); - flyingEnemy.setAntagonistX(flyingEnemy.getX()-movingSpeed); - // flyingEnemy.setAntagonistX(flyingEnemy.getX() -10); + private void movePowerUps() { + if (isPowerUpActive) { - // Om - if (!gameOver) { + if (num == 0) { - if (!collided) { - // collided = enemy.playerAntagonistCollision(player); - collided = flyingEnemy.playerAntagonistCollision(player); + speedUp.setX(speedUp.getX() - movingSpeed); + speedUp.handle(player, this); + } else if (num == 1) { - if (Integer.valueOf(player.getLives()) == 0) { - gameOver = true; - } - } - - //återställer boolean när enemy passerat - if (collided && flyingEnemy.getX() < player.getPlayerX()) { - collided = false; - } + extraLife.setX(extraLife.getX() - movingSpeed); + extraLife.checkCollision(player, this); + } + } + } + private void movePlayer() { + if (up) { - if (up) { + player.jump(movingSpeed); + } - player.jump(movingSpeed); - } + if (player.getPlayerY() == 265) { + up = false; + } + } - if (player.getPlayerY() == 265) { - up = false; - } - if (down) { + private void checkGroundCollision() { + if (!collided && enemy.playerObjectCollision(player)) { - player.slide(slidingPlayer); + collided = true; + if (collisionX == -1.00) { + collisionX = enemy.getX(); + System.out.println("Player-Enemy Collision X Coordinate: " + collisionX); } + player.decreaseLives(); + } + if (Integer.valueOf(player.getLives()) == 0) { + gameOver = true; + } + } + + + private void checkBombCollision() { + if (bomb != null) { + bomb.setY(bomb.getY() + movingSpeed); + + if (bomb.playerObjectCollision(player)) { + System.out.println("Bomb hit the player!"); + player.decreaseLives(); // Assume there's a method to decrement player lives + bomb = null; // Destroy the bomb after collision + + } else if (bomb.getY() > Constants.screenHeight) { + bomb = null; // Destroy the bomb if it goes off-screen + System.out.println("Bomb went off-screen and was destroyed"); + } + } } + private void moveEnemies() { + if (isFlyingEnemyActive) { + + flyingEnemy.setX(flyingEnemy.getX() -movingSpeed); + + Enemy droppedBomb = flyingEnemy.dropBomb(player, bombImg); + + if (droppedBomb != null) { + bomb = droppedBomb; + } + } else { + enemy.setX(enemy.getX() - movingSpeed); + } + } // Here one would probably instead move the player and any // enemies / moving obstacles currently active. diff --git a/src/states/Player.java b/src/states/Player.java index f1dfab951a659b1f86416d8f2346d8cff1c3e9f7..9b3c279de52cfb7cf34d4cae809662fbe9c205e9 100644 --- a/src/states/Player.java +++ b/src/states/Player.java @@ -1,79 +1,63 @@ package states; import java.io.FileInputStream; - - import java.io.FileNotFoundException; - import constants.Constants; import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import javafx.scene.input.KeyCode; -import javafx.scene.input.KeyEvent; -import javafx.scene.shape.Rectangle; +/** + * @author oscarwiberg, filipyhde + * player hanterar hur den rör sig efter vilka tangeter vi trycker på i playstate. + * Hanterar hur långt spelaren har kommit i spelet(passes), samt justerar sina liv utefter kollisioner. + */ public class Player { - -// TODO se över funktioner, kanske lättare att slå samman vissa + + // TODO se över funktioner, kanske lättare att slå samman vissa private double playerX = (Constants.screenWidth - Constants.playerWidth) / 2; private double playerY = 265.00; - private int score = 0; private int lives = 3; private Image image; private boolean down = false; - private boolean up = false; - private Image slidingImage; - private Image currImage = null; - private int passes = 0; - private Rectangle bounds; - private double topPos = playerY; - - - - - - public int getPasses() { - return passes; - } - - - - - - public void updatePasses(int passes) { - this.passes += passes; - } - + private int passes = 0; + private boolean livesLocked = false; public Player(String playerImg) { - bounds = new Rectangle(playerX, topPos, Constants.playerWidth, Constants.playerHeight); try { image = new Image(new FileInputStream(playerImg)); //slidingImage = new Image(new FileInputStream(Constants.slidingPlayerImg)); - + } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } - currImage = image; + + } + + + + + + public int getPasses() { + return passes; } - public double getRect() { - return topPos; + public void updatePasses(int passes) { + this.passes += passes; } + public Image getImage() { - return currImage; + return image; } @@ -84,9 +68,14 @@ public class Player { public void decreaseLives() { + if (!livesLocked) { + this.lives--; + } - this.lives--; + } + public void resetLives() { + this.lives = 3; } @@ -110,7 +99,6 @@ public class Player { if (!down) { playerY -= movingSpeed; - topPos -= movingSpeed; if (playerY <= 110) { @@ -123,9 +111,9 @@ public class Player { if (down) { playerY += movingSpeed; - topPos += movingSpeed; - if (playerY == 265) { + if (playerY >= 265) { + playerY = 265; down = false; } @@ -134,22 +122,12 @@ public class Player { } - public void slide(String img) { - try { - slidingImage = new Image(new FileInputStream(img)); - //slidingImage = new Image(new FileInputStream(Constants.slidingPlayerImg)); - - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - currImage = slidingImage; - topPos = 305.00; - - - } + + + + + public void setPlayerX(double playerX) { @@ -162,10 +140,35 @@ public class Player { } - public void standUp() { - currImage = image; - topPos = playerY; - + + + public void moveLeft(int movingSpeed) { + + if (playerX > 0) { + + playerX -= movingSpeed; + } + + + } + + + + + public void moveRight(int movingSpeed) { + + if (playerX < Constants.screenWidth - Constants.playerWidth) { + + playerX += movingSpeed; + + } + + } + + + public void lockLives(boolean b) { + livesLocked = b; + } diff --git a/src/states/PowerUp.java b/src/states/PowerUp.java index 0b5901d4abe5a36e92ce17495ef92fc02af0938f..9a8609a7a059ec6bfae0f4da5cce2048cc594a9b 100644 --- a/src/states/PowerUp.java +++ b/src/states/PowerUp.java @@ -2,53 +2,61 @@ package states; import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.util.Random; -import constants.Constants; import javafx.scene.image.Image; -public abstract class PowerUp { +/** + * @author oscarwiberg, filipyhde + * Powerup bygger vidare på object eftersom vi fortfarande vill komma åt kollisionshanteringen + * när vi vill kolla kollision med powerup kallar vi däremot på checkcCollision, då kallar den på use om det blir en collision. + * De spawnar också in på en random y-coordinat inom det spannet som player kan nå med sitt hopp. + */ +public abstract class PowerUp extends Object{ - private double powerUpX = (Constants.screenWidth - Constants.playerWidth) / 2; - private double powerUpY = 265.00; - private Image powerUpImage; - - PowerUp(String image) { - - try { - powerUpImage = new Image(new FileInputStream(image)); - - } catch (FileNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + private int scoreSinceActive = 0; + private Random random = new Random(); + private int maxH = 110; + private int minH = 265; + + public PowerUp(String image, double x, double h, double w) { + super(image, x, h, w); + this.posY = spawn(); } - public double getPowerUpX() { - return powerUpX; - } - - public void setPowerUpX(double powerUpX) { - this.powerUpX = powerUpX; - } + + +// lägg in en ny constructor som bara tar in String image +// lägg till en funktion som returnerar en powerup, likt det som har gjortd för bomben i flying enemy - public double getPowerUpY() { - return powerUpY; - } - public Image getImage() { - return powerUpImage; + public double spawn() { + int x = random.nextInt(minH - maxH + 1) + maxH; + return (double) x; } - public boolean powerUpPlayerCollision(Player player) { - boolean hit = false; - -// här ska det finnas kod för att kolla kollisioner mellan spelare och powerup - - return hit; + protected int getScoreSinceActive() { + return scoreSinceActive; } - public abstract void use(Player player); + public void checkCollision(Player player, PlayState playState) { + if (this.playerObjectCollision(player)) { + use(player, playState); + this.setX(-1000); + scoreSinceActive = player.getPasses(); + + } + } -// här kommer de två olika powerupsen avgöra vad som händer när ma ta den, denna klass kallar på kollisionen + public void setImage(String s) { + try { + this.img = new Image(new FileInputStream(s)); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + + } + } -} + public abstract void use(Player player, PlayState playState); + + } diff --git a/src/states/SpeedPowerUp.java b/src/states/SpeedPowerUp.java new file mode 100644 index 0000000000000000000000000000000000000000..f4774fda86fb0164d80b9baccf89d43b453612e0 --- /dev/null +++ b/src/states/SpeedPowerUp.java @@ -0,0 +1,52 @@ +package states; + +import constants.Constants; + +/** + * @author oscarwiberg, filipyhde + * Denhär klassen har en liten längre chain of events vid kollision. Vi kallar på handle i playstate, sparar hur många passes vi gjort samt nuvarande hastighet i spelet + * därfter kallar vi på kollision, om det blir kollision kallar den på use som låser liven på player och ökar spelhastigheten till 100. + * När det har gått 10 passeringar sen kollision återgår hastigheten till den som den var innan. + */ +public class SpeedPowerUp extends PowerUp { + + private boolean active = false; + private int speed; + private int start; + + public SpeedPowerUp(String image, double x, double h, double w) { + super(image, x, h, w); + } + + @Override + public void use(Player player, PlayState playState) { + + + + player.lockLives(true); + + playState.setSpeed(100); + + active = true; + + } + + public void handle(Player player, PlayState playState) { + if (!active) { + + start = player.getPasses(); + speed = playState.getSpeed(); + + this.checkCollision(player, playState); + + } else { + if ((player.getPasses() - start) >= 5) { + playState.setSpeed(speed); + player.lockLives(false); + player.setPlayerY(265); + active = false; + + } + } + } +} \ No newline at end of file diff --git a/src/testing/Tester.java b/src/testing/Tester.java deleted file mode 100644 index 9fe95fcad9e613cd5ae7e48f6dcad51394eef9f5..0000000000000000000000000000000000000000 --- a/src/testing/Tester.java +++ /dev/null @@ -1,119 +0,0 @@ -package testing; - -import javafx.scene.canvas.GraphicsContext; - -import javafx.scene.image.Image; -import javafx.scene.transform.Rotate; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; - -import constants.Constants; - - - -/** - * This class is only used for testing that PlayState works as intended. You - * will probably not have a similar class in your game. - */ -public class Tester { - // Internal class, mostly to show how it works in case you need it. - public class Point { - double x; - double y; - - public Point(double x, double y) { - this.x = x; - this.y = y; - } - } - - private Point position; - private Image banana; - private Image car; - private Image player; - private Image smile; - private int angle = 0; - - public Tester() { - position = new Point(0, 0); - - try { - banana = new Image(new FileInputStream("src/Images1/h-banana.png")); - car = new Image(new FileInputStream("src/Images1/car.png")); - smile = new Image(new FileInputStream("src/Images1/smiley.png")); - player = new Image(new FileInputStream(Constants.playerImg)); - - - } catch (FileNotFoundException e) { - System.out.println("Unable to find image-files!"); - } - } - - /** - * Sets the transform for the GraphicsContext to rotate around a pivot point. - * - * @param gc the graphics context the transform to applied to. - * @param angle the angle of rotation. - * @param px the x pivot coordinate for the rotation (in canvas coordinates). - * @param py the y pivot coordinate for the rotation (in canvas coordinates). - */ - private void rotate(GraphicsContext gc, double angle, double px, double py) { - Rotate r = new Rotate(angle, px, py); - gc.setTransform(r.getMxx(), r.getMyx(), r.getMxy(), r.getMyy(), r.getTx(), r.getTy()); - } - - /** - * Draws an image on a graphics context. - * - * The image is drawn at (topLeftX, topLeftY) rotated by angle pivoted around the point: - * (topLeftX + image.getWidth() / 2, topLeftY + image.getHeight() / 2) - * - * @param g the graphics context the image is to be drawn on. - * @param angle the angle of rotation. - * @param topLeftX the top left x coordinate where the image will be plotted (in canvas coordinates). - * @param topLeftY the top left y coordinate where the image will be plotted (in canvas coordinates). - */ - private void drawRotatedImage(GraphicsContext g, Image image, double angle, double topLeftX, double topLeftY) { - g.save(); // saves the current state on stack, including the current transform - rotate(g, angle, topLeftX + image.getWidth() / 2, topLeftY + image.getHeight() / 2); - g.drawImage(image, topLeftX, topLeftY); - g.restore(); // back to original state (before rotation) - } - - /** - * Updates the position of the car and the banana. - */ - public void update() { - // We move the position for the images each "tick", or call from the timer. - // Can be adjusted to accomodate how fast you wish to move. - position.x -= 2; -// position.y -= 2; - angle -= 3; // Updates the angle of the rotating image - // angle -= 3; // Updates the angle of the rotating image - } - - public void delegate(GraphicsContext g) { - if (g != null) { - draw(g); - } - } - - private void draw(GraphicsContext g) { - // if (position.x >= SCREEN_WIDTH || position.y >= SCREEN_HEIGHT) { - if (position.x <= 0 || position.y >= Constants.screenHeight) { - // The position is exiting the screen, so we reset it - // position.x = 0.0; - position.x = 1000.0; - // position.y = 0.0; - position.y = 600.0; - } - -// drawRotatedImage(g, smile, angle, 500, 400); - g.drawImage(car, position.x, position.y, 100, 100); - g.drawImage(player, Constants.screenWidth/2-50, 600, 100, 100); - g.drawImage(banana, position.x, position.y, 100, 100); - } -} - -