Пример #1
0
  public void drawLineShapePart(
      Vector2 center,
      int verts,
      float innerPos,
      float outerPos,
      float rotation,
      Color innerCol,
      Color outerCol) {
    setType(GL20.GL_TRIANGLE_STRIP);

    n_verts = (verts + 1) * 2 + 2;
    checkMaxVerts(n_verts);

    a.set(CircleLogic.findPos(center, innerPos, 0 * (360f / verts) + rotation, 0f));

    // We place the vertex twice at the start and at the end to ensure no crosover from the last
    // shape
    putVertex(a.x, a.y, innerCol);
    putVertex(a.x, a.y, innerCol);
    for (int i = 0; i < verts + 1; i++) {
      a.set(CircleLogic.findPos(center, outerPos, i * (360f / verts) + rotation, 0f));
      putVertex(a.x, a.y, outerCol);
      a.set(CircleLogic.findPos(center, innerPos, i * (360f / verts) + rotation, 0f));
      putVertex(a.x, a.y, innerCol);
    }
    putVertex(a.x, a.y, innerCol);
  }
  public static boolean inLineOfSight(Vector2 p1, Vector2 p2, Polygon polygon, boolean obstacle) {
    tmp.set(p1);
    tmp2.set(p2);

    float verts[] = polygon.getTransformedVertices();

    for (int i = 0; i < verts.length; i += 2) {
      if (lineSegmentsCross(
          tmp.x,
          tmp.y,
          tmp2.x,
          tmp2.y,
          verts[i],
          verts[i + 1],
          verts[(i + 2) % verts.length],
          verts[(i + 3) % verts.length])) return false;
    }

    tmp.add(tmp2);
    tmp.x /= 2;
    tmp.y /= 2;

    boolean result = PolygonUtils.isPointInside(polygon, tmp.x, tmp.y, !obstacle);

    return obstacle ? !result : result;
  }
Пример #3
0
  private void drawCullingRectangles(ShapeRenderer shapeRenderer, Color color) {
    for (BoundingBox br : boundingBoxes) {

      Rectangle r = br.rectangle;
      Rectangle cullingArea = getCullingArea(tmpRectangle, r, angleRad, position, scale);

      shapeRenderer.set(ShapeRenderer.ShapeType.Filled);

      Color fillColor = tmpColor.set(color);
      fillColor.a *= 0.25f;

      shapeRenderer.setColor(fillColor);

      shapeRenderer.rect(cullingArea.x, cullingArea.y, cullingArea.width, cullingArea.height);

      tmp.set(r.x, r.y).rotateRad(angleRad).add(position);
      tmp1.set(r.x + r.width, r.y).rotateRad(angleRad).add(position);
      tmp2.set(r.x + r.width, r.y + r.height).rotateRad(angleRad).add(position);
      tmp3.set(r.x, r.y + r.height).rotateRad(angleRad).add(position);

      shapeRenderer.set(ShapeRenderer.ShapeType.Line);
      shapeRenderer.setColor(color);

      shapeRenderer.line(tmp, tmp1);
      shapeRenderer.line(tmp1, tmp2);
      shapeRenderer.line(tmp2, tmp3);
      shapeRenderer.line(tmp3, tmp);
    }
  }
