animations
play

Animations Animations with Timers Double Buffering 1 CS 349 - - PowerPoint PPT Presentation

Animations Animations with Timers Double Buffering 1 CS 349 - Animations Animation A simulation of movement created by displaying a series of pictures, or frames. Animation: drawing frames at a consistent rate . Goals: Move


  1. Animations Animations with Timers Double Buffering 1 CS 349 - Animations

  2. Animation • A simulation of movement created by displaying a series of pictures, or frames. – Animation: drawing frames at a consistent rate . • Goals: – Move things around on the screen – Repaint 24 - 60 times per second (frames-per- second, frame rate, or “FPS”) – Make sure events are handled on timely basis – Don’t use more CPU than necessary – Easily understood code CS 349 - Animations 2

  3. Respond to Events (non-blocking) public void eventLoop() { while (true) { if (eventQueue.hasEvents()) { // pending events? // yes, process them this.handleEvent(eventQueue.nextEvent()); } // process animation and repaint component this.handleAnimation(); this.paintComponent(this.getGraphics()); } } This doesn’t block, but it doesn’t work very well either… This example recreates Xlib's explict event loop style of programming in Java. It is for pedagogical purposes only. DO NOT USE THIS CODE for a "real" Swing application! 6 CS 349 - Animations

  4. Key to Animation: Managing Time public void eventLoop() { while (true) { if (eventQueue.hasEvents()) { // pending events? // yes, process them this.handleEvent(eventQueue.nextEvent()); } // process animation and repaint component this.handleAnimation(); this.paintComponent(this.getGraphics()); Thread.sleep(1000 / this.FPS); // FPS = 30 } } Much better, but still not great… 7 CS 349 - Animations

  5. Key to Animation: Managing Time public void eventLoop() { while (true) { while (eventQueue.hasEvents()) { // pending events? // yes, process them this.handleEvent(eventQueue.nextEvent()); } // process animation and repaint component this.handleAnimation(); this.paintComponent(this.getGraphics()); Thread.sleep(1000 / this.FPS); // FPS = 30 } } The solution is to let the thread sleep only when there are no events to process. 8 CS 349 - Animations

  6. X Code Demo: animation.cpp while( true ) { while (XPending(display) > 0) { // pending events? XNextEvent(display, &event ); // yes, process them switch( event.type ) { // handle event cases here ... } } handleAnimation(xinfo); // update animation objects repaint(xinfo); // repaint the frame // sleep for about 1/30 second const int FPS = 30; usleep(1000000/FPS); } And this is the proper solution with X lib… 9 CS 349 - Animations

  7. Screen Flicker During Drawing • Imagine you are animating two balls on the display in a game of breakout • As the balls get close to each other, you notice that one seems to flicker – Why? • If you paint the balls sequentially, then you might clear a rectangle of the first ball’s position, paint the first ball in the new position, then clear rect for the second ball and paint the second ball • Ball 1 has a bite out of it – Or may even vanish … 1 – Until next update 2 CS 349 - Animations 10

  8. • Flickering: when an intermediate image is on Fix: Double Buffering the display. – We need to prevent this, and ensure that only complete images are drawn (redraw strategies) • Solution: – Create an off screen image buffer – Draw to the buffer – Copy the buffer to the screen as quickly as possible (between refreshes) • In X, this is a manual process • In most other situations it is done for you CS 349 - Animations 11

  9. Double Buffering // create off screen buffer xinfo.pixmap = XCreatePixmap( xinfo.display, xinfo.window, width, height, depth); // size and *depth* of pixmap // draw into the buffer // note that a window and a pixmap are “ drawables ” XFillRectangle( xinfo.display, xinfo.pixmap, xinfo.gc[0], 0, 0, width, height); // copy buffer to window XCopyArea( xinfo.display, xinfo.pixmap, xinfo.window, xinfo.gc[0], 0, 0, width, height, // pixmap region to copy 0, 0); // top left corner of pixmap in window XFlush( xinfo.display ); 12 CS 349 - Animations

  10. Java Code: set Double Buffering • Modern toolkits often have double-buffering built-in – e.g. in Java Swing, double buffering is built into the JComponent class (which is a base class for all most drawable components, so they inherit this functionality) • Two methods: – public boolean isDoubleBuffered(); – public void setDoubleBuffered(boolean o); – Double-buffering enabled by default ! • If set in top-level container, all subcomponents will be double buffered regardless of individual settings CS 349 - Animations 14

  11. Java Code: manual Double Buffering protected void paintComponent(Graphics g) { // dBuff and gBuff are used for double buffering Image dBuff = new BufferedImage(this.getWidth(), this.getHeight(), TYPE_3BYTE_BGR); Graphics gBuff = dBuff.getGraphics(); gBuff.setClip(0, 0, this.getWidth(), this.getHeight()); gBuff.setColor(Color.ORANGE); gBuff.fillRect(0, 0, this.getWidth(), this.getHeight()); // do other painting using gBuff... g.drawImage(dBuff, 0, 0, this.getWidth(), this.getHeight(), null); // copy buffer to Graphics } CS 349 - Animations 15

  12. Animation using a Timer in Java class ColouredX extends JComponent { ... private Point ballPos = new Point(100, 0); private final int FPS = 40; FPS = Frames Per Second private Timer timer ; javax.swing.Timer public ColouredX() { this .addMouseListener(...); this . timer = new Timer(1000/ FPS , new ActionListener() { @Override public void actionPerformed(ActionEvent e) { ballPos . y += 2; repaint(); } }); this . timer .start(); } public void paintComponent(Graphics g) { Paint the ball at ... its new location. g2.setColor(Color. ORANGE ); g2.fillOval( this . ballPos . x , this . ballPos . y , 30, 30); } 17 CS 349 - Animations }

  13. Summary • Animation with Timers • Double Buffering CS 349 - Animations 18

Recommend


More recommend