无法剪辑/裁剪图像

发布于 2025-01-03 12:04:51 字数 2023 浏览 1 评论 0原文

以下代码旨在使用图像条和画布上的一些指甲在屏幕上绘制数字,但它没有显示。

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); 
    } 
  } 
  } 
} 

The following code is intend to draw numbers on screen using a image strip and some nails on canvas, but it is not displaying.

1) When i comment/remove "setSourceRect", it displays the complete image.
2) the initnails function is not displaying anything

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); 
    } 
  } 
  } 
} 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

御弟哥哥 2025-01-10 12:04:51

除了设置源矩形之外,还需要设置图像层的目标尺寸,否则它们将与原始图像的尺寸相同。原始图像是 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 次(在理想情况下)。您每帧都不必要地创建和销毁图像层。您应该为每个潜在数字创建一个图像层,然后每帧更新其源矩形。您还以极其昂贵的方式获取您的积分值。

下面的代码不太可能让游戏开发者晚上哭着入睡:

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);
  }
}

In addition to setting the source rect, you need to set the target dimensions for the image layer, otherwise they will be the same as the size of the original image. The original image is 160x16, but you want to render a single character, so you should have 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); 

I also can't resist pointing out that this is hugely inefficient in multiple ways.

The update() method runs 60 times per second (in an ideal world). You are needlessly creating and destroying image layers every frame. You should create an image layer once for each potential digit and then just update its source rect every frame. You are also obtaining the digits of your points value in an extravagantly expensive manner as well.

The following code is less likely to make a game developer cry themselves to sleep at night:

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);
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文