Gravitational Fourks

This is a two-player game, but the players must share a mouse - networking is not on the cards. Take it in turns to fire missiles, aiming to hit the other player. Once you fire a missile the only force to act on it will be gravity, so you must judge the initial course and speed carefully. Control is entirely with the mouse.

http://cheddarmonk.org/java4k/gravfourks/grav4k_latest.jnlp

Error :-X

No applet found on web page, try as JNLP direct
java.lang.InternalError: 
****************************************************************
ERROR: the javaplugin.version system property wasn't picked up
by the com.sun.deploy.Environment class. This probably happened
because of a change to the initialization order in PluginMain
where the deployment classes are being initialized too early.
This will break jar cache versioning, and possibly other things.
Please undo your recent changes and rethink them.
****************************************************************
	at sun.plugin2.applet.Applet2Environment.initialize(Unknown Source)
	at sun.plugin2.applet.viewer.JNLP2Viewer.run(Unknown Source)
	at sun.plugin2.applet.viewer.JNLP2Viewer.main(Unknown Source)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at com.sun.javaws.Launcher.executeApplet(Unknown Source)
	at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
	at com.sun.javaws.Launcher.doLaunchApp(Unknown Source)
	at com.sun.javaws.Launcher.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
java.lang.NullPointerException
	at a.start(Unknown Source)
	at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Exception: java.lang.NullPointerException

For some reason its talking about applets…

Does your code do anything with applets? If so that might be the problem.

I’ve no idea what “recent changes” it thinks someone has made to something. The game is an applet launched by JNLP which works fine for me - and I just cleared my cache to make sure. It seems to find the class and then throw an NPE, which is a bit odd. Which version of Java are you using?

Worked fine for me - bit tricky to guestimate though… (can’t you zoom out to keep the missiles on the screen? ;))

That’s on the list of possible but improbable additions. It would mean expanding the size of the backbuffer, which would make the fading operation slow.

This reminds me of a game I used to play with a sheet of paper and pencil (during University lectures many years ago… tut)… Each player had 5 ships and could either move or shoot… Movement/shooting was done by flicking the pencil downwards at an angle, and following the path… Wot fun… Maybe something similar (ie Move ability too and maybe 3 ships each?) ps. Any reason you didnt use antialiasing? This should greatly improve the graphics…

Also on the list. It will mean reworking the collision detection. At the moment I do that by XORing the missile onto the backbuffer, scanning its bounding box for pixels of the colour which that turns planets into, and then XORing again to clean up the backbuffer. I think it should just be a case of extending the pixel test a bit.

The latest release has much snazzier graphics, including anti-aliasing.

Java Plug-in 1.6.0_12
Using JRE version 1.6.0_12-ea Java HotSpot(TM) Client VM

The “Gravitational Fourks” JFrame/Frame comes up with a grey contents and I get that exception in the Java Console.

EDIT:

D:\Program Files\Java\jre1.6.0_11\bin>javaws http://www.toothycat.net/~pjt33/java4k/grav4k_latest.jnlp

WORKS (jre1.6.0_11)

and

D:\Program Files\Java\jre6\bin>javaws http://www.toothycat.net/~pjt33/java4k/grav4k_latest.jnlp

DOESN’T WORK (jre1.6.0_12)

lol it’s epic when you do a full orbit and shoot yourself in the ass. It’s very rewarding when you acctualy hit the opponent though!
The guides really help.

Nice game. I would tend to have less planets though, gravity becomes a bit hard to predict after more than about 3 bodies. Also if you want even better looking planets I wrote a tutorial a while back on just that topic see here. If you have minimal space to spare, running the input coordinates to your texture function through this will give you nice spherical looking planets:


