sprite sheet vs flip book

David DeHaven david.dehaven at oracle.com
Thu Aug 16 10:32:27 PDT 2012


One other point: In Java you have to consider GC load. If you're using then dumping images repeatedly, the GC load will be higher than using a single image tile bank, which could potentially kill performance. If you're not allowing anything to be collected then that's pretty much a moot point, but it's still a consideration.

I'd be interested in seeing any results you come up with.

-DrD-

> Thanks for the feedback guys.  
> 
> Looks like there is some speculation as to which might be better but nothing conclusive at this point.  Might not be a bad idea to do a test of the two methods and post the results somewhere as this might benefit the community as a whole.
> 
> I imagine that the two things to check for would be FPS and total memory usage.  The test I have in mind would create and put on the screen dozens or hundreds of animated ImageViews.  It will let you select the method of animation, flip booking or moving viewport.  The FPS will be calculated using AnimationTimer and displayed on the screen.  RunTime will be used to display the totaltal, max, and free memory.
> 
> If any feedback on what test for or what would constitute a good test or what to check for please let me know.
> 
> thanks
> jose
> 
> 
> ________________________________
> From: David DeHaven <david.dehaven at oracle.com>
> To: openjfx-dev at openjdk.java.net 
> Sent: Tuesday, August 14, 2012 4:39 PM
> Subject: Re: JFX Forum feedback (was: socket communications in JFX)
> 
> 
> Traditionally (as in: this may or may not be the case in JavaFX) moving the viewport simply changes texture coordinates which is far more efficient than uploading new texture data. However if the alternate images are already loaded into textures then the performance difference to switch textures would be minimal to none, but memory and graphics resource footprint could be a concern depending on the number of images in question.
> 
> In this case, you don't have any control over whether the image exists in VRAM, so the safer bet would be to use tile offsets in a larger tile bank rather than swapping images each update cycle and possibly causing a texture upload.
> 
> Just my $0.02…
> 
> -DrD-
> 
>> I would imagine moving the viewport would be faster than swapping images on the ImageView, but it would be nice to have some data on that.
>> 
>> Richard
>> 
>> On Aug 14, 2012, at 12:36 PM, Daniel Zwolenski wrote:
>> 
>>> Yes, the OTN forum is the place to be. If jsmith doesn't give you a
>>> response, I'll be very surprised :)
>>> 
>>> The one area that is a bit of black box for us end users however is the
>>> performance side of things. I wouldn't know whether Sprite sheets or Node
>>> flippng or what would be more efficient and that probably is something that
>>> will need input from someone who has worked on the internals. I'd be
>>> inclined to say try the forums first but if you genuinely can't get an
>>> answer there for truly advanced topics, then post a note on here linking
>>> back to your forum post.
>>> 
>>> I imagine we don't want to fill up this mailing list with "why is my button
>>> not showing" type questions, but if it's not abused I personally wouldn't
>>> mind if the odd tough topic came this way. I can't speak for the rest of
>>> the mailing list however.
>>> 
>>> 
>>> On Tue, Aug 14, 2012 at 9:57 AM, Jose Martinez <jmartine_1026 at yahoo.com>wrote:
>>> 
>>>> Maybe "dead" was too harsh an adjective.  Just not too much activity going
>>>> on.  The top posters do a good job at tackling questions.  There was a few
>>>> day span when i was trying to go toe to toe with them at answering
>>>> questions but my knowledge was not as deep since most of the questions
>>>> pertained to enterprise business stuff like cells and tables.  I have an
>>>> open question on this mailing list about sprite sheets which I will post on
>>>> the OTN forum, wish me luck.
>>>> 
>>>> This JFX forum is dead,
>>>> http://www.java-gaming.org/boards/javafx/58/view.html, but its mainly
>>>> because no questions, versus questions going unanswered.
>>>> 
>>>> thanks
>>>> jose
>>>> ------------------------------
>>>> *From:* Daniel Zwolenski <zonski at gmail.com>
>>>> *To:* Jose Martinez <jmartine_1026 at yahoo.com>
>>>> *Cc:* "jonathan.giles at oracle.com" <jonathan.giles at oracle.com>; "
>>>> openjfx-dev at openjdk.java.net" <openjfx-dev at openjdk.java.net>
>>>> *Sent:* Monday, August 13, 2012 4:47 PM
>>>> *Subject:* JFX Forum feedback (was: socket communications in JFX)
>>>> 
>>>> 
>>>> The JFX OCN forum is kind of dead, I find you guys to be more enlightened
>>>> and responsive.  I will make an effort to go back to the OCN forum.
>>>> 
>>>> 
>>>> That is quite sad to hear. Last I checked jsmith was answering questions
>>>> faster than my browser could load them and his answers were usually spot
>>>> on. If the forums aren't working then this is something the JFX team might
>>>> want to look into.
>>>> 
>>>> Maybe it's your specific topics though (multi-player gaming is not
>>>> everyone's cup of tea) - can you provide some more specific feedback and
>>>> maybe a link or two to some examples?
>>>> 
>>>> 
>>>> 
>>>> thanks
>>>> jose
>>>> ------------------------------
>>>> *From:* Daniel Zwolenski <zonski at gmail.com>
>>>> *To:* Jose Martinez <jmartine_1026 at yahoo.com>
>>>> *Cc:* "jonathan.giles at oracle.com" <jonathan.giles at oracle.com>; "
>>>> openjfx-dev at openjdk.java.net" <openjfx-dev at openjdk.java.net>
>>>> *Sent:* Monday, August 13, 2012 5:46 AM
>>>> *Subject:* Re: socket communications in JFX
>>>> 
>>>> oops
>>>> 
>>>>> Either use two *threads* (one for asynch events and another for
>>>> request-response)
>>>> 
>>>> That should be use two "*sockets" *not threads.
>>>> 
>>>> 
>>>> On Mon, Aug 13, 2012 at 7:44 PM, Daniel Zwolenski <zonski at gmail.com>wrote:
>>>> 
>>>> Hey guys,
>>>> 
>>>> Sorry for the rough reply earlier. This is actually probably a question
>>>> best for the forums, and if this doesn't provide what you need I'd suggest
>>>> moving the conversation over to there (and let me know, as I don't hit the
>>>> forums as often as I'd like to).
>>>> 
>>>> The Worker/Task/Service stuff is useful when your action originates from
>>>> within the UI (such as from a Button click) and you then want to do a long
>>>> running task (like sending data to the server).
>>>> 
>>>> For listening to asynchronous messages from the server (i.e. random events
>>>> sent down the socket), everything is reversed: your action is triggered by
>>>> the server and you want to update your UI. For this, I would use a normal
>>>> Java thread with a loop that reads from the socket's input stream and then
>>>> "calls out" to your GUI to update it. The call out is the bit that needs to
>>>> happen in the JFX thread, so you need to wrap this in a Platform.runLater.
>>>> 
>>>> Here's some very rough code that does more or less what you want (I've
>>>> used an ObjectReader and assumed the server is serializing Java Objects
>>>> down the wire) but you could stream anything (bytes, XML, JSON, etc).
>>>> 
>>>>    public void listenToServer() {
>>>> 
>>>>        try {
>>>>            Socket socket = new Socket("myserver.com", 9000);
>>>>            ObjectInputStream in = new
>>>> ObjectInputStream(socket.getInputStream());
>>>> 
>>>>            Object next;
>>>>            while ((next = in.readObject()) != null) {
>>>>                final Object messageFromServer = next;
>>>>                Platform.runLater(new Runnable() {
>>>>                    public void run() {
>>>>                        handleServerMessage(messageFromServer);
>>>>                    }
>>>>                });
>>>>            }
>>>>        } catch (IOException e) {
>>>>            // probably some retry attempts - depends on what you are doing
>>>>        } catch (ClassNotFoundException e) {
>>>>            // server sent a dodgy message
>>>>            e.printStackTrace();
>>>>        }
>>>>    }
>>>> 
>>>>    public void handleServerMessage(Object messageFromServer) {
>>>>        // you can now update your GUI in the JFX main thread
>>>>        if (messageFromServer instanceof PlayerMoved) {
>>>>            PlayerMoved playerMoved = (PlayerMoved)messageFromServer;
>>>>            playerSprite.moveTo(playerMoved.getX(), playerMoved.getY());
>>>>        } else if (messageFromServer instanceof GameOverMessage) {
>>>>            my.setText("Game Over Man");
>>>>        }
>>>>    }
>>>> 
>>>> Note that this is for *listening* (and I'm assuming you are using an
>>>> asynchronous message approach - where your server can send arbitrary
>>>> messages at any time). For *sending* to the server then the Task (or
>>>> Service) stuff is the way to go.
>>>> 
>>>>    public void sendMessageToServer(final Object message) {
>>>>        Task worker = new Task() {
>>>>            protected Object call() throws Exception {
>>>>                // where 'out' is the OutputStream of the Socket
>>>>                out.writeObject(message);
>>>>                return null;
>>>>            }
>>>> 
>>>>            protected void succeeded() {
>>>>                // message got through, yay
>>>>            }
>>>> 
>>>>            protected void failed() {
>>>>                // message failed, curse you unreliable internet
>>>>                getException().printStackTrace();
>>>>            }
>>>>        };
>>>>        new Thread(worker).start();
>>>>    }
>>>> 
>>>> If you want to do synchronous messaging (i.e. where you server responds to
>>>> the message you sent it), then you need to be careful with threads. The
>>>> 'succeeded' method above can read the next response from the server, but
>>>> the other listener thread will likely intercept it first (or you might get
>>>> a random message coming down while you are waiting for your response).
>>>> Either use two threads (one for asynch events and another for
>>>> request-response) or put IDs on your request+response and match them up on
>>>> the client using queues, etc.
>>>> 
>>>> Also use the Task stuff when first setting up your connection to the sever
>>>> (i.e. when you new the Socket and open the input/output stream). Much the
>>>> same as above.
>>>> 
>>>> On a side note, there's some cool stuff with WebSockets now (
>>>> http://tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html) if you can
>>>> use a server new enough. Avoids lots of nasty port/firewall issues.
>>>> 
>>>> Oh and also consider Hessian for serializing really nice small data down
>>>> the wire that can be read by lots of languages (for when you do that iPhone
>>>> version): http://hessian.caucho.com/
>>>> 
>>>> 
>>>> 
>>>> 
>>>> On Mon, Aug 13, 2012 at 2:14 PM, Daniel Zwolenski <zonski at gmail.com>wrote:
>>>> 
>>>> Hey Jose,
>>>> 
>>>> I will reply properly later when I get home, but in general you can do
>>>> normal Java socket stuff in JFX2.
>>>> 
>>>> I wouldn't use the Task/Worker stuff for this but make use of the
>>>> low-level Platform.runLater method.
>>>> 
>>>> i.e. Start a new thread that reads from the thread, when you get some data
>>>> you want to process just use Platform.runLater()
>>>> 
>>>> roughly:
>>>> 
>>>> new Thread() {
>>>> 
>>>>   run() {
>>>> 
>>>>    while (data = socket.readNext()) {
>>>> 
>>>>        Platform.runLater(new Runabble() {
>>>>            // update JavaFX UI with 'data' read from socket
>>>>        }
>>>> 
>>>>    }
>>>> 
>>>> 
>>>> }
>>>> 
>>>> }
>>>> 
>>>> 
>>>> 
>>>> On Mon, Aug 13, 2012 at 11:53 AM, Jose Martinez <jmartine_1026 at yahoo.com>wrote:
>>>> 
>>>> Jonathon,
>>>> 
>>>> Thank you.  I will digest this info and respond back with any questions.
>>>> 
>>>> jose
>>>> 
>>>> 
>>>> ________________________________
>>>> From: Jonathan Giles <jonathan.giles at oracle.com>
>>>> To: openjfx-dev at openjdk.java.net
>>>> Sent: Sunday, August 12, 2012 9:33 PM
>>>> Subject: Re: socket communications in JFX
>>>> 
>>>> The generally accepted approach is to keep the slow running tasks off of
>>>> the UI thread (in our case the JavaFX Application Thread). If you don't,
>>>> you subject the user to a slow user interface, but I'm sure you're well
>>>> aware of this based on your comments.
>>>> 
>>>> Generally how you approach this is not defined by JavaFX, rather it comes
>>>> down to how your architecture needs to work. One place to look is the
>>>> JavaFX Worker and Task API:
>>>> http://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm
>>>> http://docs.oracle.com/javafx/2/api/javafx/concurrent/Task.html
>>>> 
>>>> -- Jonathan
>>>> 
>>>> On 13/08/2012 1:27 p.m., Jose Martinez wrote:
>>>>> Hello,
>>>>> 
>>>>> I am preparing to implement multiplayer capabilities.  Saw one or two
>>>> articles out there about socket communications and JFX but they were from
>>>> JFX 1.x.
>>>>> 
>>>>> I guess my first question is, is there a way to communicate from a
>>>> socket thread directly to the JFX main thread or does the JFX main thread
>>>> need to poll some shared object?  Is there any recent documentation out
>>>> there on either the topic of socket communications within JFX or even just
>>>> multithreading in JFX applications?
>>>>> 
>>>>> thanks!
>>>>> jose
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>> 



More information about the openjfx-dev mailing list