Example project discussion.

Recent events have started me thinking about the community, and communities at large. I would appreciate your input. No offense will be taken if you think I’m a crackpot, this sucks, or any other thoughts. I’m offering this up for discussion.

I love java-gaming.org. I love the people here. However, over the past two years I’ve noted that one thing that we do seem to be doing is answering the same questions. The latest actions by Sun and the new GTG have REALLY helped, and I’m aware of Space Ghost calling out to us to help out by contributing. I’m all for that, in fact, I’m actively preparing to start writing articles for the Wiki. I’ll likely start posting stuff this weekend.

However, I came up with a very interesting possibility as a result of answering a newbie’s question in this forum that I’d like your input on.

How would you feel about contributing to a group project, specifically, a demonstration game? I’m suggesting that we, as a whole, would contribute to a very small scale, simple, demonstration game that would show off various technologies.

I’m not proposing this be done now, nor should we start even thinking about what a “technology demonstrator” should entail. I’m just wondering what you all think about the effectiveness and relevance of such a thing would be.

Specifically I would say we’d need several “demos.” Maybe even if they were full contributions that might be worth it.

I suggest:

. Java2D
. 3D (JOGL, LWJGL, or Xith, though the concepts behind 3D are what i’m recommending be shown)
. Sound
. Networking

My goal here is to assist new game developers in giving them something to look at. Too often I hear that “I’ve looked for x and can’t find good examples.”

Any thoughts are appreciated.

I am planning to create a tutorial session on top of j2da, kevglass has written a boulderdash clone as a start. i will create the tutorial on “how to build a boudlerdash game”. i will anounce it when it’s done (hopefully on sunday)

Could we perhaps focus on very very simple demo games first? Both you and I have come up with a need in the last 24 hours :slight_smile: for simple games with source to use as examples in articles/tutorials…If nothing else, creating a small collection of these, that can be re-used in different articles (so that the reader is very familiar with the code, and finds it easier to understand what each article is changing), is probably a sensible stepping-stone to what you are proposing?

I really like the idea of games which start off very simple, and get new features added each time a new article comes along :slight_smile: - of course, the old versions of the games remain, attached to the earlier articles. I’m trying it out at the moment, and it seems to produce quite a nice flow as you move through more elaborate/complex additions to the game.

Ok, I’ll start:


package org.javagaming.demo.<insert demo name/package here>;

// TBD

There you go - it won’t compile as it’s just a 0.01 alpha ;D

Oh, Thanks a LOT!

Seriously, though, your 0.01 alpha did provide one thing we can agree on:

A package naming convention. Yay!

In the interest of disagreement, I suggest:
package org.javagaming.demos.<insert demo name/package here>;
;D

I disagree. I am not going to disagree with you Shawn. :wink:

I like it. More and more I like where this is headed.

[quote]In the interest of disagreement, I suggest:
package org.javagaming.demos.<insert demo name/package here>;
;D
[/quote]
Ah, you mean like java.utils. and java.awt.events.? :wink:

[quote] My goal here is to assist new game developers in giving them something to look at. Too often I hear that “I’ve looked for x and can’t find good examples.”
[/quote]
This sounds great. But if I think we should plan a little bit before we throw ourselves into work.
When Java gaming technology is accepted even more the number of demo applications may raise and I think it would be a good idea to keep them structered and well ordered in short catalogued. IMHO we should not do the simple type of listing with a description, an image and a download link. The more the user knows about a demo in advance (programming skills needed, used techniques/API) and can search for, the more she/he gets adopted to the site and especially for the Java language.

What do you think?

As a complete newb to java gamming and this community in general i just wanted to make a quick comment that a demo game is exactly what i’m looking for.

i agree with blahblahblahh in that a very simple game shell that is slowly improved step-by-step is one of the best ways to teach someone new like me.

another item of feedback i have is it is rather difficult for me right now to figure out exactly what technologies i should be using for a 3D game. I realize that different technologies meet the needs of different projects, but a type of “game blueprint” that explains best practices and technology stacks for 70-80% of the projects out there would be hugely useful. Maybe come up with a typical project case and explain the stack and recommended technology.

