Bug 18: Separated ShapeRenderer IV

This commit is contained in:
Robert Vokac 2024-10-12 18:06:44 +02:00
parent af02008445
commit 2c6bd52566
Signed by: robertvokac
GPG Key ID: FB9CE8E20AADA55F
10 changed files with 343 additions and 62 deletions

View File

@ -21,7 +21,7 @@ package com.pixelgamelibrary.api.graphics;
import com.pixelgamelibrary.api.Disposable;
import com.pixelgamelibrary.api.math.Rectangle;
import com.pixelgamelibrary.api.math.Rotation;
import com.pixelgamelibrary.api.math.Angle;
/**
*
@ -41,10 +41,14 @@ public interface ShapeRenderer extends Disposable {
Color getColor();
void filledRectangle(float x, float y, float width, float height, float rotation, Color color);
void filledRectangle(float x, float y, float width, float height, Angle rotation, Color color);
default void filledRectangle(float x, float y, float width, float height, float rotation, Color color) {
filledRectangle(x, y, width, height, Angle.ofDegrees(rotation), color);
}
default void filledRectangle(float x, float y, float width, float height, Color color) {
filledRectangle(x, y, width, height, Rotation.DEFAULT_ROTATION_IN_ANGLES, color);
filledRectangle(x, y, width, height, Angle.DEFAULT_ROTATION_IN_ANGLES, color);
}
default void filledRectangle(float x, float y, float width, float height, float rotation) {
@ -52,7 +56,7 @@ public interface ShapeRenderer extends Disposable {
}
default void filledRectangle(float x, float y, float width, float height) {
filledRectangle(x, y, width, height, Rotation.DEFAULT_ROTATION_IN_ANGLES, getColor());
filledRectangle(x, y, width, height, Angle.DEFAULT_ROTATION_IN_ANGLES, getColor());
}
default void filledRectangle(Rectangle rectangle, Color color) {
@ -66,6 +70,9 @@ public interface ShapeRenderer extends Disposable {
default void filledRectangle(Rectangle rectangle) {
filledRectangle(rectangle.getX(), rectangle.getY(), rectangle.getWidth(), rectangle.getHeight());
}
void setTextureRegion(TextureRegion textureRegion);
TextureRegion getTextureRegion();
void setTexture(Texture texture);
}

View File

@ -36,5 +36,6 @@ public interface Texture extends Disposable {
void makeColorTransparent(int r, int g, int b);
void scale(double d);
void setColorMode(ColorMode colorMode, int bitCount);
void clear();
}

View File

@ -31,4 +31,6 @@ public interface TextureFactory {
Texture create(File file);
Texture create(Pixmap pixmap);
Texture create(int width, int height);
Texture createTransparent(int width, int height);
}

View File

@ -81,40 +81,40 @@ public interface Graphics {
return getTextureFactory().create(width, height);
}
SpriteBatchFactory newSpriteBatchFactory();
SpriteBatchFactory getSpriteBatchFactory();
default SpriteBatch newSpriteBatch() {
return newSpriteBatchFactory().create();
return getSpriteBatchFactory().create();
}
BitmapFontFactory newBitmapFontFactory();
BitmapFontFactory getBitmapFontFactory();
default BitmapFont newBitmapFont() {
return newBitmapFontFactory().create();
return getBitmapFontFactory().create();
}
default BitmapFont newBitmapFont(boolean flip) {
return newBitmapFontFactory().create(flip);
return getBitmapFontFactory().create(flip);
}
default BitmapFont newBitmapFont(File fontFile, TextureRegion region) {
return newBitmapFontFactory().create(fontFile, region);
return getBitmapFontFactory().create(fontFile, region);
}
default BitmapFont newBitmapFont(File fontFile, TextureRegion region, boolean flip) {
return newBitmapFontFactory().create(fontFile, region, flip);
return getBitmapFontFactory().create(fontFile, region, flip);
}
default BitmapFont newBitmapFont(File fontFile) {
return newBitmapFontFactory().create(fontFile);
return getBitmapFontFactory().create(fontFile);
}
default BitmapFont newBitmapFont(File fontFile, boolean flip) {
return newBitmapFontFactory().create(fontFile, flip);
return getBitmapFontFactory().create(fontFile, flip);
}
default BitmapFont newBitmapFont(File fontFile, File imageFile, boolean flip) {
return newBitmapFontFactory().create(fontFile, imageFile, flip);
return getBitmapFontFactory().create(fontFile, imageFile, flip);
}
}

View File

@ -0,0 +1,83 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// Pixel: Game library.
// Copyright (C) 2024 the original author or authors.
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.math;
/**
*
* @author robertvokac
*/
public class Angle {
public static final float DEFAULT_ROTATION_IN_ANGLES = 0f;
private float degrees;
public static Angle ofDegrees(float degrees) {
return new Angle(degrees);
}
public static Angle ofRadians(float radians) {
return new Angle(radians, AngleUnit.RADIAN);
}
public static Angle ofGradians(float gradians) {
return new Angle(gradians, AngleUnit.GRADIAN);
}
public static Angle ofNormalized(float normalized) {
return new Angle(normalized, AngleUnit.NORMALIZED);
}
public Angle(float value, AngleUnit angleUnit) {
this(value, angleUnit, false);
}
public Angle(float rotatioInAnglesIn) {
this(rotatioInAnglesIn, false);
}
public Angle(float value, AngleUnit angleUnit, boolean anticlockwise) {
this.degrees = AngleUnitConverter.normalizeAnticlockwiseDegrees(AngleUnit.convert(value, angleUnit, AngleUnit.DEGREE), anticlockwise);
}
public Angle(float rotatioInAnglesIn, boolean anticlockwise) {
this.degrees = AngleUnitConverter.normalizeAnticlockwiseDegrees(rotatioInAnglesIn, anticlockwise);
}
public float asDegrees() {
return degrees;
}
public float asRadians() {
return as(AngleUnit.RADIAN);
}
public float asGradians() {
return as(AngleUnit.GRADIAN);
}
public float asNormalized() {
return as(AngleUnit.NORMALIZED);
}
public float as(AngleUnit angleUnit) {
if(angleUnit == AngleUnit.DEGREE) {
return degrees;
}
return AngleUnit.convert(degrees, AngleUnit.DEGREE, angleUnit);
}
public void set(float value, AngleUnit angleUnit) {
this.degrees = AngleUnit.convert(value, angleUnit, AngleUnit.DEGREE);
}
}

