/*
* 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.collision;
import android.graphics.RectF;
import java.util.Random;
import dan.dit.whatsthat.util.flatworld.look.Look;
/**
* Created by daniel on 30.05.15.
*/
public class HitboxRect extends Hitbox {
private float mLeft;
private float mTop;
private float mBottom;
private float mRight;
private Tester mTester = new Tester();
private HitboxRect(final float left, final float top, final float width, final float height) {
mLeft = left;
mTop = top;
mRight = left + width;
mBottom = top + height;
mBoundingRect.set(mLeft, mTop, mRight, mBottom);
}
private boolean checkCollision(HitboxRect other) {
return mRight >= other.mLeft && mLeft <= other.mRight && mBottom >= other.mTop && mTop <= other.mBottom;
}
@Override
public RectF getBoundingRect() {
return mBoundingRect;
}
@Override
public boolean isInside(float x, float y) {
return x >= mLeft && x <= mRight && y >= mTop && y <= mBottom;
}
@Override
public boolean checkRandomPointCollision(Hitbox other, Random rand, RectF pointInRect) {
float rx = getRandomFloatInRange(Math.max(pointInRect.left, mLeft), Math.min(pointInRect.right, mRight), rand);
float ry = getRandomFloatInRange(Math.max(pointInRect.top, mTop), Math.min(pointInRect.bottom, mBottom), rand);
return other.isInside(rx, ry);
}
@Override
public void move(float x, float y) {
mLeft += x;
mRight += x;
mTop += y;
mBottom += y;
mBoundingRect.set(mLeft, mTop, mRight, mBottom);
}
@Override
public void setTop(float newTop) {
mBottom = newTop + mBottom - mTop;
mTop = newTop;
mBoundingRect.top = mTop;
mBoundingRect.bottom = mBottom;
}
@Override
public void setLeft(float newLeft) {
mRight = newLeft + mRight - mLeft;
mLeft = newLeft;
mBoundingRect.right = mRight;
mBoundingRect.left = mLeft;
}
@Override
public void setRight(float right) {
mLeft = right - (mRight - mLeft);
mRight = right;
mBoundingRect.right = mRight;
mBoundingRect.left = mLeft;
}
@Override
public void setBottom(float bottom) {
mTop = bottom - (mBottom - mTop);
mBottom = bottom;
mBoundingRect.top = mTop;
mBoundingRect.bottom = mBottom;
}
@Override
public void setCenter(float centerX, float centerY) {
float width = mRight - mLeft;
float height = mBottom - mTop;
mTop = centerY - height / 2.f;
mLeft = centerX - width / 2.f;
mRight = mLeft + width;
mBottom = mTop + height;
mBoundingRect.set(mLeft, mTop, mRight, mBottom);
}
@Override
public float getCenterX() {
return mLeft + (mTop - mLeft) / 2.f;
}
@Override
public float getCenterY() {
return mTop + (mBottom - mTop) / 2.f;
}
@Override
public CollisionTester getCollisionTester() {
return mTester;
}
@Override
public int accept(CollisionTester collisionTester) {
return collisionTester.collisionTest(this);
}
private class Tester extends CollisionTester {
@Override
public int collisionTest(HitboxRect toCheck) {
return checkCollision(toCheck) ? RESULT_COLLISION : RESULT_NO_COLLISION;
}
}
public static HitboxRect makeHitbox(Look look, float hitboxWidthFraction, float hitboxHeightFraction, float frameLeft, float frameTop) {
float offsetX = -look.getWidth() * (1 - hitboxWidthFraction) / 2.f;
float offsetY = -look.getHeight() * (1 - hitboxHeightFraction) / 2.f;
look.setOffset(offsetX, offsetY);
return new HitboxRect(frameLeft - offsetX, frameTop - offsetY, look.getWidth() * hitboxWidthFraction, look.getHeight() * hitboxHeightFraction);
}
}