I added a smal tutorial on J2DA onto our Site (http://j2da.sf.net) . Please tell me if it is OK, or if not, how to improve it.

It’s the first tutorial I have ever written :slight_smile:

How far are you with the other Example stuff? Hope to see something soon!

troggan

Hello All,

I tend to be a lurker on these boards, but I do try and keep up with what happens. I just thouigh I would write this to voice my opinion that having a number of tutorial projects held in a central location would be a very good idea.

Quite often it seems that alot of interesting points and information is raised and is then buried under a host of new threads. I know you can search but it really is a pain when you get a load of inappropriate results.

I do feel that they would have to be projects that the majority of experienced members considered “good quality” though. If new programmers are going to learn from them, they do need to promote good practice as well as illustrate a point.

Well thats my 2p for a while,

Dan.

Ps. troggan I thought your J2DA introduction was very clear, thanks.

I’ve been putting a little polish on a very simple 2D game with the intent to release the source code to the public domain as one of the proposed example projects.

I have started the project using very basic Java 2D APIs, the only ‘fancy’ bit is that it uses the 1.4 features for fullscreen and a BufferStrategy.

The game doesn’t use openGL
It doesn’t use JInput
It doesn’t have sound at all yet.
It doesn’t even use traditional sprites or tiles - no blitting.

I started that way for a few reasons. One to show that it was possible, but mainly so it could evolve.

Currently it uses AWT listeners to set booleans for key states. I want to evolve it to use JInput as part of a JInput tutorial.

It uses Java 2D Shapes and Affine Transforms to draw the level, ship, and ‘treasures’ that must be collected. Eventually that can evolve to openGL via JOGL(still 2D), or even a tile-based map using Gage or J2DA as part of tutorials for those technologies.

I will add some sounds with regular Java Sound APIs, then migrate that to JOAL as part of a tutrorial for that.

It does not have an installer or use Java Web Start - yet. That will come as a tutorial exercise as well.

The intention is to show the basic structure of a Java game. How it is done using the traditional methods, and how it is done using the new gaming APIs… but to slowly evolve from one to the other, and add features to the game slowly as part of some sort of tutorial.

I will not have time to do all this myself… So when I have version 1.0 ready I will post it somewhere and hopefully your guys can help out. Keeping a history of versions as new techniques are used and game features are added, so newcomers can see where we are coming from.

The game is extremely simple at the moment. The basic idea is that you fly a ship around a level and collect treasure (keys). When you get all the treasure you go to the next level (eventually I will have you exit through a portal that opens, but now just getting the treasures is enough). There is gravity that will pull you into the ground. If you collide with the level you die. There are no enemies yet, but they can be added as a tutorial. There is no two-player network play, but it could be added as a tutorial. There is only one very simple hard-coded level now.

Does this sound like a reasonable project & approach for teaching the basics of Java Gaming? Do you want to see it done? And, more importantly, do any of you have time to help? Perhaps I (or anyone really) should set up a project on dev.games.java.net if the community wants to make a serious example of it.

[quote]I’ve been putting a little polish on a very simple 2D game with the intent to release the source code to the public domain as one of the proposed example projects.

I started that way for a few reasons. One to show that it was possible, but mainly so it could evolve.

I will not have time to do all this myself… So when I have version 1.0 ready I will post it somewhere and hopefully your guys can help out. Keeping a history of versions as new techniques are used and game features are added, so newcomers can see where we are coming from.

There is no two-player network play, but it could be added as a tutorial.

Does this sound like a reasonable project & approach for teaching the basics of Java Gaming? Do you want to see it done? And, more importantly, do any of you have time to help?
[/quote]
Sounds good. Since I haven’t had time to make use of Orangy Tang’s code as an example for my nio articles, I could first try using this instead.

I have a major point to make, though, before I could use it:
“Must be architected as a modular game”

I.e. “vanilla” monotonically increasing versioning is going to be a waste of time here. What we need is to be able to develop this simultaneously in different directions with FULL forwards and backwards compatibility [nb: this of course is not trivially possible; hence my desire for a good versioning system which enables you to startup with any set of modules, and it tells you which bits conflict].

The one thing I’m not prepared to do is write tutorials that have to have the source code rewritten every few weeks in order to retain the functionality inside the overall game - e.g. because interfaces between different sections of the game keep changing all the time. IMHO that situation defeats the purpose :).

Heavy use of interface’s would go a long way to achieving this. In addition, a proper versioning system is needed - none of this rubbish sellotape-and-cardboard rubbish that is the current state of JAR versioning (IIRC in the official Sun docs it’s made clear that the current manifest-versioning is a quick-fix to make J2EE package management bearable until something better comes along)

