Esempio n. 1
0
  private void drawFeatheredFullLine(
      Vector2 a, Vector2 b, float width, float feather, Color color) {
    checkMaxVerts(3 * 6);

    // Calculate the normal that defines the center rectangle
    norm.set(b);
    norm.sub(a);
    norm.rotate(90);
    norm.setLength(width / 2); // Scale to line width

    // Calculate the normal that defines feathering
    feath.set(norm);
    feath.setLength(feather / 2);

    zeroAlpha.set(color);
    zeroAlpha.a = 0;

    // ORDER OF RENDERING

    // 1                    2
    // top feather
    // 3                    4

    // center

    // 5                    6
    // bottom feather
    // 7                    8

    // Top feather
    tL.set(a).add(norm).add(feath);
    tR.set(b).add(norm).add(feath);
    bL.set(a).add(norm);
    bR.set(b).add(norm);

    // Draw it
    // Top feather  (1-2-3)
    uncheckedTriangle(tL.x, tL.y, tR.x, tR.y, bL.x, bL.y, zeroAlpha, zeroAlpha, color);
    uncheckedTriangle(tR.x, tR.y, bL.x, bL.y, bR.x, bR.y, zeroAlpha, color, color);

    // Center line
    tL.set(a).add(norm);
    tR.set(b).add(norm);
    bL.set(a).sub(norm);
    bR.set(b).sub(norm);

    // Draw it
    uncheckedTriangle(tL.x, tL.y, tR.x, tR.y, bL.x, bL.y, color, color, color);
    uncheckedTriangle(tR.x, tR.y, bL.x, bL.y, bR.x, bR.y, color, color, color);

    // Bottom feather
    tL.set(a).sub(norm);
    tR.set(b).sub(norm);
    bL.set(a).sub(norm).sub(feath);
    bR.set(b).sub(norm).sub(feath);

    // Draw it
    uncheckedTriangle(tL.x, tL.y, tR.x, tR.y, bL.x, bL.y, color, color, zeroAlpha);
    uncheckedTriangle(tR.x, tR.y, bL.x, bL.y, bR.x, bR.y, color, zeroAlpha, zeroAlpha);
  }
Esempio n. 2
0
  public void drawArrow(
      Vector2 a,
      Vector2 b,
      float width,
      float feather,
      float headDist,
      float headWidth,
      Color color) {
    // Firstly, draw the body of the arrow. B is the front.
    drawLine(a, b, width, feather, color);

    // Get the direction vector a->b
    dir.set(a);
    dir.sub(b);
    dir.scl(1 / dir.len());

    // Get the point down the line that the arrow head lines get to
    d.set(dir);
    d.scl(headDist);
    d.add(b);

    // Now, move d out to the sides
    amount.set(dir);
    amount.rotate(90);
    amount.scl(headWidth);

    right.set(d).add(amount);
    left.set(d).sub(amount);

    // Draw the arrow heads to not-quite-b to make it prettier
    c.set(b);
    c.sub(dir.scl(-width * 0.2f));
    drawLine(c, left, width, feather, color);
    drawLine(c, right, width, feather, color);
  }
Esempio n. 3
0
  @Override
  public void update() {
    if (!isActive()) return;

    posCpy.set(GameModel.getPlayer().position);
    diffToPlayer.set(posCpy.sub(position));

    float wantedAngle = MathUtils.atan2(diffToPlayer.y, diffToPlayer.x);
    /*
                      ^
            3,14 <--- |----> 0
    */
    if (direction == AbstractMap.N && (wantedAngle > MathUtils.PI || wantedAngle < 0)) return;
    else if (direction == AbstractMap.S && wantedAngle > 0) return;
    else if (direction == AbstractMap.W
        && (!(wantedAngle < MathUtils.PI / 2f && wantedAngle > -MathUtils.PI / 2f))) return;
    else if (direction == AbstractMap.E
        && (!(wantedAngle > MathUtils.PI / 2f || wantedAngle < -MathUtils.PI / 2f))) return;

    body.setTransform(position.x, position.y, wantedAngle);

    if (diffToPlayer.len() < Config.getDimensions().WORLD_WIDTH / 2f)
      if (MathUtils.random()
          < (type == CANNON_TYPE.SINGLE ? Config.BULLET_RATE_LOW : Config.BULLET_RATE_MEDIUM)) {
        float angle = body.getAngle() * MathUtils.radiansToDegrees;

        origin.set(position).add(diffToPlayer.scl(.1f));
        posCpy.set(GameModel.getPlayer().position);

        if (type == CANNON_TYPE.SINGLE) {
          weapon.fire1(origin, posCpy.rotate(MathUtils.random(-1, 1)));
          createGunSmoke(angle);
        } else if (type == CANNON_TYPE.DOUBLE) {
          weapon.fire1(origin, posCpy.rotate(MathUtils.random(-1, 1)));
          weapon.fire2(origin, posCpy.rotate(MathUtils.random(-1, 1)));
        }
      }
  }