Пример #4
0
  /**
   * Determine if the requested line could be tacked on to the end of this line with no kinks or
   * gaps. If it can, the current LineSegment will be extended by the length of the passed
   * LineSegment.
   *
   * @param lineSegment
   * @return boolean true if line was extended, false if not.
   */
  public boolean extendIfPossible(LineSegment lineSegment) {
    /** First, let's see if the slopes of the two segments are the same. */
    double slope1 = Math.atan2(end.y - start.y, end.x - start.x);
    double slope2 =
        Math.atan2(
            lineSegment.end.y - lineSegment.start.y, lineSegment.end.x - lineSegment.start.x);

    if (Math.abs(slope1 - slope2) > 1e-9) {
      return false;
    }

    /**
     * Second, check if either end of this line segment is adjacent to the requested line segment.
     * So, 1 pixel away up through sqrt(2) away.
     *
     * <p>Whichever two points are within the right range will be "merged" so that the two outer
     * points will describe the line segment.
     */
    if (start.dst(lineSegment.start) <= Math.sqrt(2) + 1e-9) {
      start.set(lineSegment.end);
      return true;
    } else if (end.dst(lineSegment.start) <= Math.sqrt(2) + 1e-9) {
      end.set(lineSegment.end);
      return true;
    } else if (end.dst(lineSegment.end) <= Math.sqrt(2) + 1e-9) {
      end.set(lineSegment.start);
      return true;
    } else if (start.dst(lineSegment.end) <= Math.sqrt(2) + 1e-9) {
      start.set(lineSegment.start);
      return true;
    }

    return false;
  }
Пример #5
0
 private TextField findNextTextField(
     Array<Actor> actors, TextField best, Vector2 bestCoords, Vector2 currentCoords, boolean up) {
   for (int i = 0, n = actors.size; i < n; i++) {
     Actor actor = actors.get(i);
     if (actor == this) continue;
     if (actor instanceof TextField) {
       TextField textField = (TextField) actor;
       if (textField.isDisabled() || !textField.focusTraversal) continue;
       Vector2 actorCoords =
           actor.getParent().localToStageCoordinates(tmp3.set(actor.getX(), actor.getY()));
       if ((actorCoords.y < currentCoords.y
               || (actorCoords.y == currentCoords.y && actorCoords.x > currentCoords.x))
           ^ up) {
         if (best == null
             || (actorCoords.y > bestCoords.y
                     || (actorCoords.y == bestCoords.y && actorCoords.x < bestCoords.x))
                 ^ up) {
           best = (TextField) actor;
           bestCoords.set(actorCoords);
         }
       }
     } else if (actor instanceof Group)
       best =
           findNextTextField(((Group) actor).getChildren(), best, bestCoords, currentCoords, up);
   }
   return best;
 }
Пример #6
0
  /**
   * Calculates the culling area of the bounding box after it has scaled, rotated and translates.
   * This bounding box contains a bunch of vertices. This way i don't have to merge hundreds of
   * vertices to get a reasonable culling area, just the four of the bounding box.
   */
  private Rectangle getCullingArea(
      Rectangle cullingArea,
      Rectangle boundingBox,
      float rotation,
      Vector2 translation,
      float scale) {

    tmp.set(boundingBox.x, boundingBox.y).scl(scale).rotateRad(rotation).add(translation);
    cullingArea.set(tmp.x, tmp.y, 0, 0);

    tmp.set(boundingBox.x + boundingBox.width, boundingBox.y)
        .scl(scale)
        .rotateRad(rotation)
        .add(translation);
    cullingArea.merge(tmp);

    tmp.set(boundingBox.x + boundingBox.width, boundingBox.y + boundingBox.height)
        .scl(scale)
        .rotateRad(rotation)
        .add(translation);
    cullingArea.merge(tmp);

    tmp.set(boundingBox.x, boundingBox.y + boundingBox.height)
        .scl(scale)
        .rotateRad(rotation)
        .add(translation);
    cullingArea.merge(tmp);

    return cullingArea;
  }
Пример #7
0
  public void actBehavior(float deltaTime) {
    Random rand = new Random();

    switch (state) {
      case RESTING:
        if (stateTime > restTime) {
          state = MOVING;
          accel.x = rand.nextFloat() * 2 - 1; // -1 to 1
          accel.y = rand.nextFloat() * 2 - 1;
          accel.nor().scl(ACCEL);
          stateTime = 0.0f;
        } else {
          // still resting...
        }
        break;
      case MOVING:
        if (stateTime > moveTime) {
          state = RESTING;
          accel.set(0, 0);
          velocity.set(0, 0);
          stateTime = 0.0f;
        } else {
          // still moving...
          // Continue accel'ing in current direction
          accel.set(velocity.x, velocity.y).nor().scl(ACCEL);
        }
        break;
      default:
        break;
    }
    stateTime += deltaTime;
  }
