【发布时间】:2015-09-12 13:43:03
【问题描述】:
我正在编写一个 Android 游戏。在游戏中,不同颜色的方块会掉到地上。当两个具有相同颜色的块相互重叠时,它们将合并为一个颜色较深的块。但是,我观察到具有相同颜色的块有时不会合并。经过一番调试,我发现它们的颜色实际上略有不同:-16757700 和 -16757444。我使用Color.colorToHSV 和Color.HSVToColor 使颜色变深,如下面的代码所示(checkLanded 方法)。所以我认为这两种hsv方法一定有问题。这是我的代码(其实我认为代码没有其他问题,你可以看看checkLanded方法。但是我粘贴了其他代码,因为问题可能不是我认为的问题。只是几乎滚动到底部,您将看到checkLanded 方法):
package com.shades;
import android.graphics.Color;
import android.support.annotation.IntDef;
import com.shades.util.BlockView;
import com.shades.util.Timer;
import java.util.HashMap;
import java.util.Random;
public class Block {
private static Random r = new Random ();
private static HashMap<Integer, Float> colorValuesMap;
@IntDef ({LEFT, RIGHT})
public @interface Direction {}
public static final int LEFT = -1;
public static final int RIGHT = 1;
static {
colorValuesMap = new HashMap<> ();
colorValuesMap.put (4, 0.1F);
colorValuesMap.put (3, 0.3F);
colorValuesMap.put (2, 0.5F);
colorValuesMap.put (1, 0.7F);
colorValuesMap.put (0, 0.9F);
}
private int x;
private int y;
private int color;
protected Timer timer;
public int getX() {
return x;
}
public int getY() {
return y;
}
private void setY(int y) {
Block[][] matrix = Game.getInstance ().getBlockMatrix ();
matrix[this.x][this.y] = null;
this.y = y;
matrix[this.x][this.y] = this;
BlockView.updateViews ();
}
private void setX(int x) {
Block[][] matrix = Game.getInstance ().getBlockMatrix ();
matrix[this.x][this.y] = null;
this.x = x;
matrix[this.x][this.y] = this;
BlockView.updateViews ();
}
private void setXY (int x, int y) {
Block[][] matrix = Game.getInstance ().getBlockMatrix ();
matrix[this.x][this.y] = null;
this.y = y;
this.x = x;
matrix[x][y] = this;
BlockView.updateViews ();
}
public int getColor () {
return color;
}
public Block(int x, int y) {
setXY (x, y);
this.y = y;
float[] hsv = new float[3];
hsv[0] = Game.getInstance ().getHueNumber ();
hsv[1] = 1F;
hsv[2] = colorValuesMap.get (r.nextInt (4));
color = Color.HSVToColor (hsv);
BlockView.updateViews ();
timer = new Timer (new Runnable () {
@Override
public void run() {
moveDown ();
}
}, 1000, true);
}
private void moveDown () {
//if reached bottom
if (getY () == Game.MATRIX_HEIGHT - 1) {
timer.stopTimer ();
Game.getInstance ().nextBlock (r);
return;
}
color = Game.getInstance ().getBlockViewMatrix ()[x][y].getColor ();
Block[][] matrix = Game.getInstance ().getBlockMatrix ();
if (checkLanded (matrix[x][y + 1])) {
Game.getInstance ().nextBlock(r);
return;
}
setY (getY () + 1);
}
private boolean checkLanded(Block blockBelow) {
//if it can merge into another block
float[] currentHSV = new float[3];
Color.colorToHSV (color, currentHSV);//here is the possible inaccurate method
if (blockBelow != null &&
blockBelow.getColor () == color &&
currentHSV[2] != colorValuesMap.get (4)) {
Color.colorToHSV (blockBelow.getColor (), currentHSV);
currentHSV[2] -= 0.2F;
blockBelow.color = Color.HSVToColor (currentHSV); //here is the possible inaccurate method
selfDestroy ();
timer.stopTimer ();
//if the block below is not the block at the bottom
if (blockBelow.getY () != Game.MATRIX_HEIGHT - 1) {
blockBelow.checkLanded (Game.getInstance ().
getBlockMatrix ()[blockBelow.getX ()][blockBelow.getY () + 1]);
}
return true;
}
//if a block is touched
if (blockBelow != null &&
blockBelow.getColor () != color) {
timer.stopTimer ();
return true;
}
return false;
}
private void selfDestroy () {
Game.getInstance ().getBlockMatrix ()[x][y] = null;
BlockView.updateViews ();
}
private boolean checkPositionValid (int x, int y) {
return !(x < 0 || x >= Game.MATRIX_WIDTH ||
y < 0 || y >= Game.MATRIX_HEIGHT)
&& Game.getInstance ().getBlockMatrix ()[x][y] == null;
}
public void moveHorizontally (@Direction int direction) {
if (checkPositionValid (x + direction, y)) {
setX (x + direction);
}
}
}
谁能告诉我Color.colorToHSV 和Color.HSVToColor 是否不准确或者我哪里做错了?
只是让您知道,Game.getInstance().getHueNumber() 如果有帮助会返回 167
【问题讨论】:
-
HSV 表示使用
floats。如果您在基于int的RGB 和HSV 之间进行转换,您通常会损失一些精度。如果你想要准确不变的表示,你应该坚持使用 RGB。 -
但是如何增加 RGB 中颜色的暗度? @Cinnam
-
要使 RGB 颜色更深,您可以将 R、G、B 分量除以某个常数。这将保持色调和饱和度。理想情况下,像
newR = oldR * 75 / 100这样可以获得 75% 的亮度。 G、B 也一样。 -
(通过“将 R、G、B 分量除以某个常数”我的意思是按相同的百分比减少 R、G、B 分量)