Slick PNGDecoder错误 - java.lang.UnsupportedOperationException:此图像的格式不受支持

时间:2014-05-12 13:24:22

标签: java image-processing png lwjgl slick

我正在使用Slick库在Java中创建一个简单的小Galaga克隆。不幸的是,我遇到了一个问题,我遇到了这个错误,然后是游戏关闭:

Mon May 12 08:54:32 EDT 2014 WARN:class org.newdawn.slick.opengl.PNGImageData failed to
read the data
java.lang.UnsupportedOperationException: Unsupported format for this image
at org.newdawn.slick.opengl.PNGDecoder.decode(PNGDecoder.java:272)
at org.newdawn.slick.opengl.PNGImageData.loadImage(PNGImageData.java:97)
    at org.newdawn.slick.opengl.CompositeImageData.loadImage(CompositeImageData.
    java:62)
    at org.newdawn.slick.opengl.CompositeImageData.loadImage(CompositeImageData.
    java:43)
    at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.
    java:292)
    at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.
    java:254)
at org.newdawn.slick.opengl.InternalTextureLoader.getTexture(InternalTextureLoader.
    java:187)
at org.newdawn.slick.Image.<init>(Image.java:192)
at org.newdawn.slick.Image.<init>(Image.java:166)
at org.newdawn.slick.Image.<init>(Image.java:154)
at org.newdawn.slick.Image.<init>(Image.java:132)
at com.othinolis.danmaku.Play.init(Play.java:21)
at com.othinolis.danmaku.Game.initStatesList(Game.java:20)
at org.newdawn.slick.state.StateBasedGame.init(StateBasedGame.java:164)
at org.newdawn.slick.AppGameContainer.setup(AppGameContainer.java:393)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:317)
at com.othinolis.danmaku.Game.main(Game.java:29)
Mon May 12 08:54:35 EDT 2014 ERROR:null
java.lang.NullPointerException
at com.othinolis.danmaku.Play.render(Play.java:32)
at org.newdawn.slick.state.StateBasedGame.render(StateBasedGame.java:199)
at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:688)
at org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:411)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:321)
at com.othinolis.danmaku.Game.main(Game.java:29)
Mon May 12 08:54:35 EDT 2014 ERROR:Game.render() failure - check the game code.
org.newdawn.slick.SlickException: Game.render() failure - check the game code.
at org.newdawn.slick.GameContainer.updateAndRender(GameContainer.java:691)
at org.newdawn.slick.AppGameContainer.gameLoop(AppGameContainer.java:411)
at org.newdawn.slick.AppGameContainer.start(AppGameContainer.java:321)
at com.othinolis.danmaku.Game.main(Game.java:29)

当我首次加载PNG时,尝试将状态从主菜单移动到正确的游戏中时会发生这种情况。我所有的资源都是PNG。这是我的其他课程文件:

Game.java:

package com.othinolis.danmaku;

import org.newdawn.slick.*;
import org.newdawn.slick.state.*;

public class Game extends StateBasedGame{

   public static final String gamename = "Danmaku Courage";
   public static final int menu = 0;
   public static final int play = 1;

   public Game(String gamename){
      super(gamename);
      this.addState(new Menu(menu));
      this.addState(new Play(play));
   }

   public void initStatesList(GameContainer gc) throws SlickException{
      this.getState(menu).init(gc, this);
      this.getState(play).init(gc, this);
      this.enterState(menu);
   }

   public static void main(String[] args) {
      AppGameContainer appgc;
      try{
         appgc = new AppGameContainer(new Game(gamename));
         appgc.setDisplayMode(600, 600, false);
         appgc.start();
      }catch(SlickException e){
         e.printStackTrace();
      }
   }

}

Menu.java(状态0,运行没有问题):

package com.othinolis.danmaku;

import org.lwjgl.input.Mouse;
import org.newdawn.slick.*;
import org.newdawn.slick.state.*;

public class Menu extends BasicGameState{

   Image playNow;
   Image exitGame;

   public Menu(int state){
   }

   public void init(GameContainer gc, StateBasedGame sbg) throws SlickException{
      playNow = new Image("res/playButton.png");
      exitGame = new Image("res/exitGame.png");
   }

   public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
      g.drawString("Danmaku Courage", 230, 50);
      g.drawString("mousex: " + Mouse.getX() + " mousey: " + Mouse.getY(), 300, 400);
      playNow.draw(200,100);
      exitGame.draw(200,200);
   }

   public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException{
      int posX = Mouse.getX();
      int posY = Mouse.getY();
      //play now button
      if((posX>237 && posX<364)&&(posY>425 && posY<460)){
         if(Mouse.isButtonDown(0)){
            sbg.enterState(1);
         }
      }

      //exit game
      if((posX>254 && posX<335)&&(posY>338 && posY<361)){
         if(Mouse.isButtonDown(0)){
            System.exit(0);
         }
      }
   }

   public int getID(){
      return 0;
   }
}

