[java] Java Star Map Help

Started by
13 comments, last by RobAU78 20 years, 5 months ago
Hello everyone, I didn''t realize that there was a special Java section of the forum! But I''m glad I finally found it Anyways, I am working on a rather ambitious and challenging (but hopefully, in the end, satisfying) space-strategy game. Unfortunately, I''m already having trouble with a major aspect of it - the star map. I was wondering if anyone here could be of any help. Here is what I want to implement: 1. The star map will (on the screen) be a 2-dimensional representation of a 3-dimensional virtual space. Right now, I''m thinking of using 2-d graphics with resizing (i.e. the "closer" they are, the bigger and brighter they appear on the screen). Is this a good path to follow, or is there a better way? 2. The map will be able to be rotated around the x and y axes. However, this poses two problems. First, how do I make all the stars stay visible if they are (in essence) rectangular components? Second, how do I ensure that the "closest" stars will overlap ones behind them, and not vice-versa? I''m thinking that maybe using the BufferedImage class will solve those problems, but I''m not sure. 3. The stars themselves will be components - that is, they will be able to respond to user-generated events (i.e. clicking the mouse). Does this mean I should have the Star class extend the (J)Component class? Or are BufferedImages components themselves? Any help on these issues will be greatly appreciated. Thanks, Rob
Advertisement
Is this game real time? Using Swing/Java2D for a real time game is tough. AWT''s scaling mechanisms are not very fast and generate lots of dead objects. As an example I''m currently working on a paint program (a relatively lax program as far as requirements go), and getting it to scale an image beyond oh 300% in a way that was usable took a rather elaborate mechanism (but now I can scale to 5000% and paint away, I''m so happy )

Anyway, if this game is real time and you haven''t really started yet, you may want to stop and assess what your needs are and if AWT can handle them. There are other alternatives, almost all OpenGL based and significantly faster/more powerful.

BufferedImages are not components. If you want them to participate in Swing you need to create say a JPanel that paints the images onto themselves, and have the panel deal with the events and such.

As for problem two, what about giving all stars a z coordinate as well?
Er, that was me, here at work...
Hey Tortoise,

Thanks for your reply. No, it''s not real-time; it''s going to be a turn-based space-strategy game. I agree that real-time would be much harder to implement, but I am actually more of a fan of turn-based games, so that is what I''m making Also, I have already given my Star class a variable for z-coordinate, but thanks for the suggestion.

In #2, I meant that if an instance of the Star class is represented graphically as a rectangular component with an image in it, other Stars could be hidden behind the Star''s corners (which is not realistic). Also, I would need to come up with a system whereby the program draws the Stars in closest-to-farthest order (in terms of z-coordinate/"depth").

Is there any way that I could make a Sprite class where things that are behind an object''s boundaries but not behind its painted area can still show up? Would this be a good idea to do for what I want?

What are the alternatives to AWT/Swing? I''m very interested in hearing about them.

Thanks,
Rob
You should have a look in this thread http://www.gamedev.net/community/forums/topic.asp?topic_id=185508
it has some of the packages that are currently used to model complex graphics in java....
garazdawi - 'I put the laughter back in slaughter'
If you are using an image to represent the stars, then just use a gif with transparency enabled. If you are generating the star images yourself, then you have to look at ImageProducer and ColorModel to create an image with transparency.

If you are using JComponent for each star, then you need to use the method setOpaque() and set it to false.


First make it work,
then make it fast.

--Brian Kernighan

The problems of this world cannot possibly be solved by skeptics or cynics whose horizons are limited by the obvious realities. We need men and women who can dream of things that never were. - John Fitzgerald Kennedy(35th US President)

Do not interrupt your enemy when he is making a mistake. - Napolean Bonaparte
"None of us learn in a vacuum; we all stand on the shoulders of giants such as Wirth and Knuth and thousands of others. Lend your shoulders to building the future!" - Michael Abrash[JavaGaming.org][The Java Tutorial][Slick][LWJGL][LWJGL Tutorials for NeHe][LWJGL Wiki][jMonkey Engine]
Use BufferedImages, newer and better, one reason for their creation was to get rid of the producer/consumer model.