Пример #8
0
  private void restart() {
    for (int i = 0; i < MAX_BALL_COUNT; i++) {
      float tx = rand.nextFloat() * 1.0f - 0.5f;
      float ty = WORLD_SIZE.y / 2 + BALL_SIZE.y * 5;
      float angle = rand.nextFloat() * MathUtils.PI * 2;

      ballModels[i].setActive(false);
      ballModels[i].setLinearVelocity(tmpVec.set(0, 0));
      ballModels[i].setAngularVelocity(0);
      ballModels[i].setTransform(tmpVec.set(tx, ty), angle);
    }

    if (timer != null) timer.cancel();

    timerBallIndex = 0;
    timer = new Timer();
    timer.scheduleAtFixedRate(
        new TimerTask() {
          @Override
          public void run() {
            if (timerBallIndex < ballModels.length) {
              ballModels[timerBallIndex].setAwake(true);
              ballModels[timerBallIndex].setActive(true);
              timerBallIndex += 1;
            } else {
              timer.cancel();
            }
          }
        },
        100,
        100);
  }
Пример #9
0
 /**
  * Calculate the bounds of the possible children of the given actor. If actor has no children,
  * then resultOrigin and resultSize are set to actor's bounds.
  */
 public static void calculateBounds(Actor actor, Vector2 resultOrigin, Vector2 resultSize) {
   resultOrigin.set(0, 0);
   resultSize.set(actor.getWidth(), actor.getHeight());
   if (actor instanceof Group && ((Group) actor).getChildren().size > 0) {
     calculateBounds(((Group) actor).getChildren(), resultOrigin, resultSize);
   }
 }
Пример #10
0
 @Override
 public boolean onEnd(
     final Draggable draggable, final Actor actor, final float stageX, final float stageY) {
   if (actor == null || actor.getStage() == null) {
     return CANCEL;
   }
   final Actor overActor = actor.getStage().hit(stageX, stageY, true);
   if (overActor == null || overActor == actor) {
     return CANCEL;
   } else if (overActor.isAscendantOf(actor)) {
     final DragPane dragPane = getDragPane(actor);
     if (dragPane != null && dragPane.isFloating()) {
       DRAG_POSITION.set(stageX, stageY);
       return addToFloatingGroup(draggable, actor, dragPane);
     }
     return CANCEL;
   }
   DRAG_POSITION.set(stageX, stageY);
   if (overActor instanceof DragPane) {
     return addDirectlyToPane(draggable, actor, (DragPane) overActor);
   }
   final DragPane dragPane = getDragPane(overActor);
   if (accept(actor, dragPane)) {
     return addActor(draggable, actor, overActor, dragPane);
   }
   return CANCEL;
 }
Пример #11
0
 private void respawn() {
   position.set(spawnLocation);
   lastFramePosition.set(spawnLocation);
   velocity.setZero();
   jumpState = Enums.JumpState.FALLING;
   facing = Direction.RIGHT;
   walkState = Enums.WalkState.NOT_WALKING;
 }
