无法剪辑/裁剪图像

时间:2012-02-09 06:02:34

标签: playn

以下代码打算使用图像条和画布上的一些钉子在屏幕上绘制数字,但它不显示。

1)当我评论/删除“setSourceRect”时,它会显示完整的图像。 2)initnails函数没有显示任何内容

package com.myGame.mavenproject3.core; 
import org.jbox2d.collision.shapes.CircleShape; 
import playn.core.*; 
import static playn.core.PlayN.assetManager; 
import static playn.core.PlayN.graphics; 

public class mavenproject3 implements Game { 
 Canvas canvas; 
    private float radius; 
    Image pointsFontImage; 
 GroupLayer pointsLayer; 
@Override 
  public void init() { 
// create and add background image layer 
int width = 640; 
int height = 480; 
CanvasImage bgImage = graphics().createImage(width, height); 
canvas = bgImage.canvas(); 
canvas.setFillColor(0xff87ceeb); 
canvas.fillRect(0, 0, width, height); 
ImageLayer bg = graphics().createImageLayer(bgImage); 
graphics().rootLayer().add(bg); 
pointsLayer = graphics().createGroupLayer(); 
  pointsLayer.setScale(3.0f, 3.0f); 
  pointsFontImage = assetManager().getImage("images/font.png"); 
  graphics().rootLayer().add(pointsLayer); 
  } 
  @Override 
  public void paint(float alpha) { 
// the background automatically paints itself, so no need to do 
anything here! 
  } 
int points = 50; 
  @Override 
  public void update(float delta) { 
  initNails(); 
  float x = 0f; 
  pointsLayer.clear(); 
  for (char c : Integer.toString(points).toCharArray()) { 
    ImageLayer digit = graphics().createImageLayer(pointsFontImage); 
    digit.setSourceRect(((c - '0' + 9) % 10) * 16, 0, 16, 16); 
    pointsLayer.add(digit); 
    digit.setTranslation(x, 0f); 
    x += 16f; 
  } 
  } 
  @Override 
  public int updateRate() { 
    return 25; 
  } 
  public void initNails() { 
  for (int x = 100; x < 300 - 100; x += 50) { 
    for (int y = 150; y < 450; y+= 100) { 
        canvas.setFillColor(0xffaaaaaa); 
        canvas.fillCircle(x, y, radius); 
    CircleShape circleShape = new CircleShape(); 
    circleShape.m_radius = 5f*2; 
    circleShape.m_p.set(x*2, 
                        y*2); 
    } 
  } 
  } 
} 

1 个答案:

答案 0 :(得分:0)

除了设置源矩形之外,还需要设置图像层的目标尺寸,否则它们将与原始图像的尺寸相同。原始图像为160x16,但您想渲染单个字符,因此您应该使用16x16:

ImageLayer digit = graphics().createImageLayer(pointsFontImage); 
digit.setSourceRect(((c - '0' + 9) % 10) * 16, 0, 16, 16); 
digit.setWidth(16);
digit.setHeight(16);
pointsLayer.add(digit); 
digit.setTranslation(x, 0f); 

我也无法抗拒地指出,这在很多方面都是非常低效。

update()方法每秒运行60次(在理想情况下)。你每帧都在不必要地创建和销毁图像层。您应该为每个潜在的数字创建一次图像层,然后每帧更新其源矩形。您也以极其昂贵的方式获取points值的数字。

以下代码不太可能让游戏开发者在晚上哭泣自己睡觉:

int points = 50;

final float DIGIT_WIDTH = 16;
final float DIGIT_HEIGHT = 16;
final int MAX_DIGITS = 5;

@Override
public void update(float delta) {
  initNails();

  // peel off the right-most digit of points and update its layer;
  // creating the layer on demand if we don't have one yet
  int ll = 0;
  for (int p = points; p > 0 || ll == 0; p /= 10, ll++) {
    ImageLayer digit;
    if (pointsLayer.size() <= ll) {
      digit = graphics().createImageLayer(pointsFontImage);
      digit.setWidth(DIGIT_WIDTH);
      digit.setHeight(DIGIT_HEIGHT);
      digit.setTranslation((MAX_DIGITS-ll-1) * DIGIT_WIDTH, 0);
      pointsLayer.add(digit);
    } else {
      digit = (ImageLayer)pointsLayer.get(ll);
      digit.setVisible(true);
    }
    int d = p%10, ix = ((d + 9) % 10);
    digit.setSourceRect(ix * DIGIT_WIDTH, 0, DIGIT_WIDTH, DIGIT_HEIGHT);
  }
  // hide layers for leading zeros
  while (ll < pointsLayer.size()) {
    pointsLayer.get(ll++).setVisible(false);
  }
}