Puppytron!

http://www.puppygame.net/applets/puppytron.jnlp

Java 1.4+, OpenGL

Works on Mac OS X, Windows, Linux x86

Cas :slight_smile:

Hi Cas,

Thatā€™s awesome! It tools me a minute to get used to it, but it was a lot of fun once I did! A few suggestions:

  1. Can you replace the ā€œshieldsā€ number with a progress bar? Itā€™s very difficult to look at a number in the middle of a game. It would be even better if it went from green to yellow to red to flashing red.

  2. It REALLY needs a high score board, in the tradition of the old arcade games. That will help you bring back customers to your site. ;D

As for the ā€œrun anywhereā€ problem, is it just a matter of JVM versions, or is it a problem with browsers? If itā€™s the former, we might be able to whip something up for you. :wink:

got some strange (and computer-locking console output!):

I had to use the infamous ctrl+alt+del because ā€œPausedā€ kept printing to the console like an infinite loop.

In case it helps you diagnose the problem:
Windows XP Home Edition SP1 // 1.5GHz // AMD Athalon 2400+ // JRE 1.4.2_03 // Internet Explorer 6.0 (also tested with Mozilla Firefox 1.0)

Woogley - try reloading the applet, looks like the jar is corrupted. Or if itā€™s a bug in ImageIO, try upgrading your VM to 1.4.2_06. Or even 1.5.0_01.

Cas :slight_smile:

Jerry - yes, and yes :slight_smile: Patience!

Cas :slight_smile:

[quote]-- Opera Java Console ā€“

Java vendor: Sun Microsystems Inc.
Java version: 1.4.2_03

type ā€˜hā€™ for help