Each version of each section needs to state which other versions of which other sections it’s compatible with. A way of doing this (NB it’s a long time since I’ve built a versioning system from scratch - please chime in if I say something dumb here!) is for each module to implement a method:


public void isCompatibleWith( HashMap h );

Where the hm is a mapping from “module-names” to “current version that’s being loaded”. If there’s any incompatibility, the implementor throws a custom Exception, one of:


MissingDependencyException
{
public Vector requiredModules();
}

IncompatibleVersionsException
{
public HashMap conflictingModules();
}

The first is thrown where a given module needs a module that just isn’t present - e.g. this is an easy way for the game GUI to automatically provide a warning when a library is missing, usually because the user forgot to download it :), instead of crashing etc.

The second is for when a module requires “at least version XXX” of another module. It is ALSO for when system-testing has shown that particular versions of sets of modules are incompatible in some way. The HM is a mapping from module-name to a String describing the versions that this IS compatible with.

Anyway, SWP could you post a summary Class Diagram to show the core structure of the game? I’m rather busy right now, but I can certainly do UML modelling and analysis. If you’ve not got good UML modeller at the moment, and you could write a set of interfaces (to whatever level of detail you have time for), I can do the Class diagram for you and post it here for discussion (as JPG/PNG … the state of intra-modeller file import/export being as dire as it currently is :().

Anyone with experience of linux-package-management development care to speak up? Most linux users are all too painfully aware of their failings, but even in the poorer ones (like RPM etc) there’s a lot of good solid design; let alone the widely praised Debian system…

Well, at the moment the game is very much NOT modular. It is trying to be as simple as is humanly possible. IMHO making it modular at this stage would add complexity that it doesn’t need. I do think that it should branch out in multiple directions instead of following a single path, as the bagage that would build up could cloud what is happening with the tutorial relating to the next step.

It is currently even just a single class! Just a simple game loop - very basically it is this:

while( gameOn )
{
    Graphics2D g = getDrawingContextFromBufferStrategy();
    drawBackground(Graphics2D g); // the basic level/map
    drawTreasures(Graphics2D g); // the things to collect
    drawShip(Graphics2D g); // players ship
    drawOverlay(Graphics2D g); // score and stuff
    flipBuffers();
    doGameLogic();
}

But I may introduce some interfaces for the basic blocks in the loop above. Refactoring it to use interfaces could also be the subject of a tutorial.

Don’t let the fact that it is a single class scare you. There wasn’t a need up to this point, so that refactoring just hasn’t happened… it will soon though.
In fact I would like to see how people would choose to arrange the class heirarchy. That aspect of OO design is often difficult for beginners, and everyone may do it differently. It would be interesting to debate the various structural alternatives.

[quote]Well, at the moment the game is very much NOT modular. It is trying to be as simple as is humanly possible. IMHO making it modular at this stage would add complexity that it doesn’t need. I do think that it should branch out in multiple directions instead of following a single path, as the bagage that would build up could cloud what is happening with the tutorial relating to the next step.
[/quote]
I see what you’re saying. Although increasing modularity here probably won’t add complexity. E.g. at this stage, just turning each of those method calls into method calls on 5 separate interfaces works nicely?

while( gameOn )
{
...    doGameLogic();
}

[/quote]
I think this is probably the first bit that needs fleshing out a bit / designing. All the other steps appear to modularise nicely and obviously, but this will (potentially) have a lot of interdependent parts that need to be designed to work together neatly, or risk the nightmare of having umpteen callbacks - and even callbacks within callbacks to more callbacks (seen it happen :().

I’m travelling all this week and much of next, and my laptop KB just broke :frowning: so I can’t login (only three letters broke - but two of them are present one or both in all the login names!!!). I’ll try to post some suggestions in the next day or so - technology permitting :slight_smile:

SWP, do you have any working code for this at the moment? I’m profiling and testing server apps for the next few days, which means lots of waiting around while stuff happens…if you’ve got some code, I’d like to modularise it a little, and then try prototyping a new idea I’ve had for an animation system. In the process, I might be able to add some useful bits :slight_smile:

I will get the code up on a web site when I get home. At my folks house for Thanksgiving at the moment.

There is much to optimize in the code. I was going to go through the optimization with a tutorial.

ah what the heck… I’ll just post it here… It’s on this laptop…


import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;

/*
 * Created on 18-Sep-2003
 *
 */

/**
 * @author scottpalmer
 *
 */
public abstract class RenderLoop
{
      public RenderLoop() {}
      public void renderLoop(BufferStrategy bs)
      {
            boolean keepGoing = true;
            while( keepGoing )
            {
                  Graphics2D g = (Graphics2D) bs.getDrawGraphics();
                  if (!bs.contentsLost())
                  {
                        keepGoing = render( g );
                        g.dispose();
                        bs.show();
                  }
                  g.dispose();
            }            
      }
      // TODO add things like default rendering hints etc...
      // TODO make this an interface member that can be changed
      // by the game logic to implement different 'modes' or
      // rendering states.
      public abstract boolean render( Graphics2D g );
}


import java.awt.BufferCapabilities;
import java.awt.Color;
import java.awt.DisplayMode;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferStrategy;
import java.text.NumberFormat;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;

/*
 * Created on Jun 7, 2003
 */

/**
 * @author scottpalmer
 *
 */

public class VectorCollector implements KeyListener
{
      static
      {      // stuff for debugging mac version
            //System.setProperty("apple.awt.fakefullscreen", "true");
      }

      
      private static DisplayMode[] BEST_DISPLAY_MODES =
            new DisplayMode[] {
                  new DisplayMode(640, 480, 32, 0),
                  new DisplayMode(640, 480, 16, 0),
                  new DisplayMode(640, 480, 8, 0)
            };

      private Rectangle bounds;
      private boolean gameOn = true;
      private int fpsTick = 0;
      private double FAC = 1.0;
      private int tick = 0;
      private int ctick = 0; // corrected tick
      private long tickTime = 0;
      private String msg = null;
      private String fpsS = "";
      private double fps = 0;
      static int keyRot = 0;
      private int shipRot = 0;
      private double shipAngle = 0;
      private double shipVelX = 0;
      private double shipVelY = 0;
      private double shipX = 0;
      private double shipY = 0;
      private int lives = 5;
      private String livesS = "5";
      private Collection treasureBag;
      private int worldX = 0;
      private int worldY = 0;
      private static double ACCEL = 0.55;
      private static double GRAVITY = 0.075;
      private static double TERMINAL_VELOCITY = 50;
      private static final double RF = Math.PI/8; // 16 possible ship angles 2*PI/16
      
      // for AWT keyboard "polling" TODO use JInput
      private boolean thrust = false;
      private boolean left = false;
      private boolean right = false;
      private boolean space = false;

      private VCLevel level = new DefaultLevel();

      private Shape keyShape = new Polygon(
            new int [] { -8,-8,-4,-4, 8,8,7,7,6,6,5,5,4,4,3,3,-4,-4},
            new int [] {  2,-2,-2,-1,-1,2,2,0,0,2,2,1,1,2,2,0, 0, 2},
            18 );
      protected static Shape [] rotKeys = new Shape[16];
            
      private Shape shipShape = new Polygon(
            new int [] { -3, 0, 3 },
            new int [] {  5,-5, 5 }, 3);
      private Shape thrustShape = new Polygon(
            new int [] { -2,  0, 2 },
            new int [] {  5, 10, 5 }, 3 );
      private int score = 0;
      private String scoreS = "0";
      Frame mainFrame;

      public VectorCollector(int numBuffers, GraphicsDevice device, boolean doFullScreen)
      {
            computeRotatedKeyShapes();
            GraphicsConfiguration gc = device.getDefaultConfiguration();
            mainFrame = new Frame(gc) {
                  public void paint(Graphics g){}
                  public void update(Graphics g){} };
            mainFrame.setIgnoreRepaint(true);
            
            if ( doFullScreen && device.isFullScreenSupported())
            {
                  mainFrame.setUndecorated(true);
                  device.setFullScreenWindow(mainFrame);
                  if (device.isDisplayChangeSupported())
                  {
                        chooseBestDisplayMode(device);
                        mainFrame.setBounds(0,0,640,480);
                  }
            }
            else
            {
                  mainFrame.setBounds(0,0,640,480);
                  mainFrame.show();
            }
            
            mainFrame.createBufferStrategy(numBuffers);
            mainFrame.addKeyListener( this );

            // Debug info
            BufferCapabilities bc =      gc.getBufferCapabilities();
            System.out.println("BufferCapabilities");
            System.out.println(" isFullScreenRequired:"+bc.isFullScreenRequired());
            System.out.println(" isMultiBufferAvailable:"+bc.isMultiBufferAvailable());
            System.out.println(" isPageFlipping:"+bc.isPageFlipping());
      }