Skip to content

Commit

Permalink
(#10) Add rotation/scale support to Text2D
Browse files Browse the repository at this point in the history
- Added constructors that don't require translation parameters, and constructors that allow initial scale/rotation.
  • Loading branch information
lucasstarsz committed Jun 21, 2021
1 parent 6c6130c commit 18d06d5
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 33 deletions.
7 changes: 5 additions & 2 deletions src/main/java/tech/fastj/graphics/Transform2D.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import java.awt.geom.AffineTransform;

/** Convenience class for storing/performing 2D transformations using {@link AffineTransform}. */
public class Transform2D {

/** {@link Pointf} representing a default translation of {@code (0f, 0f)}. */
Expand Down Expand Up @@ -39,16 +40,18 @@ public Pointf getScale() {

public float getRotation() {
float approximatedRotation = (float) Math.toDegrees(Math.atan2(rotationTransform.getShearY(), rotationTransform.getScaleY()));
float normalizedRotation = rotation % 360f;

if (Maths.floatEquals(rotation % 360f, approximatedRotation)) {
if (Maths.floatEquals(normalizedRotation, approximatedRotation)) {
return rotation;
}

float rotationCheck = Math.abs(rotation % 360f) + Math.abs(approximatedRotation);
float rotationCheck = Math.abs(normalizedRotation) + Math.abs(approximatedRotation);
if (Maths.floatEquals(rotationCheck, 360f) || Maths.floatEquals(rotationCheck, 0f)) {
return rotation;
}

// according to logical thinking, this should not be reached.
throw new IllegalStateException(
"Something went wrong calculating the rotation.... we expected " + rotation + ", but we got " + approximatedRotation + " instead. :("
);
Expand Down
64 changes: 57 additions & 7 deletions src/main/java/tech/fastj/graphics/game/Text2D.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,36 +36,85 @@ public class Text2D extends GameObject {
private boolean hasMetrics;

/**
* {@code Text2D} Constructor that takes in a string of text and a location.
* {@code Text2D} Constructor that takes in a string of text.
* <p>
* This constructor defaults the color to {@link #DefaultColor}, the font to {@link #DefaultFont}, and sets the
* {@code show} boolean to {@link #DefaultShow}.
*
* @param setText Sets the displayed text.
*/
public Text2D(String setText) {
this(setText, DefaultColor, DefaultFont, DefaultShow);
}

/**
* {@code Text2D} Constructor that takes in a string of text and an initial translation.
* <p>
* This constructor defaults the color to {@link #DefaultColor}, the font to {@link #DefaultFont}, and sets the
* {@code show} boolean to {@link #DefaultShow}.
*
* @param setText Sets the displayed text.
* @param setTranslation Sets the x and y location of the text.
* @param setTranslation Sets the initial x and y translation of the text.
*/
public Text2D(String setText, Pointf setTranslation) {
this(setText, setTranslation, DefaultColor, DefaultFont, DefaultShow);
this(setText, DefaultColor, DefaultFont, DefaultShow);
setTranslation(setTranslation);
}

/**
* {@code Text2D} Constructor that takes in a string of text, a location, a color, a font, and a show variable.
* {@code Text2D} Constructor that takes in a string of text, a color, a font, and a show variable.
*
* @param setText Sets the displayed text.
* @param setColor Sets the text's color.
* @param setFont Sets the text's font.
* @param show Sets whether the text will be drawn to the screen.
*/
public Text2D(String setText, Color setColor, Font setFont, boolean show) {
text = setText;
font = setFont;

setColor(setColor);
setFont(setFont);
setShouldRender(show);
}

/**
* {@code Text2D} Constructor that takes in a string of text, a translation, a color, a font, and a show variable.
*
* @param setText Sets the displayed text.
* @param setTranslation Sets the x and y location of the text.
* @param setTranslation Sets the initial x and y translation of the text.
* @param setColor Sets the text's color.
* @param setFont Sets the text's font.
* @param show Sets whether the text will be drawn to the screen.
*/
public Text2D(String setText, Pointf setTranslation, Color setColor, Font setFont, boolean show) {
this(setText, setColor, setFont, show);
setTranslation(setTranslation);
}

/**
* {@code Text2D} Constructor that takes in a string of text, a translation/rotation/scale, a color, a font, and a
* show variable.
*
* @param setText Sets the displayed text.
* @param setTranslation Sets the initial x and y translation of the text.
* @param setRotation Sets the initial rotation of the text.
* @param setScale Sets the initial scale of the text.
* @param setColor Sets the text's color.
* @param setFont Sets the text's font.
* @param show Sets whether the text will be drawn to the screen.
*/
public Text2D(String setText, Pointf setTranslation, float setRotation, Pointf setScale, Color setColor, Font setFont, boolean show) {
text = setText;
font = setFont;

setTranslation(setTranslation);
setRotation(setRotation);
setScale(setScale);

setColor(setColor);
setFont(setFont);
setShouldRender(show);

setMetrics(FastJEngine.getDisplay().getGraphics());
}

/**
Expand Down Expand Up @@ -162,6 +211,7 @@ public void destroy(Scene originScene) {
text = null;
color = null;
font = null;
hasMetrics = false;

super.destroyTheRest(originScene);
}
Expand Down
93 changes: 69 additions & 24 deletions src/test/java/unittest/testcases/graphics/game/Text2DTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
import org.junit.jupiter.api.Test;
import unittest.EnvironmentHelper;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static unittest.EnvironmentHelper.runFastJWith;

Expand All @@ -24,6 +24,20 @@ public static void onlyRunIfNotHeadless() {
assumeFalse(EnvironmentHelper.IsEnvironmentHeadless);
}

@Test
void checkText2DConstructor_withStringTextParam() {
runFastJWith(() -> {
String text = "Hello, world!";

Text2D text2D = new Text2D(text);

assertEquals(text, text2D.getText(), "The actual text should match the expected text.");
assertEquals(Text2D.DefaultColor, text2D.getColor(), "The actual color should match the expected color.");
assertEquals(Text2D.DefaultFont, text2D.getFont(), "The actual font should match the default font.");
assertEquals(Text2D.DefaultShow, text2D.shouldRender(), "The actual show variable should match the default show variable.");
});
}

@Test
void checkText2DConstructor_withStringTextParam_andPointfTranslationParam() {
runFastJWith(() -> {
Expand All @@ -41,45 +55,82 @@ void checkText2DConstructor_withStringTextParam_andPointfTranslationParam() {
}

@Test
void checkText2DConstructor_withStringTextParam_andPointfTranslationParam_andColorParam_andFontParam_andShowParam() {
void checkText2DConstructor_withStringTextParam_andRandomlyGeneratedTranslationParam_andRandomlyGeneratedColorFontShowParams() {
runFastJWith(() -> {
String text = "Hello, world!";

Pointf randomTranslation = new Pointf(Maths.random(-50f, 50f), Maths.random(-50f, 50f));
Color randomColor = DrawUtil.randomColorWithAlpha();
Font randomFont = DrawUtil.randomFont();
boolean shouldRender = Maths.randomBoolean();
boolean randomShouldRender = Maths.randomBoolean();

Text2D text2D = new Text2D(text, randomTranslation, randomColor, randomFont, shouldRender);
Text2D text2D = new Text2D(text, randomTranslation, randomColor, randomFont, randomShouldRender);

assertEquals(text, text2D.getText(), "The actual text should match the expected text.");
assertEquals(randomTranslation, text2D.getTranslation(), "The actual translation should match the expected translation.");
assertEquals(randomColor, text2D.getColor(), "The actual color should match the expected random color.");
assertEquals(randomFont, text2D.getFont(), "The actual font should match the expected random font.");
assertEquals(shouldRender, text2D.shouldRender(), "The actual show variable should match the expected random show variable.");
assertEquals(randomShouldRender, text2D.shouldRender(), "The actual show variable should match the expected random show variable.");
});
}

@Test
void checkText2DConstructor_withStringTextParam_andPointfTranslationParam_andColorParam_andFontParam_andShowParam_usingMethodChaining() {
void checkText2DConstructor_withStringTextParam_andRandomlyGeneratedTransformationParams_andRandomlyGeneratedColorFontShowParams() {
runFastJWith(() -> {
String text = "Hello, world!";

Color randomColor = DrawUtil.randomColorWithAlpha();
Font randomFont = DrawUtil.randomFont();
boolean randomShouldRender = Maths.randomBoolean();

Pointf randomTranslation = new Pointf(Maths.random(-50f, 50f), Maths.random(-50f, 50f));
Pointf randomScale = new Pointf(Maths.random(-50f, 50f), Maths.random(-50f, 50f));
float randomRotation = Maths.random(-5000f, 5000f);
float expectedNormalizedRotation = randomRotation % 360;

Text2D text2D = new Text2D(text, randomTranslation, randomRotation, randomScale, randomColor, randomFont, randomShouldRender);

assertEquals(text, text2D.getText(), "The actual text should match the expected text.");
assertEquals(randomTranslation, text2D.getTranslation(), "The actual translation should match the expected translation.");
assertEquals(randomRotation, text2D.getRotation(), "The created polygon's rotation should match the randomly generated rotation.");
assertEquals(expectedNormalizedRotation, text2D.getRotationWithin360(), "The created model's normalized rotation should match the normalized rotation.");
assertEquals(randomScale, text2D.getScale(), "The created polygon's scaling should match the randomly generated scale.");
assertEquals(randomColor, text2D.getColor(), "The actual color should match the expected random color.");
assertEquals(randomFont, text2D.getFont(), "The actual font should match the expected random font.");
assertEquals(randomShouldRender, text2D.shouldRender(), "The actual show variable should match the expected random show variable.");
});
}

@Test
void checkText2DConstructor_withStringTextParam_andRandomlyGeneratedTransformationParams_andRandomlyGeneratedColorFontShowParams_usingMethodChaining() {
runFastJWith(() -> {
String text = "Hello, world!";

Color randomColor = DrawUtil.randomColorWithAlpha();
Font randomFont = DrawUtil.randomFont();
boolean shouldRender = Maths.randomBoolean();
boolean randomShouldRender = Maths.randomBoolean();

Pointf randomTranslation = new Pointf(Maths.random(-50f, 50f), Maths.random(-50f, 50f));
Pointf randomScale = new Pointf(Maths.random(-50f, 50f), Maths.random(-50f, 50f));
float randomRotation = Maths.random(-5000f, 5000f);
float expectedNormalizedRotation = randomRotation % 360;

Text2D text2D = (Text2D) new Text2D(text, randomTranslation)
Text2D text2D = (Text2D) new Text2D(text)
.setColor(randomColor)
.setFont(randomFont)
.setShouldRender(shouldRender);
.setTranslation(randomTranslation)
.setRotation(randomRotation)
.setScale(randomScale)
.setShouldRender(randomShouldRender);

assertEquals(text, text2D.getText(), "The actual text should match the expected text.");
assertEquals(randomTranslation, text2D.getTranslation(), "The actual translation should match the expected translation.");
assertEquals(randomRotation, text2D.getRotation(), "The created polygon's rotation should match the randomly generated rotation.");
assertEquals(expectedNormalizedRotation, text2D.getRotationWithin360(), "The created model's normalized rotation should match the normalized rotation.");
assertEquals(randomScale, text2D.getScale(), "The created polygon's scaling should match the randomly generated scale.");
assertEquals(randomColor, text2D.getColor(), "The actual color should match the expected random color.");
assertEquals(randomFont, text2D.getFont(), "The actual font should match the expected random font.");
assertEquals(shouldRender, text2D.shouldRender(), "The actual show variable should match the expected random show variable.");
assertEquals(randomShouldRender, text2D.shouldRender(), "The actual show variable should match the expected random show variable.");
});
}

Expand All @@ -101,34 +152,28 @@ void checkTranslateText2D_shouldMatchExpected() {
}

@Test
void checkRotateText2D_shouldThrowException() {
void checkRotateText2D_shouldMatchExpected() {
runFastJWith(() -> {
String text = "Hello, world!";
Pointf originalTranslation = Pointf.Origin.copy();
float randomRotation = Maths.random(-50f, 50f);

Text2D text2D = new Text2D(text, originalTranslation);
Throwable exception = assertThrows(IllegalStateException.class, () -> text2D.rotate(randomRotation, Pointf.Origin));
Text2D text2D = new Text2D(text);

String expectedErrorMessage = "ERROR: The game crashed, due to the call of a method not yet implemented.";
String actualErrorMessage = exception.getMessage();
assertEquals(expectedErrorMessage, actualErrorMessage);
assertDoesNotThrow(() -> text2D.rotate(randomRotation, Pointf.Origin), "Rotating Text2D objects is implemented, and should not throw an exception.");
assertEquals(randomRotation, text2D.getRotation(), "The actual rotation should match the expected rotation.");
});
}

@Test
void checkScaleText2D_shouldThrowException() {
void checkScaleText2D_shouldMatchExpected() {
runFastJWith(() -> {
String text = "Hello, world!";
Pointf originalTranslation = Pointf.Origin.copy();
Pointf randomScale = new Pointf(Maths.random(-50f, 50f), Maths.random(-50f, 50f));

Text2D text2D = new Text2D(text, originalTranslation);
Throwable exception = assertThrows(IllegalStateException.class, () -> text2D.scale(randomScale, originalTranslation));
Text2D text2D = new Text2D(text);

String expectedErrorMessage = "ERROR: The game crashed, due to the call of a method not yet implemented.";
String actualErrorMessage = exception.getMessage();
assertEquals(expectedErrorMessage, actualErrorMessage);
assertDoesNotThrow(() -> text2D.scale(randomScale), "Scaling Text2D objects is implemented, and should not throw an exception.");
assertEquals(Pointf.add(randomScale, 1f), text2D.getScale(), "The actual scale should match the expected scale.");
});
}
}

0 comments on commit 18d06d5

Please sign in to comment.