Esempio n. 4
0
  public void add(float centreX, float centreY) {
    positionEmiter.rotate(EndlessMode.delta15 * speed);

    tmp.x = (centreX - SparklesColorOverTime.HALF_HEIGHT) + positionEmiter.x;
    tmp.y = centreY + positionEmiter.y;

    angle = Physic.getAngleWithPlayer(tmp, SparklesColorOverTime.HALF_HEIGHT, 0);
    angle += 110 - (Player.shield * 10);

    SparklesColorOverTimeWide.add(
        (centreX - SparklesColorOverTime.HALF_HEIGHT) + positionEmiter.x,
        centreY + positionEmiter.y,
        angle,
        PrecalculatedParticles.colorsOverTimeBlue,
        Particles.COLOR_OVER_TIME_FOREGROUND,
        1);

    SparklesColorOverTimeWide.add(
        (centreX - SparklesColorOverTime.HALF_HEIGHT) - positionEmiter.x,
        centreY - positionEmiter.y,
        angle,
        PrecalculatedParticles.colorsOverTimeYellowToGreen,
        Particles.COLOR_OVER_TIME_FOREGROUND,
        1);

    if (!EndlessMode.triggerStop) {
      SparklesColorOverTimeWide.add(
          (centreX - SparklesColorOverTime.HALF_HEIGHT) + positionEmiter.x * 0.9f,
          centreY - positionEmiter.y * 0.9f,
          -angle,
          PrecalculatedParticles.colorsOverTimeYellowToGreen,
          Particles.COLOR_OVER_TIME_FOREGROUND,
          1);

      SparklesColorOverTimeWide.add(
          (centreX - SparklesColorOverTime.HALF_HEIGHT) - positionEmiter.x * 0.9f,
          centreY + positionEmiter.y * 0.9f,
          -angle,
          PrecalculatedParticles.colorsOverTimeBlue,
          Particles.COLOR_OVER_TIME_FOREGROUND,
          1);
    }
  }
Esempio n. 5
0
  public void drawLine(Vector2 a, Vector2 b, float width, Color color) {
    setType(GL20.GL_TRIANGLES);

    // Calculate the normal that defines the center rectangle
    norm.set(b);
    norm.sub(a);
    norm.rotate(90);
    norm.setLength(width / 2); // Scale to line width

    // 1                    2
    // top feather
    // 3                    4

    // Top feather
    tL.set(a).add(norm);
    tR.set(b).add(norm);
    bL.set(a).sub(norm);
    bR.set(b).sub(norm);

    uncheckedTriangle(tL.x, tL.y, tR.x, tR.y, bL.x, bL.y, color, color, color);
    uncheckedTriangle(tR.x, tR.y, bL.x, bL.y, bR.x, bR.y, color, color, color);
  }
