Java-Gaming.org Hi !
Featured games (81)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
   Home   Help   Search   Login   Register   
  Show Posts
Pages: [1] 2 3 ... 9
1  Discussions / General Discussions / Re: Eclipse editor and dynamic .class/.jar reload at runtime? on: 2011-12-19 17:34:41
Thx, I was trying to find similar topic but critical failed on search criteria. I need to study my Eclipse and redefine workflow after seeing how powerful hotswap actually is.
2  Discussions / General Discussions / Eclipse editor and dynamic .class/.jar reload at runtime? on: 2011-12-18 22:21:38
This is a live video Notch programming 48h game so you might not see what I mean but here it goes.
Notch 48h Minicract live video

He is using Eclipse on Win7. When he is changing a code say color or XY offsets its seems many times he does not reload game instance. How is it happening?
3  Discussions / General Discussions / Re: Early reports on JavaFX 2 are in. on: 2011-08-03 18:56:09
The applet takes some time to load. Just have faith :3
Yes now applet was fine. My laptop Core i5 430M 2.27GHz/Mobility Radeon HD5650 1GB RAM runs it fine java.exe cpu only 10-12% load. About the video clip at the start is it .flv flash video?
4  Discussions / General Discussions / Re: Early reports on JavaFX 2 are in. on: 2011-08-03 13:45:07
Javafx2 is the bee's knees
http://www.prime.programming-designs.com/galaxy/Galaxy.html
Can I get some feedback on how awesome this is?
Embedded applet just keeps loading something, but webstart link started an application in 20 seconds. System was Win7-64bit, Firefox5.0-32bit, javafx-2_0-beta-b37-windows-i586-19_jul_2011.exe.  About the application itself....well....I saw the starfield, you(?) blabbing, heard Linkin Park = Total Awesome Experience. We the people want to see the source code.
5  Java Game APIs & Engines / Java 2D / Re: "Stuttering" in windowed mode using Java2D on: 2011-03-29 15:26:26
How can I make this simple game loop better? topic has few different game loops to compare. This message in a link is what I use nowdays. Main loop may look complex...well it is...but a good update+render logic is not the easy task.
6  Discussions / Miscellaneous Topics / Re: Check out Gaikai on: 2011-03-05 00:21:41
Just played Mass Effect 2 and Dead Space 2 games on Win7,Firefox,Java 1.6.0_24 platform. Worked great and ME2 demo delivered, so I'm going to buy ps3 bluray version now. They let play 90 mins or predefined end is reached. I can see a potential how offering easy to access demos this way. No installs, no downloads, no driver issues, no nothing. Just play a heavy weight "game video stream". Its not a state of the art 5.1 audio or resolution but get the job done for demos. Buy a full game to access premium experience.

Mass Effect 2, wait for until main page shows ME2 popup in a lower corner, then click play now.
Dead Space 2, fill in the survey and play.
Spore
SIMS 3
Second Life maps

This is jvm arguments the pass to gaikai-loader-2.1.5.jar APPLET tag. Actually DS2 html page has two applets and one flash object in a html page. During the game play java.exe process took CPU% 9-20 and 174MB ram.
[CODE]
  <param name="separate_jvm" value="true">
  <param name="java_arguments" value="-Dsun.java2d.opengl=false -Dsun.java2d.noddraw=true -Dsun.java2d.d3d=false -Dsun.awt.noerasebackground=true">
[/CODE]

I think they run a customized x264(?) encoder, which processes game framebuffer splitted to few regions. Each region is concurrently compressed of its own and streamed to the client.
7  Discussions / General Discussions / WebM decoder in Flash, yes someone was bold enough to try it on: 2011-01-14 15:52:13
http://www.bluishcoder.co.nz/2011/01/15/webm-decoder-in-flash-using-alchemy.html
http://twitter.com/UnitZeroOne
http://www.webmproject.org/code/
Quote
Ralph Hauwert has been posting on twitter about work he’s done on getting WebM decoding to work in Flash by compiling the libvpx source code using Adobe’s Alchemy technology. Alchemy is a research project that allows compilation of C and C++ libraries into code that runs on the ActionScript virtual machine used by Flash. The intial performance of a 1920x1080 VP8 video with no audio was decoding to YUV at about 1.5 frames per second.

Congrats for trying it out in ActionScript, not many want to try porting WebM video decoder to an another language.

Googling Java+WebM around gives WebM Image decoder, but not video decoders. I guess its something no real reason to do it, much much easier to plug into ffmpeg/mencoder/vlc/gstreamer binary libraries.
8  Java Game APIs & Engines / OpenGL Development / Re: Translucency 3d LWJGL/JOGL windows? on: 2010-10-17 12:00:36
Some progress, using ellipse window, AWTGLCanvas and JPanel panel components, rotating rectangles. Here is a screenshot.
http://koti.mbnet.fi/akini/lwjgl/transparentwindow1.jpeg


But it is unusable at the moment, runs very slow eating CPU 100%. Lower part jpanel is transparent but lwjgl upper part is always opaque. I guess it was not that simple to use java 3d libraries as was hoping for. Working DirectX 3d demos I've seen might do some heavy tricks, although they run super smooth and low cpu%.

[CODE]
/**
 * http://koti.mbnet.fi/akini/
 * @author Aki Nieminen
 * @version $Id$
 */
package fi.mbnet.akini.lwjgl;

import java.nio.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;

import org.lwjgl.opengl.*;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.util.glu.*;

import com.sun.awt.AWTUtilities;

/**
 * Test translucent Java window
 * http://www.java-gaming.org/topics/translucency-3d-lwjgl-jogl-windows/23127/view.html
 */
public class AWTTest extends Frame {
   private Thread renderThread;
   private GameCanvas canvas;
   private FooPanel panel;

