Problema com g.drawimage

6 respostas
java
P

alguem pode me ajudar… nao to conseguindo usar o g.drawimage na clase Palyer,
bom consigo usar normalmente fora do array, segui um vídeo olhei mil x mas não achei onde errei .

Erro não entendi!

Exception in thread main java.awt.image.RasterFormatException: (x + width) is outside of Raster

at sun.awt.image.ByteInterleavedRaster.createWritableChild(Unknown Source)

at java.awt.image.BufferedImage.getSubimage(Unknown Source)

at mls.Graficos.Spritesheet.getSprite(Spritesheet.java:24)

at mls.Entities.Player.(Player.java:27)

at mls.Game.Game.(Game.java:48)

at mls.Game.Game.main(Game.java:81)

_______________________________________________

package mls.Entities;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

import mls.Game.Game;

public class Player extends Entity {

	public boolean right= true, left, up, down;
	public int right_Dir = 0, left_dir =1;
public int dir =right_Dir;
	public double speed = 3.5;
	
	private int frames = 0;
	private BufferedImage [ ] rightPlayer;
	private BufferedImage [ ] leftPlayer;
	
	public Player(int x, int y, int wight, int height, BufferedImage sprite) {
		super(x, y, wight, height, sprite);
		
		
		rightPlayer = new BufferedImage[3];
		leftPlayer = new BufferedImage[3];
		
		for(int i = 0 ; i < 3; i++) {
			rightPlayer[i] = Game.spritesheet.getSprite(750+(i*56), 351, 56, 56);
		}
		for(int i = 0 ; i < 3; i++) {
			leftPlayer[i] = Game.spritesheet.getSprite(750+(i*56), 396, 56, 56);
		}
	

	}

	public void tick() {
		if (right) {
			x += speed;

		} else if (left) {
			x -= speed;
		}
		if (up) {
			y -= speed;
		} 
		else if (down) {
			y += speed;
		}

	}
	
	public void render(Graphics g) {
	if(dir == right_Dir) {
		g.drawImage(rightPlayer[0], this.getX(),this.getY(), null);
	}
	else if(dir == left_dir) {
		g.drawImage(rightPlayer[0], this.getX(),this.getY(), null);
	}
	}
}
_____________________________________________________________
package mls.Entities;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

public class Entity {

	protected double x;
	protected double y;
	protected int width;
	protected int height;
	
	
	public BufferedImage sprite;
	
	public Entity(int x, int y, int wight, int height,BufferedImage sprite ) {
			
		this.x = x;
		this.y = y;
		this.width =wight;
		this.height = height;
		this.sprite = sprite;
			
	}

	public double getX() {
		return (int)this.x;
	}

	public double getY() {
		return (int)this.y;
	}

	public int getWidth() {
		return this.width;
	}

	public int getHeight() {
		return this.height;
	}
	
	public void tick() {
		
	}
	
	public void render(Graphics g) {
		g.drawImage(sprite,(int)this.getX(),(int)this.getY(), null);
	
	}
	
}

6 Respostas

J

Pelo erro, acredito que a subImage() que você tá tentando pegar, não está contido na BufferedImage. Mostre esse método completo e o tamanho do seu Sprite:

E aqui você não fez o casting para int na posição X e Y

P

tb achei q era o casting mas não, vou mandar tudo… tamanho da sprity e de 900 por 640
esse erro so da por q to tentando por a imagem em aray se não for o aray ele fuciona normalmente " só q imagem estática.

package mls.Game;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;

import mls.Entities.Entity;
import mls.Entities.Player;
import mls.Graficos.Spritesheet;

public class Game extends Canvas implements Runnable, KeyListener {

	private static final long serialVersionUID = 1L;
	public static JFrame frame;
	private Thread thread;
	private boolean isRunning = true;
	private final int WIDTH = 900;
	private final int HEIGHT = 640;

	private BufferedImage image;

	public List<Entity> entities;
	public static Spritesheet spritesheet;
	

	private Player player; // criar uma variavel player por que o player tinha sido adicionado diretamente
							// na classe entities!

	public Game() {
		addKeyListener(this); // lista dos controles!
		setPreferredSize(new Dimension(WIDTH, HEIGHT));
		initFrame();
		image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);

		entities = new ArrayList<Entity>();
		spritesheet = new Spritesheet("/sp.png");

		player = new Player(0, 0, 56, 46, spritesheet.getSprite(746, 308, 56, 46));
		entities.add(player);