void distort(float x, float y, Vector2D dest) {
  float z;
  float nxangle, nyangle, theta1, theta2;
  float ri = 0.5f; // refraction index

  z = (float)Math.sqrt ((1 - x * x  - y * y ));

  nxangle = (float)Math.acos(x / Math.sqrt(x * x + z * z));
  theta1 = PI / 2 - nxangle;
  theta2 = (float)Math.asin (Math.sin (theta1) * ri);
  theta2 = PI / 2 - nxangle - theta2;
  dest.x = x - (float)Math.tan (theta2) * z;

  nyangle = (float)Math.acos (y / Math.sqrt(y * y + z * z));
  theta1 = PI / 2 - nyangle;
  theta2 = (float)Math.asin(Math.sin (theta1) * ri);
  theta2 = PI / 2 - nyangle - theta2;
  dest.y = y - (float)Math.tan (theta2) * z;
}

Cool, this is sort of like what my Spoo4k game originally started out as.

It seems sort of sparse at this point, however, and it can be very difficult. I even shot myself instead of my opponent once.

Thanks, but I’m puzzled by jre1.6.0_12, because I can’t find anything more recent than update 11 on sun.java.com. Where did you download it? Edit: oh, I see an -ea at the end. If you will beta-test stuff you’ve got to expect it to have problems :stuck_out_tongue:

Thanks for the comment on the guides.

sws26, I’ll check out your guide. My guess is that it’s basically spherical lighting, but I haven’t looked yet. The idea had occurred to me, although it will have to be either that or Perlin noise until I optimise the noise.

The gravity is supposed to be hard to predict: after a bit of practice, ones with four or five planets get too easy.

Might be interesting to overlay a grid that displays the gravitational sheer at each vertex.
Or maybe a full gravity map, using a color gradient to display the magnitude of the gravitational force at each pixel (the direction of the force would not be needed, as it would be obvious by the color of the surrounding pixels)

Ok, now that I’ve read the accompanying page I see that it’s a bit more complicated than I thought. Having said that, the code is more complicated than it obviously needs to be. Are there good numerical analytic reasons for not simplifying it thus?


void distort(float x, float y, Vector2D dest) {
  float z;
  float tmp, theta;
  float ri = 0.5f; // refraction index

  z = (float)Math.sqrt(1 - x * x  - y * y);

  tmp = x / (float)Math.sqrt(1 - y * y);
  theta = (float)Math.acos(tmp) + (float)Math.asin(tmp * ri);
  dest.x = x - z / (float)Math.tan(theta);

  tmp = y / (float)Math.sqrt(1 - x * x);
  theta = (float)Math.acos(tmp) + (float)Math.asin(tmp * ri);
  dest.y = y - z / (float)Math.tan(theta);
}

Edit: in fact if my algebra is correct the trig functions can be eliminated entirely so: (warning: untested code, as is the stuff above)


void distort(float x, float y, Vector2D dest) {
  float z;
  float tmp, rx, ry;
  float ri = 0.5f; // refraction index

  z = (float)Math.sqrt(1 - x * x  - y * y);

  rx = ri * x;
  tmp = (float)Math.sqrt(1 - rx * rx - y * y);
  dest.x = rx * (1 - y * y) / (z * tmp + rx * x);

  ry = ri * y;
  tmp = (float)Math.sqrt(1 - x * x - ry * ry);
  dest.y = ry * (1 - x * x) / (z * tmp + ry * y);
}

Entirely possible that the code is horribly inefficient, I never bothered trying to simplify it any further (wasn’t for a 4k contest). I’ll try your code tonight, if it works I’ll update my tutorial (assuming you have no objections to me using your version).

None at all. I’m not going to use it as is, though, because it occurs to me that that’s the forward transform and unless I plan to write a ray tracer I’d need the reverse transform. Is it the same with reciprocal index of refraction? Have to think about it some more.

Why would you need the reverse transform?

If I understand your page correctly (this may be the problem!) then I pass texture coords to that method and it passes back screen coords. Is it really the other way round?

Correct, pass in screen coords to get texture coords (probably should have made that clearer.

I’ve added the latter. I think you may be overestimating the ability of the average punter to visualise a Laplacian, but I like the look.