Пример #12
0
  @Override
  public RubeImage read(Json json, JsonValue jsonData, Class type) {
    if (scene.getBodies() == null) return null;

    RubeImage defaults = RubeDefaults.Image.image;

    RubeImage image = new RubeImage();

    image.angle = json.readValue("angle", float.class, defaults.angle, jsonData);
    int bodyIndex = json.readValue("body", int.class, jsonData);
    if (bodyIndex >= 0 && bodyIndex < scene.getBodies().size)
      image.body = scene.getBodies().get(bodyIndex);

    image.center.set(json.readValue("center", Vector2.class, defaults.center, jsonData));

    RubeVertexArray corners = json.readValue("corners", RubeVertexArray.class, jsonData);
    if (corners != null) {
      tmp.set(corners.x[0], corners.y[0]).sub(corners.x[1], corners.y[1]);
      image.width = tmp.len();
      tmp.set(corners.x[1], corners.y[1]).sub(corners.x[2], corners.y[2]);
      image.height = tmp.len();
    }

    image.file = json.readValue("file", String.class, jsonData);

    if (stripImageFile) {
      int fslashIndex = image.file.lastIndexOf('/');
      int dotIndex = image.file.lastIndexOf('.');

      if (fslashIndex != -1 && dotIndex != -1 && fslashIndex < dotIndex) {
        image.file = image.file.substring(fslashIndex + 1, dotIndex);
      }
    }

    image.filter = json.readValue("filter", int.class, defaults.filter, jsonData);
    image.name = json.readValue("name", String.class, jsonData);
    image.opacity = json.readValue("opacity", float.class, defaults.opacity, jsonData);
    image.renderOrder = json.readValue("renderOrder", int.class, defaults.renderOrder, jsonData);
    image.scale = json.readValue("scale", float.class, defaults.scale, jsonData);
    image.flip = json.readValue("flip", boolean.class, defaults.flip, jsonData);

    int[] colorArray =
        json.readValue("colorTint", int[].class, RubeDefaults.Image.colorArray, jsonData);

    image.color.r = (float) colorArray[0] / 255;
    image.color.g = (float) colorArray[1] / 255;
    image.color.b = (float) colorArray[2] / 255;
    image.color.a = (float) colorArray[3] / 255;

    RubeCustomProperty customProperty = null;
    if (json.getSerializer(RubeCustomProperty.class) != null)
      customProperty = json.readValue("customProperties", RubeCustomProperty.class, jsonData);

    scene.onAddImage(image, customProperty);

    return image;
  }
Пример #13
0
  public void recalculateButtonPositions() {

    moveLeftCenter.set(Constants.BUTTON_SIZE * 3 / 4, Constants.BUTTON_SIZE);
    moveRightCenter.set(Constants.BUTTON_SIZE * 2, Constants.BUTTON_SIZE * 3 / 4);

    shootCenter.set(
        viewport.getWorldWidth() - Constants.BUTTON_SIZE * 2f, Constants.BUTTON_SIZE * 3 / 4);

    jumpCenter.set(viewport.getWorldWidth() - Constants.BUTTON_SIZE * 3 / 4, Constants.BUTTON_SIZE);
  }
Пример #14
0
  @Override
  public void resize(int width, int height) {
    screenSize.set(width, height);
    midpoint.set(width / 2, height / 2);

    stage2d.getViewport().update(width, height, true);
    setActiveCamera();
    activeCamera.update(true);
    resizeElements();
  }