Esempio n. 6
0
  public Beaver(World world, Island island) {
    this.island = island;
    float scale = 2.0f;
    float radius = 1.0f;
    BodyDef bd = new BodyDef();
    bd.type = BodyDef.BodyType.DynamicBody;

    Vector2 pos = island.physicsBody.getPosition();
    ang = island.physicsBody.getAngle();

    float islandW = island.getPhysicsWidth();
    float islandH = island.getPhysicsHeight();

    Vector2 off = new Vector2(islandW * MathUtils.random(0.3f, 0.6f), islandH);
    off.rotate(MathUtils.radiansToDegrees * ang);

    bd.position.set(new Vector2(pos.x + off.x, pos.y + off.y));
    bd.angle = ang;

    off.set(islandW * 0.075f, islandH);
    off.rotate(MathUtils.radiansToDegrees * ang);
    Vector2 rightEdge = new Vector2(pos.x + off.x, pos.y + off.y).scl(Mane.PTM_RATIO);
    off.set(islandW * 0.85f, islandH);
    off.rotate(MathUtils.radiansToDegrees * ang);
    Vector2 leftEdge = new Vector2(pos.x + off.x, pos.y + off.y).scl(Mane.PTM_RATIO);

    float speed = MathUtils.random(1.0f, 3.0f);
    addAction(
        Actions.delay(
            MathUtils.random(0.0f, 1.0f),
            Actions.forever(
                Actions.sequence(
                    Actions.moveTo(rightEdge.x, rightEdge.y, speed),
                    Actions.moveTo(leftEdge.x, leftEdge.y, speed)))));

    bd.linearDamping = 0.2f;

    Body body = world.createBody(bd);

    FixtureDef fd = new FixtureDef();

    fd.density = 1.0f;
    fd.filter.categoryBits = Collision.BEAVER;
    fd.filter.maskBits = Collision.SHARK;

    fd.restitution = 0.0f;
    fd.friction = 0.0f;
    fd.isSensor = true;

    CircleShape cs = new CircleShape();
    cs.setRadius(radius);
    cs.setPosition(new Vector2(radius, radius));

    fd.shape = cs;

    body.createFixture(fd);
    cs.dispose();
    super.initPhysicsBody(body);

    setSize(scale * Mane.PTM_RATIO, scale * Mane.PTM_RATIO);
    setOrigin(0.0f, 0.0f);
  }
