Pull Request #92: Possibility to flip a Monster Sprite horizontally

This commit is contained in:
Nut.andor
2025-09-09 14:23:16 +02:00
9 changed files with 46 additions and 7 deletions

View File

@@ -30,11 +30,14 @@ public final class Monster extends Actor {
public final MonsterType monsterType;
public final MonsterSpawnArea area;
public final boolean isFlippedX;
public Monster(MonsterType monsterType, MonsterSpawnArea area) {
super(monsterType.tileSize, false, monsterType.isImmuneToCriticalHits());
this.monsterType = monsterType;
this.area = area;
this.iconID = monsterType.iconID;
this.isFlippedX = Constants.roll100(monsterType.horizontalFlipChance);
this.nextPosition = new CoordRect(new Coord(), monsterType.tileSize);
resetStatsToBaseTraits();
this.ap.setMax();

View File

@@ -37,6 +37,7 @@ public final class MonsterType {
public final Size tileSize;
public final int iconID;
public final int horizontalFlipChance;
public final int maxAP;
public final int maxHP;
public final int moveCost;
@@ -64,6 +65,7 @@ public final class MonsterType {
, AggressionType aggressionType
, Size tileSize
, int iconID
, int horizontalFlipChance
, int maxAP
, int maxHP
, int moveCost
@@ -90,6 +92,7 @@ public final class MonsterType {
this.aggressionType = aggressionType;
this.tileSize = tileSize;
this.iconID = iconID;
this.horizontalFlipChance = horizontalFlipChance;
this.maxAP = maxAP;
this.maxHP = maxHP;
this.moveCost = moveCost;

View File

@@ -55,6 +55,8 @@ public final class MonsterTypeParser extends JsonCollectionParserFor<MonsterType
final int exp = getExpectedMonsterExperience(attackCost, attackChance, damagePotential, criticalSkill, criticalMultiplier, blockChance, damageResistance, hitEffect, maxHP, maxAP);
final int horizontalFlipChance = o.optInt(JsonFieldNames.Monster.horizontalFlipChance, 0);
return new Pair<String, MonsterType>(monsterTypeID, new MonsterType(
monsterTypeID
, translationLoader.translateMonsterTypeName(o.getString(JsonFieldNames.Monster.name))
@@ -68,6 +70,7 @@ public final class MonsterTypeParser extends JsonCollectionParserFor<MonsterType
, MonsterType.AggressionType.fromString(o.optString(JsonFieldNames.Monster.movementAggressionType, null), MonsterType.AggressionType.none)
, ResourceParserUtils.parseTilesetTileSize(tileLoader, o.optString(JsonFieldNames.Monster.iconID, null), size1x1)
, ResourceParserUtils.parseImageID(tileLoader, o.getString(JsonFieldNames.Monster.iconID))
, horizontalFlipChance
, maxAP
, maxHP
, o.optInt(JsonFieldNames.Monster.moveCost, 10)

View File

@@ -105,6 +105,7 @@ public final class JsonFieldNames {
public static final class Monster {
public static final String monsterTypeID = "id";
public static final String iconID = "iconID";
public static final String horizontalFlipChance = "horizontalFlipChance";
public static final String name = "name";
public static final String spawnGroup = "spawnGroup";
public static final String monsterClass = "monsterClass";

View File

@@ -2,6 +2,7 @@ package com.gpl.rpg.AndorsTrail.resource.tiles;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
public final class TileCollection {
@@ -22,6 +23,17 @@ public final class TileCollection {
}
public void drawTile(Canvas canvas, int tile, int px, int py, Paint mPaint) {
canvas.drawBitmap(bitmaps[tile], px, py, mPaint);
drawTile(canvas, tile, px, py, mPaint, false);
}
public void drawTile(Canvas canvas, int tile, int px, int py, Paint mPaint, boolean isFlippedX) {
if (isFlippedX)
canvas.drawBitmap(flipBitmapX(bitmaps[tile]), px, py, mPaint);
else canvas.drawBitmap(bitmaps[tile], px, py, mPaint);
}
public Bitmap flipBitmapX(Bitmap source) {
Matrix matrix = new Matrix();
matrix.postScale(-1, 1, source.getWidth() / 2f, source.getHeight() / 2f);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
}
}

View File

@@ -431,13 +431,13 @@ public final class MainView extends SurfaceView
for (MonsterSpawnArea a : currentMap.spawnAreas) {
for (Monster m : a.monsters) {
if (!m.hasVFXRunning) {
drawFromMapPosition(canvas, area, m.rectPosition, m.iconID);
drawFromMapPosition(canvas, area, m.rectPosition, m.iconID, m.isFlippedX);
} else if (area.intersects(m.rectPosition) || area.intersects(new CoordRect(m.lastPosition,m.rectPosition.size))) {
int vfxElapsedTime = (int) (System.currentTimeMillis() - m.vfxStartTime);
if (vfxElapsedTime > m.vfxDuration) vfxElapsedTime = m.vfxDuration;
int x = ((m.position.x - mapViewArea.topLeft.x) * tileSize * vfxElapsedTime + ((m.lastPosition.x - mapViewArea.topLeft.x) * tileSize * (m.vfxDuration - vfxElapsedTime))) / m.vfxDuration;
int y = ((m.position.y - mapViewArea.topLeft.y) * tileSize * vfxElapsedTime + ((m.lastPosition.y - mapViewArea.topLeft.y) * tileSize * (m.vfxDuration - vfxElapsedTime))) / m.vfxDuration;
tiles.drawTile(canvas, m.iconID, x, y, mPaint);
tiles.drawTile(canvas, m.iconID, x, y, mPaint, m.isFlippedX);
}
}
}
@@ -503,10 +503,18 @@ public final class MainView extends SurfaceView
if (!area.contains(p)) return;
_drawFromMapPosition(canvas, area, p.x, p.y, tile);
}
private void drawFromMapPosition(Canvas canvas, final CoordRect area, final Coord p, final int tile, final boolean isFlippedX) {
if (!area.contains(p)) return;
_drawFromMapPosition(canvas, area, p.x, p.y, tile, isFlippedX);
}
private void drawFromMapPosition(Canvas canvas, final CoordRect area, final CoordRect p, final int tile) {
if (!area.intersects(p)) return;
_drawFromMapPosition(canvas, area, p.topLeft.x, p.topLeft.y, tile);
}
private void drawFromMapPosition(Canvas canvas, final CoordRect area, final CoordRect p, final int tile, final boolean isFlippedX) {
if (!area.intersects(p)) return;
_drawFromMapPosition(canvas, area, p.topLeft.x, p.topLeft.y, tile, isFlippedX);
}
private void _drawFromMapPosition(Canvas canvas, final CoordRect area, int x, int y, final int tile) {
x -= mapViewArea.topLeft.x;
y -= mapViewArea.topLeft.y;
@@ -515,6 +523,14 @@ public final class MainView extends SurfaceView
tiles.drawTile(canvas, tile, x * tileSize, y * tileSize, mPaint);
// }
}
private void _drawFromMapPosition(Canvas canvas, final CoordRect area, int x, int y, final int tile, final boolean isFlippedX) {
x -= mapViewArea.topLeft.x;
y -= mapViewArea.topLeft.y;
// if ( (x >= 0 && x < mapViewArea.size.width)
// && (y >= 0 && y < mapViewArea.size.height)) {
tiles.drawTile(canvas, tile, x * tileSize, y * tileSize, mPaint, isFlippedX);
// }
}
private void drawEffectText(Canvas canvas, final CoordRect area, final VisualEffectAnimation e, int textYOffset, Paint textPaint) {
int x = (e.position.x - mapViewArea.topLeft.x) * tileSize + tileSize/2;

View File

@@ -928,4 +928,4 @@
"blockChance":70,
"damageResistance":4
}
]
]

View File

@@ -5,7 +5,8 @@
"iconID":"monsters_mage2:0",
"monsterClass":"humanoid",
"spawnGroup":"mikhail",
"phraseID":"mikhail_start_select"
"phraseID":"mikhail_start_select",
"horizontalFlipChance":100
},
{
"id":"leta",
@@ -116,4 +117,4 @@
"spawnGroup":"jan",
"phraseID":"jan_start_select"
}
]
]

View File

@@ -511,4 +511,4 @@
"blockChance":30,
"damageResistance":2
}
]
]