View File

@ -26,7 +26,7 @@ package com.pixelgamelibrary.api.math;
public enum AngleUnit {
DEGREE, NORMALIZED, RADIAN, GRADIAN;
public float convert(float value, AngleUnit inputAngleUnit, AngleUnit outputAngleUnit) {
public static float convert(float value, AngleUnit inputAngleUnit, AngleUnit outputAngleUnit) {
return AngleUnitConverter.convert(value, inputAngleUnit, outputAngleUnit);
}
}

View File

@ -101,7 +101,7 @@ class AngleUnitConverter {
* @return the angle converted to degrees
*/
public static float convertGradiansToDegrees(float gradians) {
return gradians / GRADIANS_PER_90_DEGREES * 90f;
return gradians / GRADIANS_PER_90_DEGREES * _90_DEGREES;
}
/**
@ -132,6 +132,13 @@ class AngleUnitConverter {
// No conversion needed if the units are the same
return value;
}
if(inputAngleUnit == null) {
throw new PixelException("inputAngleUnit is null");
}
if(outputAngleUnit == null) {
throw new PixelException("outputAngleUnit is null");
}
if (inputAngleUnit == AngleUnit.DEGREE) {
// Convert from degrees to the specified output unit
switch (outputAngleUnit) {
@ -164,4 +171,11 @@ class AngleUnitConverter {
float degrees = convert(value, inputAngleUnit, AngleUnit.DEGREE);
return convert(degrees, AngleUnit.DEGREE, outputAngleUnit);
}
public static float normalizeAnticlockwiseDegrees(float degrees, boolean enabled) {
return enabled ? _360_DEGREES - degrees : degrees;
}
public static float normalizeAnticlockwiseDegrees(float degrees) {
return normalizeAnticlockwiseDegrees(degrees, true);
}
}

View File

@ -1,45 +0,0 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// Pixel: Game library.
// Copyright (C) 2024 the original author or authors.
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.math;
/**
*
* @author robertvokac
*/
public class Rotation {
public static final float DEFAULT_ROTATION_IN_ANGLES = 0f;
private float rotatioInAngles;
public static Rotation ofAngles(float angles) {
return new Rotation(angles);
}
public static Rotation ofRadians(float radians) {
return new Rotation(convertRadiansToAngles(radians));
}
private Rotation(float rotatioInAnglesIn) {
this.rotatioInAngles = rotatioInAnglesIn;
}
public float getAsRadians() {
return convertAnglesToRadians(rotatioInAngles);
}
}

View File

@ -0,0 +1,112 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// Pixel: Game library.
// Copyright (C) 2024 the original author or authors.
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.math;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class AngleTest {
private static final float TOLERANCE = 0.0001f;
@Test
void testOfDegrees() {
Angle angle = Angle.ofDegrees(90f);
assertEquals(90f, angle.asDegrees(), TOLERANCE);
assertEquals((float) Math.PI / 2, angle.asRadians(), TOLERANCE);
assertEquals(100f, angle.asGradians(), TOLERANCE);
assertEquals(0.25f, angle.asNormalized(), TOLERANCE);
}
@Test
void testOfRadians() {
Angle angle = Angle.ofRadians((float) Math.PI);
assertEquals(180f, angle.asDegrees(), TOLERANCE);
assertEquals((float) Math.PI, angle.asRadians(), TOLERANCE);
assertEquals(200f, angle.asGradians(), TOLERANCE);
assertEquals(0.5f, angle.asNormalized(), TOLERANCE);
}
@Test
void testOfGradians() {
Angle angle = Angle.ofGradians(100f);
assertEquals(90f, angle.asDegrees(), TOLERANCE);
assertEquals((float) Math.PI / 2, angle.asRadians(), TOLERANCE);
assertEquals(100f, angle.asGradians(), TOLERANCE);
assertEquals(0.25f, angle.asNormalized(), TOLERANCE);
}
@Test
void testOfNormalized() {
Angle angle = Angle.ofNormalized(0.5f);
assertEquals(180f, angle.asDegrees(), TOLERANCE);
assertEquals((float) Math.PI, angle.asRadians(), TOLERANCE);
assertEquals(200f, angle.asGradians(), TOLERANCE);
assertEquals(0.5f, angle.asNormalized(), TOLERANCE);
}
@Test
void testConstructorWithDegrees() {
Angle angle = new Angle(270f);
assertEquals(270f, angle.asDegrees(), TOLERANCE);
assertEquals((float) (3 * Math.PI / 2), angle.asRadians(), TOLERANCE);
assertEquals(300f, angle.asGradians(), TOLERANCE);
assertEquals(0.75f, angle.asNormalized(), TOLERANCE);
}
@Test
void testConstructorWithDegreesAndAnticlockwise() {
Angle angle = new Angle(270f, true);
assertEquals(90f, angle.asDegrees(), TOLERANCE);
assertEquals((float) Math.PI / 2, angle.asRadians(), TOLERANCE);
assertEquals(100f, angle.asGradians(), TOLERANCE);
assertEquals(0.25f, angle.asNormalized(), TOLERANCE);
}
@Test
void testSetAngle() {
Angle angle = Angle.ofDegrees(45f);
angle.set(90f, AngleUnit.DEGREE);
assertEquals(90f, angle.asDegrees(), TOLERANCE);
assertEquals((float) Math.PI / 2, angle.asRadians(), TOLERANCE);
assertEquals(100f, angle.asGradians(), TOLERANCE);
assertEquals(0.25f, angle.asNormalized(), TOLERANCE);
}
@Test
void testSetAngleFromRadians() {
Angle angle = Angle.ofRadians((float) Math.PI / 4);
angle.set((float) Math.PI / 2, AngleUnit.RADIAN);
assertEquals(90f, angle.asDegrees(), TOLERANCE);
assertEquals((float) Math.PI / 2, angle.asRadians(), TOLERANCE);
assertEquals(100f, angle.asGradians(), TOLERANCE);
assertEquals(0.25f, angle.asNormalized(), TOLERANCE);
}
@Test
void testSetAngleFromGradians() {
Angle angle = Angle.ofGradians(50f);
angle.set(100f, AngleUnit.GRADIAN);
assertEquals(90f, angle.asDegrees(), TOLERANCE);
assertEquals((float) Math.PI / 2, angle.asRadians(), TOLERANCE);
assertEquals(100f, angle.asGradians(), 0.001f);
assertEquals(0.25f, angle.asNormalized(), TOLERANCE);
}
}

View File

@ -0,0 +1,107 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// Pixel: Game library.
// Copyright (C) 2024 the original author or authors.
//
// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation, either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// <https://www.gnu.org/licenses/> or write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
///////////////////////////////////////////////////////////////////////////////////////////////
package com.pixelgamelibrary.api.math;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
import com.pixelgamelibrary.api.PixelException;
class AngleUnitConverterTest {
private static final float TOLERANCE = 0.0001f;
@Test
void testConvertDegreesToRadians() {
assertEquals((float) Math.PI, AngleUnitConverter.convertDegreesToRadians(180f), TOLERANCE);
assertEquals((float) Math.PI / 2, AngleUnitConverter.convertDegreesToRadians(90f), TOLERANCE);
assertEquals(0f, AngleUnitConverter.convertDegreesToRadians(0f), TOLERANCE);
}
@Test
void testConvertDegreesToGradians() {
assertEquals(100f, AngleUnitConverter.convertDegreesToGradians(90f), TOLERANCE);
assertEquals(0f, AngleUnitConverter.convertDegreesToGradians(0f), TOLERANCE);
assertEquals(200f, AngleUnitConverter.convertDegreesToGradians(180f), TOLERANCE);
}
@Test
void testConvertDegreesToNormalized() {
assertEquals(0.5f, AngleUnitConverter.convertDegreesToNormalized(180f), TOLERANCE);
assertEquals(0f, AngleUnitConverter.convertDegreesToNormalized(0f), TOLERANCE);
assertEquals(1f, AngleUnitConverter.convertDegreesToNormalized(360f), TOLERANCE);
}
@Test
void testConvertRadiansToDegrees() {
assertEquals(180f, AngleUnitConverter.convertRadiansToDegrees((float) Math.PI), TOLERANCE);
assertEquals(90f, AngleUnitConverter.convertRadiansToDegrees((float) Math.PI / 2), TOLERANCE);
assertEquals(0f, AngleUnitConverter.convertRadiansToDegrees(0f), TOLERANCE);
}
@Test
void testConvertGradiansToDegrees() {
assertEquals(90f, AngleUnitConverter.convertGradiansToDegrees(100f), TOLERANCE);
assertEquals(0f, AngleUnitConverter.convertGradiansToDegrees(0f), TOLERANCE);
assertEquals(180f, AngleUnitConverter.convertGradiansToDegrees(200f), TOLERANCE);
}
@Test
void testConvertNormalizedToDegrees() {
assertEquals(180f, AngleUnitConverter.convertNormalizedToDegrees(0.5f), TOLERANCE);
assertEquals(0f, AngleUnitConverter.convertNormalizedToDegrees(0f), TOLERANCE);
assertEquals(360f, AngleUnitConverter.convertNormalizedToDegrees(1f), TOLERANCE);
}
@Test
void testConvertBetweenUnits() {
// Degrees to Radians
assertEquals((float) Math.PI, AngleUnitConverter.convert(180f, AngleUnit.DEGREE, AngleUnit.RADIAN), TOLERANCE);
// Radians to Degrees
assertEquals(180f, AngleUnitConverter.convert((float) Math.PI, AngleUnit.RADIAN, AngleUnit.DEGREE), TOLERANCE);
// Degrees to Gradians
assertEquals(200f, AngleUnitConverter.convert(180f, AngleUnit.DEGREE, AngleUnit.GRADIAN), TOLERANCE);
// Gradians to Degrees
assertEquals(180f, AngleUnitConverter.convert(200f, AngleUnit.GRADIAN, AngleUnit.DEGREE), TOLERANCE);
// Degrees to Normalized
assertEquals(0.5f, AngleUnitConverter.convert(180f, AngleUnit.DEGREE, AngleUnit.NORMALIZED), TOLERANCE);
// Normalized to Degrees
assertEquals(180f, AngleUnitConverter.convert(0.5f, AngleUnit.NORMALIZED, AngleUnit.DEGREE), TOLERANCE);
}
@Test
void testNormalizeAnticlockwiseDegrees() {
assertEquals(270f, AngleUnitConverter.normalizeAnticlockwiseDegrees(90f), TOLERANCE);
assertEquals(360f, AngleUnitConverter.normalizeAnticlockwiseDegrees(0f), TOLERANCE);
assertEquals(0f, AngleUnitConverter.normalizeAnticlockwiseDegrees(360f), TOLERANCE);
}
@Test
void testNormalizeAnticlockwiseDegreesIfNeeded() {
// Enabled
assertEquals(270f, AngleUnitConverter.normalizeAnticlockwiseDegrees(90f, true), TOLERANCE);
// Disabled
assertEquals(90f, AngleUnitConverter.normalizeAnticlockwiseDegrees(90f, false), TOLERANCE);
}
@Test
void testUnsupportedConversion() {
assertThrows(PixelException.class, () -> AngleUnitConverter.convert(1f, AngleUnit.DEGREE, null));
assertThrows(PixelException.class, () -> AngleUnitConverter.convert(1f, null, AngleUnit.RADIAN));
}
}