   public void initialize() throws LWJGLException {
      setUndecorated(true);
      setBackground(new Color(0,0,0,0));
      setTitle("AWTTest");
      setSize(640, 480);
      setLocation(40,40);

      setLayout(new GridLayout(2,1));

      canvas = new GameCanvas();
      add(canvas);

      panel = new FooPanel();
      add(panel);

      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent evt) {
            try {
               renderThread.interrupt();
               renderThread.join(5*1000);
               // set to opaque or window area may show garbage
               Shape shape = new Rectangle(0, 0, getWidth(), getHeight());
               AWTUtilities.setWindowShape(AWTTest.this, shape);
               AWTUtilities.setWindowOpaque(AWTTest.this, true);
            } catch (Exception ex) { }
            renderThread = null;
            dispose();
         }
      });

      addComponentListener(new ComponentAdapter() {
         public void componentShown(ComponentEvent evt) {
            if (!AWTUtilities.isWindowOpaque(AWTTest.this))
               return;
            AWTUtilities.setWindowOpaque(AWTTest.this, false);
            System.out.println("setWindowOpaque=false");

         }
         public void componentMoved(ComponentEvent evt) {
            canvas.isInitialized = false;
            System.out.println( String.format("moved to %d,%d"
               , getX(), getY()
            ));
         }
         public void componentResized(ComponentEvent evt) {
            //Shape shape = new Rectangle(0, 0, getWidth(), getHeight());
            Shape shape = new Ellipse2D.Float(0, 0, getWidth(), getHeight());
            AWTUtilities.setWindowShape(AWTTest.this, shape);

            canvas.isInitialized = false;
            System.out.println( String.format("resized to %d,%d"
               , getWidth(), getHeight()
            ));
         }
      });

      // add same listeners to frame and canvas objects
      addKeyListener(new KeyAdapter() {
         public void keyReleased(KeyEvent evt) {
            switch(evt.getKeyCode()) {
            case KeyEvent.VK_ESCAPE:
               Frame frm = AWTTest.this;
               frm.dispatchEvent(new WindowEvent(frm, WindowEvent.WINDOW_CLOSING));
               break;
            }
         }
      });
      for(KeyListener listener : getKeyListeners()) {
         canvas.addKeyListener(listener);
      }
   
      renderThread = new Thread(new Runnable() {
         public void run() {
            while(true) {
               try {
                  Thread.sleep( (long)1000/15 );
                  panel.update();
                  canvas.update();
                  //panel.repaint();
                  //canvas.repaint();
                  AWTTest.this.repaint();
               } catch (InterruptedException ex) {
                  break;
               } catch (Exception ex) {
                  ex.printStackTrace();
                  //break;
               }
            }
         }
      });
      renderThread.start();
   }

//************************************************************
//************************************************************

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            AWTTest test = new AWTTest();
            try {
               test.initialize();
               test.setResizable(true);
               test.setVisible(true);
            } catch (Exception ex) {
               ex.printStackTrace();
            }
         }
      });
   }

//************************************************************
//************************************************************

   private class GameCanvas extends AWTGLCanvas {
      private int curHeight = -1;
      private int curWidth = -1;
      private volatile float angle;
      private volatile boolean isInitialized;

      private GameCanvas() throws LWJGLException  {
         super();
      }

      private void initialize() {
         System.out.println("initialize");
         curWidth  = getWidth();
         curHeight = getHeight();
         GL11.glViewport(0, 0, curWidth, curHeight);
         GL11.glLoadIdentity();
         GLU.gluOrtho2D(0.0f, (float)curWidth, 0.0f, (float)curHeight);
         GL11.glMatrixMode(GL11.GL_MODELVIEW);
      }

      public void update() {
         angle += 2.0f;
      }

      public void paintGL() {
         try {
            //if (getWidth() != curWidth || getHeight() != curHeight) {
            if (!isInitialized) {
               initialize();
               isInitialized = true;
            }

            // clear background
            GL11.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

            // rotate box at a center
            GL11.glPushMatrix();
            GL11.glColor3f(1f, 1f, 0f);
            GL11.glTranslatef((float)curWidth / 2.0f, (float)curHeight / 2.0f, 0.0f);
            GL11.glRotatef(angle, 0f, 0f, 1.0f);
            GL11.glRectf(-50.0f, -50.0f, 50.0f, 50.0f);
            GL11.glPopMatrix();

            swapBuffers();
         } catch (Exception ex) {
            throw new RuntimeException(ex);
         }
      }
   }


//************************************************************
//************************************************************

   private class FooPanel extends JPanel {
      double angle = 0;
      private void update() {
         angle += 2;
         if (angle >= 360) angle = 0;
      }

      protected void paintComponent(Graphics g) {
         final int R = 040;
         final int G = 140;
         final int B = 240;
         Paint p = new GradientPaint(0.0f, 0.0f,
            new Color(R, G, B, 0),
            getWidth(), getHeight(),
            new Color(R, G, B, 255),
            false
         );
         Graphics2D g2d = (Graphics2D)g;
         g2d.setPaint(p);
         g2d.fillRect(0, 0, getWidth(), getHeight());

         g2d.setColor(new Color(150,60,170,127));
         g2d.rotate(Math.toRadians(angle), getWidth()/2, getHeight()/2);
         g2d.translate(getWidth()/2-100, getHeight()/4-40);
         g2d.fillRect(50, 50, 100, 100);
      }
   }

}
[/CODE]
9  Java Game APIs & Engines / OpenGL Development / Re: Translucency 3d LWJGL/JOGL windows? on: 2010-10-16 17:17:29
I gave a test LWJGL-2.6 library, could not get it work. Trying to run a simple 3d animation with fully transparent background. Animation objects may have 0-100% translucency pixels.

AWTUtilities.setWindowOpaque(this, false);
If I give true its a normal undecored window and animation works properly. Giving false seems to render nothing and window is like a ghost. Its there but not really shown anything.

[CODE]
package fi.mbnet.akini.lwjgl;

import java.nio.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;

import org.lwjgl.opengl.*;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.util.glu.*;

import com.sun.awt.AWTUtilities;

public class AWTTest extends Frame {
   private Thread renderThread;
   private GameCanvas canvas;

   public void initialize() throws LWJGLException {
      setUndecorated(true);
      setBackground(new Color(0,0,0,0));
      setTitle("AWTTest");
      setSize(640, 480);
      setLocation(40,40);

      // true  = opaque undecored window works
      // false = per-pixel transparency window does not work
      AWTUtilities.setWindowOpaque(this, false);

      setLayout(new GridLayout(1,1));

      canvas = new GameCanvas();
      add(canvas);

      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent evt) {
            try {
               renderThread.interrupt();
               renderThread.join(5*1000);
            } catch (Exception ex) { }
            renderThread = null;
            dispose();
         }
      });

      addComponentListener(new ComponentAdapter() {
         public void componentMoved(ComponentEvent evt) {
            canvas.isInitialized = false;
            System.out.println( String.format("moved to %d,%d", getX(), getY()) );
         }
         public void componentResized(ComponentEvent evt) {
            Shape shape = new Rectangle(0, 0, getWidth(), getHeight());
            //Shape shape = new Ellipse2D.Float(0, 0, getWidth(), getHeight());

            AWTUtilities.setWindowShape(AWTTest.this, shape);

            canvas.isInitialized = false;
            System.out.println( String.format("resized to %d,%d", getWidth(), getHeight()) );
         }
      });

      // add same listeners to frame and canvas objects
      addKeyListener(new KeyAdapter() {
         public void keyReleased(KeyEvent evt) {
            switch(evt.getKeyCode()) {
            case KeyEvent.VK_ESCAPE:
               Frame frm = AWTTest.this;
               frm.dispatchEvent(new WindowEvent(frm, WindowEvent.WINDOW_CLOSING));
               break;
            }
         }
      });
      for(KeyListener listener : getKeyListeners())
         canvas.addKeyListener(listener);
   
      renderThread = new Thread(new Runnable() {
         public void run() {
            while(true) {
               try {
                  Thread.sleep( (long)1000/60 );
                  canvas.update();
                  canvas.repaint();
               } catch (InterruptedException ex) {
                  break;
               } catch (Exception ex) {
                  ex.printStackTrace();
                  //break;
               }
            }
         }
      });
      renderThread.start();
   }

