/* * Copyright 2015 Daniel Dittmar * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package dan.dit.whatsthat.util.flatworld.world; import android.graphics.RectF; import java.util.Random; import dan.dit.whatsthat.util.flatworld.collision.CollisionController; import dan.dit.whatsthat.util.flatworld.collision.Hitbox; import dan.dit.whatsthat.util.flatworld.effects.WorldEffect; import dan.dit.whatsthat.util.flatworld.look.NinePatchLook; /** * Created by daniel on 05.06.15. */ public class FlatRectWorld extends FlatWorld { public static final int BORDER_FLAG_LEFT = 1; public static final int BORDER_FLAG_RIGHT = 2; public static final int BORDER_FLAG_TOP = 4; public static final int BORDER_FLAG_BOTTOM = 8; private static final float TEXT_EFFECT_MAX_WIDTH_FACTOR = 0.3f; private RectF mWorldRect; public FlatRectWorld(RectF worldRect, CollisionController collider, FlatWorldCallback callback) { super(collider, callback); mWorldRect = worldRect; if (worldRect == null || worldRect.width() <= 0.f || worldRect.height() <= 0.f) { throw new IllegalArgumentException("Illegal world: " + worldRect); } } @Override protected void checkReachOutside(Actor actor) { RectF bound = actor.getHitbox().getBoundingRect(); float x = bound.centerX(); float y = bound.centerY(); int flags = 0; if (bound.left < mWorldRect.left) { flags |= BORDER_FLAG_LEFT; x = mWorldRect.left; } if (bound.right > mWorldRect.right) { flags |= BORDER_FLAG_RIGHT; x = mWorldRect.right; } if (bound.top < mWorldRect.top) { flags |= BORDER_FLAG_TOP; y = mWorldRect.top; } if (bound.bottom > mWorldRect.bottom) { flags |= BORDER_FLAG_BOTTOM; y = mWorldRect.bottom; } if (flags != 0) { mCallback.onReachedEndOfWorld(actor, x, y, flags); } } @Override protected void checkLeaveWorld(Actor actor) { RectF bound = actor.getHitbox().getBoundingRect(); int flags = 0; if (bound.left > mWorldRect.right) { flags |= BORDER_FLAG_RIGHT; } if (bound.right < mWorldRect.left) { flags |= BORDER_FLAG_LEFT; } if (bound.top > mWorldRect.bottom) { flags |= BORDER_FLAG_BOTTOM; } if (bound.bottom < mWorldRect.top) { flags |= BORDER_FLAG_TOP; } if (flags != 0) { mCallback.onLeftWorld(actor, flags); } } @Override public void setRandomPositionInside(Actor actor, Random rand) { RectF bounds = actor.getHitbox().getBoundingRect(); float paddingLeft = bounds.centerX() - bounds.left; float paddingRight = bounds.right - bounds.centerX(); float paddingTop = bounds.centerY() - bounds.top; float paddingBottom = bounds.bottom - bounds.centerY(); float x = mWorldRect.left + paddingLeft + rand.nextFloat() * (mWorldRect.width() - paddingRight - paddingLeft); float y = mWorldRect.top + paddingTop + rand.nextFloat() * (mWorldRect.height() - paddingTop - paddingBottom); actor.getHitbox().setCenter(x, y); checkReachOutside(actor); checkLeaveWorld(actor); } public WorldEffect attachTimedMessage(Actor attachTo, NinePatchLook[] cornerPatches, String text, long duration) { float width = getRight() - getLeft(); float height = getBottom() - getTop(); NinePatchLook look; Hitbox hitbox = attachTo.getHitbox(); float x = hitbox.getCenterX(); float y = hitbox.getCenterY(); float offsetX; float offsetY; float heightFactor; if (x < getLeft() + width / 2) { offsetX = hitbox.getBoundingRect().width() / 2.f; if (y < getTop() + height / 2) { offsetY = hitbox.getBoundingRect().height() / 2.f; look = cornerPatches[0]; heightFactor = 0; } else { offsetY = -hitbox.getBoundingRect().height() / 2.f; look = cornerPatches[3]; heightFactor = -1; } } else { offsetX = -hitbox.getBoundingRect().width() / 2.f; if (y < getTop() + height / 2) { offsetY = hitbox.getBoundingRect().height() / 2.f; look = cornerPatches[1]; heightFactor = 0; } else { offsetY = -hitbox.getBoundingRect().height() / 2.f; look = cornerPatches[2]; heightFactor = -1; } } look.reset(); WorldEffect effect = attachTimedMessage(look, text, (int) (width * TEXT_EFFECT_MAX_WIDTH_FACTOR), attachTo, duration); look.setOffset(offsetX + (offsetX < 0 ? -look.getWidth() : 0), offsetY + heightFactor * look.getHeight()); return effect; } public float getLeft() { return mWorldRect.left; } public float getWidth() { return mWorldRect.width(); } public float getRight() { return mWorldRect.right; } public float getTop() { return mWorldRect.top; } public float getBottom() { return mWorldRect.bottom; } public float getHeight() { return mWorldRect.height(); } }