Невозможно обрезать / обрезать изображения - PullRequest
0 голосов
/ 09 февраля 2012

Следующий код предназначен для рисования чисел на экране с использованием полосы изображения и нескольких гвоздей на холсте, но он не отображается.

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 голосов
/ 13 февраля 2012

В дополнение к настройке исходного прямоугольника, вам необходимо установить целевые размеры для слоя изображения, иначе они будут такими же, как размер исходного изображения. Исходное изображение имеет размер 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);
  }
}
...