Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (539)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (603)
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  
  Challenge for everyone  (Read 2974 times)
0 Members and 1 Guest are viewing this topic.
Offline deragun

Senior Newbie




Java games rock!


« Posted 2005-03-16 20:47:54 »

If you are curious about my perspective take a look at my topic in the Java2D forum.  I order to convince myself that there is a solution to my problem (jittery and jumpy movement in animating), I issue this challenge to anyone willing to take it up:

Create and post code for a SIMPLE application that 'correctly' animates a ball moving on the screen.  The size  should be like 600 x 400, and the ball (or square or whatever) should move at a rate of 250 pixels per second in the x direction and 200 pixels per second in the y direction.  The catch is that it MUST appear as a smooth animation.  I'm trying to get a basic animation loop structure made so I can start building a game, but this has proven to be a nearly impossible for me.  I would prefer if your solution used accelerated graphics, etc.  Anyone's help would be much appreciated because I CANNOT figure out what is wrong with my code.

Thanks all.
Offline darkprophet

Senior Devvie




Go Go Gadget Arms


« Reply #1 - Posted 2005-03-16 21:09:48 »

have you tried fixing your fps? so that the calls to paint and whatnot are regular?

DP

Friends don't let friends make MMORPGs.

Blog | Volatile-Engine
Offline deragun

Senior Newbie




Java games rock!


« Reply #2 - Posted 2005-03-16 22:25:23 »

At this point I have tried: Thread.sleep(x), Thread.yield() only with time weighted movement, a combo of the two, animating on the main thread, animating on a seperate thread, using accelerated graphics, just painting a moving fillRect, and probably about 1/2 a dozen more...all of them end up with varying amounts of jittering and skipping, but none of them come close to smooth.  I have run all of these on both Win XP and Win 2000....So I've basically tried every method I could find online...that is why I am so flabbergasted by this...I know Java pretty well and it really seems that what I have written should work.  My last thought is to see someone else's very basic example and try to figure out what to do from there.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline weston

Junior Devvie





« Reply #3 - Posted 2005-03-16 23:28:43 »

I've had this problem in the past (still do really), problem seems to be that your trying to draw at fractions of pixels (if your doing time based movement) so rounding has to be done and sometimes it will move your object 2px sometimes 1px etc. The solution that was suggested to me was to use a movement rate that is a factor of your games framerate. For example, if your framerate is 50 then you should move your objects at 2/5/10/25/50 px per second. If you do this then rounding won't have to be done and you should get smooth animation. Here is an example that shows this: http://cyntaks.com/projects/wjge/test.html

the framerate is 50fps and the sprites are moving at 25px/sec everything is smooth. Now if you press 'R' then it will randomize their velocities and the movments become jittering because of the rounding I described previously.

edit: that example still isn't 'perfectly' smooth, but that is only because the game is not vsynced. If you want to see an extremely smooth java2D game, try this link: http://www.brackeen.com/javagamebook/tilegame.jnlp

edit2: other solutions: the first thing you could do is write your game to be 'tick-based' instead of time-based, no rounding will occur this way. The solution I ended up choosing (for other reasons as well) was just to use a 3D rendering api which will use the graphics card and be fast enough to use some techniques to approximate fractional pixel positions.

for(int i = 1; i > 0; i++)
{
System.out.println(i+" cups of java downed");
}
Offline tom
« Reply #4 - Posted 2005-03-17 00:14:16 »

Here is a lwjgl example of a moving ball. It is sub pixel acurate and is fairly smooth. You can still notice some bumps do to os threading. It is very difficult to make this kind of thing completely smooth. The eyes are extremely perseptive. Do a 3d scene and you don't notice it.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
import org.lwjgl.*;
import org.lwjgl.opengl.*;