		// Tambem fuciona assim, adicionando o Player direntamente na Lysta de clases
		// Entity!!
		// entities.add(new Player(50, 50, 56, 46, spritesheet.getSprite(746, 308,
		// 56,46)));

	}

	public void initFrame() {
		frame = new JFrame("Novo RPG");
		frame.add(this);
		frame.setResizable(false);
		frame.pack();
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}

	public synchronized void start() {
		thread = new Thread(this);
		isRunning = true;
		thread.start();

	}

	public synchronized void stop() {

	}

	public static void main(String[] args) {

		Game game = new Game();

		game.start();

	}

	public void tick() {
		for (int i = 0; i < entities.size(); i++) {
			Entity e = entities.get(i);
			if (e instanceof Player) {
				// System.out.println("estou dando tick no player!");
			}
			e.tick();
		}
	}

	public void render() {
		BufferStrategy bs = this.getBufferStrategy();
		if (bs == null) {
			this.createBufferStrategy(3);
			return;
		}
		Graphics g = image.getGraphics();
		g.setColor(new Color(0, 50, 0));
		g.fillRect(0, 0, WIDTH, HEIGHT);
		// Retangulo Laranja.
		g.setColor(new Color(255, 132, 51));
		g.fillRect(200, 200, 100, 100);

		for (int i = 0; i < entities.size(); i++) {
			Entity e = entities.get(i);
			e.render(g); // <------- Esqueço!!
		}

		
		
		g.dispose();
		g = bs.getDrawGraphics();
		g.drawImage(image, 0, 0, WIDTH, HEIGHT, null);
		bs.show();

	}

	@Override
	public void run() {
		long lestTime = System.nanoTime();
		double amauntOfTicks = 60;
		double ns = [telefone removido] / amauntOfTicks;
		double delta = 0;
		int frames = 0;
		double time = System.currentTimeMillis();

		while (isRunning) {

			long now = System.nanoTime();
			delta += (now - lestTime) / ns;
			lestTime = now;

			if (delta >= 1) {
				tick();
				render();
				frames++;
				delta--;
			}

			if (System.currentTimeMillis() - time >= 1000) {
				System.out.println("FPS: " + frames);
				frames = 0;
				time += 1000;
			}

		}
		stop();        // <--------------- Esqueço, metoo para asegurar q a thread vai parar se houver erro!!
	}

	@Override
	public void keyPressed(KeyEvent e) {

		if (e.getKeyCode() == KeyEvent.VK_RIGHT) {

			player.right = true;

		} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
			player.left = true;
		} else if (e.getKeyCode() == KeyEvent.VK_UP) {
			player.up = true;
		} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
			player.down = true;
		}

	}

	@Override
	public void keyReleased(KeyEvent e) {
		if (e.getKeyCode() == KeyEvent.VK_RIGHT) {

			player.right = false;
			

		} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
			player.left = false;
		} else if (e.getKeyCode() == KeyEvent.VK_UP) {
			player.up = false;
		} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
			player.down = false;
		}

	}

	@Override
	public void keyTyped(KeyEvent e) {

	}

}

package mls.Graficos;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Spritesheet {

	private BufferedImage spritesheet;
	
	public Spritesheet(String path) {
		
		try {
			spritesheet = ImageIO.read(getClass().getResource(path));
		} catch (IOException e) {
		
			e.printStackTrace();
		}
		
	}
	
public BufferedImage getSprite(int x, int y, int width, int height) {
	return spritesheet.getSubimage(x,y, width, height);
	
}
	
}

package mls.Entities;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

public class Entity {

	protected double x;
	protected double y;
	protected int width;
	protected int height;
	
	
	public BufferedImage sprite;
	
	public Entity(int x, int y, int wight, int height,BufferedImage sprite ) {
			
		this.x = x;
		this.y = y;
		this.width =wight;
		this.height = height;
		this.sprite = sprite;
			
	}

	public double getX() {
		return (int)this.x;
	}

	public double getY() {
		return (int)this.y;
	}

	public int getWidth() {
		return this.width;
	}

	public int getHeight() {
		return this.height;
	}
	
	public void tick() {
		
	}
	
	public void render(Graphics g) {
		g.drawImage(sprite,(int)this.getX(),(int)this.getY(), null);
	
	}
	
}

package mls.Entities;

import java.awt.Graphics;
import java.awt.image.BufferedImage;

import mls.Game.Game;

public class Player extends Entity {

	public boolean right, left, up, down;
	public int right_Dir = 0, left_dir =1;
public int dir =right_Dir;
	public double speed = 3.5;
	
	private int frames = 0;
	private BufferedImage [ ] rightPlayer;
	private BufferedImage [ ] leftPlayer;
	
	public Player(int x, int y, int wight, int height, BufferedImage sprite) {
		super(x, y, wight, height, sprite);
		
	
		rightPlayer = new BufferedImage[3];
		leftPlayer = new BufferedImage[3];
		
		for(int i = 0 ; i < 3; i++) {
			rightPlayer[i] = Game.spritesheet.getSprite(750+(i*56), 351, 56, 56);
		}
		for(int i = 0 ; i < 3; i++) {
			leftPlayer[i] = Game.spritesheet.getSprite(750+(i*56), 396, 56, 56);
		}
	

	}

	public void tick() {
		if (right) {
			x += speed;

		} else if (left) {
			x -= speed;
		}
		if (up) {
			y -= speed;
		} 
		else if (down) {
			y += speed;
		}

	}
	
		public void render(Graphics g) {
		
	if(dir == right_Dir) {
		g.drawImage(rightPlayer[0], this.getX(),this.getY(), null)
	}
	else if(dir == left_dir) {
		g.drawImage(leftPlayer[0], this.getX(),this.getY(), null)
	}
	}
}
J

Opa! Então acho que é isso:

Quando o teu i for dois:
750 + 2 ×56 = 862
Mais o comprimento da imagem:
862 + 56 = 918
Passou da largura do sprite de 900!
Os dois primeiro parâmetros séria o “ponto de partida” e os dois últimos o comprimento da imagem, no teu caso ele tá excedendo o Sprite.

P

nao ainda nao é isso :frowning:
no
g.drawImage(rightPlayer[0], this.getX(),this.getY(), null);

ele fica poedindo para trocar para g.drawLine ai boto drawLine ele pede para trocar para drawImage.

J

:thinking: certifique-se que esteja escrevendo corretamente e passando os parâmetros correto!
g.drawImage(img, x int, y int, null);

Eu também te aconselho a usar o Graphics2d, pelo menos na documentação do java e alguns tutoriais eles sempre recomendam. Na função render() da classe game mude:

Para:
Graphics2D g = image.createGraphics ();
No geral você só vai precisar mudar os parâmetros das outras funções que recebe o Graphics para Graphics2D.

P

hum valeu vou tentar

Criado 5 de março de 2020
Ultima resposta 5 de mar. de 2020
Respostas 6
Participantes 2