This site requires JavaScript, please enable it in your browser!
Greenfoot back
Transpire
Transpire wrote ...

2011/5/15

Help With Abysmal Performance?

1
2
3
Transpire Transpire

2011/5/15

#
This is my project. There are two issues with it: 1. The part where the player actually jumps off the platform isn't working. 2. Performance is abysmal. 3. I do get IllegalArgumentExceptions when the Player falls to the bottom, but I expect to. It can be ignored for now. So... can anyone help me figure why my performance is so bad? I mean, act() takes nearly 2 seconds to complete! I'm sorry... this is sort of my first *real* Greenfoot project where haven't tried something my teacher asked us to make. By the way, map(int x) is what I'm using to translate my increasing y = going up model into the increasing y = going down that greenfoot uses.
davmac davmac

2011/5/15

#
Regarding (2), you assumption that the act() takes nearly 2 seconds to complete is incorrect. The biggest problem is the use of the 'long' (integer) datatype in the Player.getGravityTick() method:
    private double gravityTick()
    {
        long interval = System.currentTimeMillis() - startTimeMillis;
        interval = interval / 1000;
        return initialLocation + velocity*interval + interval*interval*g/2;
    }
You calculate interval as the time passed in milliseconds since "startTimeMillis", which is fine, but then you divide by 1000 which means you get an integer (whole number, no fractional part) count of the seconds passed since startTimeMillis. If you change the declared type for "interval" from "long" to "double" it already works much better. By the way - it's much easier if you upload scenarios here to the gallery rather than the site you were using. I was forced to wait 20 seconds before I could download the file, which took less than a second to download once it actually started. Another benefit of uploading to the gallery is we can run it without downloading it.
davmac davmac

2011/5/15

#
(Just to make it clear - due to the use of an integral type for "interval", gravityTick() could only return a different value every second - thus your player only moved every second - which may be where you got your "nearly 2 seconds" from).
Transpire Transpire

2011/5/15

#
davmac, is it ok to upload non-functioning scenarios? Anyways, I see now. Arithmetic bites again! I have to go for a lifeguard training session until about 10 hours from now. I have some other bugs I found poring over a printed copy; perhaps it will be better then.
Transpire Transpire

2011/5/16

#
First of all, copy to clipboard on that code segment isn't working. Chrome 11 on Vista. Second of all, I've posted my project. Modifications to come yet! EDIT: Sorry for being an idiot, but where's the add scenario button?
davmac davmac

2011/5/16

#
From within Greenfoot, "Scenario" menu, "Export...", choose the "Publish" tab, supply requested information and hit "Export". If the "copy to clipboard" doesn't work (it doesn't seem to work for me either), you can still "view plain" and then select and copy the result (right click/copy, or ctrl+c).
Transpire Transpire

2011/5/16

#
Ok, done. I did use plain and copy. There seems to be a swing bug with the export screen, the checkboxes seem to turn blue on Vista far too quickly, compared to native apps. I'm not sure at all whether this is a bug, but the behavior just threw me a bit. And I can't seem to figure out why my quasi-listener method isn't being called. I put a sout call in there, and nothing is ever printed. I think there's something wrong with my navigable set/concurrent skip list set. I'm using a ConcurrentSkipListSet if I ever decide to use threads; I'll be able to do so as long as I manually stop them and never call Greenfoot. (I think it might be possible.)
davmac davmac

2011/5/16

#
It seems you didn't check the "include source" checkbox, so I can't see the source of the scenario. Re: the checkboxes turning blue too quickly, I'm not sure as I use Ubuntu/Mac OS, but it's probably just a limitation or bug with Java's "Windows look-and-feel".
Transpire Transpire

2011/5/16