public class MovingBall {
      public static void main(String args[]) throws Exception {
            try {
                  Display.setDisplayMode(new DisplayMode(640, 480));
                  Display.create();
                  GL11.glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
                  float ballx = 320;
                  float bally = 240;
                  float dirx = 250f;
                  float diry = 200f;
                  long timerFreq = Sys.getTimerResolution();
                  long lastTime = Sys.getTime();
                  while (!Display.isCloseRequested()) {
                        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
                        GL11.glLoadIdentity();
                        GL11.glTranslatef(ballx, bally, 0);
                       
                        long now = Sys.getTime();
                        double timeDelta = (now-lastTime)/(double)timerFreq;
                        lastTime = now;
                        ballx += (float)(dirx * timeDelta);
                        bally += (float)(diry * timeDelta);
                        dirx = (ballx > 640 ? -250 : dirx);
                        dirx = (ballx < 0   ?  250 : dirx);
                        diry = (bally > 480 ? -200 : diry);
                        diry = (bally < 0   ?  200 : diry);
                       
                        float radius = 30;
                        GL11.glBegin(GL11.GL_TRIANGLE_FAN);
                        GL11.glVertex3f(0, 0, 0);
                        for (int i=0; i<=64; i++) {
                              double angle = (Math.PI*2*i)/64;
                              GL11.glVertex3f((float)Math.sin(angle)*radius, (float)Math.cos(angle)*radius, 0);
                        }
                        GL11.glEnd();
                       
                        Display.update();
                        Thread.yield();
                  }
            } catch (Exception e) {
                  e.printStackTrace();
            } finally {
                  Display.destroy();      
            }
      }
}


Download lwjgl 0.95 from https://sourceforge.net/project/showfiles.php?group_id=58488. Create the file in the lwjgl-win32-0.95\lwjgl-win32-0.95 folder. Compile and run like this:
1  
2  
javac -classpath lwjgl.jar *.java
java -classpath lwjgl.jar;. MovingBall

Offline CaptainJester

JGO Knight


Medals: 12
Projects: 2
Exp: 14 years


Make it work; make it better.


« Reply #5 - Posted 2005-03-17 11:23:37 »

This works with no choppiness for me.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class MovingBall extends JPanel implements Runnable, WindowListener {
    private Dimension size = new Dimension(600, 400);
    private float x = 300;
    private float y = 200;
    private float deltaX = 250;
    private float deltaY = 200;
    private boolean running = true;
    private long lastTime, currentTime, diff;
    private Image backBuff;

    public MovingBall() {
        currentTime = System.currentTimeMillis();
        lastTime = currentTime;
        setDoubleBuffered(true);
    }
    public void run() {
        while(running) {
            currentTime = System.currentTimeMillis();
            diff = currentTime - lastTime;
            diff = (diff == 0) ? 1 : diff;
            x += (deltaX / (float)diff / 1000);
            y += (deltaY / (float)diff / 1000);
            if(x >= 580 || x <= 0) {
                deltaX = -deltaX;
            }
            if(y >= 380 || y <= 0) {
                deltaY = -deltaY;
            }
            repaint();
            Thread.yield();
            lastTime = currentTime;
        }
    }
    public void paintComponent(Graphics g) {
        g.setColor(Color.BLUE);
        g.fillRect(0,0,600,400);
        g.setColor(Color.WHITE);
        g.fillOval((int)x, (int)y, 20, 20);
    }
    public Dimension getPreferredSize() {
        return size;
    }
    public Dimension getMinimumSize() {
        return size;
    }
    public Dimension getMaximumSize() {
        return size;
    }
    
    public void windowActivated(WindowEvent arg0) {
    }
    public void windowClosed(WindowEvent arg0) {
    }
    public void windowClosing(WindowEvent arg0) {
        running = false;
        System.exit(0);
    }
    public void windowDeactivated(WindowEvent arg0) {
    }
    public void windowDeiconified(WindowEvent arg0) {
    }
    public void windowIconified(WindowEvent arg0) {
    }
    public void windowOpened(WindowEvent arg0) {
    }
    public static void main(String args[]) throws Exception {
        MovingBall mb = new MovingBall();
        Thread t = new Thread(mb);
        t.start();
        JFrame f = new JFrame();
        f.getContentPane().add(mb);
        f.addWindowListener(mb);
        f.pack();
        f.show();
    }
}


This is on P4 2.0GHz with WIndows 2000.

Will test on a slower machine later.

Offline deragun

Senior Newbie




Java games rock!


« Reply #6 - Posted 2005-03-17 15:36:13 »