Пример #15
0
 /**
  * Adjusts the parent and child bone rotations so the tip of the child is as close to the target
  * position as possible. The target is specified in the world coordinate system.
  *
  * @param child Any descendant bone of the parent.
  */
 public static void apply(
     Bone parent, Bone child, float targetX, float targetY, int bendDirection, float alpha) {
   float childRotation = child.rotation, parentRotation = parent.rotation;
   if (alpha == 0) {
     child.rotationIK = childRotation;
     parent.rotationIK = parentRotation;
     return;
   }
   Vector2 position = temp;
   Bone parentParent = parent.parent;
   if (parentParent != null) {
     parentParent.worldToLocal(position.set(targetX, targetY));
     targetX = (position.x - parent.x) * parentParent.worldScaleX;
     targetY = (position.y - parent.y) * parentParent.worldScaleY;
   } else {
     targetX -= parent.x;
     targetY -= parent.y;
   }
   if (child.parent == parent) position.set(child.x, child.y);
   else parent.worldToLocal(child.parent.localToWorld(position.set(child.x, child.y)));
   float childX = position.x * parent.worldScaleX, childY = position.y * parent.worldScaleY;
   float offset = (float) Math.atan2(childY, childX);
   float len1 = (float) Math.sqrt(childX * childX + childY * childY),
       len2 = child.data.length * child.worldScaleX;
   // Based on code by Ryan Juckett with permission: Copyright (c) 2008-2009 Ryan Juckett,
   // http://www.ryanjuckett.com/
   float cosDenom = 2 * len1 * len2;
   if (cosDenom < 0.0001f) {
     child.rotationIK =
         childRotation
             + ((float) Math.atan2(targetY, targetX) * radDeg - parentRotation - childRotation)
                 * alpha;
     return;
   }
   float cos =
       clamp(
           (targetX * targetX + targetY * targetY - len1 * len1 - len2 * len2) / cosDenom, -1, 1);
   float childAngle = (float) Math.acos(cos) * bendDirection;
   float adjacent = len1 + len2 * cos, opposite = len2 * sin(childAngle);
   float parentAngle =
       (float)
           Math.atan2(
               targetY * adjacent - targetX * opposite, targetX * adjacent + targetY * opposite);
   float rotation = (parentAngle - offset) * radDeg - parentRotation;
   if (rotation > 180) rotation -= 360;
   else if (rotation < -180) //
   rotation += 360;
   parent.rotationIK = parentRotation + rotation * alpha;
   rotation = (childAngle + offset) * radDeg - childRotation;
   if (rotation > 180) rotation -= 360;
   else if (rotation < -180) //
   rotation += 360;
   child.rotationIK =
       childRotation + (rotation + parent.worldRotation - child.parent.worldRotation) * alpha;
 }
Пример #16
0
  private int generate(Array<Vector2> input, int mult) {
    int c = tristrip.size;
    if (endcap <= 0) {
      tristrip.add(input.get(0));
    } else {
      Vector2 p = input.get(0);
      Vector2 p2 = input.get(1);
      perp.set(p).sub(p2).scl(endcap);
      tristrip.add(new Vector2(p.x + perp.x, p.y + perp.y));
    }
    texcoord.add(new Vector2(0f, 0f));

    for (int i = 1; i < input.size - 1; i++) {
      Vector2 p = input.get(i);
      Vector2 p2 = input.get(i + 1);

      // get direction and normalize it
      perp.set(p).sub(p2).nor();

      // get perpendicular
      perp.set(-perp.y, perp.x);

      float thick = thickness * (1f - ((i) / (float) (input.size)));

      // move outward by thickness
      perp.scl(thick / 2f);

      // decide on which side we are using
      perp.scl(mult);

      // add the tip of perpendicular
      tristrip.add(new Vector2(p.x + perp.x, p.y + perp.y));
      // 0.0 -> end, transparent
      texcoord.add(new Vector2(0f, 0f));

      // add the center point
      tristrip.add(new Vector2(p.x, p.y));
      // 1.0 -> center, opaque
      texcoord.add(new Vector2(1f, 0f));
    }

    // final point
    if (endcap <= 0) {
      tristrip.add(input.get(input.size - 1));
    } else {
      Vector2 p = input.get(input.size - 2);
      Vector2 p2 = input.get(input.size - 1);
      perp.set(p2).sub(p).scl(endcap);
      tristrip.add(new Vector2(p2.x + perp.x, p2.y + perp.y));
    }
    // end cap is transparent
    texcoord.add(new Vector2(0f, 0f));
    return tristrip.size - c;
  }
Пример #17
0
 public void rayCast(RayCastCallback callback, Vector2 point1, Vector2 point2) {
   if (point1.dst2(point2) <= ZERO) {
     Gdx.app.log("World.rayCast", "Called with zero distance");
     return;
   }
   callback.reset();
   callback.result.start.set(toBox(tmp1.set(point1)));
   callback.result.end.set(toBox(tmp2.set(point2)));
   world.rayCast(callback, tmp1, tmp2);
   callback.result.scl(toWorldScale());
 }
