所以我有一个从资源文件(PNG图像)加载的位图:
Bitmap map = BitmapFactory.decodeResource(getResources(), R.drawable.wave);
如果我使用canvas.drawBitmap(...);
仅绘制一次此位图,则没有问题。但是,如果我多次绘制相同的位图,那么图像会一直闪烁,而不像以前那样稳定。
我怀疑我不能多次使用相同的位图,因此我每次想要绘制相同的图片时都尝试将图像加载到新的位图中,但它没有帮助,行为仍然存在。
程序很复杂,但基本上,我想绘制海浪。我有一个小波浪的图像。使波浪的效果从屏幕的左边缘移动到右边缘。我跟踪位图左边缘的位置。
// The ocean.
private ArrayList<Wave> waves;
// Draw the waves and update their positions.
for (int i = 0; i < this.waves.size(); i++)
{
Wave wave = this.waves.get(i);
// Go through each of the sub-waves of this current wave.
for (int j = 0; j < wave.getSubWaveEdges().size(); j++)
{
// Get the sub wave.
final float subWaveEdge = wave.getSubWaveEdges().get(j);
canvas.drawBitmap( wave.getSubWave(j), subWaveEdge, 40, brush);
wave.setSubWaveEdge(j, subWaveEdge + (float) 0.5);
}
// Update this current wave.
wave.update();
// If the wave has passed the left edge of the screen then add a new sub-wave.
if (wave.getFarthestEdge() >= 0)
wave.addSubWaveEdges(wave.getFarthestEdge() - this.getWidth());
}
如果位图的左边缘在屏幕内,那么我从同一图像文件创建一个新的位图并绘制。这是Wave类:
private class Wave
{
private Bitmap wave;
private float farthestEdge;
private ArrayList<Float> subWaveEdges;
private ArrayList<Bitmap> subWaves;
public Wave(Bitmap wave)
{
this.wave = wave;
this.farthestEdge = 0;
this.subWaveEdges = new ArrayList<Float>();
this.subWaves = new ArrayList<Bitmap>();
}
public Bitmap getWave ()
{ return this.wave; }
public void setWave (Bitmap wave)
{ this.wave = wave; }
public float getFarthestEdge ()
{ return this.farthestEdge; }
public void setFarthestEdge (final float furthestEdge)
{ this.farthestEdge = furthestEdge; }
public ArrayList<Float> getSubWaveEdges ()
{ return subWaveEdges; }
public void setSubWaveEdge (final int index, final float value)
{
this.subWaveEdges.remove(index);
this.subWaveEdges.add(value);
}
public void addSubWaveEdges (final float edge)
{
this.subWaveEdges.add(edge);
Bitmap newSubWave = BitmapFactory.decodeResource(getResources(), R.drawable.wave);
newSubWave = Bitmap.createScaledBitmap(newSubWave, MasterView.this.getWidth(), newSubWave.getHeight(), true);
this.subWaves.add(newSubWave);
}
public Bitmap getSubWave(final int index)
{ return this.subWaves.get(index); }
public void update ()
{
// Check to see if there is any sub-wave going outside of the screen.
// If there is then remove that wave.
for (int index = 0; index < this.subWaveEdges.size(); index++)
if (this.subWaveEdges.get(index) > MasterView.this.getWidth())
{
this.subWaveEdges.remove(index);
this.subWaves.remove(index);
}
// Set the farthest edge to the other side of the screen.
this.farthestEdge = MasterView.this.getWidth();
// Get the farthest edge of the wave.
for (int index = 0; index < this.subWaveEdges.size(); index++)
if (this.subWaveEdges.get(index) < this.farthestEdge)
this.farthestEdge = this.subWaveEdges.get(index);
}
}
我怀疑的另一个可能是当我从同一资源文件创建两个位图时,图像的像素被分成两个位图,这意味着每个位图只获得部分像素,而不是全部。我怀疑这是因为当绘制位图时,它们重叠的部分会稳定地绘制,不会闪烁。
任何人都偶然发现了这个问题并知道如何修复?
谢谢,
答案 0 :(得分:1)
ViktorLannér,谢谢你的帮助,但我认为这不是问题所在。我知道很难阅读我的代码,因为它只是大型程序的一小部分。
然而,我发现了问题:我的原始问题中没有提到这个问题,但是为了模拟两个波浪相继移动,我必须在第一个波进入屏幕后立即绘制下一个波。但是,每个波长都比屏幕的宽度长。因此,如果您知道我的意思,我必须从屏幕的“外部”绘制下一波。这意味着下一个波是从屏幕外部的负x坐标绘制的:
// If the wave has passed the left edge of the screen then add a new sub-wave.
if (wave.getFarthestEdge() >= 0)
wave.addSubWaveEdges(wave.getFarthestEdge() - this.getWidth());
我发现它不喜欢这个。这就是导致闪烁来回的原因。
为了解决这个问题,我不是从屏幕外部绘制下一个波形,而是使用这个方法:
canvas.drawBitmap (Bitmap bitmap, Rect source, Rect destination, Paint paint)
此方法允许您在要绘制到屏幕的位图上指定矩形区域,并在屏幕上指定将绘制位图部分的矩形区域。我用这种方法绘制下一波。当下一个波移动到屏幕时,我会相应地更改“源”和“目标”以绘制位图的一部分。
答案 1 :(得分:1)
我只想说我有一个问题,我的画布上的图像来回闪烁,或者在黑色和我的第一帧之间闪烁,直到我做出一个动作,几乎就像画布快速切换当前和最后一张图片。
这可能与你的情况有关,并且修复它我发现这是因为我每帧都锁定画布,即使我没有任何东西可以绘制。无论出于何种原因,我认为这种锁定造成了这种情况。
通过做这样的事情我解决了这个问题:
if (needToRedraw == true) {
canvas = mSurfaceHolder.lockCanvas(null);
... logic to eventually draw on that canvas ...
}
答案 2 :(得分:0)
在canvas.drawBitmap(...)
致电之前;尝试使用canvas.drawColor(Color.BLACK)
清除之前图纸中的Canvas
。
示例代码:
// Stuff.
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(wave.getSubWave(j), subWaveEdge, 40, brush);
// Stuff.