//************************************************************
//************************************************************

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            AWTTest test = new AWTTest();
            try {
               test.initialize();
               test.setResizable(true);
               test.setVisible(true);
            } catch (Exception ex) {
               ex.printStackTrace();
            }
         }
      });
   }

//************************************************************
//************************************************************

   private class GameCanvas extends AWTGLCanvas {
      private int curHeight = -1;
      private int curWidth = -1;
      private volatile float angle;
      private volatile boolean isInitialized;

      private GameCanvas() throws LWJGLException  {
         super();
      }

      private void initialize() {
         System.out.println("initialize");
         curWidth  = getWidth();
         curHeight = getHeight();
         GL11.glViewport(0, 0, curWidth, curHeight);
         GL11.glLoadIdentity();
         GLU.gluOrtho2D(0.0f, (float)curWidth, 0.0f, (float)curHeight);
         GL11.glMatrixMode(GL11.GL_MODELVIEW);
      }

      public void update() {
         angle += 2.0f;
      }

      public void paintGL() {
         try {
            //if (getWidth() != curWidth || getHeight() != curHeight) {
            if (!isInitialized) {
               initialize();
               isInitialized = true;
            }

            // clear background
            GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

            // rotate box at a center
            GL11.glPushMatrix();
            GL11.glColor3f(1f, 1f, 0f);
            GL11.glTranslatef((float)curWidth / 2.0f, (float)curHeight / 2.0f, 0.0f);
            GL11.glRotatef(angle, 0f, 0f, 1.0f);
            GL11.glRectf(-50.0f, -50.0f, 50.0f, 50.0f);
            GL11.glPopMatrix();

            swapBuffers();
         } catch (Exception ex) {
            throw new RuntimeException(ex);
         }
      }
   }

}
[/CODE]
10  Java Game APIs & Engines / OpenGL Development / Re: Translucency 3d LWJGL/JOGL windows? on: 2010-10-15 17:17:12
Thx, do anyone has or know a simple demo JOGL application doing it?
Would love to see LWJGL demo as well if its capable of doing it.
11  Java Game APIs & Engines / OpenGL Development / Translucency 3d LWJGL/JOGL windows? on: 2010-10-15 08:52:21
JDK6 has an unofficial translucency window API and JDK7 supposed to give a public API.
http://download.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html
http://java.sun.com/developer/technicalArticles/GUI/translucent_shaped_windows/
http://www.curious-creature.org/2007/09/28/translucent-shaped-windows-extreme-gui-makeover/

Demos works fine in WinXP/Win7 machine, applications use Java2D rendering. I have not tried animated j2d windows yet how its working.

But is there a way use LWJGL or JOGL app pixel-perfect translucent windows?

I have seen some DirectX 3d animated demos doing it so technically its possible in Windows.
12  Discussions / General Discussions / Re: JavaFX is *officially* dead! on: 2010-10-01 15:52:46
Well, actually that's a good thing.  I didn't like the development effort being split as it was rather than feeding effort into the existing framework.  Video in Swing is awesome, as you say

I found a test application from the internet, its using JavaFX jmc.jar and jmc.dll libraries. Running on Windows it can play any file supported by DirectX filters. Test application draws a simple overlay graphics. It works but what makes it almost unusable is a very very bad video rendering quality. Maybe am spoiled by EVRRenderer filter quality but this specific issue is where JavaFX video support must do better.

Flash is able to blend sprites, transparent drawings and h264 video rendering with decent rendering quality. I am looking for what Oracle does here.

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  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
205  
206  
207  
208  
209  
210  
211  
212  
213  
214  
215  
216  
217  
218  
219  
220  
221  
222  
223  
224  
225  
226  
227  
228  
229  
230  
231  
232  
233  
234  
235  
[ testvideo.bat script ]
  set file=c:/test/testvideo.mp4
  java.exe -cp ./lib/test.jar;./lib/jmc.jar -Djava.library.path=./lib   XMP2   %file%



[ XMP2.java ]

// XMP2 (eXperimental Media Player #2).java
// javajeff.mb.ca

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.awt.geom.Rectangle2D;

import java.net.URI;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.sun.media.jmc.MediaProvider;

import com.sun.media.jmc.control.AudioControl;
import com.sun.media.jmc.control.VideoRenderControl;

import com.sun.media.jmc.event.VideoRendererEvent;
import com.sun.media.jmc.event.VideoRendererListener;

public class XMP2 extends JFrame
{
  MediaProvider mp;

  public XMP2 (String mediaURI)
  {
   super ("XMP2: "+mediaURI);
   setDefaultCloseOperation (EXIT_ON_CLOSE);

   try {
     mp = new MediaProvider(new URI(mediaURI));
   } catch (Exception e) {
     System.out.println("Error opening media: "+e.toString ());
     System.exit (1);
   }

   JPanel panel = new JPanel ();
   panel.setLayout (new BorderLayout ());
   panel.add (new MediaPanelXMP2(mp), BorderLayout.CENTER);
   panel.add (createControlPanel (), BorderLayout.SOUTH);

   setContentPane (panel);

   pack ();
   setVisible (true);
  }