Пример #18
0
  public void init() {
    position.set(spawnLocation);
    lastFramePosition.set(spawnLocation);
    velocity.setZero();
    jumpState = Enums.JumpState.FALLING;
    facing = Direction.RIGHT;
    walkState = Enums.WalkState.NOT_WALKING;

    // TODO: Initialize ammo
    ammo = Constants.INTIAL_AMMO;
  }
Пример #19
0
  @Override
  public Vector2 valueAt(Vector2 out, float t) {
    int index = getStartIndex(t);
    Destination start = destinations.get(index);

    if (index == destinations.size() - 1) {
      return out.set(start);
    }

    Vector2 next = destinations.get(index + 1);
    return out.set(next).sub(start).scl((t - start.startTime) / start.moveTime).add(start);
  }
  /**
   * Slack, like weapon recoil on the joint.
   *
   * @param attached
   */
  protected void updateSlack(final Attached attached) {

    float len = vTmp.set(attached.slackX, attached.slackY).len() - world.delta * attached.tension;
    if (len > 0) {
      vTmp.nor().scl(len);
    } else {
      vTmp.set(0, 0);
    }

    attached.slackX = vTmp.x;
    attached.slackY = vTmp.y;
  }
Пример #21
0
 /**
  * Focuses the next TextField. If none is found, the keyboard is hidden. Does nothing if the text
  * field is not in a stage.
  *
  * @param up If true, the TextField with the same or next smallest y coordinate is found, else the
  *     next highest.
  */
 public void next(boolean up) {
   Stage stage = getStage();
   if (stage == null) return;
   getParent().localToStageCoordinates(tmp1.set(getX(), getY()));
   TextField textField = findNextTextField(stage.getActors(), null, tmp2, tmp1, up);
   if (textField == null) { // Try to wrap around.
     if (up) tmp1.set(Float.MIN_VALUE, Float.MIN_VALUE);
     else tmp1.set(Float.MAX_VALUE, Float.MAX_VALUE);
     textField = findNextTextField(getStage().getActors(), null, tmp2, tmp1, up);
   }
   if (textField != null) stage.setKeyboardFocus(textField);
   else Gdx.input.setOnscreenKeyboardVisible(false);
 }
Пример #22
0
  public void init(float x, float y, float tx, float ty) {
    position.set(x, y);
    start.set(position);
    target.set(tx, ty);
    effect.reset();
    duration = target.dst(position) / 6;
    active = true;
    light.setActive(true);
    light.setPosition(x, y);

    for (ParticleEmitter emitter : effect.getEmitters()) {
      emitter.setContinuous(true);
    }
  }
Пример #23
0
  protected static Collision AABBvsCircle(AABB A, Circle B) {

    Vector2 AtoB = B.getPosition().cpy().sub(A.getCenter());

    float xe = A.getDimensions().x / 2;
    float ye = A.getDimensions().y / 2;

    Vector2 closest =
        new Vector2(MathUtils.clamp(AtoB.x, -xe, xe), MathUtils.clamp(AtoB.y, -ye, ye));

    boolean inside = false;
    if (AtoB.epsilonEquals(closest, (float) 1e-4)) {
      inside = true;

      if (Math.abs(AtoB.x) > Math.abs(AtoB.y)) {
        if (closest.x > 0.0f) {
          closest.x = xe;
        } else {
          closest.x = -xe;
        }
      } else {
        if (closest.y > 0.0f) {
          closest.y = ye;
        } else {
          closest.y = -ye;
        }
      }
    }

    Vector2 normal = new Vector2(AtoB).sub(closest);
    float d = normal.len2();
    float r = B.radius;

    // No collision
    if (d > r * r && !inside) {
      return null;
    }

    d = (float) Math.sqrt(d);

    float penetration = r + d;
    if (inside) {
      normal.set(AtoB).mul(1.0f).nor();
    } else {
      normal.set(AtoB).mul(-1.0f).nor();
    }

    return new Collision(normal, penetration);
  }