Esempio n. 7
0
  /**
   * Creates an array of PolySpatials based on fixture information from the scene. Note that
   * fixtures create aligned textures.
   *
   * @param scene
   */
  private void createPolySpatialsFromRubeFixtures(RubeScene scene) {
    Array<Body> bodies = scene.getBodies();

    EarClippingTriangulator ect = new EarClippingTriangulator();

    if ((bodies != null) && (bodies.size > 0)) {
      polySpatials = new Array<PolySpatial>();
      Vector2 bodyPos = new Vector2();
      // for each body in the scene...
      for (int i = 0; i < bodies.size; i++) {
        Body body = bodies.get(i);
        bodyPos.set(body.getPosition());

        Array<Fixture> fixtures = body.getFixtureList();

        if ((fixtures != null) && (fixtures.size > 0)) {
          // for each fixture on the body...
          for (int j = 0; j < fixtures.size; j++) {
            Fixture fixture = fixtures.get(j);

            String textureName = (String) scene.getCustom(fixture, "TextureMask", null);
            if (textureName != null) {
              String textureFileName = "data/" + textureName;
              Texture texture = textureMap.get(textureFileName);
              TextureRegion textureRegion = null;
              if (texture == null) {
                texture = new Texture(textureFileName);
                texture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
                textureMap.put(textureFileName, texture);
                textureRegion = new TextureRegion(texture);
                textureRegionMap.put(texture, textureRegion);
              } else {
                textureRegion = textureRegionMap.get(texture);
              }

              // only handle polygons at this point -- no chain, edge, or circle fixtures.
              if (fixture.getType() == Shape.Type.Polygon) {
                PolygonShape shape = (PolygonShape) fixture.getShape();
                int vertexCount = shape.getVertexCount();
                float[] vertices = new float[vertexCount * 2];

                // static bodies are texture aligned and do not get drawn based off of the related
                // body.
                if (body.getType() == BodyType.StaticBody) {
                  for (int k = 0; k < vertexCount; k++) {

                    shape.getVertex(k, mTmp);
                    mTmp.rotate(body.getAngle() * MathUtils.radiansToDegrees);
                    mTmp.add(
                        bodyPos); // convert local coordinates to world coordinates to that textures
                                  // are
                    // aligned
                    vertices[k * 2] = mTmp.x * PolySpatial.PIXELS_PER_METER;
                    vertices[k * 2 + 1] = mTmp.y * PolySpatial.PIXELS_PER_METER;
                  }

                  short[] triangleIndices = ect.computeTriangles(vertices).toArray();
                  PolygonRegion region =
                      new PolygonRegion(textureRegion, vertices, triangleIndices);
                  PolySpatial spatial = new PolySpatial(region, Color.WHITE);
                  polySpatials.add(spatial);
                } else {
                  // all other fixtures are aligned based on their associated body.
                  for (int k = 0; k < vertexCount; k++) {
                    shape.getVertex(k, mTmp);
                    vertices[k * 2] = mTmp.x * PolySpatial.PIXELS_PER_METER;
                    vertices[k * 2 + 1] = mTmp.y * PolySpatial.PIXELS_PER_METER;
                  }
                  short[] triangleIndices = ect.computeTriangles(vertices).toArray();
                  PolygonRegion region =
                      new PolygonRegion(textureRegion, vertices, triangleIndices);
                  PolySpatial spatial = new PolySpatial(region, body, Color.WHITE);
                  polySpatials.add(spatial);
                }
              } else if (fixture.getType() == Shape.Type.Circle) {
                CircleShape shape = (CircleShape) fixture.getShape();
                float radius = shape.getRadius();
                int vertexCount = (int) (12f * radius);
                float[] vertices = new float[vertexCount * 2];
                System.out.println("SpatialFactory: radius: " + radius);
                if (body.getType() == BodyType.StaticBody) {
                  mTmp3.set(shape.getPosition());
                  for (int k = 0; k < vertexCount; k++) {
                    // set the initial position
                    mTmp.set(radius, 0);
                    // rotate it by 1/vertexCount * k
                    mTmp.rotate(360f * k / vertexCount);
                    // add it to the position.
                    mTmp.rotate(body.getAngle() * MathUtils.radiansToDegrees);
                    mTmp.add(mTmp3);
                    mTmp.add(
                        bodyPos); // convert local coordinates to world coordinates to that textures
                                  // are aligned
                    vertices[k * 2] = mTmp.x * PolySpatial.PIXELS_PER_METER;
                    vertices[k * 2 + 1] = mTmp.y * PolySpatial.PIXELS_PER_METER;
                  }
                  short[] triangleIndices = ect.computeTriangles(vertices).toArray();
                  PolygonRegion region =
                      new PolygonRegion(textureRegion, vertices, triangleIndices);
                  PolySpatial spatial = new PolySpatial(region, Color.WHITE);
                  polySpatials.add(spatial);
                } else {
                  mTmp3.set(shape.getPosition());
                  for (int k = 0; k < vertexCount; k++) {
                    // set the initial position
                    mTmp.set(radius, 0);
                    // rotate it by 1/vertexCount * k
                    mTmp.rotate(360f * k / vertexCount);
                    // add it to the position.
                    mTmp.add(mTmp3);
                    vertices[k * 2] = mTmp.x * PolySpatial.PIXELS_PER_METER;
                    vertices[k * 2 + 1] = mTmp.y * PolySpatial.PIXELS_PER_METER;
                  }
                  short[] triangleIndices = ect.computeTriangles(vertices).toArray();
                  PolygonRegion region =
                      new PolygonRegion(textureRegion, vertices, triangleIndices);
                  PolySpatial spatial = new PolySpatial(region, body, Color.WHITE);
                  polySpatials.add(spatial);
                }
              }
            }
          }
        }
      }
    }
  }
 private Vector2 getLocalPosition() {
   absolutePosition.set(localPosition.x, localPosition.y);
   absolutePosition.rotate(parent.getAngle());
   absolutePosition.set(absolutePosition.x + parent.getX(), absolutePosition.y + parent.getY());
   return absolutePosition;
 }
 @Override
 public float projectY(float x, float y) {
   tmp.set(x - getX(), y - getY());
   tmp.rotate(-getAngle());
   return tmp.y;
 }