  public JPanel createControlPanel ()
  {
   JPanel panel = new JPanel ();

   JButton btnPlay = new JButton ("Play");
   ActionListener alPlay = new ActionListener ()
               {
                 public void actionPerformed (ActionEvent ae)
                 {
                   mp.play ();
                 }
               };
   btnPlay.addActionListener (alPlay);
   panel.add (btnPlay);

   JButton btnPause = new JButton ("Pause");
   ActionListener alPause = new ActionListener ()
                {
                  public void actionPerformed (ActionEvent ae)
                  {
                   mp.pause ();
                  }
                };
   btnPause.addActionListener (alPause);
   panel.add (btnPause);

   JButton btnStop = new JButton ("Stop");
   ActionListener alStop = new ActionListener ()
               {
                 public void actionPerformed (ActionEvent ae)
                 {
                   mp.pause ();
                   mp.setMediaTime (0.0);
                 }
               };
   btnStop.addActionListener (alStop);
   panel.add (btnStop);

   JCheckBox cbMute = new JCheckBox ("Mute");
   ChangeListener clMute = new ChangeListener ()
               {
                 public void stateChanged (ChangeEvent ce)
                 {
                   JCheckBox cb;
                   cb = (JCheckBox) ce.getSource ();
                   AudioControl ac;
                   ac = mp.getControl (AudioControl.class);
                   ac.setMute (cb.isSelected ());
                 }
               };
   cbMute.addChangeListener (clMute);
   panel.add (cbMute);

   panel.add (new JLabel ("Duration: "+mp.getDuration ()));

   return panel;
  }

  public static void main (final String [] args) throws Exception {
   if (args.length != 1)
   {
     System.err.println ("usage: java XMP2 mediaURI");
     return;
   }

   final String file = args[0].trim().replace('\\', '/');

   Runnable r = new Runnable ()
          {
            public void run ()
            {
             new XMP2(file);
            }
          };
   EventQueue.invokeLater (r);
  }
}

class MediaPanelXMP2 extends JPanel
{
  private AlphaComposite ac1 =
   AlphaComposite.getInstance (AlphaComposite.SRC_OVER, 0.1f);

  private AlphaComposite ac2 =
   AlphaComposite.getInstance (AlphaComposite.SRC_OVER, 0.3f);

  private AlphaComposite ac3 =
   AlphaComposite.getInstance (AlphaComposite.SRC_OVER, 0.6f);

  private Dimension frameSize;

  private Font font = new Font ("Arial", Font.BOLD, 16);

  private Rectangle frame = new Rectangle (0, 0, 0, 0);

  private Rectangle2D r2d = new Rectangle2D.Double (0.0, 0.0, 0.0, 0.0);

  private VideoRenderControl vrc;

  MediaPanelXMP2(MediaProvider mp) {
   vrc = mp.getControl(VideoRenderControl.class);
   if (vrc == null) {
     System.err.println ("no video renderer control");
     System.exit (-1);
   }
   frameSize = vrc.getFrameSize ();
   VideoRendererListener vrl;
   vrl = new VideoRendererListener ()
      {
        public void videoFrameUpdated (VideoRendererEvent vre)
        {
          repaint ();
        }
      };
   vrc.addVideoRendererListener (vrl);
   setPreferredSize (new Dimension (frameSize.width/2, frameSize.height/2));
  }

  protected void paintComponent(Graphics g)
  {
   frame.width = getWidth();
   frame.height = getHeight();
   vrc.paintVideoFrame(g, frame);

   double ar1 = frame.width/(double) frameSize.width;
   double ar2 = frame.height/(double) frameSize.height;

   double x, y;

   if (ar1 < ar2)
   {
     x = (frame.width-frameSize.width*ar1)/2+10.0;
     y = (frame.height-frameSize.height*ar1)/2+10.0;
   }
   else
   {
     x = (frame.width-frameSize.width*ar2)/2+10.0;
     y = (frame.height-frameSize.height*ar2)/2+10.0;
   }
   
   //x = y = 10;

   Graphics2D g2d = (Graphics2D) g;
   g2d.setRenderingHint (RenderingHints.KEY_ANTIALIASING,
              RenderingHints.VALUE_ANTIALIAS_ON);

   g2d.setComposite (ac2);
   g2d.setPaint (Color.black);
   r2d.setFrame(x, y, 125.0, 50.0);
   g2d.fill(r2d);

   g2d.setComposite(ac3);
   g2d.setPaint (Color.blue);
   r2d.setFrame( (frame.width/2)-(125/2), (frame.height/2)-(50/2), 125.0, 50.0);
   g2d.fill(r2d);

   g2d.setComposite (ac2);
   g2d.setFont (font);
   g2d.setPaint (Color.yellow);
   g2d.drawString ("javajeff.mb.ca", (int) x+10, (int) y+30);
  }
}
13  Discussions / General Discussions / Re: annoying gaps playing Java2D games on: 2010-04-24 09:14:16
Have anyone suffered from this??
Yes, see few topics about the same issue. Maybe gives you some ideas to try.
see this smooth scroll topic
simple game loop
14  Discussions / General Discussions / Re: Cortado works! on: 2010-04-23 20:06:43
Has anyone tried this library?
http://www.mat.ucsb.edu/~a.forbes/PROCESSING/jmcvideo/jmcvideo.html  'the Java openGL bindings' they mean JOGL.
I downloaded and tried it, maybe its my +4 year old laptop with ancient OGL driver but it was not a fast playback. Must copy files to a desktop machine when at home and try again. Anyway, functionality point of view it does work and am slightly impressed.

Running demos was a pain first as I know nothing about Processing toolkit. Its a some sort of simplified programming language and graphics runtime environment running on Java. It has some very nice graphics demos, I recommend try it out.