Пример #24
0
 private void accelerate() {
   shipRot = (float) (body.getTransform().getRotation() + MathUtils.PI / 2);
   xSpeed = MathUtils.cos(shipRot);
   ySpeed = MathUtils.sin(shipRot);
   movement.set(speed * xSpeed, speed * ySpeed);
   setExhaustRotation();
 }
Пример #25
0
  /**
   * Applies a mouse moved event to the stage and returns true if an actor in the scene {@link
   * Event#handle() handled} the event. This event only occurs on the desktop.
   */
  public boolean mouseMoved(int screenX, int screenY) {
    if (screenX < viewport.getScreenX()
        || screenX >= viewport.getScreenX() + viewport.getScreenWidth()) return false;
    if (Gdx.graphics.getHeight() - screenY < viewport.getScreenY()
        || Gdx.graphics.getHeight() - screenY >= viewport.getScreenY() + viewport.getScreenHeight())
      return false;

    mouseScreenX = screenX;
    mouseScreenY = screenY;

    screenToStageCoordinates(tempCoords.set(screenX, screenY));

    InputEvent event = Pools.obtain(InputEvent.class);
    event.setStage(this);
    event.setType(Type.mouseMoved);
    event.setStageX(tempCoords.x);
    event.setStageY(tempCoords.y);

    Actor target = hit(tempCoords.x, tempCoords.y, true);
    if (target == null) target = root;

    target.fire(event);
    boolean handled = event.isHandled();
    Pools.free(event);
    return handled;
  }
Пример #26
0
  /**
   * Applies a touch up event to the stage and returns true if an actor in the scene {@link
   * Event#handle() handled} the event. Only {@link InputListener listeners} that returned true for
   * touchDown will receive this event.
   */
  public boolean touchUp(int screenX, int screenY, int pointer, int button) {
    pointerTouched[pointer] = false;
    pointerScreenX[pointer] = screenX;
    pointerScreenY[pointer] = screenY;

    if (touchFocuses.size == 0) return false;

    screenToStageCoordinates(tempCoords.set(screenX, screenY));

    InputEvent event = Pools.obtain(InputEvent.class);
    event.setType(Type.touchUp);
    event.setStage(this);
    event.setStageX(tempCoords.x);
    event.setStageY(tempCoords.y);
    event.setPointer(pointer);
    event.setButton(button);

    SnapshotArray<TouchFocus> touchFocuses = this.touchFocuses;
    TouchFocus[] focuses = touchFocuses.begin();
    for (int i = 0, n = touchFocuses.size; i < n; i++) {
      TouchFocus focus = focuses[i];
      if (focus.pointer != pointer || focus.button != button) continue;
      if (!touchFocuses.removeValue(focus, true)) continue; // Touch focus already gone.
      event.setTarget(focus.target);
      event.setListenerActor(focus.listenerActor);
      if (focus.listener.handle(event)) event.handle();
      Pools.free(focus);
    }
    touchFocuses.end();

    boolean handled = event.isHandled();
    Pools.free(event);
    return handled;
  }
Пример #27
0
  /**
   * Applies a touch down event to the stage and returns true if an actor in the scene {@link
   * Event#handle() handled} the event.
   */
  public boolean touchDown(int screenX, int screenY, int pointer, int button) {
    if (screenX < viewport.getScreenX()
        || screenX >= viewport.getScreenX() + viewport.getScreenWidth()) return false;
    if (Gdx.graphics.getHeight() - screenY < viewport.getScreenY()
        || Gdx.graphics.getHeight() - screenY >= viewport.getScreenY() + viewport.getScreenHeight())
      return false;

    pointerTouched[pointer] = true;
    pointerScreenX[pointer] = screenX;
    pointerScreenY[pointer] = screenY;

    screenToStageCoordinates(tempCoords.set(screenX, screenY));

    InputEvent event = Pools.obtain(InputEvent.class);
    event.setType(Type.touchDown);
    event.setStage(this);
    event.setStageX(tempCoords.x);
    event.setStageY(tempCoords.y);
    event.setPointer(pointer);
    event.setButton(button);

    Actor target = hit(tempCoords.x, tempCoords.y, true);
    if (target == null) {
      if (root.getTouchable() == Touchable.enabled) root.fire(event);
    } else {
      target.fire(event);
    }

    boolean handled = event.isHandled();
    Pools.free(event);
    return handled;
  }