Esempio n. 10
0
  @Override
  public void update(BaseObject parent) {
    Vector2f acceleration = ((GameObject) parent).getAcceleration();
    acceleration.set(0, 0);

    if (sys.keyboard.isKeyPressed(ButtonActions.MOVE_UP)) {
      acceleration.y = ACCELERATION;
    }
    if (sys.keyboard.isKeyPressed(ButtonActions.MOVE_DOWN)) {
      acceleration.y = -ACCELERATION;
    }
    if (sys.keyboard.isKeyPressed(ButtonActions.MOVE_LEFT)) {
      acceleration.x = -ACCELERATION;
    }
    if (sys.keyboard.isKeyPressed(ButtonActions.MOVE_RIGHT)) {
      acceleration.x = ACCELERATION;
    }

    if (sys.currentTime - lastTime < fireRate) {
      return;
    }

    // FIXME I really shouldn't be using hardcoded values to figure out where to
    // shoot the bullets from.
    // FIXME I also REALLY REALLY need to get my vectors sorted out so that I don't have to
    // resort to this ugliness.
    bulletVelocity.set(
        ((GameObject) parent).getVelocity().x, ((GameObject) parent).getVelocity().x);
    bulletPosition.set(16f, 0f);

    if (sys.keyboard.isKeyPressed(ButtonActions.FIRE_LEFT)) {
      bulletVelocity.x -= BULLET_VELOCITY;
      bulletPosition.y = 16f;
      bulletPosition.x = 0f;
    }

    if (sys.keyboard.isKeyPressed(ButtonActions.FIRE_RIGHT)) {
      bulletVelocity.x += BULLET_VELOCITY;
      bulletPosition.y = 16f;
      bulletPosition.x = 32f;
    }

    if (sys.keyboard.isKeyPressed(ButtonActions.FIRE_UP)) {
      bulletVelocity.y += BULLET_VELOCITY;
      bulletPosition.y = 32f;
    }

    if (sys.keyboard.isKeyPressed(ButtonActions.FIRE_DOWN)) {
      bulletVelocity.y -= BULLET_VELOCITY;
      bulletPosition.y = 0f;
    }

    if (bulletVelocity.x != 0f || bulletVelocity.y != 0f) {
      Vector2f position = ((GameObject) parent).getPosition();
      bulletPosition.x += position.x;
      bulletPosition.y += position.y;

      GameObject bullet = bulletPool.obtain();

      if (bullet != null) {
        bullet.setPosition(bulletPosition.x, bulletPosition.y);

        bulletVelocity.rotate(bulletCounter * spreadDegree);

        bullet.setVelocity(bulletVelocity.x, bulletVelocity.y);

        sys.manager.add(bullet);

        if (bulletCounter == spreadCount / 2) {
          bulletCounter = -bulletCounter;
        } else {
          bulletCounter++;
        }
      }
    }
    lastTime = sys.currentTime;
  }
Esempio n. 11
0
 public void transformVectorToParent(Vector2 vector) {
   vector.rotate(this.getRotation());
 }