#
Derp, I even tagged my thing with "with-source" but never included the source. Sorry. Btw, this popped up when I was exporting again: :1:3: The markup declarations contained or pointed to by the document type declaration must be well-formed. Exception in thread "Thread-249" java.lang.UnsupportedOperationException at java.util.AbstractList.remove(AbstractList.java:144) at greenfoot.gui.export.ExportPublishPane$6.construct(ExportPublishPane.java:669) at bluej.utility.SwingWorker$2.run(SwingWorker.java:129) at java.lang.Thread.run(Thread.java:619) I must be a bug magnet. So, my current issues... 1. Collision is broken 2. There's a slight lag upon starting the world. 3. Adjusting the act speed while running causes unpredictable results, while it should only change the fps due to design. Also, a note to myself: investigate why static imports aren't working.
davmac davmac

2011/5/17

#
One problem: your Platform.addedToWorld() method takes no arguments, but is probably meant to override addedToWorld(World). You should add a World argument. I think you'd be better off not doing your own collision detection too. You could just move the actor between one position and the next in steps and use Greenfoot's own collision checking routines each "step" of the way.
davmac davmac

2011/5/17

#
Then, it's defined like this:
    protected void addedToWorld(World world)
    {
        if(csls.add(this))
            throw new OddDuplicateAddException(this);
        yLocation = map(getY());
    }
But: csls.add(...) returns true if the object is not already in the list. You want to invert the condition of the check:
    protected void addedToWorld(World world)
    {
        if(! csls.add(this))
            throw new OddDuplicateAddException(this);
        yLocation = map(getY());
    }
That gets it more-or-less working for me.
Transpire Transpire

2011/5/17

#
I could have sworn I had corrected addedToWorld. A quick check indicates I only added the parameter to the Player class - doh! I didn't see the adding to the list bug. However, it is sort of weird... how come the OddDuplicateAddException never got written to the output? EDIT: I now see why you say it works "more or less". I need to adjust default velocity, and I forgot about the center being in the middle.
davmac davmac

2011/5/18

#
Transpire wrote...
However, it is sort of weird... how come the OddDuplicateAddException never got written to the output?
It does get written to the output... once you add the World parameter to the addedToWorld(...) method. Before that, there was no exception because the method was never called. By the way, if you want to make sure you are overriding a method, you can use the @Override annotation:
    @Override
    protected void addedToWorld(World world)
    {
        if(! csls.add(this))
            throw new OddDuplicateAddException(this);
        yLocation = map(getY());
    }
If you put "@Override" on a method which doesn't override a method from a superclass, you'll get an error when you compile.
Transpire Transpire

2011/5/18

#
So, in effect, before, exceptions should have been thrown, except the method was never called. Now that I've fixed both issues - missing parameter and the boolean returned from add( ) - the method is called but never throws an exception. Thanks for reminding me about annotations. I put them in. One question: is it legal to call, within my code, methods intended as Greenfoot hooks? Will I get race condition issues? I want to call stopped() in world in my own code, because of the "2. There's a slight lag upon starting the world." issue. Finally, I noticed a non-bug. Moving actors around in the world in my scenario will cause "ghost" platforms in my program logic, so it's not safe to do so. Just a note to myself. Finally, if anyone ever needs a start-stop independent clock, here's a bit of code to do so:
    private long timeLost, lastStoppedTime;
    public long getTimeMillis()
    {
        return System.currentTimeMillis() - timeLost;
    }
    
    public void started()
    {
        timeLost += System.currentTimeMillis() - lastStoppedTime;
    }
    
    public void stopped()
    {
        lastStoppedTime = System.currentTimeMillis();
    }
Just replace any System.currentTimeMillis() calls with WorldReference.getCurrentTime();. Obviously, if you are also using the stopped and started methods, you'll need to add the two lines of code, preferably at the beginning if you have any cleanup code that lasts for a long time. EDIT: I need to remember to modify that snippet; there's no way to adjust the time, which you may want to do during debugging, similar to the act button.
davmac davmac

2011/5/18

#
Transpire wrote...
One question: is it legal to call, within my code, methods intended as Greenfoot hooks? Will I get race condition issues? I want to call stopped() in world in my own code, because of the "2. There's a slight lag upon starting the world." issue.
Absolutely it is legal (though it's not clear to me at this point how/why you need to do it to resolve that issue) and it won't cause race conditions. Those methods are only called by Greenfoot itself when other user methods (such as act()) are not executing.
There are more replies on the next page.
1
2
3