和Play.java(在菜单和播放之间移动是问题发生的地方。与屏幕一侧碰撞的数字以及你可能不准确的数字。):

package com.othinolis.danmaku;

import org.newdawn.slick.*;
import org.newdawn.slick.state.*;

public class Play extends BasicGameState{

   Animation player, movingLeft, movingRight; //2 animations, player will be set to one
   Image worldMap;
   boolean quit = false;
   int[] duration = {200,200}; //length of the frame
   float playerPositionX = 0; //player will start at coordinates 0,0
   float playerPositionY = 0;
   float shiftX = buckyPositionX + 320; //this will shift the screen so bucky appears in middle
   float shiftY = buckyPositionY + 160; //half the length and half the width of the screen

   public Play(int state){
   }

   public void init(GameContainer gc, StateBasedGame sbg) throws SlickException{
      worldMap = new Image("res/background.png");
      Image[] walkLeft = {new Image("res/player.png"), new Image("res/player.png")};
      Image[] walkRight = {new Image("res/player.png"), new Image("res/player.png")};

      movingLeft = new Animation(walkLeft, duration, false);
      movingRight = new Animation(walkRight, duration, false);
      player = movingDown; //by default as soon as game loads, player will be facing down
   }

   public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException{
      worldMap.draw(buckyPositionX,buckyPositionY); //draw the map at 0,0 to start
      player.draw(shiftX,shiftY); //draw player at 320, 160 (center of the screen)
      g.drawString("player's X: "+playerPositionX+"\nplayer's Y: "+playerPositionY, 400, 20); //indicator to see where player is

      //when they press escape
      if(quit==true){
         g.drawString("Resume (R)", 250, 100);
         g.drawString("Main Menu (M)", 250, 150);
         g.drawString("Quit Game (Q)", 250, 200);
         if(quit==false){
            g.clear();
         }
      }
   }

   public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException{
      Input input = gc.getInput();
      if(input.isKeyDown(Input.KEY_LEFT)){
         player = movingLeft;
         playerPositionX += delta * .1f;
         if(playerPositionX>324){
            playerPositionX -= delta * .1f;
         }
      }
      if(input.isKeyDown(Input.KEY_RIGHT)){
         player = movingRight;
         playerPositionX -= delta * .1f;
         if(playerPositionX<-840){
            playerPositionX += delta * .1f;
         }
      }

      //escape
      if(input.isKeyDown(Input.KEY_ESCAPE)){
         quit = true;
      }      

      //when they hit escape
      if(quit==true){
         if(input.isKeyDown(Input.KEY_R)){
            quit = false;
         }
         if(input.isKeyDown(Input.KEY_M)){
            sbg.enterState(0);
            try{
               Thread.sleep(250);
            }catch(InterruptedException e){
               e.printStackTrace();
            }
         }
         if(input.isKeyDown(Input.KEY_Q)){
            System.exit(0);
         }
      }
   }

   public int getID(){
      return 1;
   }
}

我所知道的浮油来自几个论坛帖子我已经读到过像这样的问题,(当然没有一个有确切的问题或解决方案)和Bucky的Slick教程那是here。如果您要下载项目以便导入它并看看是否可以帮助我,我已将其投放到Dropbox here上。

2 个答案:

答案 0 :(得分:3)

对于任何人来说,读取或调试的代码太多了。但是对于实际问题:AFAIK,Slick PNG加载器只支持非常少的PNG文件类型(在阅读它们时以某种方式与性能有关,但这可能是一个神话......)。应该可以用

之类的东西加载图像
// "Image" here refers to a Slick Image, and NOT to java.awt.Image!
private static Image loadImage(String path) throws IOException
{
    BufferedImage bufferedImage = ImageIO.read(new File(path));
    Texture texture = BufferedImageUtil.getTexture("", bufferedImage);
    Image image = new Img(texture.getImageWidth(), texture.getImageHeight());
    image.setTexture(texture); 
    return image;
}

答案 1 :(得分:1)

使用Slick-util库加载PNG图像时出现了同样的错误。我唯一做的就是打开PNG文件到Paint(是的,Windows图像编辑器)并保存为新的PNG图像。问题可能与PNG图像的类型(PNG Basics)有关,而Paint将其保存为其他类型。

我的功能如下所示(来自Loading Images for LWJGL):

public int loadTexture(String fileName) {
Texture texture = null;
try {                
    texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("res/" + fileName + ".png"));

    GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
    GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER,
                        GL11.GL_LINEAR_MIPMAP_LINEAR);
    GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, 0f);
} catch (Exception e) {
    e.printStackTrace();
    System.err.println("Tried to load texture " + fileName + ".png , didn't work");
    System.exit(-1);
}
    textures.add(texture.getTextureID());
    return texture.getTextureID();
}