Groovy and Jmonkey w/ HelloIntersection Tutorial

Hey all,



Have been working with several Java Game books and coding basic stuff in Groovy. I've learned alot about converting and working with Java code and converting minor things to get it to work with Groovy. Usuallt the vast majority of the code is the same but there are only minor changes that need to be made to get things to work in Groovy.



I recently decided to work with Jmonkey and have been going through the tutorials without too many issues and converting things over fairly easily but ran into a stumbling block.



The HelloIntersection Tutorial references something called cam.getLocation() at line 160. In looking at other code, I can see this as part of com.jme.renderer. But when I try to run the code, I'm always getting an error like the following when firing a bullet:



java.lang.NullPointerException
   at HelloIntersection$FireBullet.propertyMissing(HelloIntersection.groovy)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88)
   at groovy.lang.MetaClassImpl.invokeMissingProperty(MetaClassImpl.java:754)
   at groovy.lang.MetaClassImpl$11.getProperty(MetaClassImpl.java:1775)
   at org.codehaus.groovy.runtime.callsite.GetEffectivePogoPropertySite.getProperty(GetEffectivePogoPropertySite.java:69)
   at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:241)
   at HelloIntersection$FireBullet.performAction(HelloIntersection.groovy:160)
   at com.jme.input.ActionTrigger.performAction(ActionTrigger.java:264)
   at com.jme.input.ActionTrigger$CommandTrigger.performAction(ActionTrigger.java:291)
   at com.jme.input.InputHandler.processTriggers(InputHandler.java:425)
   at com.jme.input.InputHandler.update(InputHandler.java:410)
   at com.jme.app.BaseSimpleGame.updateInput(BaseSimpleGame.java:327)
   at com.jme.app.BaseSimpleGame.update(BaseSimpleGame.java:219)
   at com.jme.app.SimpleGame.update(SimpleGame.java:56)
   at com.jme.app.BaseGame.start(BaseGame.java:84)
   at com.jme.app.BaseGame$start.call(Unknown Source)
   at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
   at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117)
   at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:121)
   at HelloIntersection.main(HelloIntersection.groovy:65)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88)
   at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
   at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1305)
   at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:717)
   at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:270)
   at groovy.lang.GroovyShell.run(GroovyShell.java:226)
   at groovy.lang.GroovyShell.run(GroovyShell.java:156)
   at groovy.ui.GroovyMain.processOnce(GroovyMain.java:494)
   at groovy.ui.GroovyMain.run(GroovyMain.java:309)
   at groovy.ui.GroovyMain.process(GroovyMain.java:295)
   at groovy.ui.GroovyMain.processArgs(GroovyMain.java:112)
   at groovy.ui.GroovyMain.main(GroovyMain.java:93)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:108)
   at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:130)



For all intents and purposes, none of the code changed, only small cleanups are done (like making sure variables are properly declared so Groovy doesn't try to do it dynamically).

Does anyone know what would be causing this issue? Line 160 appears to be...


bullet.setLocalTranslation(new Vector3f(cam.getLocation()));




Omg, now that I saw a stacktrace from groovy I am sure I will never use it :smiley:



Umm, in that line only cam or bullet could be null, can you check if it is really the cam object?



Cheers,

Normen

Heh. Preaching to the choir. It's a <a href=http://josh-in-antarctica.blogspot.com/2009/08/groovy-stacktraces-showstopper.html>point of contention for some</a>.



So trying to test using isNull() and echoing out to logger but that's not working on either. Got any suggestions?

orubel said:

So trying to test using isNull() and echoing out to logger but that's not working on either. Got any suggestions?

Huh? If its really that complicated finding out if a variable is null or not before a line is called in groovy then I really cant help you :D

Ok got it. Just tested for equals(null) on both and bullet is being set just fine but the Vector3f declaration is where it fails. I separated out the Vector3f variable declaration on instinct that was where the failure was (keep in mind I have stared at lots of Groovy to Java conversion and just have an eye for it at this point). And it seems to have a problem with converting cam.getLocation() to a vector.



         Vector3f vec = new Vector3f(cam.getLocation());
         bullet.setLocalTranslation(vec);



Keep in mind that Groovy code tries to dynamically assign so I assume I should try to cast as a Vector3f or something. Normally I either declare the variable ahead of time or use built in functions such as toFloat(),toString(), or toInteger() but know in this case I won't have the luxury of using toVector3f() :)

Any suggestions? I believe I have tried casting as a Vector3f and that doesn't work.

I think the main problem that I am seeing is that this is a nested class and the 'cam' variable is never declared in the outer class or anywhere else that I can see in the tutorial. I can see it in the logger being instantiated but there is no instance that can be referenced that I can see in the class.



As such, this inner class is wondering where the hell I got 'cam' from. I could point it to the outer class but the problem is it isn't declared there.



Therein lies the problem.



Is there an easy way to declare camera for this tutorial. I believe it is using AbstractCamera.

The cam varibale is located in BaseSimpleGame and its protected, dont know if that helps.

You can also use DisplaySystem.getDisplaySystem().getRenderer().getCamera() to get the cam without having to point to an object.

Bingo! Using DisplaySystem.getDisplaySystem().getRenderer().getCamera().getLocation worked perfectly. Still getting other errors but that one was a show stopper for me. Thanks a bunch. :slight_smile:



Most of the other errors are due to using nested classes (YECH) which forces me to try and create workarounds.



Still I took this on as a challenge as I saw that Jmonkey was developing a plugin for Griffon and wanted to get a headstart :slight_smile:

orubel said:
Still I took this on as a challenge as I saw that Jmonkey was developing a plugin for Griffon and wanted to get a headstart :)
Well the Griffon plugin is not by any means an official project and frankly I doubt any of us in the team know much of it. I looked into it a while back, but I must have dismissed it as there wasn't any notable progress. Maybe I didn't look hard enough. Anyhow, if the author wants to contact us about a closer collaboration he's welcome to it :)

It may be something that Andres Almiray was working on (the creator of Griffon). I know he has written an article or two about JMonkey in Griffon and even given a couple presentations on it. Hell, I know he would love to have you guys helping him as he spends most of his time on Griffon and trying to get out the book on Griffon these days.