These seem to be a bit better than mine, but none of them seem to be as smooth as most average Java games I have played before.  

Multiple people have suggested using a 3d scene to solve the problem...but can you create a 2d game easily this way?  My goal is to make something of a cross between pong and bubble trouble.  If a 3d api would be best for solving this problem does anyone know of a good tutorial that I could read to see how to go about doing that?

Thanks
Offline CaptainJester

JGO Knight


Medals: 12
Projects: 2
Exp: 14 years


Make it work; make it better.


« Reply #7 - Posted 2005-03-17 16:43:10 »

LWJGL is a direct binding to OpenGL.  You can use it for full 3D or also for 2D.  If you look at NeHe Lesson21, it has a complete 2D game in OpenGL.  You can also look at the Space Invaders tutorial.

Offline 20thCenturyBoy

Senior Devvie


Medals: 3


So much to learn, so little time.


« Reply #8 - Posted 2005-03-17 23:13:12 »

Windowed Java2D games will never be as smooth as full screen ones.

The Brackeen example posted above is silky smooth on my AMD64 3000+, but jerks slightly on my other P3 600.

I actually have the Brackeen book and the 2D engine he builds is pretty good and a nice example of good OOP design without getting too complicated. He uses vanilla Java2D for everything.

Basically, to get smooth animation in Java2D he does the following:

1. Use setFullScreenWindow() to enter full screen exclusive mode.

2. Use a BufferStrategy with 2 buffers. This will automatically use page flipping if the hardware supports it (which virtually all cards these days do). Page flips will synced to the monitor vertical retrace by default. If page flipping is not available it will use double-buffering, which is a lot slower.

3. Use a NullRepaintManager which catches AWT repaint requests and discards them, so they don't conflict with your own rendering.

4. Use floats for your x, y coords, not integers.

Even after doing all this you may still find motion jerky for another reason: the granularity of System.currentTimeMillis on Windows XP is  10-15ms, on Win9x it is a whopping 55ms. This means that you cannot always rely on getting precise times for your update code, which translates to jerkiness on the screen.

Brackeen gets around this by using a TimerSmootie class which averages out the values returned by the last few calls to currentTimeMillis. This results in noticeably smoother animation. However, this technique is only useful for games in which the frame rate is fairly consistent. If it varies wildly, the average values will be skewed, giving innacurate results.

It could be improved further by using a higher resolution timer, for which several alternatives exist under Windows:

1. Java 5.0 includes one, however, you might not want to force your users to Java 5.0 just for this feature.