Пример #28
0
  private Actor fireEnterAndExit(Actor overLast, int screenX, int screenY, int pointer) {
    // Find the actor under the point.
    screenToStageCoordinates(tempCoords.set(screenX, screenY));
    Actor over = hit(tempCoords.x, tempCoords.y, true);
    if (over == overLast) return overLast;

    // Exit overLast.
    if (overLast != null) {
      InputEvent event = Pools.obtain(InputEvent.class);
      event.setStage(this);
      event.setStageX(tempCoords.x);
      event.setStageY(tempCoords.y);
      event.setPointer(pointer);
      event.setType(InputEvent.Type.exit);
      event.setRelatedActor(over);
      overLast.fire(event);
      Pools.free(event);
    }
    // Enter over.
    if (over != null) {
      InputEvent event = Pools.obtain(InputEvent.class);
      event.setStage(this);
      event.setStageX(tempCoords.x);
      event.setStageY(tempCoords.y);
      event.setPointer(pointer);
      event.setType(InputEvent.Type.enter);
      event.setRelatedActor(overLast);
      over.fire(event);
      Pools.free(event);
    }
    return over;
  }
  /**
   * Clamp the point to the nearest polygon segment
   *
   * @param poly The polygon
   * @param x The original point X
   * @param y The original point Y
   * @param dest The clamped point
   * @return The segment where the clamped point belongs
   */
  public static int getClampedPoint(Polygon poly, float x, float y, Vector2 dest) {
    float verts[] = poly.getTransformedVertices();
    float dTmp;

    Intersector.nearestSegmentPoint(verts[0], verts[1], verts[2], verts[3], x, y, dest);

    int nearest = 0;
    float d = Vector2.dst(x, y, dest.x, dest.y);

    for (int i = 2; i < verts.length; i += 2) {
      Intersector.nearestSegmentPoint(
          verts[i],
          verts[i + 1],
          verts[(i + 2) % verts.length],
          verts[(i + 3) % verts.length],
          x,
          y,
          tmp);
      dTmp = Vector2.dst(x, y, tmp.x, tmp.y);

      if (dTmp < d) {
        d = dTmp;
        nearest = i;
        dest.set(tmp);
      }
    }

    return nearest;
  }
Пример #30
0
 /**
  * Complete arc
  *
  * @param center
  * @param radInner
  * @param radOuter
  * @param segs
  * @param innerCol
  * @param outerCol
  */
 public void drawArc(
     Vector2 center, float radInner, float radOuter, int segs, Color innerCol, Color outerCol) {
   setType(GL20.GL_TRIANGLE_STRIP);
   n_verts = (segs + 1) * 2 + 2;
   checkMaxVerts(n_verts);
   a.set(CircleLogic.findPos(center, radOuter, 0 * (360f / segs), 0f));
   putVertex(a.x, a.y, outerCol);
   putVertex(a.x, a.y, outerCol);
   for (int i = 0; i < segs + 1; i++) {
     a.set(CircleLogic.findPos(center, radOuter, i * (360f / segs), 0f));
     putVertex(a.x, a.y, outerCol);
     a.set(CircleLogic.findPos(center, radInner, i * (360f / segs), 0f));
     putVertex(a.x, a.y, innerCol);
   }
   putVertex(a.x, a.y, innerCol);
 }