better defined Hangul Johab font, correction on FloatingIslands to utilise new 4096 tiles, multiple type beach (white, black, green), ACHTUNG! ActorWithBody has temporal debugger! (sout), former HSV is now HSVUtil, new HSV for HSV dimension, HSVUtil.toRGB and HSVUtil.fromRGB, more jakanaJP and isIC in polyglot.csv

Former-commit-id: e8cd234d1140d623ba7ab551d3429fc4a453b5c1
Former-commit-id: e11bc93da0d37e385e375fbb0086cf7dbb3a5454
This commit is contained in:
Song Minjae
2016-03-10 23:42:53 +09:00
parent 8b558902e7
commit d76fd97e5a
25 changed files with 304 additions and 150 deletions

View File

@@ -1,76 +1,49 @@
package com.Torvald.ColourUtil;
import com.jme3.math.FastMath;
import org.newdawn.slick.Color;
/**
* Created by minjaesong on 16-01-16.
* Created by minjaesong on 16-03-10.
*/
public class HSV {
private float H;
private float S;
private float V;
/**
* Convert HSV parameters to RGB color.
* @param h 0-359 Hue
* @param s 0-255 Saturation
* @param v 0-255 Value
* @return org.newdawn.slick.Color
* @link http://www.rapidtables.com/convert/color/hsv-to-rgb.htm
*/
public static Color toRGB(int h, int s, int v) {
int H = h;
if (H < 0 || H >= 360) {
H %= 360;
}
float S = s / 255f;
float V = v / 255f;
float C = V * S;
float X = C * (1 - FastMath.abs(
(H / 60f) % 2 - 1
));
float m = V - C;
float R_prime = Float.NaN;
float G_prime = Float.NaN;
float B_prime = Float.NaN;
if (H < 60) {
R_prime = C;
G_prime = X;
B_prime = 0;
}
else if (H < 120) {
R_prime = X;
G_prime = C;
B_prime = 0;
}
else if (H < 180) {
R_prime = 0;
G_prime = C;
B_prime = X;
}
else if (H < 240) {
R_prime = 0;
G_prime = X;
B_prime = C;
}
else if (H < 300) {
R_prime = X;
G_prime = 0;
B_prime = C;
}
else if (H < 360) {
R_prime = C;
G_prime = 0;
B_prime = X;
}
return new Color(
(int) ((R_prime + m) * 255)
, (int) ((G_prime + m) * 255)
, (int) ((B_prime + m) * 255)
);
public HSV() {
}
/**
*
* @param h 0-359
* @param s 0-1
* @param v 0-1
*/
public HSV(float h, float s, float v) {
H = h;
S = s;
V = v;
}
public float getH() {
return H;
}
public void setH(float h) {
H = h;
}
public float getS() {
return S;
}
public void setS(float s) {
S = s;
}
public float getV() {
return V;
}
public void setV(float v) {
V = v;
}
}

View File

@@ -0,0 +1,109 @@
package com.Torvald.ColourUtil;
import com.jme3.math.FastMath;
import org.newdawn.slick.Color;
/**
* Created by minjaesong on 16-01-16.
*/
public class HSVUtil {
/**
* Convert HSV parameters to RGB color.
* @param H 0-359 Hue
* @param S 0-1 Saturation
* @param V 0-1 Value
* @return org.newdawn.slick.Color
* @link http://www.rapidtables.com/convert/color/hsv-to-rgb.htm
*/
public static Color toRGB(float H, float S, float V) {
H %= 360;
float C = V * S;
float X = C * (1 - FastMath.abs(
(H / 60f) % 2 - 1
));
float m = V - C;
float R_prime = Float.NaN;
float G_prime = Float.NaN;
float B_prime = Float.NaN;
if (H < 60) {
R_prime = C;
G_prime = X;
B_prime = 0;
}
else if (H < 120) {
R_prime = X;
G_prime = C;
B_prime = 0;
}
else if (H < 180) {
R_prime = 0;
G_prime = C;
B_prime = X;
}
else if (H < 240) {
R_prime = 0;
G_prime = X;
B_prime = C;
}
else if (H < 300) {
R_prime = X;
G_prime = 0;
B_prime = C;
}
else if (H < 360) {
R_prime = C;
G_prime = 0;
B_prime = X;
}
return new Color(
(int) ((R_prime + m) * 255)
, (int) ((G_prime + m) * 255)
, (int) ((B_prime + m) * 255)
);
}
public static Color toRGB(HSV hsv) {
return toRGB(hsv.getH(), hsv.getS(), hsv.getV());
}
public static HSV fromRGB(Color color) {
float r = color.getRed() / 255f;
float g = color.getGreen() / 255f;
float b = color.getBlue() / 255f;
float rgbMin = FastMath.min(r, g, b);
float rgbMax = FastMath.max(r, g, b);
float h;
float s;
float v = rgbMax;
float delta = rgbMax - rgbMin;
if (rgbMax != 0)
s = delta / rgbMax;
else {
h = 0;
s = 0;
return new HSV(h, s, v);
}
if (r == rgbMax)
h = (g - b) / delta;
else if (g == rgbMax)
h = 2 + (b - r) / delta;
else
h = 4 + (r - g) / delta;
h *= 60;
if (h < 0) h += 360;
return new HSV(h, s, v);
}
}

View File

@@ -112,24 +112,30 @@ public class GameFontBase implements Font {
return hanIndex % JONG_COUNT;
}
private int getHanChoseongShift(int hanIndex) {
private int getHanChoseongRow(int hanIndex) {
int jungseongIndex = getHanJungseong(hanIndex);
Integer[] jungseongWide = {8, 12, 13, 17, 18, 21};
Integer[] jungseongComplex = {9, 10, 11, 14, 15, 16, 22};
int ret;
if (getHanJongseong(hanIndex) != 0)
return (Arrays.asList(jungseongWide).contains(jungseongIndex))
? 1 : 0;
else
return (Arrays.asList(jungseongWide).contains(jungseongIndex))
? 1 : 0;
if (Arrays.asList(jungseongWide).contains(jungseongIndex)) {
ret = 2;
}
else if (Arrays.asList(jungseongComplex).contains(jungseongIndex)) {
ret = 4;
}
else {
ret = 0;
}
return (getHanJongseong(hanIndex) == 0) ? ret : ret + 1;
}
private int getHanJungseongShift(int hanIndex) {
return (getHanJongseong(hanIndex) == 0) ? 4 : 5;
private int getHanJungseongRow(int hanIndex) {
return (getHanJongseong(hanIndex) == 0) ? 6 : 7;
}
private int getHanJongseongShift() {
return 6;
private int getHanJongseongRow() {
return 8;
}
private boolean isAsciiEF(char c) {
@@ -356,9 +362,9 @@ public class GameFontBase implements Font {
int indexJung = getHanJungseong(hIndex);
int indexJong = getHanJongseong(hIndex);
int choRow = getHanChoseongShift(hIndex);
int jungRow = getHanJungseongShift(hIndex);
int jongRow = getHanJongseongShift();
int choRow = getHanChoseongRow(hIndex);
int jungRow = getHanJungseongRow(hIndex);
int jongRow = getHanJongseongRow();
int glyphW = getWidth("" + ch);

View File

@@ -119,6 +119,12 @@ public class ActorWithBody implements Actor, Visible, Glowing {
*/
public final int INVINCIBILITY_TIME = 500;
/**
* Will ignore fluid resistance if (submerged height / actor height) <= this var
*/
private final float FLUID_RESISTANCE_IGNORE_THRESHOLD_RATIO = 0.2f;
private final float FLUID_RESISTANCE_APPLY_FULL_RATIO = 0.5f;
private GameMap map;
/**
@@ -268,11 +274,11 @@ public class ActorWithBody implements Actor, Visible, Glowing {
// order of the if-elseif chain is IMPORTANT
if (isColliding(CONTACT_AREA_BOTTOM)) {
adjustHitBottom();
if (veloY != 0) veloY = -veloY * elasticity;
elasticReflectY();
grounded = true;
}
else if (isColliding(CONTACT_AREA_BOTTOM, 0, 1)) {
if (veloY != 0) veloY = -veloY * elasticity;
elasticReflectY();
grounded = true;
}
else {
@@ -285,10 +291,10 @@ public class ActorWithBody implements Actor, Visible, Glowing {
// order of the if-elseif chain is IMPORTANT
if (isColliding(CONTACT_AREA_TOP)) {
adjustHitTop();
if (veloY != 0) veloY = -veloY * elasticity;
elasticReflectY();
}
else if (isColliding(CONTACT_AREA_TOP, 0, -1)) {
if (veloY != 0) veloY = -veloY * elasticity; // for reversed gravity
elasticReflectY(); // for reversed gravity
}
else {
}
@@ -333,33 +339,39 @@ public class ActorWithBody implements Actor, Visible, Glowing {
private void updateHorizontalPos() {
if (!isNoCollideWorld()) {
// check right
if (veloX > 0) {
if (veloX >= 0.5) {
// order of the if-elseif chain is IMPORTANT
if (isColliding(CONTACT_AREA_RIGHT) && !isColliding(CONTACT_AREA_LEFT)) {
adjustHitRight();
if (veloX != 0) veloX = -veloX * elasticity;
elasticReflectX();
}
else if (isColliding(CONTACT_AREA_RIGHT, 1, 0)
&& !isColliding(CONTACT_AREA_LEFT, -1, 0)) {
if (veloX != 0) veloX = -veloX * elasticity;
elasticReflectX();
}
else {
}
}
else { // fix for float-point rounding; veloX of zero should be treated as moving left
else if (veloX <= 0.5) {
System.out.println("collidingleft");
// order of the if-elseif chain is IMPORTANT
if (isColliding(CONTACT_AREA_LEFT) && !isColliding(CONTACT_AREA_RIGHT)) {
adjustHitLeft();
if (veloX != 0) veloX = -veloX * elasticity;
elasticReflectX();
}
else if (isColliding(CONTACT_AREA_LEFT, -1, 0)
&& !isColliding(CONTACT_AREA_RIGHT, 1, 0)) {
if (veloX != 0) veloX = -veloX * elasticity;
elasticReflectX();
}
else {
}
}
else {
System.out.println("updatehorizontal - |velo| < 0.5");
if (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT)) {
// elasticReflectX();
}
}
}
}
@@ -399,6 +411,14 @@ public class ActorWithBody implements Actor, Visible, Glowing {
nextHitbox.setPosition(newX, newY); // + 1; float-point rounding compensation (i think...)
}
private void elasticReflectX() {
if (veloX != 0) veloX = -veloX * elasticity;
}
private void elasticReflectY() {
if (veloY != 0) veloY = -veloY * elasticity;
}
private boolean isColliding(int side) {
return isColliding(side, 0, 0);
}
@@ -485,7 +505,6 @@ public class ActorWithBody implements Actor, Visible, Glowing {
*/
private void applyBuoyancy() {
int fluidDensity = getTileDensity();
int fluidResistance = getTileMvmtRstc();
float submergedVolume = getSubmergedVolume();
if (!isPlayerNoClip() && !grounded) {
@@ -493,24 +512,18 @@ public class ActorWithBody implements Actor, Visible, Glowing {
veloY -= ((fluidDensity - this.density)
* map.getGravitation() * submergedVolume
* Math.pow(mass, -1)
// * mvmtRstcToMultiplier(fluidResistance) // eliminate shoot-up
* SI_TO_GAME_ACC);
}
}
private float getSubmergedVolume(){
private float getSubmergedVolume() {
float GAME_TO_SI_VOL = FastMath.pow((1f/METER), 3);
if( density > 0 ){
return FastMath.clamp(
(nextHitbox.getPointedY() - getFluidLevel()) // submerged height
* nextHitbox.getWidth() * nextHitbox.getWidth()
* GAME_TO_SI_VOL
, 0
, nextHitbox.getHeight()
* nextHitbox.getWidth() * nextHitbox.getWidth()
* GAME_TO_SI_VOL
);
return getSubmergedHeight()
* nextHitbox.getWidth() * nextHitbox.getWidth()
* GAME_TO_SI_VOL
;
//System.out.println("fluidHeight: "+fluidHeight+", submerged: "+submergedVolume);
//submergedHeight / TILE_SIZE * 1^2 (pixel to meter)
}
@@ -519,7 +532,15 @@ public class ActorWithBody implements Actor, Visible, Glowing {
}
}
private int getFluidLevel(){
private float getSubmergedHeight() {
return FastMath.clamp(
nextHitbox.getPointedY() - getFluidLevel()
, 0
, nextHitbox.getHeight()
);
}
private int getFluidLevel() {
int tilePosXStart = Math.round(nextHitbox.getPosX() / TSIZE);
int tilePosXEnd = Math.round(nextHitbox.getHitboxEnd().getX() / TSIZE);
int tilePosY = Math.round(nextHitbox.getPosY() / TSIZE);
@@ -635,15 +656,33 @@ public class ActorWithBody implements Actor, Visible, Glowing {
private void updateNextHitboxFromVelo() {
float fluidResistance = mvmtRstcToMultiplier(getTileMvmtRstc());
float submergedRatio = FastMath.clamp(
getSubmergedHeight() / nextHitbox.getHeight()
, 0f, 1f
);
boolean applyResistance = (!isNoSubjectToFluidResistance()
&& submergedRatio > FLUID_RESISTANCE_IGNORE_THRESHOLD_RATIO
);
float resistanceMulInterValueSize = FLUID_RESISTANCE_APPLY_FULL_RATIO - FLUID_RESISTANCE_IGNORE_THRESHOLD_RATIO;
float resistanceMultiplier = FastMath.interpolateLinear(
(submergedRatio - FLUID_RESISTANCE_IGNORE_THRESHOLD_RATIO)
* FastMath.pow(resistanceMulInterValueSize, -1)
, 0, 1
);
float adjustedResistance = FastMath.interpolateLinear(
resistanceMultiplier
, 1f, fluidResistance
);
nextHitbox.set(
Math.round(hitbox.getPosX()
+ (veloX
* (isNoSubjectToFluidResistance() ? 1 : fluidResistance)
* (!applyResistance ? 1 : adjustedResistance)
))
, Math.round(hitbox.getPosY()
+ (veloY
* (isNoSubjectToFluidResistance() ? 1 : fluidResistance)
* (!applyResistance ? 1 : adjustedResistance)
))
, Math.round(baseHitboxW * scale)
, Math.round(baseHitboxH * scale)
@@ -731,11 +770,6 @@ public class ActorWithBody implements Actor, Visible, Glowing {
return referenceID;
}
public float pointedPosX() { return hitbox.getPointedX(); }
public float pointedPosY() { return hitbox.getPointedY(); }
public float topLeftPosX() { return hitbox.getPosX(); }
public float topLeftPosY() { return hitbox.getPosY(); }
private float clampW(float x) {
if (x < TSIZE + nextHitbox.getWidth() / 2) {
return TSIZE + nextHitbox.getWidth() / 2;

View File

@@ -4,10 +4,10 @@ import com.Torvald.Rand.HQRNG;
public class FloatingIslandsPreset {
public static int presets = 5;
public static final int PRESETS = 5;
static int[][] generatePreset(HQRNG random) {
int index = random.nextInt(presets);
int index = random.nextInt(PRESETS);
return generatePreset(index, random);
}

View File

@@ -7,6 +7,8 @@ import com.Torvald.Terrarum.TileProperties.TileNameCode;
import com.jme3.math.FastMath;
import com.sun.istack.internal.NotNull;
import java.util.Random;
public class MapGenerator {
@NotNull private static GameMap map;
@@ -100,10 +102,10 @@ public class MapGenerator {
* Todo: more perturbed overworld (harder to supra-navigate)
* Todo: veined ore distribution (metals) -- use veined simplex noise
* Todo: clustered gem distribution (Groups: [Ruby, Sapphire], Amethyst, Yellow topaz, emerald, diamond) -- use regular simplex noise
* Todo: Lakes! Aquifers! Lava chamber!
* Todo: desert areas (variants: SAND_DESERT, SAND_RED
* Todo: Lakes! Aquifers! Lava chambers!
* Todo: deserts (variants: SAND_DESERT, SAND_RED)
* Todo: volcano(es?)
* Todo: variants of beach (SAND_BEACH, SAND_BLACK, SAND_GREEN)
* Done: variants of beach (SAND_BEACH, SAND_BLACK, SAND_GREEN)
*/
carveCave(
@@ -889,10 +891,12 @@ public class MapGenerator {
int nIslands = random.nextInt(nIslandsMax - nIslandsMin) + nIslandsMin;
int prevIndex = -1;
int[] tiles = {TileNameCode.AIR, TileNameCode.STONE, TileNameCode.DIRT, TileNameCode.GRASS};
for (int i = 0; i < nIslands; i++) {
int currentIndex = random.nextInt(FloatingIslandsPreset.presets);
int currentIndex = random.nextInt(FloatingIslandsPreset.PRESETS);
while (currentIndex == prevIndex) {
currentIndex = random.nextInt(FloatingIslandsPreset.presets);
currentIndex = random.nextInt(FloatingIslandsPreset.PRESETS);
}
int[][] island = FloatingIslandsPreset.generatePreset(currentIndex, random);
@@ -902,8 +906,9 @@ public class MapGenerator {
for (int j = 0; j < island.length; j++) {
for (int k = 0; k < island[0].length; k++) {
if (island[j][k] > 0) {
map.getTerrainArray()[j + startingPosY][k + startingPosX]
= (byte) island[j][k];
map.setTileTerrain(k + startingPosX, j + startingPosY
, tiles[island[j][k]]
);
}
}
}
@@ -975,6 +980,18 @@ public class MapGenerator {
/* Post-process */
private static void fillOcean() {
int[] thisSandList = {TileNameCode.SAND_BEACH, TileNameCode.SAND_BLACK, TileNameCode.SAND_GREEN
, TileNameCode.SAND_BEACH, TileNameCode.SAND_BEACH, TileNameCode.SAND_BLACK
};
Random thisRand = new HQRNG(seed ^ random.nextLong());
int thisSand = thisSandList[thisRand.nextInt(thisSandList.length)];
String thisSandStr = (thisSand == TileNameCode.SAND_BLACK) ? "black"
: (thisSand == TileNameCode.SAND_GREEN) ? "green"
: "white"
;
System.out.println("[MapGenerator] Beach sand type: " + thisSandStr);
for (int ix = 0; ix < OCEAN_WIDTH * 1.5; ix++) {
//flooding
if (ix < OCEAN_WIDTH) {
@@ -1000,16 +1017,16 @@ public class MapGenerator {
int terrainPoint = getTerrainHeightFromHeightMap(ix);
map.setTileTerrain(ix, terrainPoint + iy, TileNameCode.SAND_BEACH);
map.setTileTerrain(ix, terrainPoint + iy, thisSand);
// clear grass and make the sheet thicker
map.setTileTerrain(ix, terrainPoint + iy - 1, TileNameCode.SAND_BEACH);
map.setTileTerrain(ix, terrainPoint + iy - 1, thisSand);
}
else if (worldOceanPosition == TYPE_OCEAN_RIGHT) {
int terrainPoint = getTerrainHeightFromHeightMap(map.width - 1 - ix);
map.setTileTerrain(map.width - 1 - ix, terrainPoint + iy, TileNameCode.SAND_BEACH);
map.setTileTerrain(map.width - 1 - ix, terrainPoint + iy, thisSand);
// clear grass and make the sheet thicker
map.setTileTerrain(map.width - 1 - ix, terrainPoint + iy - 1, TileNameCode.SAND_BEACH);
map.setTileTerrain(map.width - 1 - ix, terrainPoint + iy - 1, thisSand);
}
}
}

View File

@@ -75,7 +75,7 @@ public class TilePropCodex {
prop.setOpacity((char) intVal(record, "opacity"));
prop.setStrength(intVal(record, "strength"));
prop.setDensity(intVal(record, "spcg"));
prop.setDensity(intVal(record, "dsty"));
prop.setLuminosity((char) intVal(record, "lumcolor"));
prop.setDrop(intVal(record, "drop"));
prop.setDropDamage(intVal(record, "ddmg"));

View File

@@ -34,6 +34,7 @@
package com.jme3.math;
import java.util.Arrays;
import java.util.Random;
/**
@@ -636,10 +637,10 @@ final public class FastMath {
/**
* Returns the determinant of a 4x4 matrix.
*/
public static float determinant(double m00, double m01, double m02,
double m03, double m10, double m11, double m12, double m13,
double m20, double m21, double m22, double m23, double m30,
double m31, double m32, double m33) {
public static float determinant(double m00, double m01, double m02, double m03,
double m10, double m11, double m12, double m13,
double m20, double m21, double m22, double m23,
double m30, double m31, double m32, double m33) {
double det01 = m20 * m31 - m21 * m30;
double det02 = m20 * m32 - m22 * m30;
@@ -837,4 +838,16 @@ final public class FastMath {
| ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00)
| ((f >> 13) & 0x03ff));
}
public static float min(float... f) {
float[] sorted = f.clone();
Arrays.sort(f.clone());
return sorted[0];
}
public static float max(float... f) {
float[] sorted = f.clone();
Arrays.sort(f.clone());
return sorted[sorted.length - 1];
}
}