ā€“
Image cache enabled
Audio cache: enabled
ClassLoader cache size: 10
Created Game
Initingā€¦
Java version 1.4.2_03
Puppygames Applet Version $Revision: 1.6 $
Startingā€¦
Windows XP
java.security.AccessControlException: access denied (java.lang.RuntimePermission loadLibrary.timer)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkLink(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at com.dnsalias.java.timer.windows.WindowsTimer.loadLibrary(WindowsTimer.java:30)
at com.dnsalias.java.timer.windows.WindowsTimer.available(WindowsTimer.java:18)
at com.dnsalias.java.timer.AdvancedTimer.init(AdvancedTimer.java:40)
at com.dnsalias.java.timer.AdvancedTimer.(AdvancedTimer.java:26)
at net.puppygames.applet.Game$1.run(Game.java:204)
Puppytron $Revision: 1.4 $
Loading bullet-up-left.pngā€¦sun.misc.ServiceConfigurationError: javax.imageio.spi.ImageOutputStreamSpi: : java.io.IOException: Connection failed.
at sun.misc.Service.fail(Unknown Source)
at sun.misc.Service.parse(Unknown Source)
at sun.misc.Service.access$100(Unknown Source)
at sun.misc.Service$LazyIterator.hasNext(Unknown Source)
at javax.imageio.spi.IIORegistry.registerApplicationClasspathSpis(Unknown Source)
at javax.imageio.spi.IIORegistry.(Unknown Source)
at javax.imageio.spi.IIORegistry.getDefaultInstance(Unknown Source)
at javax.imageio.ImageIO.(Unknown Source)
at puppytron.Resources.getImage(Resources.java:172)
at puppytron.Resources.init(Resources.java:78)
at puppytron.Puppytron.doInit(Puppytron.java:77)
at net.puppygames.applet.Game$1.run(Game.java:210)
[/quote]
Windows XP SP1, Opera version 7.51.

Saw that woogley was getting a ImageIO/Zip related exception. You are using the ImageIO bug workaround, right?

Ah no - whatā€™s that?
Iā€™m just using


URL url = Resources.class.getResource(imageName);
ret = ImageIO.read(url);

Whatā€™s the fix?

Cas :slight_smile:

I think with Applets you really need to use:

Toolkit.getDefaultToolkit().getImage(url);

ImageIO has a few problems in Applets.

BTW, is that GAGETimer I see? :wink:

[quote]Ah no - whatā€™s that?
Iā€™m just using


URL url = Resources.class.getResource(imageName);
ret = ImageIO.read(url);

Whatā€™s the fix?

Cas :slight_smile:
[/quote]
Donā€™t you read the Java2D section of the forum :wink: Seems like it comes up every week. The workaround is to get a InputStream and wrap it in a BufferedInputStream:


ret = ImageIO.read(new BufferedInputStream(Resources.class.getResourceAsStream(imageName)));

Haha :slight_smile: I just put in a hugely more fiddly fix. Iā€™ll change it to that one instead!

Cas :slight_smile:

Hmmm ā€¦ I get the following exception:
Created Game

Initingā€¦

Java version 1.4.2_05

Puppygames Applet Version $Revision: 1.6 $

Startingā€¦

Windows 2000

java.lang.UnsatisfiedLinkError: no timer in java.library.path

  at java.lang.ClassLoader.loadLibrary(Unknown Source)

  at java.lang.Runtime.loadLibrary0(Unknown Source)

  at java.lang.System.loadLibrary(Unknown Source)

  at com.dnsalias.java.timer.windows.WindowsTimer.loadLibrary(WindowsTimer.java:30)

  at com.dnsalias.java.timer.windows.WindowsTimer.available(WindowsTimer.java:18)

  at com.dnsalias.java.timer.AdvancedTimer.init(AdvancedTimer.java:40)

  at com.dnsalias.java.timer.AdvancedTimer.<init>(AdvancedTimer.java:26)

  at net.puppygames.applet.Game$1.run(Game.java:204)

Puppytron $Revision: 1.4 $

followed by the image loading messages and an infinity of ā€˜pausedā€™

I donā€™t have the GAGE timer anywhere, still using the Java3D timer for all my stuff, could that be it ? Game actually seemed to run all right though, if a little slowww I got up into the thousands with 8 or 9 shields and the (cute !) little robots were still popping in one by one at a rate of about one every couple of seconds and meandering slowly toward me before i gave up on it ā€¦

D.

Itā€™s okay, itā€™s supposed to do that. GAGETimer is investigating its environment and trying to find a copy of the DLL for Windows. If it canā€™t find it, it falls back on System.currentTimeMillis(). If you have 1.5 installed, you wonā€™t even see it try to use the DLL. :slight_smile:

[quote]http://www.puppygames.net/puppytron.html

Java 1.4+

This is a WIP. Let me know if it works. Iā€™m having problems making it ā€œrun anywhereā€ (bloody typical).

Cas :slight_smile:
[/quote]
cert is signed by ā€œshaven puppyā€ā€¦

I really donā€™t think itā€™s good that GAGE is SUPPOSED to print an exceptionā€¦ I think it should just handle it and never print anything out. That makes people think itā€™s screwing up when itā€™s not.

As for the game, I had no troubles running it. However after a minute or two on occasion when a guy would explode it would DRASTICALLY slow down. I couldnā€™t find any sense to why it was slowing down so much, but it would go at like 3fps until the explosion finished, and then resume a normal speed. Not all of the explosions would do itā€¦ just like 1 in 3 or 4ā€¦ something like that.

[quote]I really donā€™t think itā€™s good that GAGE is SUPPOSED to print an exceptionā€¦
[/quote]
Sure it is. It makes the newless cluebies pay attention. Far too often they come around and say ā€œGAGETimer doesnā€™t work for timing my 150fps, super-1337, Pong game!ā€ Which invariably works out to them doing something weird that prevents the DLL from loading. At least with the exception they go ā€œIt doesnā€™t seem to work right, but there is this exception!ā€ At which point I give them the standard lecture about how DLL loading works. :slight_smile:

[quote] I think it should just handle it and never print anything out. That makes people think itā€™s screwing up when itā€™s not.
[/quote]
No, that would probably be a bad thing. Keep in mind that GAGETimer supports Applets. It was not designed with them in mind. Most people who use the timer are going to want the DLL to load. If no indication is given, then how are they supposed to know what the problem is?

Iā€™ve toyed around with putting up a message that says ā€œWarning! DLL not found, reverting to System.currentTimeMillis()!ā€, but I have two concerns:

  1. That newbies will ignore it. (Nothing like a stack trace to shake them up. ;-))

  2. That someone will find some horrible bug, and Iā€™ll have no Stack Trace to figure out whatā€™s going on.