BufferedImage myImage = createBuffImage(width, height, transparent);Graphics2D g2 = myImage.createGraphics();Composite originalComp = g2.getComposite();/* * Normally transparent source does not overtake dest, with this * composite set the src completely overtakes the destination */AlphaComposite imageComposite = AlphaComposite.getInstance(AlphaComposite.SRC);g2.setComposite(imageComposite);// full transparencyg2.setColor(new Color(0,0,0,0));g2.fillRect(0, 0, myImage.getWidth(), myImage.getHeight());// myImage is now fully transparent// restore standard method of drawingg2.setComposite(originalComp);// now fill in opaque areas as needed


I wouldn''t create a new composite each time, and all that, but just for demonstration.

If you want to create images that are compatible with your hardware and thus drawn as
quickly as possible, you need to get involved with the GraphicsConfiguration classes. Like...

BufferedImage createBuffImage(int w, int h, boolean transparent) {	// setup graphics config	GraphicsEnvironment genv =		GraphicsEnvironment.getLocalGraphicsEnvironment();	GraphicsDevice device = genv.getDefaultScreenDevice();	GraphicsConfiguration graphicsConfig = device.getDefaultConfiguration();		if (transparent) {		return graphicsConfig.createCompatibleImage(w, h, Transparency.TRANSLUCENT);	} else {		return graphicsConfig.createCompatibleImage(w,h,Transparency.OPAQUE);	}}


That will create what''s been dubbed a "managed" image, ie AWT will make it accelerated if possible, and it
will always be compatible with your hardware (like if your hardware expects BGR, this will give you BGR aligned
images and not RGB, which would mean the system would have to flip the bands around each time they are drawn,
really slowing things down).

Gifs work for premade images with transparency, but pngs offer full alpha possibilities. Both are easily loaded with one line
of code:

BufferedImage img = ImageIO.read(/* URL, File or InputStream to the image */);
Thanks tortoise. I haven''t done much of the image stuff yet. It''s nice to know the better way of doing things.


First make it work,
then make it fast.

--Brian Kernighan

The problems of this world cannot possibly be solved by skeptics or cynics whose horizons are limited by the obvious realities. We need men and women who can dream of things that never were. - John Fitzgerald Kennedy(35th US President)

Do not interrupt your enemy when he is making a mistake. - Napolean Bonaparte
"None of us learn in a vacuum; we all stand on the shoulders of giants such as Wirth and Knuth and thousands of others. Lend your shoulders to building the future!" - Michael Abrash[JavaGaming.org][The Java Tutorial][Slick][LWJGL][LWJGL Tutorials for NeHe][LWJGL Wiki][jMonkey Engine]
Tortoise, CaptainJester, and Garazdawi, thanks for your replies. Right now what I''m thinking about doing is using gif images to represent my stars. How would I go about putting these images in the BufferedImages? Or would I?

Here is what I have so far:

Graphically speaking, each Star will be a transparent image loaded onto a JPanel.

Tortoise, would I include that image-loading line along with all the other BufferedImage code?

- Rob
Unless the image on disks changes or something, you only want to load it once.

Somewhere in a constructor or some initialization code, load the image. ImageIO is a new class that was added to java 1.4 (you really want to be using 1.4+ if possible, a lot of these niceties are quite new). ImageIO does many things, but one thing it does easily is load gif, jpeg or png images. You can also register new image handlers with it that can load any kind of image you want.

Just do something like...

URL u = getClass().getClassLoader().getResource("images/mygif.gif");try {     myImage = ImageIO.read(u);} catch(IOException e) {    // handle error}


By using the class loader, you can load images relative to the classpath, which means these images will be found in the same place no matter what the machine is.

read() is overloaded for URLs, Files and InputStreams, so you can get the image into ImageIO in just about any manner. You can just as easily write() images to disk too, ImageIO is awesome stuff.

That createBuffImage() method is a good thing to have. I always place it either in my main class or in the class that''s most logical (like if my program has a Renderer class), and make it static. Depending on the situation, using compatible/managed images can greatly increase performance, especially under Windows.

ImageIO does not return managed images. If performance is an issue, create blank managed images via createBuffImage() and then draw the image that ImageIO gave you into the blank image, flush() the ImageIO image, and use the new one, now it''s managed.

This topic is closed to new replies.

Advertisement