Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - AGP

#1486
And here's the cleverer approach by Alexander Hristov under the lesser general public license (which probably means you can use on jPCT but I haven't read it). The first is the tester I wrote (ArrayIndexOutOfBoundsException will be thrown if your gif doesn't have at least 4 frames), and the second is his FrameReader.

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;

public class FrameReaderTester extends Frame implements WindowListener {
      private BufferedImage[] frames;
      private int currentFrame = 0;
      public FrameReaderTester(String fileName) {
this.setTitle("AGP's");
try {
      frames = FrameReader.getAllFrames(new FileInputStream(fileName));
}
catch (IOException e) {System.err.println("Shit happened: "+e.getMessage());}
this.addWindowListener(this);
this.setSize(800, 600);
this.setVisible(true);
      }

      public void paint(Graphics g) {
g.drawImage(frames[0], 10, 30, null);
g.drawImage(frames[1], 20+frames[0].getWidth(), 30, null);
g.drawImage(frames[2], 10, 40+frames[0].getHeight(), null);
g.drawImage(frames[3], 20+frames[0].getWidth(), 40+frames[1].getHeight(), null);
      }

      public void windowClosing(WindowEvent e) {
if (e.getWindow().equals(this)) {
      this.dispose();
      System.exit(0);
}
      }
      public void windowClosed(WindowEvent e) {}
      public void windowOpened(WindowEvent e) {}
      public void windowActivated(WindowEvent e) {}
      public void windowDeactivated(WindowEvent e) {}
      public void windowIconified(WindowEvent e) {}
      public void windowDeiconified(WindowEvent e) {}
      public static void main(String[] args) {
if (args == null || args.length == 0)
      return;
new FrameReaderTester(args[0]);
      }
}


import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;

import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.spi.IIORegistry;
import javax.imageio.spi.ImageInputStreamSpi;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.spi.ServiceRegistry;
import javax.imageio.stream.ImageInputStream;

class FrameReader {
  public static BufferedImage[] getAllFrames(InputStream in) throws IOException {
    IIORegistry providers = IIORegistry.getDefaultInstance();
    Iterator it = providers.getServiceProviders(ImageInputStreamSpi.class,true);
    ImageInputStream imgStream = null;
   
    // Create an ImageInputStream with the first appropriate SPI
    while (it.hasNext()) {
      ImageInputStreamSpi spi = (ImageInputStreamSpi)it.next();
      if (spi.getInputClass().isInstance(in)) {
        imgStream = spi.createInputStreamInstance(in);
        break;
      }
    }
    if (imgStream == null)
      throw new IOException("No appropriate SPI for this input stream ");
   
    it = providers.getServiceProviders(
        ImageReaderSpi.class, new CanDecodeFilter(imgStream),true);
    if (!it.hasNext())
      throw new IOException("No class can read this image format");
   
    ImageReaderSpi readerSpi = (ImageReaderSpi)it.next();
    ImageReader reader = readerSpi.createReaderInstance();
    ImageReadParam param = reader.getDefaultReadParam();
   
    reader.setInput(imgStream, false, true);
    int numFrames = reader.getNumImages(true);
    BufferedImage[] frames = new BufferedImage[numFrames];
    for (int i = 0; i < numFrames; i++) {
      frames[i] = reader.read(i,param);
    }
   
    imgStream.close();
    reader.dispose();
    return frames;
  }
 
  static class CanDecodeFilter implements ServiceRegistry.Filter {
    ImageInputStream stream;
    public CanDecodeFilter(ImageInputStream stream) {
      this.stream = stream;
    }
    public boolean filter(Object element) {
      try {
          ImageReaderSpi spi = (ImageReaderSpi)element;
          boolean canDecode = false;
          stream.mark();
          canDecode = spi.canDecodeInput(stream);
          stream.reset();
          return canDecode;
      } catch (IOException e) {
          return false;
      }
    }
  }
}
#1487
I did this so far, but I have to do something else now. I might get back to it tonight. What I don't get about the Wikipedia article I found (http://en.wikipedia.org/wiki/Graphics_Interchange_Format) is whether I'm looking for a black (0, 0, 0) value and then a white (255, 255, 255) to determine the beginning and end of the color table or whether it's something else. This approach might be overkill anyway. There might be a cleverer way to find the individual frames with the provided Gif loaders.

import java.io.*;

public class AnimatedGIF {
      private static boolean animated;
      private static int width, height;
      private static int backColor;
      private static Pixel[] colorTable;//I THINK THE COLOR TABLE IS 24 BITS/PIXEL
      private static int[] thePixels;

      private static void readGIF(String[] args) throws IOException {
byte[] staticAnimated = new byte[6];
FileInputStream inStream =  new FileInputStream(args[0]);
inStream.read(staticAnimated);
if (staticAnimated[4] == 57)//IS IT GIF87a (STATIC) OR GIF89a (ANIMATED)?
      animated = true;
else animated = false;
byte[] twoBytes = new byte[2];
inStream.read(twoBytes);
width = fromSignedByte(twoBytes[0]) +fromSignedByte(twoBytes[1])*256;
inStream.read(twoBytes);
height = fromSignedByte(twoBytes[0]) +fromSignedByte(twoBytes[1])*256;
inStream.read(twoBytes);
backColor = twoBytes[1];//SKIPPED THE GCT BYTE ON PURPOSE (WHO CARES?)
System.out.println("Multiple Images: "+animated);
System.out.println("Width: "+width +", Height: "+height);
      }
      private static int fromSignedByte(byte signedBastard) {
int value = 0;
for (int i = 7; i >= 0; i--) {
     if ((signedBastard & (1 << i)) > 0) //IF (BYTE TOPRINT ANDED WITH A BYTE WHOSE ONLY BIT 1 IS ON POSITION i) > 0, ADD
value += (int)Math.pow(2.0, (double)i);
}
return value;
      }

      public static void main(String[] args) {
if (args == null || args.length == 0) {
      System.err.println("USAGE: java AnimatedGIF [filename]");
      System.exit(1);
}
try {
      readGIF(args);
}
catch (IOException e) {System.err.println("Problem loading file: "+e.getMessage());}
      }
}

class Pixel {
      protected int red, green, blue;
      public Pixel(byte[] pixel) {
red = pixel[0];
green = pixel[1];
blue = pixel[2];
      }
}
#1488
I can probably figure it out quickly enough. I'll report back with any findings soon.
#1489
Thanks to both of you again. I'm not sure the Overlay class would be my first choice, but I'll give it a try to see what happens. And Egon, a lot of my games use animated gifs. You load them as you would a static image, but with every iteration of the game loop Java2D draws a different frame (and loops them too).
#1490
I want to draw an animated gif.
#1491
I actually solved the ArrayIndexOutOfBoundsException. That little program I had written over a few years (it was the first one I built with jPCT) and it uses both the software and the hardware renderer (not at the same time obviously). And in changing it a million times I had introduced a stupid glitch in which I called run in one part of it (one attempt at getting the non-canvas OpenGL renderer to use the software loop), and started a separate thread that called it. So sometimes, draw() was being called twice at the same time (and before it draws it moves the objects). So that's that.

But now here's a question: what's the point of using AWTGLCanvas if the FrameBuffer's Graphics object will still be null (or useless, whichever it is)? I can no more use canvas.getGraphics()'s Graphics instance than I could a frame's (I can, but the screen will flicker). So is this a jPCT bug (I hope so)?
#1492
I can send you the whole thing if you want to have a look. I find it really weird.
#1493
I will look into the KeyMapper, thanks.

For my other game, I told you about this already: ever since I switched the renderer from the old hardware method to the AWTGLCanvas, I keep getting ArrayIndexOutOfBoundsExceptions. No event threads either draw or change the models, and all the draw() calls are in a single game loop. So what are all the circumstances in which the World.draw(FrameBuffer) method might throw this right after a succesful call to World.renderScene(FrameBuffer)?
#1494
But to address your list of suggestions:

  • I will rescale the textures later (probably the last thing I do, really, because there's so much more to do).
  • I'm not double-loading them, but perhaps the process of loading an image, then making it a texture does that? Your suggestion!
  • Some trees for some reason aren't transparent, but fortunately they're further from camera than the trees that work. I'll look into the problem later, but I looked at the textures and I see nothing wrong with them (same as the ones that work).
  • Only way I see to improve input is to implement lwjgl's keyboard, which I guess I'll do.
  • Are you sure the steering thing isn't your joystick?
  • The cars are a little smaller, but believe it or not that's a choice I made for the gameplay. I don't know, if it bothers people too much, I might rescale them.
  • Good point about the hardware renderer, I will do that.
  • What exactly is MipMapping and how will it improve the game?

Thanks for your suggestions and do read what I wrote in response to your analog stick troubles.
#1495
And the joystick uses a button for accelerating and another for braking. as opposed to up and down like the keyboard.
#1496
Egon, I fixed the Street Fighter link. As for the joystick spinning the camera, no one in the lwjgl group seems to have a suggestion about it, so at the beginning of Racer I tell you to move the analog sticks before the car moves. I also find that if I press the accelerator button one or two seconds before the race the analog sticks default to zero value (as it always should).
#1497
Egon, I really hate showing my stuff to people because I really hate criticism, but here it goes: http://www.agpgames.com

All but the starship game is working to the point of showing it (if maybe not yet bragging!). Check out the racer. And by the way, I didn't do collision between the two cars yet. Thanks a whole lot both to you and to paulscode for the help with the opponent car. Street Fighter was a family joke between me, my wife my brother-in-law and his girlfriend (now wife). I'm still going to add blood and black eyes. All games are meant for an analog joystick, even if they work (badly) with the keyboard.
#1498
Thanks for the suggestion, paulscode. Is your way any faster?

And Egon, how fast is it to make something visible/invisble? Because as I understand, I'm going to have to make my object visible, test for collision, then make it invisible before I draw for every iteration. So is it just flipping an internal boolean or does work get done?
#1499
But it wasn't able until I loaded them through ImageIcon. I can't explain it either. Anyway, as long as it works I am happy. I will post you a link of that racing game you liked soon. At this point I'm just working out the collision-detection. And here's a question: invisibility won't affect collision-detection, will it (I thought once that it did but I hope I'm wrong)?

Oh, and I was going to write that I think the latest version of Firefox changed the way it handles its cache, because all of a sudden I can run, change, recompile, repackage, and run again without it giving me headaches, which is making it much easier on me to test my stuff.
#1500
That did the trick. So simple! Still, I wish it had worked. What is the purpose of 1.1 compatibility, anyway?