Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (498)
Games in Android Showcase (115)
games submitted by our members
Games in WIP (563)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Problems with vsync and TimerTask  (Read 1802 times)
0 Members and 1 Guest are viewing this topic.
Offline karlund

Junior Newbie




Java games rock!


« Posted 2005-01-09 18:05:22 »

I am new to Java game programming, but I've done a bit of Allegro, so I thought it could be fun trying a bit of Java  Grin

I decided to make a small program with a sliding ball to get vsync in order...

Here is the code:

import java.applet.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.awt.image.BufferStrategy;
import java.awt.Graphics2D.*;
import java.util.*;

public class PlayingField extends Applet{

 public void init() {
   setLayout(new BorderLayout());
   add(new PField());
 }
}

class PField extends Canvas {
 PaintTimer pt;
 Timer t;
 int x;
 BufferedImage bi;
 Graphics2D big;
 Rectangle area;
 BufferStrategy strategy;
 boolean firstTime = true;
 boolean increasing = true;

 public PField() {
   x = 0;
   pt = new PaintTimer();
   t = new Timer();
   t.scheduleAtFixedRate(pt,200,10);
 }

 public void paint(Graphics g) {
   update(g);
 }

 public void update(Graphics g) {
   if(firstTime) {
     Dimension d = getSize();
     area = new Rectangle(d);
     bi = (BufferedImage)createImage(d.width,d.height);
     big = bi.createGraphics();
     createBufferStrategy(3);
     strategy = getBufferStrategy();
     firstTime = false;
   }
   Graphics2D g2d = (Graphics2D)strategy.getDrawGraphics();
   g2d.setColor(Color.white);
   g2d.clearRect(0,0,area.width,area.height);
   g2d.setColor(Color.red);
   g2d.fill(new Ellipse2D.Double(x,50,32,32));

   strategy.show();
   g2d.dispose();
 }

 class PaintTimer extends TimerTask {
   public void run() {
     if(x+32>=area.width && increasing==true)
       increasing = false;
     if(x<=0 && increasing==false)
       increasing = true;
       
     if(increasing)
       x = x + 2;
     else
       x = x - 2;
     repaint();
   }
 }
}

Here vsync seems to be ok, however the speed is not constant. Why is that, is there any timing method which is more constant than TimerTask?

I have tried to remove Graphics g from update, which I should be able to as update don't use g at all. But that really messes up things. The vsync goes completely, so as well as speed problems I also get flickering!

Why is that?

Could anybody pls enlighten me  Cool

Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #1 - Posted 2005-01-09 18:29:25 »

Dont use timertask for anything, it is an incomplete API.

One day, maybe, Sun will finish writing it. It is somewhat incredible that it's even included in the standard libraries, since it's clearly not production ready. I guess enough Sun customers were desperate enough for "anything, even if it's poor".

malloc will be first against the wall when the revolution comes...
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #2 - Posted 2005-01-09 18:33:38 »

Quote

I have tried to remove Graphics g from update, which I should be able to as update don't use g at all. But that really messes up things. The vsync goes completely, so as well as speed problems I also get flickering!

Why is that?



It's the most basic feature of an OOP language (although that's not to say it's obvious how this works until you already know Grin). If you "remove" that parameter then you are making a completely different method. All the method calls in the system which invoke:

yourthing.update( some-graphics-or-other );

will, for fairly obvious reasons, NOT get "secretly redirected" to some phantom method of yours which has no argument.