This is what I did.
WindowsXP, Java6
* download processing 1.1 without java
* uninstall to c:/projects/processing-1.1
* git clone jmcvideo project to have sources and dependency libraries
* copy jmcvideo folder from jmcvideo.git/processing/libraries_windows/*  to processing-1.1/libraries/ folder
* download jmcvideo.jar v1.2 and overwrite old jar in a processing-1.1/libraries/jmcvideo/library/
* download few demos from jmcvideo site and unzip to c:/projects/examples/ folder
* run processing IDE and load .pde scripts

I tried few mpeg2, .mp4 and .mkv files. WMVPro video files was audio only and ocassionally crashed. Image quality is not that great but maybe I am spoiled with my DirectX EVR renderer Delphi players.
15  Java Game APIs & Engines / JOGL Development / Re: Catch 22 for jogl on: 2010-03-30 22:07:17
S With Jogl 1.x feature frozen at GL3.0 with many outstanding bugs, and Jogl 2.x perpetually in homeless beta you'd have a hard time justifying picking Jogl for any serious project.
Why is it LWJGL wrapper is able to follow bleeding edge OpenGL specs so fast. It does not have a massive budget or labour man hours. Is/Has always been JOGL just a homeless child within (ex)Sun?
16  Game Development / Shared Code / Re: Smooth scroll on: 2010-03-30 01:31:18
Thought I'd share the code for my smooth scrolling game loop:

We had a similar topic last year, evaluating few gameloops. What I prefer is a game loop that does not eat 100% CPU. After all most java games a small "flash" games so should behave well.


I run a test through your code, but added Thread.sleep(10) to yield a cpu. Animation was still quite good.
Quote
                // Delay for a period of time equal to 1/60th of a
                // second minus the elapsed time
      Thread.sleep(10);
                elapsedTime = System.nanoTime() - time;
                delayTime = 1000000000L/60 - elapsedTime;
                time = System.nanoTime();
                while( System.nanoTime() - time <= delayTime)
                    ;
17  Game Development / Shared Code / Re: Priobit (lowlevel NIO Wrapper) on: 2010-01-31 12:13:28
(pump up)
Topic title needs a refresh, project's current name is Pyronet  Grin Good name if you ask me.
18  Discussions / General Discussions / Re: Are CPUs becoming redundant for games? on: 2010-01-26 01:06:07
Onlive and Gaikai game streaming services are a hot topic atm. Nice x264-dev blog about the use of (almost) lag free video compression. x264-dev developer is (indirectly) saying he provided a working implementation to Gaikai service. He is not grazy about Onlive variation.

It seems to work and should provide an excellent experience on certain game genres, such as RTS, Laser Squad Nemesis and point&click games. Imagine, you at the hotel with a crappy work laptop and want to play few rounds of Starcraft. Gaikai may give you that within a year or two. Only big question is do they find a working business model and subscription fees.

From the publisher point of view, the end of pirating and 2nd hand Gamestop game sells.
19  Discussions / Miscellaneous Topics / Re: Wasting my life programming ? on: 2010-01-17 23:26:34
My next challenge is to create a proper video player, we'll if my Java skills are wasted and must take Delphi/C++ compiler.
20  Discussions / General Discussions / Re: Chris (NOT CHRISM) leaving sun (and moderator at jgo?) on: 2010-01-17 11:15:24
Probably not a foolproof unless an avatar generator tries to study a name for longer time period. Say it takes my name only when an activity list was considered " a stable snapshot". A method I described is just about only solution I can think of to that kind of dynamic avatars.

About the IP address use case I don't think Riven does it, generator just returns a new image each time its reloaded. Simple and "works close enough" implementation, we really don't pay attension to an avatar...except for now on Riven's avatar is always under a radar.

edit:
Riven is using this URL to list an active users, this page shows a topic each user is reading atm. Combine that to a referer header and we have a pretty accurate dynamic avatar.
http://www.java-gaming.org/index.php?action=who
21  Discussions / General Discussions / Re: Chris (NOT CHRISM) leaving sun (and moderator at jgo?) on: 2010-01-16 23:58:24
People just assume that I have access to stuff! I wish! Cookies, the database...
Ok, I made some silly testings. JGO links give a referer header and thats about all another site see from "us". See below how referer might look. But I think does not give any meaninful data about the active user.
http://www.java-gaming.org/topics/scenegraph-api-in-shoot-emup-game/8664/msg/75099/view.html

So I went to a main page and there it is, look at the end of page it has a Users Online sorted by an activity timestamp section. That's where Riven's avatar steals a name. Maybe avatar generator then remembers who is who by an IP address knowing to return a same generated gif. I did not see cookies travelling to Riven's avatar site to identify my avatar session.

edit:
This link lists an activity by names and topic, combine that to a referer header and accuracy is good.
http://www.java-gaming.org/index.php?action=who
22  Java Game APIs & Engines / Java 2D / Re: Work-around for no Vsync in windowed mode? on: 2009-09-26 22:10:14
There's already vsync support in the jdk (as of 6u10 or so), but only signed apps will be able to use it (it involves the use of a private BufferCapabilities subclass): http://hg.openjdk.java.net/jdk7/2d/jdk/file/a389af17df10/src/share/classes/sun/java2d/pipe/hw/ExtendedBufferCapabilities.java
Do a singed application apply to applets/webstart apps only? Or do I must sign a standalone applications as well, I think its not necessary right?

What comes to the to-be-or-not public api debate. Well is it so much a problem if some systems cannot use it. Graphics and game developers are used to it anyway each gfx cards have own issues to tackle. Publish it with a disclaimer it may not work so check for capability mode after setting it.

I had a need to program a silk smooth image scroller, from right to left, in windowed application and eating <5% cpu. It was a mission impossible in Java, cpu was ok but animation was not even close to an acceptable level. In the end had to use Delphi and directx application :-(

Maybe this private api could have helped me. I must take time create a test program someday and see if there is still hope in Java.

thx.
23  Game Development / Shared Code / Re: Convenient NIO Wrapper + even more convenience stuff on: 2009-06-29 11:13:52
Thx and verified both Time* and Chat* examples work now. I study and experiment more with the wrapper classes.

ps: I think "protected NioReadStrategy defaultStrategy = NioReadStrategy.READ_CALLBACK;" field is obsolete now in NioClient class.
24  Game Development / Shared Code / Re: Convenient NIO Wrapper + even more convenience stuff on: 2009-06-28 17:28:36
Thx, I cleared a browser cache and was able to save an updated http://www.katav.nl/html_stuff2/jars/jawnae.jar file. Firefox and/or webserver is unable to give changed .jar file for some reason.

TimeServer-Client test works ok out of the box. But ChatServer-client test app does nothing, however it did not crash anymore Smiley It seems server-side does not trigger packetReceived handler.
25  Game Development / Shared Code / Re: Convenient NIO Wrapper + even more convenience stuff on: 2009-06-28 15:58:44
Before I read your reply I managed to implement this version. I do however download an updated code and continue experimenting with your NIO wrapper. I like the packet approach its so much easier to create application logic such as sending short xml messages.

What is it loop(client) call you prefer, I am now a bit lost of whether to use .register(client) call once or loop(client). Any suggestions?

NioTcpTimeClient.java
[CODE]
package test.jawnae.net2;

import java.io.IOException;
import java.net.InetSocketAddress;

import jawnae.net2.*;

public class NioTcpTimeClient {
   public static final String HOST = "127.0.0.1";
   public static final int    PORT = 8421;

   public static void main(String[] args) throws IOException {
      final ReadCallback callback = new PacketCallback() {
         @Override
         public void received(byte[] payload) {
            System.out.println("Received: " + new String(payload));
         }
      };

      NioNetworkHandler handler1 = new NioNetworkLogger();
      NioNetworkHandler handler2 = new NioNetworkExtendableHandler(handler1) {
         @Override
         public NioReadStrategy connectedClient(NioClient client) {
            System.out.println("connectedClient: " + client);
            super.connectedClient(client);
            return NioReadStrategy.READ_CALLBACK;
         }

         @Override
         public void receivedBytes(NioClient client, int bytes) {
            System.out.println("receivedBytes: " + bytes);
            callback.register(client);
         }
      };

      NioNetwork network = new NioNetwork(handler2);

      network.connect(new InetSocketAddress(HOST, PORT));

      while (true) {
         network.select();
      }
   }

}
[/CODE]

edit: and should I download all individual files from http://www.katav.nl/html_stuff2/ page or plan on releasing a zip build?
thx.

edit: And I think previous fix does not fix the original problem, my very limited understanding of the code logic indicates its NioClient.registerReadCallback method should use a default strategy. Or maybe better a way earlier should default stragegy be initialized.
26  Game Development / Shared Code / Re: Convenient NIO Wrapper + even more convenience stuff on: 2009-06-28 14:35:42
I downloaded sources from http://www.katav.nl/html_stuff2/jars/jawnae.jar link and tried NioTcpTimerServer/Client examples.

Soon as client is started both parties throw an exception. Quick look indicates its server crashing due to a NioReadStrategy attribute being a NULL. Same error applies to ChatClient/Server example. Do you have a working examples?

This is what I modified but how can I read incoming reply packets from the server?

NioTcpTimeServer.java
[CODE]
package test.jawnae.net2;

import java.io.IOException;
import java.net.InetSocketAddress;

import jawnae.net2.*;

public class NioTcpTimeServer {
   public static final String HOST = "127.0.0.1";
   public static final int    PORT = 8421;

   public static void main(String[] args) throws IOException {
      final NioNetworkHandler handler = new NioNetworkAdapter() {
         @Override
         public NioReadStrategy acceptedClient(NioClient client) {
            System.out.println("acceptedClient: " + client);
            return NioReadStrategy.READ_CALLBACK;
         }
      };

      final NioNetwork network = new NioNetwork(handler);

      final NioServer server = network.listen(new InetSocketAddress(HOST, PORT));

      final long selectTimeout = 1000;
      final long broadcastInterval = 5000;
      long lastSent = 0;

      // post timestamp every 5 secs to all registered clients
      while (true) {
         network.select(selectTimeout);

         final long now = System.currentTimeMillis();

         if (now - lastSent < broadcastInterval)
            continue;

         String text = "Server time: " + now;
         byte[] data = text.getBytes();

         Packet p = new Packet(data);
         for (NioClient client : server) {
            p.sendTo(client);
         }

         lastSent = now;
      }
   }
}
[/CODE]

NioTcpTimeClient.java
[CODE]
package test.jawnae.net2;

import java.io.IOException;
import java.net.InetSocketAddress;

import jawnae.net2.*;

public class NioTcpTimeClient {
   public static final String HOST = "127.0.0.1";
   public static final int    PORT = 8421;

   public static void main(String[] args) throws IOException {
      NioNetworkHandler handler1 = new NioNetworkLogger();
      NioNetworkHandler handler2 = new NioNetworkExtendableHandler(handler1) {
         @Override
         public NioReadStrategy connectedClient(NioClient client) {
            System.out.println("connectedClient: " + client);
            super.connectedClient(client);
            return NioReadStrategy.READ_CALLBACK;
         }

         @Override
         public void receivedBytes(NioClient client, int bytes) {
            System.out.println("receivedBytes: " + client  + ", len: " + bytes);
         }
      };

      NioNetwork network = new NioNetwork(handler2);

      network.connect(new InetSocketAddress(HOST, PORT));

      while (true) {
         network.select();
      }
   }

}
[/CODE]
27  Game Development / Networking & Multiplayer / Re: Eliminating jitter on: 2009-05-16 12:33:08
double-post
28  Game Development / Networking & Multiplayer / Re: Eliminating jitter on: 2009-05-16 12:30:50
I more or less disagree, pure Java2D is a way too hard close to impossible for a smooth windowed animations. BufferStrategy drawing is a some help but not even close to a year 2009 quality.

See this topic about a game loop it has some game loop approaches and none satisfies me. But maybe I am spoiled by windowed Direct3D vsync app with cpu affinity masked to a single core.

I don't have an answer how Java should handle a multicore timer issue, probably use a customized timer.dll.
29  Game Development / Performance Tuning / Re: How can I make this simple game loop better? on: 2009-05-12 19:24:29
Upper-left corner FPS counter was my debug value. When I posted my example code it printed run +90 fps but now I run it again. Its a steady 60-63 fps value. Go figure what was wrong last time, strange. So we come to a conclusion fps calc works after all :-)

I know and have done few native D3D apps they run fine windowed vsync lock. Its so nice a windowed non-tearing rendering loop, triple buffered flips and low cpu% usage.

Here is an another game loop borrowed from a forum post. Loop animation does not rely on a delta time but each updateWorld() call is one animation frame to be simulated. Slower machines drop renderFPS but loop tries to keep up to a updateFPS. I think it is a bit more consistent fps, but tearing is still visible. About "Toolkit.getDefaultToolkit().sync()" method I think we can forget 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  
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  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
192  
193  
194  
195  
196  
197  
198  
199  
200  
201  
202  
203  
204  
205  
206  
207  
208  
209  
210  
211  
212  
213  
214  
215  
216  
217  
218  
219  
220  
221  
222  
223  
224  
225  
226  
227  
228  
229  
230  
231  
232  
233  
// java GameLoop2 "fullscreen=true" "fps=60" "vsync=false"
//http://www.java-gaming.org/topics/how-can-i-make-this-simple-game-loop-better/19971/view.html

import java.util.*;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferStrategy;

import java.awt.DisplayMode; // for full-screen mode

// java GameLoop2 "fullscreen=true" "fps=60" "vsync=false"
public class GameLoop2 implements KeyListener {
    Frame mainFrame;

    private static final long NANO_IN_MILLI = 1000000L;  

    // num of iterations with a sleep delay of 0ms before
    // game loop yields to other threads.
    private static final int NO_DELAYS_PER_YIELD = 16;

    // max num of renderings that can be skipped in one game loop,
    // game's internal state is updated but not rendered on screen.
    private static int MAX_RENDER_SKIPS = 5;

    private static int TARGET_FPS = 60;
   
    //private long prevStatsTime;
    private long gameStartTime;
    private long curRenderTime;
    private long rendersSkipped = 0L;
    private long period; // period between rendering in nanosecs

    long fps;
    long frameCounter;
    long lastFpsTime;
   
    Rectangle2D rect;
   
    public GameLoop2(Map<String,String> args, GraphicsDevice device) {
        try {
            if (args.containsKey("fps"))
              TARGET_FPS = Integer.parseInt(args.get("fps"));


            // Setup the frame
            GraphicsConfiguration gc = device.getDefaultConfiguration();
           
            mainFrame = new Frame(gc);
            mainFrame.setUndecorated(true);
            mainFrame.setIgnoreRepaint(true);
            mainFrame.setVisible(true);
            mainFrame.setSize(640, 480);
            //mainFrame.setLocationRelativeTo();
            mainFrame.setLocation(100,100);
            mainFrame.createBufferStrategy(2);
            mainFrame.addKeyListener(this);

            if ("true".equalsIgnoreCase(args.get("fullscreen"))) {
              device.setFullScreenWindow(mainFrame);
              device.setDisplayMode(new DisplayMode(640, 480, 8, DisplayMode.REFRESH_RATE_UNKNOWN));
            }
         
            final boolean VSYNC = "true".equalsIgnoreCase(args.get("vsync"));

            // Cache the buffer strategy and create a rectangle to move
            BufferStrategy bufferStrategy = mainFrame.getBufferStrategy();
            rect = new Rectangle2D.Float(0,100,64,64);

            // loop initialization
            long beforeTime, afterTime, timeDiff, sleepTime;
            long overSleepTime = 0L;
            int noDelays = 0;
            long excess = 0L;
            gameStartTime = System.nanoTime();
            //prevStatsTime = gameStartTime;
            beforeTime = gameStartTime;
     
            period = (1000L*NANO_IN_MILLI)/TARGET_FPS;  // rendering FPS (nanosecs/targetFPS)
            System.out.println("FPS: " + TARGET_FPS + ", vsync=" + VSYNC);
            System.out.println("FPS period: " + period);
           

            // Main loop
            while(true) {
               // **2) execute physics
               updateWorld(0);              

               // **1) execute drawing
               Graphics g = bufferStrategy.getDrawGraphics();
               drawScreen(g);
               g.dispose();

               // Synchronise with the display hardware. Note that on
               // Windows Vista this method may cause your screen to flash.
               // If that bothers you, just comment it out.
               if (VSYNC) Toolkit.getDefaultToolkit().sync();

               // Flip the buffer
               if( !bufferStrategy.contentsLost() )
                   bufferStrategy.show();

               afterTime = System.nanoTime();
               curRenderTime = afterTime;
               calculateFramesPerSecond();

               timeDiff = afterTime - beforeTime;
               sleepTime = (period-timeDiff) - overSleepTime;
               if (sleepTime > 0) { // time left in cycle
                  //System.out.println("sleepTime: " + (sleepTime/NANO_IN_MILLI));
                  try {
                     Thread.sleep(sleepTime/NANO_IN_MILLI);//nano->ms
                  } catch(InterruptedException ex){}
                  overSleepTime = (System.nanoTime()-afterTime) - sleepTime;
               } else { // sleepTime <= 0;
                  System.out.println("Rendering too slow");
                  // this cycle took longer than period
                  excess -= sleepTime;
                  // store excess time value
                  overSleepTime = 0L;
                  if (++noDelays >= NO_DELAYS_PER_YIELD) {
                     Thread.yield();
                     // give another thread a chance to run
                     noDelays = 0;
                  }
               }
           
               beforeTime = System.nanoTime();
         
               //If the rendering is taking too long, then
               //update the game state without rendering
               //it, to get the UPS nearer to the required frame rate.
               int skips = 0;
               while((excess > period) && (skips < MAX_RENDER_SKIPS)) {
                  // update state but don’t render
                  System.out.println("Skip renderFPS, run updateFPS");
                  excess -= period;
                  updateWorld(0);
                  skips++;
               }
               rendersSkipped += skips;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            device.setFullScreenWindow(null);
        }
    }

    private void updateWorld(long elapsedTime) {
        // speed: 150 pixels per second
        //double xMov = (140f/(NANO_IN_MILLI*1000)) * elapsedTime;
        double xMov = 140f / (TARGET_FPS);
        rect.setRect(rect.getX()+xMov, 100, 64, 64);        
        if( rect.getX() > mainFrame.getWidth() )
            rect.setRect(-rect.getWidth(), 100, 64, 64);
    }
   
    private void drawScreen(Graphics g) {
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, mainFrame.getWidth(), mainFrame.getHeight());
        g.setColor(Color.WHITE);
        g.drawString("FPS: " + fps, 0, 17);
       
        g.setColor(Color.RED);
        g.fillRect((int)rect.getX(), (int)rect.getY(), (int)rect.getWidth(), (int)rect.getHeight());
    }
   
    private void calculateFramesPerSecond() {
        if( curRenderTime - lastFpsTime >= NANO_IN_MILLI*1000 ) {
            fps = frameCounter;
            frameCounter = 0;
            lastFpsTime = curRenderTime;
        }
        frameCounter++;
    }
   
    public void keyPressed(KeyEvent e) {
        if( e.getKeyCode() == KeyEvent.VK_ESCAPE ) {
            System.exit(0);
        }
    }
   
    public void keyReleased(KeyEvent e) { }
    public void keyTyped(KeyEvent e) { }

    public static void main(String[] args) {
        try {
       Map<String,String> mapArgs = parseArguments(args);

            GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice device = env.getDefaultScreenDevice();
            new GameLoop2(mapArgs, device);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


   /**
    * Parse commandline arguments, each parameter is a name-value pair.
    * Example: java.exe MyApp "key1=value1" "key2=value2"
    */

   private static Map<String,String> parseArguments(String[] args) {
      Map<String,String> mapArgs = new HashMap<String,String>();

      for(int idx=0; idx < args.length; idx++) {
         String val = args[idx];
         int delimIdx = val.indexOf('=');
         if (delimIdx < 0) {
            mapArgs.put(val, null);
         } else if (delimIdx == 0) {
            mapArgs.put("", val.substring(1));
         } else {
            mapArgs.put(
               val.substring(0, delimIdx).trim(),
               val.substring(delimIdx+1)
            );
         }
      }
     
      return mapArgs;
   }

}
30  Game Development / Performance Tuning / Re: How can I make this simple game loop better? on: 2009-05-06 21:26:44
Yay I finally made a good game loop (at least I think I do). Any places for improvement?