2. The AdvancedTimer in GAGE (http://java.dnsalias.com/)

3. LWJGL has a hi-res timer.

Other stuff to think about: remember Java2D is not a games framework, it's a general purpose graphics library and hence will contain overhead. The alternative is to use something like LWJGL. This does not rely on Java2D, Swing or the AWT for events. So the overheads are a lot lower. Additionally it uses OpenGL for hardware accelerated graphics. The problem is that there is a steep learning curve if you don't know OpenGL.

"I have never done unit testing and I don’t find it a very useful concept" - Jonathan Blow
Offline CaptainJester

JGO Knight


Medals: 12
Projects: 2
Exp: 14 years


Make it work; make it better.


« Reply #9 - Posted 2005-03-18 09:43:42 »

Quote
Additionally it uses OpenGL for hardware accelerated graphics. The problem is that there is a steep learning curve if you don't know OpenGL.

If you are using OpenGL for 2D only, then the learning curve is fairly shallow.  You only need to know a few of the very basic methods.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline deragun

Senior Newbie




Java games rock!


« Reply #10 - Posted 2005-03-18 17:02:27 »

Ya know, I have looked at the space invaders tutorial.  I have even tried stripping out the basic framework of that (the accelerated graphics version not the OpenGL stuff).  However, for some reason even though the entire game runs smoothly on my machine, it becomes choppy and jumpy when I try to just animate a ball moving.  That is why this is confounding me so much.  Again I have to say...I have seen and played enough java applet games that had smooth animation that it really should be possible to achieve this without OpenGL and/or full screen mode...
Offline Kommi

Junior Devvie




All opinions will be lined up and shot!


« Reply #11 - Posted 2005-03-24 12:44:59 »

Hey 20thCenturyBoy is the book any good? How much has it helped you and in what sense? I beleive Im in a position where I know all the basics, (animation, input, rendering) but cant seem to move on to some of the more advanced stuff (making an engine as oppose to a demo). I was thinking about picking the book up, but would like to get your opinion on it.

Kommi
Offline Malohkan

Senior Devvie




while (true) System.out.println("WOO!!!!");


« Reply #12 - Posted 2005-03-24 19:58:15 »

Personally I think that you're just being too picky.  If you look at just a ball moving, you'll notice even sub-pixel non-smoothness.  When you play a real game, there's many things moving.  As a result, you don't notice the little quirks that the game DOES have.  If you can block out all other motion, which is very difficulty to do even if you're trying hard at it, you will see that those games have little non-smoothness points too.  If you're playing other games that ONLY have a ball moving, then I wanna know how in the world you find games that boring.  I don't think it's the code or the performance.  I think it's the simple fact that you notice it when there's one object, but you don't notice it when there's many.

Admin and Game Developer at
GameLizard.com
Play Rimscape!    |    Play Conquer!
Offline Kommi

Junior Devvie




All opinions will be lined up and shot!


« Reply #13 - Posted 2005-03-25 12:34:26 »

Im sure if I look at Super Metroid or Super Mario World, and look at just one aspect of motion, it will still be very smooth.

Kommi
Offline weston

Junior Devvie





« Reply #14 - Posted 2005-03-25 16:40:24 »

I think malohkan is partially right in that many games don't have perfectly smooth animation and it isn't noticed because of other parts of the game. However, I think you can get it to be pretty much perfect. I've only seen it with a few java2d apps and few more opengl apps, but it can be done!

for(int i = 1; i > 0; i++)
{
System.out.println(i+" cups of java downed");
}
Offline Kommi

Junior Devvie




All opinions will be lined up and shot!


« Reply #15 - Posted 2005-03-26 12:11:38 »

Hey Weston, I dont suppose you have a link to perfection?

Kommi
Offline java_jive

Junior Newbie




Java games rock!


« Reply #16 - Posted 2005-04-05 15:35:10 »

Heya,
   Not sure if you tried double buffering, I have not yet...i found a good article at

http://docs.rinet.ru/JaTricks/ch13.htm   Animation Techniques

If you have just ignore this... Wink
Offline java_jive

Junior Newbie




Java games rock!


« Reply #17 - Posted 2005-04-05 18:14:55 »

Came across another technique in animation, see this site

http://rsb.info.nih.gov/plasma

This guy uses java.awt.image.MemoryImageSource and lets you see his source code and how he did it.

I looked at some java games online and found a pool one which uses the above method at:

http://javaboutique.internet.com/Billiards%20Game--Pool/

This is one smooth game...I looked under covers at his class file and it is chock full of math with the most bodacious doubles imaginable.

Hope that points you in a good direction...

Cheers!
Offline weston

Junior Devvie





« Reply #18 - Posted 2005-04-06 17:26:35 »

>Hey Weston, I dont suppose you have a link to perfection?

Yeah, that link I posted earlier to brackeen's game is perfect (animation that is) in my opinion. If you want to seen an OpenGL example, just take a look at any of princec's games or perhaps even this demo (assuming it will run on your system...): http://www.cyntaks.com/projects/wjge2/WJGE2-no_audio.zip

for(int i = 1; i > 0; i++)
{
System.out.println(i+" cups of java downed");
}
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.

rwatson462 (30 views)
2014-12-15 09:26:44

Mr.CodeIt (20 views)
2014-12-14 19:50:38

BurntPizza (42 views)
2014-12-09 22:41:13

BurntPizza (76 views)
2014-12-08 04:46:31

JscottyBieshaar (37 views)
2014-12-05 12:39:02

SHC (51 views)
2014-12-03 16:27:13

CopyableCougar4 (49 views)
2014-11-29 21:32:03

toopeicgaming1999 (115 views)
2014-11-26 15:22:04

toopeicgaming1999 (105 views)
2014-11-26 15:20:36

toopeicgaming1999 (31 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

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
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!