Package com.szuppe.jakub.model

Source Code of com.szuppe.jakub.model.Brick

/**
*
*/
package com.szuppe.jakub.model;

import java.awt.Dimension;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.TreeSet;

import com.szuppe.jakub.common.Coordinates2D;
import com.szuppe.jakub.common.LineSegment2D;
import com.szuppe.jakub.common.DoesnotIntersectException;
import com.szuppe.jakub.common.Ray2D;
import com.szuppe.jakub.common.SpeedVector2D;
import com.szuppe.jakub.mockups.BrickType;

/**
* @author Jakub Szuppe <j.szuppe at gmail.com>
*
*/
class Brick
{
  /** Współrzędne lewego-górnego rogu klocka. */
  private final Coordinates2D  topLeftCoordinates;
  /** Wymiary klocka (szerokość x wysokość) */
  private final Dimension    dimension;

  /**
   * Tworzy klocek o podanych wymiarach i współrzędnych.
   *
   * @param topLeftCoordinates - współrzędne lewego-górnego rogu klocka.
   * @param dimension - wymiary.
   */
  public Brick(Coordinates2D topLeftCoordinates, Dimension dimension)
  {
    this.topLeftCoordinates = topLeftCoordinates;
    this.dimension = dimension;
  }

  /**
   * Tworzy nowy klocek na podstawie podanego.
   *
   * @param brick
   */
  public Brick(Brick brick)
  {
    this(brick.getTopLeftCornerCoordinates(), brick.getDimension());
  }

  /**
   * Sprawdza, czy i kiedy zajdą kolizje między klockiem, a piłką.
   * Jeżeli tak zwraca odpowiedni kolekcję kolizji, które mogą wystąpić.
   * Jeżeli nie zwraca pustą kolekcję.
   *
   * @param ball - piłka, z którą może zajść kolizja.
   * @return Kolekcję kolizji.
   */
  public Collection<Collision> checkCollisionsWithBall(Ball ball)
  {
    TreeSet<Collision> collisionList = new TreeSet<>();
    List<LineSegment2D> brickLineSegments = getBrickWithCirleCollisionLineSegments(ball
        .getRadius());
    Side sides[] = { Side.BOTTOM, Side.RIGHT, Side.TOP, Side.LEFT, Side.CORNER,
        Side.CORNER, Side.CORNER, Side.CORNER };
    Ray2D ballMovementRay = ball.getMovementRay();
    SpeedVector2D ballSpeed = ball.getSpeed();
    Coordinates2D pointOfIntersection;
    for (LineSegment2D brickLineSegment : brickLineSegments)
    {
      try
      {
        pointOfIntersection = brickLineSegment.intersectionPoint(ballMovementRay);
        double distance = Math.sqrt(Math.pow(
            pointOfIntersection.getX() - ball.getX(), 2)
            + Math.pow(pointOfIntersection.getY() - ball.getY(), 2));
        long timeTillCollision = (long) (distance / ballSpeed.getSpeedValue());
        Side side = sides[brickLineSegments.indexOf(brickLineSegment)];
        collisionList.add(new BallWithBrickCollision(timeTillCollision, this, side));
      } catch (DoesnotIntersectException e)
      {
        // Nie ma kolizji. To nie jest silent fail.
      }
    }
    return collisionList;
  }

  /**
   * @return Współrzędne lewego-górnego rogu.
   */
  public Coordinates2D getTopLeftCornerCoordinates()
  {
    return new Coordinates2D(topLeftCoordinates);
  }

  /**
   * @return Współrzędne prawego-górnego rogu.
   */
  public Coordinates2D getTopRightCornerCoordinates()
  {
    return new Coordinates2D(
        (float) (topLeftCoordinates.getX() + dimension.getWidth()),
        topLeftCoordinates.getY());
  }