I took your mainloop and made a testrun, its very simple left-to-right animation. I have tried everything(?) to make it smooth as silk in a windowed Java application still not eating CPU100%. I think its close to impossible or I just can't.

I can cleary see occasional jumps and small tearing.

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  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
187  
188  
189  
190  
191  
//http://www.java-gaming.org/topics/how-can-i-make-this-simple-game-loop-better/19971/view.html

import java.util.*;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferStrategy;

import java.awt.DisplayMode; // for full-screen mode

public class GameLoop1 implements KeyListener {
    Frame mainFrame;

    private static final long NANO_IN_MILLI = 1000000L;  
    long desiredFPS = 60;
    long desiredDeltaLoop = (1000*1000*1000)/desiredFPS;    

    long beginLoopTime;
    long endLoopTime;
    long currentPhysicTime;
    long lastPhysicTime;

    long fps;
    long frameCounter;
    long lastFpsTime;
   
    Rectangle2D rect;
   
    public GameLoop1(Map<String,String> args, GraphicsDevice device) {
        try {
            // Setup the frame
            GraphicsConfiguration gc = device.getDefaultConfiguration();
           
            mainFrame = new Frame(gc);
            mainFrame.setUndecorated(true);
            mainFrame.setIgnoreRepaint(true);
            mainFrame.setVisible(true);
            mainFrame.setSize(640, 480);
            //mainFrame.setLocationRelativeTo();
            mainFrame.setLocation(100,100);
            mainFrame.createBufferStrategy(2);
            mainFrame.addKeyListener(this);

            if ("true".equalsIgnoreCase(args.get("fullscreen"))) {
              device.setFullScreenWindow(mainFrame);
              device.setDisplayMode(new DisplayMode(640, 480, 8, DisplayMode.REFRESH_RATE_UNKNOWN));
            }
         
            // Cache the buffer strategy and create a rectangle to move
            BufferStrategy bufferStrategy = mainFrame.getBufferStrategy();
            rect = new Rectangle2D.Float(0,100,64,64);
           
            // loop initialization
            currentPhysicTime = System.nanoTime();
            lastFpsTime = currentPhysicTime;

            // Main loop
            while(true) {
                beginLoopTime = System.nanoTime();

                // Synchronise with the display hardware. Note that on
                // Windows Vista this method may cause your screen to flash.
                // If that bothers you, just comment it out.
                //Toolkit.getDefaultToolkit().sync();
           
                // **1) execute drawing
                Graphics g = bufferStrategy.getDrawGraphics();
                drawScreen(g);
                g.dispose();

                // Flip the buffer
                if( !bufferStrategy.contentsLost() )
                    bufferStrategy.show();
               
                // **2) execute physics
                lastPhysicTime = currentPhysicTime;
                currentPhysicTime = System.nanoTime();
                updateWorld(currentPhysicTime - lastPhysicTime);              
           
                calculateFramesPerSecond();
           
                // **3) execute logic
                // executeLogic(); // handle keyboard and other inputs
                endLoopTime = System.nanoTime();
                adjustSpeed();            
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            device.setFullScreenWindow(null);
        }
    }
   
    private void adjustSpeed() {
        long deltaLoop = endLoopTime - beginLoopTime;
       
        if(deltaLoop > desiredDeltaLoop) {
            // do nothing. We are alreadyLate
            System.out.println("Late, do not sleep");
        } else {
            try {
                Thread.sleep((desiredDeltaLoop - deltaLoop) / NANO_IN_MILLI);
            } catch (InterruptedException ex) { }
        }
    }  

    private void updateWorld(long elapsedTime) {
        // speed: 150 pixels per second
        double xMov = (140f/(NANO_IN_MILLI*1000)) * elapsedTime;
        //double xMov = 2.0;
        rect.setRect(rect.getX() + xMov, 100, 64, 64);
       
        if( rect.getX() > mainFrame.getWidth() )
            rect.setRect(-rect.getWidth(), 100, 64, 64);
    }
   
    private void drawScreen(Graphics g) {
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, mainFrame.getWidth(), mainFrame.getHeight());
        g.setColor(Color.WHITE);
        g.drawString("FPS: " + fps, 0, 17);
       
        g.setColor(Color.RED);
        g.fillRect((int)rect.getX(), (int)rect.getY(), (int)rect.getWidth(), (int)rect.getHeight());
    }
   
