Package beaver.game

Source Code of beaver.game.GameplayState

package beaver.game;

import java.util.Random;

import javax.swing.JOptionPane;

import org.jbox2d.collision.WorldManifold;
import org.jbox2d.common.Vec2;
import org.newdawn.slick.Animation;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.ImageBuffer;
import org.newdawn.slick.Input;
import org.newdawn.slick.MouseListener;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.fizzy.Body;
import org.newdawn.fizzy.Circle;
import org.newdawn.fizzy.CollisionEvent;
import org.newdawn.fizzy.CompoundShape;
import org.newdawn.fizzy.DynamicBody;
import org.newdawn.fizzy.Polygon;
import org.newdawn.fizzy.Rectangle;
import org.newdawn.fizzy.Shape;
import org.newdawn.fizzy.StaticBody;
import org.newdawn.fizzy.World;
import org.newdawn.fizzy.WorldListener;

import beaver.game.GameplayState.Item;

@SuppressWarnings("rawtypes")
public class GameplayState extends BasicGameState implements WorldListener,
    MouseListener {
 
  protected int stateID = -1;
  protected World world;
  protected float scale = 1f; // the scale of what is displayed

  // Animations used for the beaver (not yet loaded)
  protected Animation team1Moving = null;
  protected Animation team1MovingR = null;
  protected Animation team2Moving = null;
  protected Animation team2MovingR = null;
  float beaverX, beaverY;

  protected float worldCenterX;
  protected float worldCenterY;
  protected float crosshairAngle;
  protected Body crosshair;
  protected Image crosshairImage;
  protected Body bullet;
  protected Image bulletImage;
  protected Image healthImage;
  protected Image ammoImage;
  protected Body boundary;

  protected float collisionX = 0f;
  protected float collisionY = 0f;
  protected float leftmostXFromExplosion = 1000000f;
  protected float rightmostXFromExplosion = -1;
 
  protected ImageBuffer terrainy;
  protected Image terrainyImage;
  protected float[][] terrainBitmap;
  protected CompoundShape[] terrain = new CompoundShape[1];
  protected CompoundShape compoundTerrain;
  protected StaticBody terrainBody = new StaticBody(new Circle(0), 0, 0);
  protected boolean drawCircle = false;

  protected String p1Name = "Player 1";
  protected String p2Name = "Player 2";
  protected Player p1 = null;
  protected Player p2 = null;
  protected Player currentPlayer = null;
 
  protected long startTime = 0;
  protected long endTime = 0;
  protected int endTurn = -1;
 
  protected int radius = 40;
  protected boolean cameraOnBullet = false;
 
  protected boolean powerSeqEngaged = false;
  protected int power = 1;
  protected Item[] item;
  protected boolean killBullet;

  protected Image bg_sprite = null;

  public GameplayState(int stateID) {
    this.stateID = stateID;
  }
 
  public GameplayState(int stateID, String remote, boolean isHost){
    this.stateID = stateID;
  }
 
  @Override
  public int getID() {
    return stateID;
  }
 
  //an item class. Has the body and the type.
  //type 1 is hp, type 2 is ammo
  protected class Item {
    private int value;
    public DynamicBody body;
    public boolean remove = false;
    protected Item() {
      int[] coord = randomFreeCoordinate(20);
      if (coord[0] < 0) this.body = new DynamicBody(new Circle(10.0f), -100, 1300);
      else this.body = new DynamicBody(new Circle(10.0f), (coord[0]-terrainyImage.getWidth()/2), (coord[1]-terrainyImage.getHeight()/2));
      this.value = 1;
      this.remove = false;
    }
    public void setTypeHP(){
      this.value = 1;
    }
    public void setTypeAmmo(){
      this.value = 2;
    }
    public boolean isTypeHP(){
      if (this.value == 1) return true;
      return false;
    }
    public boolean isTypeAmmo(){
      if (this.value == 2) return true;
      return false;
    }
    public DynamicBody getBody(){
      return this.body;
    }
  }

  @Override
  public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
   
   
    bg_sprite.draw();
    //g.setBackground(new Color(0,61,245));
    g.setAntiAlias(true);
    g.setColor(Color.white);
 
    g.pushTransform();
    g.translate(worldCenterX, worldCenterY);
    g.scale(scale, -scale);
    g.drawImage(terrainyImage, -terrainyImage.getWidth()/2, -terrainyImage.getHeight()/2);
    g.popTransform();

    g.pushTransform();
    g.translate(worldCenterX, worldCenterY);
    g.scale(scale, -scale);

    for (int i = 0; i < world.getBodyCount(); i++) {
      Body body = world.getBody(i);
      if (!body.equals(terrainBody) && !body.equals(boundary)) {
        g.setColor(Color.black);
        drawBody(g, body);
      }
    }
    g.popTransform();
   
    g.setColor(Color.white);
    placeCrosshairs();
   
    g.drawString(
        "Left/right to move, space to jump, up/down to aim, enter to shoot."
            + "\nZ and X to zoom in and out, and R to reset the crosshair."
            + "\nW,A,S,D to pan, and ESC to pause.",
        10, 25);
    g.drawString(
        "\n Time Remaining: "
            + (int)((endTime - System.currentTimeMillis()) / 1000f), 30,
        500);
    drawStats(g);
 
  }
 
  protected void placeCrosshairs(){
    Body currentBeaverBody = currentPlayer.getCurrentBeaver().getBody();
    world.remove(crosshair);
    float x = (float) (currentBeaverBody.getX() + 100*Math.sin(Math.toRadians(crosshairAngle)));
    float y = (float) (currentBeaverBody.getY() + 100*Math.cos(Math.toRadians(crosshairAngle)));
    crosshair = new StaticBody(new Circle(10),x,y);
    world.add(crosshair);
    crosshair.setActive(false);
  }
 
  protected void drawBody(Graphics g, Body body) {
    Shape shape = body.getShape();
    drawShape(g, body, shape);
  }

  private void drawShape(Graphics g, Body body, Shape shape) {
    if (shape instanceof Rectangle)
      drawRectangle(g, body, (Rectangle) shape);
    if (shape instanceof Circle)
      drawCircle(g, body, (Circle) shape);
    if (shape instanceof Polygon)
      drawPolygon(g, body, (Polygon) shape);
    if (shape instanceof CompoundShape)
      drawCompound(g, body, (CompoundShape) shape);
  }

  private void drawCompound(Graphics g, Body body, CompoundShape shape) {
    int count = shape.getShapeCount();
    for (int i = 0; i < count; i++) {
      drawShape(g, body, shape.getShape(i));
    }
  }

  private void drawPolygon(Graphics g, Body body, Polygon shape) {
    g.pushTransform();
    g.translate(body.getX(), body.getY());
    g.rotate(0, 0, (float) Math.toDegrees(body.getRotation()));
    g.translate(shape.getXOffset(), shape.getYOffset());
    g.rotate(0, 0, (float) Math.toDegrees(shape.getAngleOffset()));

    for (int i = 0; i < shape.getPointCount(); i++) {
      int n = i + 1;
      if (n >= shape.getPointCount()) {
        n = 0;
      }
      g.drawLine((int) shape.getPointX(i), (int) shape.getPointY(i),
          (int) shape.getPointX(n), (int) shape.getPointY(n));
    }
    g.popTransform();
  }

  private void drawCircle(Graphics g, Body body, Circle shape) {
    g.pushTransform();
    g.translate(body.getX(), body.getY());
    float radius = shape.getRadius();
    Beaver[] p1Team = p1.getTeam();
    Beaver[] p2Team = p2.getTeam();
   
    for(int i = 0;i<Constants.BEAVERS_PER_TEAM;i++){
      if(body.equals(p1Team[i].getBody())&&p1Team[i].isAlive()){
        boolean direction = p1Team[i].getFacingR();
        if (direction == true)
          g.drawAnimation(team1MovingR, (int) -radius, (int) -radius);
        else
          g.drawAnimation(team1Moving, (int) -radius, (int) -radius);
        // Display HP over beaver's head
        Color old = g.getColor();
        g.setColor(Color.green);

        g.pushTransform();
        g.scale(scale, -scale);
        g.drawString("HP=" + p1Team[i].getHP(), (int) -radius, -team1Moving.getHeight()-10);
       
        if (currentPlayer.getCurrentBeaver().equals(p1Team[i])) {
          // Draw the power bar over the current beaver's head
          if (powerSeqEngaged) {
            g.setColor(Color.red);
            g.fillRect((int) -radius, -team1Moving.getHeight()-20, power/3, 10);
          }
        }
       
        g.popTransform();
        g.setColor(old);
       
      }

      if(body.equals(p2Team[i].getBody())&&p2Team[i].isAlive()){
        // Get current beaver's direction *GIANNI*
        boolean direction = p2Team[i].getFacingR();
        if (direction == true)
          g.drawAnimation(team2MovingR, (int) -radius, (int) -radius);
        else
          g.drawAnimation(team2Moving, (int) -radius, (int) -radius);
        // Display HP over beaver's head
        Color old = g.getColor();
        g.setColor(Color.red);
       
        g.pushTransform();
        g.scale(scale, -scale);
        g.drawString("HP=" + p2Team[i].getHP(), (int) -radius, -team2Moving.getHeight()-10);
       
        if (currentPlayer.getCurrentBeaver().equals(p2Team[i])) {
          // Draw the power bar over the current beaver's head
          if (powerSeqEngaged) {
            g.setColor(Color.red);
            g.fillRect((int) -radius, -team1Moving.getHeight()-20, power/3, 10);
          }
        }
       
        g.popTransform();
        g.setColor(old);
      }
    }
   
    if (body.equals(crosshair)){
      g.drawImage(crosshairImage, (int) -radius, (int) -radius);
    }
   
    if (body.equals(bullet)){
      g.drawImage(bulletImage, (int) -radius, (int) -radius);
    }
   
    for (int i = 0; i < item.length; i++){
      if (body.equals(item[i].getBody())){
        if(!item[i].isTypeHP())
          g.drawImage(healthImage, (int) -radius, (int) -radius);
        else
          g.drawImage(ammoImage, (int) -radius, (int) -radius);
      }
    }
    /*g.rotate(0,0,(float) Math.toDegrees(body.getRotation()));
    g.drawOval((int) -radius,(int) -radius,(int) (radius*2),(int) (radius*2));
    g.drawLine(0,0,0,(int) -radius);*/
   
    g.popTransform();
  }
 
  protected void nextPlayer(){
    if(currentPlayer==p1){
      currentPlayer=p2;
    }
    else{
      currentPlayer=p1;
    }
    currentPlayer.nextBeaver();
  }

  private void drawRectangle(Graphics g, Body body, Rectangle shape) {
    g.pushTransform();
    g.translate(body.getX(), body.getY());
    g.rotate(0, 0, (float) Math.toDegrees(body.getRotation()));
    g.translate(shape.getXOffset(), shape.getYOffset());
    g.rotate(0, 0, (float) Math.toDegrees(shape.getAngleOffset()));

    float width = shape.getWidth();
    float height = shape.getHeight();

    if ((body.getUserData()) != null) {
      g.fillRect((int) -(width / 2), (int) -(height / 2), (int) width,
          (int) height);
    } else {
      g.drawRect((int) -(width / 2), (int) -(height / 2), (int) width,
          (int) height);
    }
    g.popTransform();
  }

  @SuppressWarnings("unchecked")
  @Override
  public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {
   
    try {
      bg_sprite = new Image("data/8bitBGgood.gif");
    } catch (SlickException e) {
      e.printStackTrace();
    }
   
    gc.setTargetFrameRate(Constants.FRAME_RATE);
    gc.setVSync(true);
    worldCenterX = gc.getWidth() / 2;
    worldCenterY = gc.getHeight() / 2;
    world = new World();
    world.setIterations(Constants.ITERATIONS);
    world.setGravity(-10);

    p1 = new Player(p1Name);
    p2 = new Player(p2Name);
   
    terrainy = new ImageBuffer(Constants.MAX_WIDTH, Constants.MAX_HEIGHT*2);
   
    terrainBitmap = Noise.GenerateWhiteNoise(Constants.MAX_WIDTH,Constants.MAX_HEIGHT*2);
    terrainBitmap = Noise.GenerateSmoothNoise(terrainBitmap,7);
    terrainBitmap = Noise.GeneratePerlinNoise(terrainBitmap,7);
   
    SlickDisplay();
    terrainyImage = terrainy.getImage();
    createTerrainBody2(-terrainyImage.getWidth()/2, -terrainyImage.getHeight()/2);
   
    for (int i = 0; i < Constants.BEAVERS_PER_TEAM; i++) {
      int[] coord = randomFreeCoordinate(20);
      if (coord[0] < 0) p1.getTeam()[i].setBody(new DynamicBody(new Circle(10.0f), -100*i, 1300));
      else p1.getTeam()[i].setBody(new DynamicBody(new Circle(10.0f), (coord[0]-terrainyImage.getWidth()/2), (coord[1]-terrainyImage.getHeight()/2)));
      p1.getTeam()[i].getBody().setDensity(1);
      p1.getTeam()[i].getBody().setFriction(1000);
      p1.getTeam()[i].getBody().setRestitution(0f);
      p1.getTeam()[i].getBody().setAngularDamping(1f);
      p1.getTeam()[i].getBody().setFixedRotation(true);
      world.add(p1.getTeam()[i].getBody());
    }
   
    for (int i = 0; i < Constants.BEAVERS_PER_TEAM; i++) {
      int[] coord = randomFreeCoordinate(20);
      if (coord[0] < 0) p2.getTeam()[i].setBody(new DynamicBody(new Circle(10.0f), -100*i, 1300));
      else p2.getTeam()[i].setBody(new DynamicBody(new Circle(10.0f), (coord[0]-terrainyImage.getWidth()/2), (coord[1]-terrainyImage.getHeight()/2)));
      p2.getTeam()[i].getBody().setDensity(1);
      p2.getTeam()[i].getBody().setFriction(1000);
      p2.getTeam()[i].getBody().setRestitution(0f);
      p2.getTeam()[i].getBody().setAngularDamping(1f);
      p2.getTeam()[i].getBody().setFixedRotation(true);
      world.add(p2.getTeam()[i].getBody());
    }

    currentPlayer = p1;
   
    //Add the invisible boundary
    boundary = addBoundary(Constants.MAX_WIDTH*2,Constants.MAX_HEIGHT*3);
    boundary.setRestitution(0f);
    world.add(boundary);
    world.addBodyListener(boundary, this);
   
    // load beaver images to use in our animation
    Image beaver = new Image("data/bazooka4.png");
    Image beaver2 = new Image("data/bazooka5.png");
    Image[] frames = {beaver.getFlippedCopy(false, true).getScaledCopy(0.5f), beaver2.getFlippedCopy(false, true).getScaledCopy(0.5f)};
    Image[] frames2 = {beaver.getFlippedCopy(true, true).getScaledCopy(0.5f), beaver2.getFlippedCopy(true, true).getScaledCopy(0.5f)};
    team1Moving = new Animation(frames, 1000, false); // duration in ms
    team1MovingR = new Animation(frames2, 1000, false); // duration in ms
    Image beaver3 = new Image("data/darkBazooka4.png");
    Image beaver4 = new Image("data/darkBazooka5.png");
    Image[] frames3 = {beaver3.getFlippedCopy(false, true).getScaledCopy(0.5f), beaver4.getFlippedCopy(false, true).getScaledCopy(0.5f)};
    Image[] frames4 = {beaver3.getFlippedCopy(true, true).getScaledCopy(0.5f), beaver4.getFlippedCopy(true, true).getScaledCopy(0.5f)};
    team2Moving = new Animation(frames3, 1000, false); // duration in ms
    team2MovingR = new Animation(frames4, 1000, false); // duration in ms
   
    // add the mouse listener
    gc.getInput().addMouseListener(this);
   
    //add two items to the world
    item = new Item[]{new Item(), new Item()};
    item[0].setTypeAmmo();
    item[1].setTypeHP();
    item[0].getBody().setFriction(1000);
    item[1].getBody().setFriction(1000);
    item[0].getBody().setRestitution(0);
    item[1].getBody().setRestitution(0);
    item[0].getBody().setFixedRotation(true);
    item[1].getBody().setFixedRotation(true);
    world.add(item[0].getBody());
    world.add(item[1].getBody());
    world.addBodyListener(item[0].getBody(), this);
    world.addBodyListener(item[1].getBody(), this);
   
    Body currentBeaverBody = currentPlayer.getCurrentBeaver().getBody();
    crosshairAngle = 45;
    crosshair = new StaticBody(new Rectangle(50f,5f),currentBeaverBody.getX(),currentBeaverBody.getY());
    world.add(crosshair);
    crosshair.setRotation(crosshairAngle);
    crosshairImage = new Image("data/crosshair.png").getScaledCopy(0.5f);
    bulletImage = new Image("data/wood.png").getScaledCopy(0.5f);
    healthImage = new Image("data/health.png").getScaledCopy(0.5f);
    ammoImage = new Image("data/ammo.png").getFlippedCopy(false, true).getScaledCopy(0.5f);
    timer(Constants.SECONDS_PER_TURN);
  }

  protected void timer(long countdown) {
    startTime = System.currentTimeMillis();
    endTime = startTime + (countdown * 1000);
  }
 
  private void endTurn(GameContainer gc){
    System.out.println("End the turn");
    Body currentBeaverBody = currentPlayer.getCurrentBeaver().getBody();
    if (currentBeaverBody.isAttached()) currentBeaverBody.setActive(true);
    //Cycle Player
    nextPlayer();
    currentBeaverBody = currentPlayer.getCurrentBeaver().getBody();
    worldCenterX = gc.getWidth()/2 - (currentBeaverBody.getX()*scale);
    worldCenterY = gc.getHeight()/2 - (currentBeaverBody.getY()*-scale);
    timer(Constants.SECONDS_PER_TURN);
  }
 
  protected void drawStats(Graphics g){
    g.drawString("\nPlayer: " + currentPlayer.getName(),300,460);
    g.drawString("\nBeaver: " + currentPlayer.getCurrentBeaver().getName(),300,480);
    g.drawString("\nWeapon: " + currentPlayer.getCurrentBeaver().getCurrentWeapon().getName(), 300, 500);
    g.drawString("\nAmmo: " + currentPlayer.getCurrentBeaver().getCurrentWeapon().getAmmo(), 300, 520);
    g.drawString("\nHP: " + currentPlayer.getCurrentBeaver().getHP(), 300, 540);
  }
 
  protected void createTerrainBody2(float x0, float y0) {
    if (terrain.length == 1) terrain = new CompoundShape[Constants.MAX_WIDTH];
    for (int x = 0; x < Constants.MAX_WIDTH; x++) {
      if (x < leftmostXFromExplosion && leftmostXFromExplosion != 1000000f) continue;
      if (x > rightmostXFromExplosion && rightmostXFromExplosion != -1f) continue;

      Polygon temp = new Polygon();
      CompoundShape compoundTemp = new CompoundShape();
      Vec2 firstPoint = null;
      Vec2 lastPoint = null;

      for (int y = 0; y < Constants.MAX_HEIGHT * 2; y++) {
        if (terrainBitmap[x][y] > 0.5) {
          if (firstPoint == null)
            firstPoint = new Vec2(x, y);
          else
            lastPoint = new Vec2(x, y);
        } else {
          if (firstPoint != null) {
            if (lastPoint == null)
              lastPoint = new Vec2(firstPoint.x + 0.1f,
                  firstPoint.y);
            temp.setPoints(new Vec2[] { firstPoint, lastPoint });
            compoundTemp.add(temp);
            temp = new Polygon();
            firstPoint = null;
            lastPoint = null;
          }
        }
      }
      if (firstPoint != null) {
        if (lastPoint == null)
          lastPoint = new Vec2(firstPoint.x + 0.1f, firstPoint.y);
        temp.setPoints(new Vec2[] { lastPoint, firstPoint });
        compoundTemp.add(temp);
        temp = new Polygon();
        firstPoint = null;
        lastPoint = null;
      }
      terrain[x] = compoundTemp;
      compoundTemp = new CompoundShape();

    }
   
    if (terrainBody.isAttached()){
      world.remove(terrainBody);
    }
   
    compoundTerrain = new CompoundShape();
    for (int i = 0; i < Constants.MAX_WIDTH; i++){
      compoundTerrain.add(terrain[i]);
    }   
   
    terrainBody = new StaticBody(compoundTerrain, x0, y0);
    terrainBody.setFriction(1000);
    terrainBody.setRestitution(0.1f);

    world.add(terrainBody);
    leftmostXFromExplosion = 1000000f;
    rightmostXFromExplosion = -1;
  }

  protected void SlickDisplay() {
    for (int x = 0; x < Constants.MAX_WIDTH; x++) {
      for (int y = 0; y < Constants.MAX_HEIGHT * 2; y++) {
        if (terrainBitmap[x][y] > 0.5) {
          terrainy.setRGBA(x, y, 184, 138, 0, (int)(255*terrainBitmap[x][y]));
          if (terrainBitmap[x][y] < 0.60)
            terrainy.setRGBA(x, y, 0, 184, 46, 255);
        } else
          terrainy.setRGBA(x, y, 0, 0, 0, 0);
      }
    }
  }

  /**Returns a random location with a circle of a certain radius free
   * */
  protected int[] randomFreeCoordinate(int radius){
    //set a boolean variable for whether there's a bottom below the found spot
    //also, a counter in case things go on for too long
    boolean hasBottom = false;
    //first pick a random point, and see if it's free in the grid
    Random gen = new Random();
    int x0 = gen.nextInt(Constants.MAX_WIDTH);
    int y0 = gen.nextInt(Constants.MAX_HEIGHT * 2);
    //Loop until we find a spot (give up after 1000 tries just in case)
    for(int i = 0; i < 1000; i++){
      //make sure there's a bottom to the spot we found
      if (terrainBitmap[x0][y0] < 0.5){
        for (int y = y0; y > 0; y--) {
          if (terrainBitmap[x0][y] > 0.5) hasBottom = true;
        }
        //then see if there's a square of the given distance around the spot we found
        try{
          if ((terrainBitmap[x0+radius][y0+radius] < 0.5) &&
            (terrainBitmap[x0-radius][y0+radius] < 0.5) &&
            (terrainBitmap[x0+radius][y0-radius] < 0.5) &&
            (terrainBitmap[x0-radius][y0-radius] < 0.5) &&
            hasBottom){  
          return new int[]{x0,y0};
          }
        } catch(Exception e){
        }
        hasBottom = false;
      }
      x0 = gen.nextInt(Constants.MAX_WIDTH);
      y0 = gen.nextInt(Constants.MAX_HEIGHT * 2);
      }
    return new int[]{-1,-1};
  }
 
  /**
   * Adds a circular impact to the terrainBitmap and redraws
   */
  protected void addExplosionToTerrain(int x0, float y0, int radius) {
    for (int x = 0; x < Constants.MAX_WIDTH; x++) {
      for (int y = 0; y < Constants.MAX_HEIGHT * 2; y++) {
        if (terrainBitmap[x][y] > 0.5) {
          double distance = Math.sqrt(Math.pow(x - terrainyImage.getWidth()/2 - x0, 2)
              + Math.pow(y - terrainyImage.getHeight()/2 - y0, 2));
          if (distance < radius) {
            terrainBitmap[x][y] = 0;
            if (x < leftmostXFromExplosion) leftmostXFromExplosion = x;
            if (x > rightmostXFromExplosion) rightmostXFromExplosion = x;
          }
        }
      }
    }
    createTerrainBody2(-terrainyImage.getWidth()/2, -terrainyImage.getHeight()/2);
    SlickDisplay();
    terrainyImage = terrainy.getImage();
  }

  @Override
  public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
   
    if(currentPlayer.hasLost()){
      if(currentPlayer==p1){
        JOptionPane.showMessageDialog(null,"Player 2 Wins!");
      }
      else{
        JOptionPane.showMessageDialog(null,"Player 1 Wins!");
      }
      sbg.enterState(BeaversGame.MAINMENUSTATE);
    }
    //if necessary remove beaver bodies
    Beaver[] p1Team = p1.getTeam();
    Beaver[] p2Team = p2.getTeam();
    for(int i=0;i<Constants.BEAVERS_PER_TEAM;i++){
      if(!p1Team[i].isAlive() && p1Team[i].getBody().isAttached()){
        p1Team[i].getBody().setActive(false);
        world.remove(p1Team[i].getBody());
      }
      if(!p2Team[i].isAlive() && p2Team[i].getBody().isAttached()){
        p2Team[i].getBody().setActive(false);
        world.remove(p2Team[i].getBody());
      }
    }
    //if necessary, kill the bullet
    if (killBullet){     
      if (bullet.isAttached()) {
        bullet.setActive(false);
        world.remove(bullet);
      }
      killBullet = false;
    }
    //if necessary, remove an item
    for (int i = 0; i < item.length; i++){
      if (item[i].remove == true && item[i].getBody().isAttached()) {
        item[i].getBody().setActive(false);
        world.remove(item[i].getBody());
      }
    }
    //Check win condition
    Body currentBeaverBody = currentPlayer.getCurrentBeaver().getBody();
    Beaver currentBeaver = currentPlayer.getCurrentBeaver();
    this.radius = currentBeaver.getCurrentWeapon().getBlastRadius();
   
    if (powerSeqEngaged) {
      if (power >= 150) power = 0;
      else power+=4;
    }
   
    // Keep the camera centered at all times *GIANNI*
    if(!cameraOnBullet){
      if (currentBeaverBody.isAttached())
        if (!currentBeaverBody.isSleeping()){
        worldCenterX = gc.getWidth()/2 - (currentBeaverBody.getX()*scale);
        worldCenterY = gc.getHeight()/2 - (currentBeaverBody.getY()*-scale);
        }
    }
    else{
      if (bullet.isAttached()){
        worldCenterX = gc.getWidth()/2 - (bullet.getX()*scale);
        worldCenterY = gc.getHeight()/2 - (bullet.getY()*-scale);
      }
    }
   
    for (int i = 0; i < Constants.UPDATES; i++) {

      Input input = gc.getInput();
     
      if (input.isKeyPressed(Input.KEY_C)) {
        worldCenterX = gc.getWidth()/2 - (currentBeaverBody.getX()*scale);
        worldCenterY = gc.getHeight()/2 - (currentBeaverBody.getY()*-scale);
      }
     
      if (input.isKeyDown(Input.KEY_Z)) { 
        if (scale > 0.001f) {
          scale = scale - 0.001f;
          worldCenterX = gc.getWidth()/2 - (currentBeaverBody.getX()*scale);
          worldCenterY = gc.getHeight()/2 - (currentBeaverBody.getY()*-scale);
        }
      }
     
      if (input.isKeyDown(Input.KEY_X)) {
        scale = scale + 0.001f;
        worldCenterX = gc.getWidth()/2 - (currentBeaverBody.getX()*scale);
        worldCenterY = gc.getHeight()/2 - (currentBeaverBody.getY()*-scale);
      }
     
      if (input.isKeyDown(Input.KEY_W)) {
        worldCenterY += 0.2f;// /updates;
      }
     
      if (input.isKeyDown(Input.KEY_S)) {
        worldCenterY -= 0.2f;// /updates;
      }
     
      if(input.isKeyPressed(Input.KEY_R)){
        System.out.println(crosshairAngle);
        crosshairAngle = 45;
      }

      if(input.isKeyPressed(Input.KEY_Q)){
        currentPlayer.getCurrentBeaver().cycleWeapon();
      }

      if (input.isKeyDown(Input.KEY_A)) {
        worldCenterX += 0.2f;// /updates;
      }
     
      if (input.isKeyPressed(Input.KEY_O)) {
        endTurn(gc);
      }
     
      if (input.isKeyDown(Input.KEY_D)) {
        worldCenterX -= 0.2f;// /updates;
      }
     
      if (input.isKeyDown(Input.KEY_RIGHT)) {
        if(endTurn>0){
          continue;
        }

        if (crosshairAngle > 180) crosshairAngle = 180-(crosshairAngle-180);
        team1MovingR.update(delta*100);
        team2MovingR.update(delta*100);
        currentPlayer.getCurrentBeaver().setFacingR(true);
        if (currentBeaverBody.getAngularVelocity() > -1.5)
          currentBeaverBody.setAngularVelocity(currentBeaverBody
              .getAngularVelocity() - 0.05f);
        currentBeaverBody.setAngularVelocity(-1.5f);
      }
     
      if (input.isKeyDown(Input.KEY_LEFT)) {
        if(endTurn>0){
          continue;
        }
        if (crosshairAngle < 180) crosshairAngle = 180+(180-crosshairAngle);
        team1Moving.update(delta*100);
        team2Moving.update(delta*100);
        currentPlayer.getCurrentBeaver().setFacingR(false);
        if (currentBeaverBody.getAngularVelocity() < 1.5)
          currentBeaverBody.setAngularVelocity(currentBeaverBody.getAngularVelocity() + 0.05f);
        currentBeaverBody.setAngularVelocity(1.5f);
      }
     
      if (input.isKeyDown(Input.KEY_UP)){
        if(endTurn>0){
          continue;
        }
        if (crosshairAngle < 180 && crosshairAngle > 0) crosshairAngle -= 0.1f;
        else if (crosshairAngle > 180 && crosshairAngle < 360) crosshairAngle += 0.1f;
      }
     
      if (input.isKeyDown(Input.KEY_DOWN)){
        if(endTurn>0){
          continue;
        }
        if (crosshairAngle < 180 && crosshairAngle > 0) crosshairAngle += 0.1f;
        else if (crosshairAngle > 180 && crosshairAngle < 360) crosshairAngle -= 0.1f;
      }
     
      if (input.isKeyPressed(Input.KEY_ENTER)) {
        if(endTurn>0){
          continue;
        }
        if(currentPlayer.getCurrentBeaver().getCurrentWeapon().getAmmo()>0){
          currentPlayer.getCurrentBeaver().useWeapon();
          if (!powerSeqEngaged) {
            power = 1;
            powerSeqEngaged = true;
          }
          else {
            powerSeqEngaged = false;
            currentBeaverBody.setActive(false);
            bullet = new DynamicBody(new Circle(5),currentBeaverBody.getX(),currentBeaverBody.getY());
            bullet.setBullet(true);
            bullet.setRestitution(0);
            float x = (float) (Math.sin(Math.toRadians(crosshairAngle)));
            float y = (float) (Math.cos(Math.toRadians(crosshairAngle)));
            float xForce = (power/50)*(x)*10000000f;
            float yForce = (power/50)*(y)*10000000f;
            //System.out.println("x is "+x+", y is "+y+", angle at"+crosshairAngle);
            world.add(bullet);
            world.addBodyListener(bullet, this);
            bullet.applyForce(xForce, yForce);
            //Shot is fired, turn is over
            cameraOnBullet = true;
          }
        }

      }
     
      if (input.isKeyPressed(Input.KEY_SPACE)) {
        if (currentBeaverBody.getYVelocity() < 0.7 && currentBeaver.getFacingR()) {
          currentBeaverBody.applyForce(0, 1500000f);// /updates);
        }
        if (currentBeaverBody.getYVelocity() > -0.7 && !currentBeaver.getFacingR()) {
          currentBeaverBody.applyForce(0, 1500000f);// /updates);
        }
      }
     
      if (input.isKeyPressed(Input.KEY_ESCAPE)){
        sbg.enterState(BeaversGame.MAINMENUSTATE);
      }
     
      if (drawCircle) {
        addExplosionToTerrain((int) collisionX, (int) collisionY, this.radius);
        drawCircle = false;
      }
     
      if (System.currentTimeMillis() >= endTime || endTurn == 0) {
        endTurn = -1;
        endTurn(gc);
        cameraOnBullet = false;
      }
     
      if (endTurn > 0) endTurn--;
      world.update(1f / Constants.UPDATES_PER_SECOND);
    }
  }

  @Override
  public void mouseReleased(int button, int x, int y) {
    drawCircle = false;
    collisionX = (x - worldCenterX)/scale;
    collisionY = (y - worldCenterY)/-scale;
    System.out.println("Click @ "+(x-worldCenterX)+", "+-(y-worldCenterY)+".");
  }
 
  public int calculateDMG(double distance){
    int damage = (int) (80-distance);
    if(damage<0){
      damage=0;
    }
    return damage;
  }

  @Override
  public void collided(CollisionEvent event) {
    this.radius = currentPlayer.getCurrentBeaver().getCurrentWeapon().getBlastRadius();
    Body currentBeaverBody = currentPlayer.getCurrentBeaver().getBody();
    Beaver[] p1Team = p1.getTeam();
    Beaver[] p2Team = p2.getTeam();
    if (event.contains(bullet)) {
     
      WorldManifold worldManifold = new WorldManifold();
      event.getContact().jboxContact.getWorldManifold(worldManifold);

      drawCircle = true;
      collisionX = worldManifold.points[0].x;
      collisionY = worldManifold.points[0].y;
     
      float bulletX = bullet.getX();
      float bulletY = bullet.getY();
      //mark the bullet to be killed on the next update cycle
      killBullet = true;
      //mark the turn to be ended
      endTurn = 2000;

      //How much damage to do?
      for(int i = 0;i<Constants.BEAVERS_PER_TEAM;i++){
        double x1 = p1Team[i].getBody().getX();
        double y1 = p1Team[i].getBody().getY();
        double x2 = p2Team[i].getBody().getX();
        double y2 = p2Team[i].getBody().getY();
        double distanceB1 = distance(x1,y1,bulletX,bulletY);
        double distanceB2 = distance(x2,y2,bulletX,bulletY);
        if(distanceB1 < this.radius ){
          int damage = calculateDMG(distanceB1);
          p1Team[i].reduceHP(damage);
        }
        if(distanceB2 < this.radius){
          int damage = calculateDMG(distanceB1);
          p2Team[i].reduceHP(damage);
        }
      }
     
     
    }
    //if a body hits the boundary and it's a bullet, remove it.
    //it a beaver hits it, kill the beaver.
    if (event.contains(boundary)) {
      Body otherBody;
      if (event.getBodyA().equals(boundary)) otherBody = event.getBodyB();
      else otherBody = event.getBodyA();
      for(int i=0;i<Constants.BEAVERS_PER_TEAM;i++){
        if(p1Team[i].getBody()==otherBody){
          p1Team[i].reduceHP(1000);
          endTurn = 2000;
          //break;
        }
        if(p2Team[i].getBody()==otherBody){
          p2Team[i].reduceHP(1000);
          endTurn = 2000;
          //break;
        }
      }
      if (otherBody.equals(bullet)) {
        killBullet = true;
        endTurn = 2000;
     
    }
    //if the current beaver collects a health pack or ammo
    for (int i = 0; i < item.length; i++){
      if (event.contains(currentBeaverBody) && event.contains(item[i].getBody())) {
        if (item[i].isTypeAmmo()) currentPlayer.getCurrentBeaver().AddHP(100);
        if (item[i].isTypeHP()) currentPlayer.getCurrentBeaver().getCurrentWeapon().addAmmo(10);
        item[i].remove = true;
      }
    }
   
  }
 
  public double distance(double x1,double y1, double x2, double y2){
    double newX = x2 - x1;
    double newY = y2 - y1;
    newX = Math.pow(newX, 2);
    newY = Math.pow(newY,2);
    double value = Math.sqrt((newX+newY));
    return value;
  }
 
  @Override
  public void separated(CollisionEvent event) {
    Body currentBeaverBody = currentPlayer.getCurrentBeaver().getBody();
    if (event.contains(currentBeaverBody)) {
      drawCircle = false;
    }
  }
 
  protected StaticBody addBoundary(int width, int height){
   
    Polygon top = new Polygon();
    Polygon left = new Polygon();
    Polygon right = new Polygon();
    Polygon bottom = new Polygon();
    Vec2[] topP = {
        new Vec2(width, height),
        new Vec2(-width, height)
    };
    top.setPoints(topP);

    Vec2[] leftP = {
        new Vec2(-width, height),
        new Vec2(-width, -height)
    };
    left.setPoints(leftP);

    Vec2[] rightP = {
        new Vec2(width, -height),
        new Vec2(width, height)
    };
    right.setPoints(rightP);

    Vec2[] bottomP = {
        new Vec2(width, -height),
        new Vec2(-width, -height)
    }
    bottom.setPoints(bottomP);

    CompoundShape boundaryShape = new CompoundShape();
    boundaryShape.add(top);
    boundaryShape.add(left);
    boundaryShape.add(right);
    boundaryShape.add(bottom);

    return new StaticBody(boundaryShape,0,0);
  }
 
}
TOP

Related Classes of beaver.game.GameplayState

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.