Lots of scripting languages hide this, and some "alternative" language designs exist where the parameters are considered unimportant, so that update( graphics ) could actually invoke a method that is just update() - but these are very off-the-wall; they are fine, but you have to adopt significantly different approaches to how you think about programming (in many people's opinion, *better* approaches - but they have yet to unseat the mainstream ones that do not work that way).

malloc will be first against the wall when the revolution comes...
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #3 - Posted 2005-01-09 18:35:56 »

Re: the update(g) stuff, you need to find a good tutorial on OOP - start with the Sun free ones (google for sun java tutorial) if you've not already done them.

PS: I've made the same mistake three times in my life that I remember, and I didn't have any excuse of ignorance - I knew perfectly well what was going on, I was just being stupid Smiley. So I can remember how easy it is to interpret the language in the way that you did.

malloc will be first against the wall when the revolution comes...
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #4 - Posted 2005-01-09 18:39:41 »

Quote
But that really messes up things. The vsync goes completely, so as well as speed problems I also get flickering!


This is because you are no longer overriding the existing ("default") method "update( Graphics g)". This is another of the most fundamental "features" of OOP: when you write a class with "extends ANOTHERCLASS" you automatically inherit all the other class's methods. And, in turn, inherit any that it had inherited from the class it extended (if it had an "extends" clause at the top).

If you look in the javadocs / API docs for Applet, and follow the tree diagram up, you'll eventually find a class that has the update( graphics g ) method in it - when you wrote your own one, you disabled that method. When you changed the parameters, you re-enabled the default version.

The default version just does:
- paint a grey background
- invoke paint( Graphics g )

the flickering is because it is, by default, wiping the screen to grey every frame.

malloc will be first against the wall when the revolution comes...
Offline karlund

Junior Newbie




Java games rock!


« Reply #5 - Posted 2005-01-09 20:06:20 »

Grin

Thx alot.
How stupid of me. Of course I am making more polymorphisme!!!

I didn't know that update was an excisting method, I thought I was declaring a new method, which paint was calling.  This is the first time I play around with graphics in Java, up until now I've only used Java for networking and data manipulation...

I have done more C/C++ work. I just want to learn more Java, so that my code will be portable.

What a shame that TimerTask isn't complete, how do I make scheduling then. Can it really be correct to use busy waiting checking the internal clock when to move the ball!

That really sounds like CPU misusage.

Is there a method in applet or canvas, which get called on a regular basis, so that it could be used to check the clock instead of a busy waiting loop?
Offline tom
« Reply #6 - Posted 2005-01-09 20:35:34 »

Just call Thread.yield() inside the loop and you'll be fine.

Offline karlund

Junior Newbie




Java games rock!


« Reply #7 - Posted 2005-01-10 04:54:20 »

Excellent just the thing I was looking for  Grin
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #8 - Posted 2005-01-10 09:34:01 »

Quote

I thought I was declaring a new method, which paint was calling.


That was much the same as what I thought when I made the same mistake a long time ago.

The sad thing is that it's actually possible that that could have been what was happening (have a look at the Reflection section of the docs sometime...lets you query what methods a class/object/etc has, and then invoke them in a type-safe manner etc).

But without using reflection (which you don't normally do without special reason to - it's much slower than direct code, because it compiles to much less efficient code (since it contains compilaiton references that cant be resolved until runtime - although in theory it needn't be as slow as it is in current implementtions)) your assumption is not possible - there is no physical way that the invoker could do what you assumed.

malloc will be first against the wall when the revolution comes...
Offline karlund

Junior Newbie




Java games rock!


« Reply #9 - Posted 2005-01-10 13:54:44 »

Ok I have had a look at my small ball program, and I have rewamped it, so that it is using a separate thread.

Here is the code:

import java.applet.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.awt.image.BufferStrategy;
import java.awt.Graphics2D.*;
import java.util.Date;

public class PlayingField extends Applet implements Runnable{
 PField pf;
 Thread t;

 public void init() {
   setLayout(new BorderLayout());
   pf = new PField();
   add(pf);
 }

 public void start() {
   t = new Thread(this);
   t.start();
 }

 public void stop() {
   pf.stop();
   t = null;
 }

 public void destroy() {
   pf.setVisible(false);
   this.setVisible(false);
 }

 public void run() {
   pf.initialise();
   pf.machine();
 }

}

class PField extends Canvas {
 int x=0;
 final static int FPS = 100;

 long newTime;
 long deltaTime;

 Rectangle area;
 BufferStrategy strategy;
 Graphics2D g2d;
 boolean firstTime = true;
 volatile boolean done = true;
 boolean increasing = true;

 /**public PField() {
   date = new Date();
 }*/

 public void initialise() {
   setBackground(Color.black);
   Dimension d = getSize();
   area = new Rectangle(d);
   createBufferStrategy(3);
   strategy = getBufferStrategy();
   firstTime = false;
   done = false;
 }

 public void stop() {
   done = true;
   firstTime = true;
 }

 public void machine() {

   while (!done) {
     newTime = System.currentTimeMillis();

     if (x + 32 >= area.width && increasing == true)
       increasing = false;
     if (x <= 0 && increasing == false)
       increasing = true;

     if (increasing)
       x = x + 4;
     else
       x = x - 2;
 
     g2d = (Graphics2D)strategy.getDrawGraphics();
     g2d.setColor(Color.black);
     g2d.clearRect(0, 0, area.width, area.height);
     g2d.setColor(Color.red);
     g2d.fill(new Ellipse2D.Double(x, 50, 32, 32));
     
     strategy.show();
     g2d.dispose();

     deltaTime = System.currentTimeMillis() - newTime;

     while (deltaTime<(1000/FPS)){
       try {
         Thread.sleep((1000/FPS)-deltaTime);
       } catch (Exception e) {
         e.printStackTrace();
       }
       deltaTime = System.currentTimeMillis()-newTime;
     }
   }
 }
}

Well, this time it is MUCH more smooth, however the are still occasional jumps in the animation!

Could this be caused because I am running it inside an applet? Or is it just me doing something stupid again  :-/
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline karlund

Junior Newbie




Java games rock!


« Reply #10 - Posted 2005-01-10 16:05:53 »

I've made an application without an extra thread, and it was also laggy, however I changed the Thread.sleep loop to:

Thread.sleep((1000/FPS)-deltaTime / 2);

and this helped tremendously, it is now acceptable for me to go on with the actual game...

Thx for the help  Grin
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

radar3301 (12 views)
2014-09-21 23:33:17

BurntPizza (30 views)
2014-09-21 02:42:18

BurntPizza (20 views)
2014-09-21 01:30:30

moogie (20 views)
2014-09-21 00:26:15

UprightPath (28 views)
2014-09-20 20:14:06

BurntPizza (32 views)
2014-09-19 03:14:18

Dwinin (48 views)
2014-09-12 09:08:26

Norakomi (74 views)
2014-09-10 13:57:51

TehJavaDev (102 views)
2014-09-10 06:39:09

Tekkerue (50 views)
2014-09-09 02:24:56
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!