    private void calculateFramesPerSecond() {
        if( currentPhysicTime - lastFpsTime >= NANO_IN_MILLI*1000 ) {
            fps = frameCounter;
            frameCounter = 0;
            lastFpsTime = currentPhysicTime;
        }
        frameCounter++;
    }
   
    public void keyPressed(KeyEvent e) {
        if( e.getKeyCode() == KeyEvent.VK_ESCAPE ) {
            System.exit(0);
        }
    }
   
    public void keyReleased(KeyEvent e) { }
    public void keyTyped(KeyEvent e) { }

    public static void main(String[] args) {
        try {
       Map<String,String> mapArgs = parseArguments(args);

            GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice device = env.getDefaultScreenDevice();
            new GameLoop1(mapArgs, device);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


   /**
    * Parse commandline arguments, each parameter is a name-value pair.
    * Example: java.exe MyApp "key1=value1" "key2=value2"
    */

   private static Map<String,String> parseArguments(String[] args) {
      Map<String,String> mapArgs = new HashMap<String,String>();

      for(int idx=0; idx < args.length; idx++) {
         String val = args[idx];
         int delimIdx = val.indexOf('=');
         if (delimIdx < 0) {
            mapArgs.put(val, null);
         } else if (delimIdx == 0) {
            mapArgs.put("", val.substring(1));
         } else {
            mapArgs.put(
               val.substring(0, delimIdx).trim(),
               val.substring(delimIdx+1)
            );
         }
      }
     
      return mapArgs;
   }

}


edit: another issue, my FPS counter clearly does not work. target fps is 60 but my debug prints +90fps all the time.
Pages: [1] 2 3 ... 9
 

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

The first screenshot will be displayed as a thumbnail.

Longarmx (49 views)
2014-10-17 03:59:02

Norakomi (38 views)
2014-10-16 15:22:06

Norakomi (31 views)
2014-10-16 15:20:20

lcass (35 views)
2014-10-15 16:18:58

TehJavaDev (65 views)
2014-10-14 00:39:48

TehJavaDev (65 views)
2014-10-14 00:35:47

TehJavaDev (55 views)
2014-10-14 00:32:37

BurntPizza (72 views)
2014-10-11 23:24:42

BurntPizza (43 views)
2014-10-11 23:10:45

BurntPizza (84 views)
2014-10-11 22:30:10
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

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
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!