я впервые использую переполнение стека, задавая вопрос, поэтому я прошу прощения, если я не отформатировал правильно; все отзывы по этому поводу приветствуются.
Я следил за обучением на Youtube от 2017 года от Majoolwip (https://youtu.be/4iPEjFUZNsw), которое написано в Java используя Eclipse IDE . В этой серии он создает игровой движок, через который вы можете запускать свои игры. Он расскажет вам, как сделать windows и принять пользовательский ввод, но, что наиболее важно для этой ситуации, он учит, как отображать файл изображения в окне.
Важной частью является то, что мой класс "Image" не может получить URL-адрес изображения в моей папке "res" . Когда я пытаюсь запустить мою программу с изображением, она просто выдает мне , что, как я знаю, правильно, потому что когда я печатаю значение объекта Image, он выводит «null» на мою консоль.
В настоящее время генерирующий код находится в моем классе GameManager , в котором мой Constructor имеет одну строку, которая создает новый объект изображения и дает ему строку с именем " путь ", который установлен как " res / test.png ".
Что касается моей переменной пути, я испробовал много разных форматов для изображения, например "/test.png", " / RougeEngine / res / test.png " и " / res / test.png "; Ни один из них не возвращает изображение.
По-видимому, ошибка возникает при создании объекта изображения с использованием
image = ImageIO.read (Image .class.getResourceAsStream (path)); мой профессор CS подумал, что, возможно, проблема заключается в литерале класса , но он не слишком знаком с getResourceAsStream () .
Вот мой код GameContainer:
package com.RougeEngine.Engine;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
public class GameContainer implements Runnable
{
private Thread thread;
private Window window;
private Renderer renderer;
private Input input;
private AbstractGame game;
private boolean running = false;
private final double UPDATE_CAP = 1.0/60.0;
private int width = 320, height = 240;
private float scale = 3f;
private String Title = "RougeEngine v1.0";
public GameContainer(AbstractGame game)
{
this.game = game;
}
public void start()
{
window = new Window(this);
renderer = new Renderer(this);
input = new Input(this);
thread = new Thread(this);
thread.run();
}
public void stop()
{
}
public void run()
{
running = true;
boolean render = false;
double firstTime = 0;
double lastTime = System.nanoTime() / 1000000000.0;
double passedTime = 0;
double unprocessedTime = 0;
double frameTime = 0;
int frames = 0;
int fps = 0;
while(running)
{
render = false;
firstTime = System.nanoTime() / 1000000000.0;
passedTime = firstTime - lastTime;
lastTime = firstTime;
unprocessedTime = unprocessedTime + passedTime;
frameTime = frameTime + passedTime;
while(unprocessedTime >= UPDATE_CAP)
{
unprocessedTime = unprocessedTime - UPDATE_CAP;
render = true;
game.update(this, (float)UPDATE_CAP);
input.update();
if(frameTime >= 1.0)
{
frameTime = 0;
fps = frames;
frames = 0;
System.out.println("FPS:"+fps);
}
}
if(render)
{
renderer.clear();
game.render(this, renderer);
window.update();
frames++;
}
else
{
try
{
Thread.sleep(1);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
dispose();
}
private void dispose()
{
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public float getScale() {
return scale;
}
public void setScale(float scale) {
this.scale = scale;
}
public String getTitle() {
return Title;
}
public void setTitle(String title) {
Title = title;
}
public Window getWindow() {
return window;
}
public Input getInput() {
return input;
}
}
Вот мой код Window:
package com.RougeEngine.Engine;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
public class Window
{
private JFrame frame;
private BufferedImage image;
private Canvas canvas;
private BufferStrategy bs;
private Graphics g;
public Window(GameContainer gc)
{
image = new BufferedImage(gc.getWidth(),gc.getHeight(), BufferedImage.TYPE_INT_RGB);
canvas = new Canvas();
Dimension s = new Dimension((int)(gc.getWidth() * gc.getScale()), (int)(gc.getHeight() * gc.getScale()));
canvas.setPreferredSize(s);
canvas.setMaximumSize(s);
canvas.setMinimumSize(s);
frame = new JFrame(gc.getTitle());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(canvas, BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
canvas.createBufferStrategy(2);
bs = canvas.getBufferStrategy();
g = bs.getDrawGraphics();
}
public JFrame getFrame() {
return frame;
}
public void update()
{
g.drawImage(image, 0, 0, canvas.getWidth(), canvas.getHeight(),null);
bs.show();
}
public BufferedImage getImage() {
return image;
}
public Canvas getCanvas() {
return canvas;
}
}
Вот мой код Renderer:
package com.RougeEngine.Engine;
import java.awt.image.DataBufferInt;
import com.RougeEngine.Engine.gfx.Image;
public class Renderer
{
private int pW, pH;
private int[] p;
public Renderer(GameContainer gc)
{
pW = gc.getWidth();
pH = gc.getHeight();
p = ((DataBufferInt)gc.getWindow().getImage().getRaster().getDataBuffer()).getData();
}
public void clear()
{
for(int i = 0; i < p.length; i++)
{
p[i] = 0;
}
}
public void setPixel(int x, int y, int value)
{
if((x < 0 || x >= pH || y < 0 || y >= pH) || value == 0xffff00ff)
{
return;
}
p[x + y * pW] = value;
}
public void drawImage(Image image, int offX, int offY)
{
for(int y = 0; y < image.getH(); y++)
{
for(int x = 0; x < image.getW(); x++)
{
setPixel(x+ offX, y + offY, image.getP()[x + y * image.getW()]);
}
}
}
}
Вот мой входной код:
package com.RougeEngine.Engine;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
public class Input implements KeyListener, MouseListener, MouseMotionListener, MouseWheelListener
{
private GameContainer gc;
private final int NUM_KEYS = 256;
private boolean[] keys = new boolean[NUM_KEYS];
private boolean[] keysLast = new boolean[NUM_KEYS];
private final int NUM_BUTTONS = 5;
private boolean[] buttons = new boolean[NUM_BUTTONS];
private boolean[] buttonsLast = new boolean[NUM_BUTTONS];
private int mouseX, mouseY;
private int scroll;
public Input(GameContainer gc)
{
this.gc = gc;
mouseX = 0;
mouseY = 0;
scroll = 0;
gc.getWindow().getCanvas().addKeyListener(this);
gc.getWindow().getCanvas().addMouseMotionListener(this);
gc.getWindow().getCanvas().addMouseListener(this);
gc.getWindow().getCanvas().addMouseWheelListener(this);
}
public void update()
{
scroll = 0;
for(int i = 0; i < NUM_KEYS; i++)
{
keysLast[i] = keys[i];
}
for(int i = 0; i < NUM_BUTTONS; i++)
{
buttonsLast[i] = buttons[i];
}
}
public boolean isKey(int keyCode)
{
return keys[keyCode];
}
public boolean isKeyUp(int keyCode)
{
return !keys[keyCode] && keysLast[keyCode];
}
public boolean isKeyDown(int keyCode)
{
return keys[keyCode] && !keysLast[keyCode];
}
public boolean isButton(int button)
{
return buttons[button];
}
public boolean isButtonUp(int button)
{
return !buttons[button] && buttonsLast[button];
}
public boolean isButtonDown(int button)
{
return buttons[button] && !buttonsLast[button];
}
@Override
public void mouseWheelMoved(MouseWheelEvent e)
{
scroll = e.getWheelRotation();
}
@Override
public void mouseDragged(MouseEvent e)
{
mouseX = (int)(e.getX() / gc.getScale());
mouseY = (int)(e.getY() / gc.getScale());
}
@Override
public void mouseMoved(MouseEvent e)
{
mouseX = (int)(e.getX() / gc.getScale());
mouseY = (int)(e.getY() / gc.getScale());
}
@Override
public void mouseClicked(MouseEvent e)
{
}
@Override
public void mousePressed(MouseEvent e)
{
buttons[e.getButton()] = true;
}
@Override
public void mouseReleased(MouseEvent e)
{
buttons[e.getButton()] = false;
}
@Override
public void mouseEntered(MouseEvent e)
{
}
@Override
public void mouseExited(MouseEvent e)
{
}
@Override
public void keyTyped(KeyEvent e)
{
}
@Override
public void keyPressed(KeyEvent e)
{
keys[e.getKeyCode()] = true;
}
@Override
public void keyReleased(KeyEvent e)
{
keys[e.getKeyCode()] = false;
}
public int getMouseX() {
return mouseX;
}
public int getMouseY() {
return mouseY;
}
public int getScroll() {
return scroll;
}
}
Вот мой AbstractGame:
package com.RougeEngine.Engine;
public abstract class AbstractGame
{
public abstract void update(GameContainer gc, float dt);
public abstract void render(GameContainer gc, Renderer r);
}
Вот мой код изображения:
package com.RougeEngine.Engine.gfx;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Image
{
private int w,h;
private int[] p;
public Image(String path)
{
BufferedImage image = null;
System.out.println(Image.class.getResourceAsStream(path));
try
{
image = ImageIO.read(Image.class.getResourceAsStream(path));
}
catch (IOException e)
{
e.printStackTrace();
}
w = image.getWidth();
h = image.getHeight();
p = image.getRGB(0, 0, w, h, null, 0, w);
image.flush();
}
public int getW()
{
return w;
}
public void setW(int w)
{
this.w = w;
}
public int getH()
{
return h;
}
public void setH(int h)
{
this.h = h;
}
public int[] getP()
{
return p;
}
public void setP(int[] p)
{
this.p = p;
}
}
Вот мой GameManager код:
package com.RougeEngine.Game;
import java.awt.event.KeyEvent;
import com.RougeEngine.Engine.AbstractGame;
import com.RougeEngine.Engine.GameContainer;
import com.RougeEngine.Engine.Renderer;
import com.RougeEngine.Engine.gfx.Image;
public class GameManager extends AbstractGame
{
private Image image;
public GameManager()
{
image = new Image("res/test.png");
}
public static void main(String[] args)
{
GameContainer gc = new GameContainer(new GameManager());
gc.start();
}
@Override
public void update(GameContainer gc, float dt)
{
if(gc.getInput().isKeyDown(KeyEvent.VK_A))
{
System.out.println("A was pressed");
}
}
@Override
public void render(GameContainer gc, Renderer r)
{
}
}
Моя иерархия
My Image (в формате .png)
Спасибо за помощь ; Я не был уверен, какой будет минимальный воспроизводимый код для этого случая, поэтому я надеюсь, что сумма в порядке.