Granted, the second point is becoming less and less valid with time. Pretty much all the issues seem to have been shaken out.

Of course, if the exception really bugs you, then just comment out the ā€œe.printStackTrace()ā€ and recompile. :slight_smile:

well, Iā€™d hardly describe myself as a java newbie :slight_smile:
I just posted the above because the game seemed to run quite slowly on my machine and I was getting the same slowdown occasionally on the explosions that Malohkan was getting. Iā€™d presumed it was falling back on SOME sort of alternate timer or presumably the thing wouldnā€™t work at all.

Although since currentTimeMillis hasnā€™t got the same resolution as the GAGE timer ( I presume its similar to the Java3D one ??) that could have something to do with the occasional jerkiness and slowdown ā€¦

D.

[quote]well, Iā€™d hardly describe myself as a java newbie :slight_smile:
[/quote]
Chuckle I wasnā€™t describing you, I was describing the programmers who ā€œcanā€™t make GAGETimer workā€. You were a user in this case. :slight_smile:

[quote]I just posted the above because the game seemed to run quite slowly on my machine and I was getting the same slowdown occasionally on the explosions that Malohkan was getting. Iā€™d presumed it was falling back on SOME sort of alternate timer or presumably the thing wouldnā€™t work at all.
[/quote]
I donā€™t think thatā€™s the timerā€™s fault. GAGETimer guarantees time slices of 10ms on Windows 2000 and up. By scheduling your frames to take multiples of that, (e.g. 20ms per frame for 50FPS) you should never see any slowdown. My guess is that thereā€™s some sort of GC thrashing going on. Perhaps related to the particle system?

[quote]Although since currentTimeMillis hasnā€™t got the same resolution as the GAGE timer ( I presume its similar to the Java3D one ??) that could have something to do with the occasional jerkiness and slowdown ā€¦
[/quote]
To be correct, ā€œcurrentTimeMillis() hasnā€™t got the same resolution as the native Windows timerā€. GAGETimer is really just an algorithm that gets its timing data from various sources. The native timer was actually added after I developed a solution to precise timing with System.currentTimeMillis().

the fix worked :stuck_out_tongue:

itā€™s a pretty fun game, the red rectangles that show where the enemeies are appearing is a great idea!

keep up the good work :wink:

no worries :slight_smile:

Interesting, I though GAGETimer was just the native timer, didnā€™t realise it could work regardless. Iā€™ll have to use it myself one of these days. I started off using Java3D to write some stuff, got annoyed with it and switched to JOGL and ported over a bunch of my C++ vector and matrix classes to replace the Java3D ones. So the only bit iā€™m using of Java3D is the timer. I presume i can plug GAGETimer in without too much difficulty ?

D.

[quote]So the only bit iā€™m using of Java3D is the timer. I presume i can plug GAGETimer in without too much difficulty ?
[/quote]
Thatā€™s the idea. :slight_smile:

Hereā€™s a snippet from the Wurm Online JNLP file:


<resources>
        <j2se href="http://java.sun.com/products/autodl/j2se" version="1.4*" initial-heap-size="64M" max-heap-size="512M"/>
      <jar href="wurmclient.jar" main="true"/>
      <jar href="wurmres.jar"/>
      <jar href="lib/joal.jar"/>
      <jar href="lib/jogl.jar"/>
        <jar href="lib/bsh-core-2.0b1.jar"/>
      <jar href="lib/gagetimer.jar"/>
        <property name="sun.java2d.noddraw" value="true"/>
    </resources>

    <resources os="Windows">
      <j2se href="http://java.sun.com/products/autodl/j2se" version="1.4+" initial-heap-size="64M" max-heap-size="256M"/>
      <nativelib href = "lib/jogl-natives-win32.jar"/>
      <nativelib href = "lib/joal-natives-win32.jar"/>
      <nativelib href = "lib/gagetimer-win32-native.jar"/>
    </resources>

Note that the DLL is only required on Windows. System.currentTimeMillis() is accurate enough on other platforms that no native code is require. And if you use Java 1.5, the DLL isnā€™t even needed! (GAGETimer used System.nanoTime() instead.)