  /**
   * @return Współrzędne prawego-dolnego rogu.
   */
  public Coordinates2D getBottomRightCornerCoordinates()
  {
    return new Coordinates2D(
        (float) (topLeftCoordinates.getX() + dimension.getWidth()),
        (float) (topLeftCoordinates.getY() - dimension.getHeight()));
  }

  /**
   * @return Współrzędne lewego-dolnego rogu.
   */
  public Coordinates2D getBottomLeftCornerCoordinates()
  {
    return new Coordinates2D((float) (topLeftCoordinates.getX()),
        (float) (topLeftCoordinates.getY() - dimension.getHeight()));
  }

  /**
   * @return Współrzędne środka klocka.
   */
  public Coordinates2D getCenterCoordiantes()
  {
    return new Coordinates2D(
        (float) (topLeftCoordinates.getX() + dimension.getWidth() / 2),
        (float) (topLeftCoordinates.getY() - dimension.getHeight() / 2));
  }

  /**
   * @return Wymiary klocka.
   */
  public Dimension getDimension()
  {
    return new Dimension(dimension);
  }

  /**
   * @return Typ klocka.
   */
  public BrickType getBrickType()
  {
    return BrickType.NormalBrick;
  }

  /**
   * Zwraca listę odcinków, które reprezentują linie kolizji
   * z okręgiem o podanym promieniu.
   * Kolejność odcinków: spód, prawa ściana, wierzch, lewa ściana,
   * lewy-dolny róg, prawy-dolny róg, prawy-góry róg, lewy-góry róg.
   *
   * @param radius - promień okręgu.
   * @return Lista odcinków.
   */
  private List<LineSegment2D> getBrickWithCirleCollisionLineSegments(final float radius)
  {
    List<LineSegment2D> brickLineSegments = new LinkedList<>();
    // spód
    Coordinates2D bottomStart = getBottomLeftCornerCoordinates().moveAlongVector(
        new Coordinates2D(0, -radius));
    Coordinates2D bottomEnd = getBottomRightCornerCoordinates().moveAlongVector(
        new Coordinates2D(0, -radius));
    brickLineSegments.add(new LineSegment2D(bottomStart, bottomEnd));
    // prawa ściana
    Coordinates2D rightSideStart = getBottomRightCornerCoordinates().moveAlongVector(
        new Coordinates2D(radius, 0));
    Coordinates2D rightSideEnd = getTopRightCornerCoordinates().moveAlongVector(
        new Coordinates2D(radius, 0));
    brickLineSegments.add(new LineSegment2D(rightSideStart, rightSideEnd));
    // wierzch
    Coordinates2D topStart = getTopRightCornerCoordinates().moveAlongVector(
        new Coordinates2D(0, radius));
    Coordinates2D topEnd = getTopLeftCornerCoordinates().moveAlongVector(
        new Coordinates2D(0, radius));
    brickLineSegments.add(new LineSegment2D(topStart, topEnd));
    // Lewa ściana przesunięte o radius na zewnątrz.
    Coordinates2D leftSideStart = getTopLeftCornerCoordinates().moveAlongVector(
        new Coordinates2D(-radius, 0));
    Coordinates2D leftSideEnd = getBottomLeftCornerCoordinates().moveAlongVector(
        new Coordinates2D(-radius, 0));
    brickLineSegments.add(new LineSegment2D(leftSideStart, leftSideEnd));
    // lewy-dolny róg
    brickLineSegments.add(new LineSegment2D(leftSideEnd, bottomStart));
    // prawy-dolny róg
    brickLineSegments.add(new LineSegment2D(bottomEnd, rightSideStart));
    // prawy-górny róg
    brickLineSegments.add(new LineSegment2D(rightSideEnd, topStart));
    // lewy-górny róg
    brickLineSegments.add(new LineSegment2D(topEnd, leftSideStart));
    return brickLineSegments;
  }
}
TOP

Related Classes of com.szuppe.jakub.model.Brick

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.