Esempio n. 12
0
  /** Sets position, rotation, scale and origin in actor to meet the 3 given points */
  public static void applyTransformation(
      Actor actor, Vector2 origin, Vector2 tangent, Vector2 normal) {
    /*
     * We are going to calculate the affine transformation for the actor to
     * fit the bounds represented by the handles. The affine transformation
     * is defined as follows:
     */
    // |a b tx|
    // |c d ty|=|Translation Matrix| x |Scale Matrix| x |Rotation
    // Matrix|
    // |0 0 1 |
    /*
     * More info about affine transformations:
     * https://people.gnome.org/~mathieu
     * /libart/libart-affine-transformation-matrices.html, To obtain the
     * matrix, we want to resolve the following equation system:
     */
    // | a b tx| |0| |o.x|
    // | c d ty|*|0|=|o.y|
    // | 0 0 1 | |1| | 1 |
    //
    // | a b tx| |w| |t.x|
    // | c d ty|*|0|=|t.y|
    // | 0 0 1 | |1| | 1 |
    //
    // | a b tx| |0| |n.x|
    // | c d ty|*|h|=|n.y|
    // | 0 0 1 | |1| | 1 |
    /*
     * where o is handles[0] (origin), t is handles[2] (tangent) and n is
     * handles[6] (normal), w is actor.getWidth() and h is
     * actor.getHeight().
     *
     * This matrix defines that the 3 points defining actor bounds are
     * transformed to the 3 points defining modifier bounds. E.g., we want
     * that actor origin (0,0) is transformed to (handles[0].x,
     * handles[0].y), and that is expressed in the first equation.
     *
     * Resolving these equations is obtained:
     */
    // a = (t.x - o.y) / w
    // b = (t.y - o.y) / w
    // c = (n.x - o.x) / h
    // d = (n.y - o.y) / h
    /*
     * Values for translation, scale and rotation contained by the matrix
     * can be obtained directly making operations over a, b, c and d:
     */
    // tx = o.x
    // ty = o.y
    // sx = sqrt(a^2+b^2)
    // sy = sqrt(c^2+d^2)
    // rotation = atan(c/d)
    // or
    // rotation = atan(-b/a)
    /*
     * Rotation can give two different values (this happens when there is
     * more than one way of obtaining the same transformation). To avoid
     * that, we ignore the rotation to obtain the final values.
     */

    Vector2 tmp1 = Pools.obtain(Vector2.class);
    Vector2 tmp2 = Pools.obtain(Vector2.class);
    Vector2 tmp3 = Pools.obtain(Vector2.class);
    Vector2 tmp4 = Pools.obtain(Vector2.class);
    Vector2 tmp5 = Pools.obtain(Vector2.class);

    Vector2 o = tmp1.set(origin.x, origin.y);
    Vector2 t = tmp2.set(tangent.x, tangent.y);
    Vector2 n = tmp3.set(normal.x, normal.y);

    Vector2 vt = tmp4.set(t).sub(o);
    Vector2 vn = tmp5.set(n).sub(o);

    // Ignore rotation
    float rotation = actor.getRotation();
    vt.rotate(-rotation);
    vn.rotate(-rotation);

    t.set(vt).add(o);
    n.set(vn).add(o);

    Vector2 bottomLeft = Pools.obtain(Vector2.class);
    Vector2 size = Pools.obtain(Vector2.class);

    calculateBounds(actor, bottomLeft, size);

    float a = (t.x - o.x) / size.x;
    float c = (t.y - o.y) / size.x;
    float b = (n.x - o.x) / size.y;
    float d = (n.y - o.y) / size.y;

    Pools.free(tmp1);
    Pools.free(tmp2);
    Pools.free(tmp3);
    Pools.free(tmp4);
    Pools.free(tmp5);
    Pools.free(bottomLeft);
    Pools.free(size);

    // Math.sqrt gives a positive value, but it also have a negatives.
    // The
    // signum is calculated computing the current rotation
    float signumX = vt.angle() > 90.0f && vt.angle() < 270.0f ? -1.0f : 1.0f;
    float signumY = vn.angle() > 180.0f ? -1.0f : 1.0f;

    float scaleX = (float) Math.sqrt(a * a + b * b) * signumX;
    float scaleY = (float) Math.sqrt(c * c + d * d) * signumY;

    actor.setScale(scaleX, scaleY);

    /*
     * To obtain the correct translation value we need to subtract the
     * amount of translation due to the origin.
     */
    tmpMatrix.setToTranslation(actor.getOriginX(), actor.getOriginY());
    tmpMatrix.rotate(actor.getRotation());
    tmpMatrix.scale(actor.getScaleX(), actor.getScaleY());
    tmpMatrix.translate(-actor.getOriginX(), -actor.getOriginY());

    /*
     * Now, the matrix has how much translation is due to the origin
     * involved in the rotation and scaling operations
     */
    float x = o.x - tmpMatrix.getValues()[Matrix3.M02];
    float y = o.y - tmpMatrix.getValues()[Matrix3.M12];
    actor.setPosition(x, y);
  }