Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (579)
games submitted by our members
Games in WIP (500)
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  
  Example project discussion.  (Read 3934 times)
0 Members and 1 Guest are viewing this topic.
Offline GergisKhan

Junior Member




"C8 H10 N4 O2"


« Posted 2003-09-06 03:19:30 »

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.  



gK

"Go.  Teach them not to mess with us."
          -- Cao Cao, Dynasty Warriors 3
Offline troggan

Junior Member




no guts no glory


« Reply #1 - Posted 2003-09-06 08:16:23 »

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)

(http://www.wannawork.de) - Will work for food
(http://tvbrowser.org) - Java EPG
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #2 - Posted 2003-09-06 09:37:57 »

Quote

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.


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 Smiley 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 Smiley - 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.

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

Junior Member





« Reply #3 - Posted 2003-09-06 13:07:44 »

Ok, I'll start:

1  
2  
3  
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 Grin
Offline GergisKhan

Junior Member




&quot;C8 H10 N4 O2&quot;


« Reply #4 - Posted 2003-09-06 14:55:09 »

<sarcasm> Oh, Thanks a LOT! </sarcasm>

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

A package naming convention.  Yay!

gK

"Go.  Teach them not to mess with us."
          -- Cao Cao, Dynasty Warriors 3
Offline shawnkendall

Senior Member





« Reply #5 - Posted 2003-09-06 23:35:16 »

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

Shawn Kendall
Cosmic Interactive, LLC
http://www.facebook.com/BermudaDash
Offline GergisKhan

Junior Member




&quot;C8 H10 N4 O2&quot;


« Reply #6 - Posted 2003-09-07 00:44:10 »

I disagree.  I am not going to disagree with you Shawn. Wink

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

gK

"Go.  Teach them not to mess with us."
          -- Cao Cao, Dynasty Warriors 3
Offline Markus_Persson

JGO Wizard


Medals: 12
Projects: 19


Mojang Specifications


« Reply #7 - Posted 2003-09-07 12:14:51 »

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


Ah, you mean like java.utils.<Foo> and java.awt.events.<Bar>? Wink

Play Minecraft!
Offline TheBohemian

Junior Member




Java will rule them all!


« Reply #8 - Posted 2003-09-10 16:30:42 »

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."


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?

cya

TheBohemian

---------------------------------------
my favorite OS: http://jnode.sf.net
Java 1.5 -> 1.4 converter: http://retroweaver.sf.net
Offline thinker

Senior Newbie




null


« Reply #9 - Posted 2003-09-11 17:02:16 »

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.

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

Junior Member




no guts no glory


« Reply #10 - Posted 2003-09-14 11:05:30 »

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 Smiley

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

troggan

(http://www.wannawork.de) - Will work for food
(http://tvbrowser.org) - Java EPG
Offline dsellars

Junior Member




Need to write more games


« Reply #11 - Posted 2003-09-18 13:46:12 »

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.
Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #12 - Posted 2003-09-18 14:27:17 »

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.


Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #13 - Posted 2003-09-18 15:35:58 »

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?


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 Smiley.

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:

1  
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:

1  
2  
3  
4  
5  
6  
7  
8  
9  
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 Smiley, 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 Sad).

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

JGO Coder


Medals: 1


http://t-machine.org


« Reply #14 - Posted 2003-09-18 15:40:13 »

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"


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

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

JGO Coder




Where's the Kaboom?


« Reply #15 - Posted 2003-09-18 17:42:50 »

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:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
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.

Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #16 - Posted 2003-09-22 15:22:06 »

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.


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?

1  
2  
3  
4  
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 Sad).

Quote

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.


I'm travelling all this week and much of next, and my laptop KB just broke Sad 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 Smiley

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

JGO Coder


Medals: 1


http://t-machine.org


« Reply #17 - Posted 2003-10-12 13:14:17 »

Quote

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

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
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();
}



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 Smiley

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

JGO Coder




Where's the Kaboom?


« Reply #18 - Posted 2003-10-12 18:30:13 »

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..
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  
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 );
}

Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #19 - Posted 2003-10-12 18:35:13 »

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  
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());
      }

Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #20 - Posted 2003-10-12 18:36:36 »

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  
      // Constructs the game level and enters the main game loop
     public void doGame()
      {
            mainFrame.setBackground( new Color(240,240,255) );
            BufferStrategy bufferStrategy = mainFrame.getBufferStrategy();
            bounds = mainFrame.getBounds();
            System.out.println("bounds = "+bounds);

            treasureBag = new LinkedList();
            level.initialize();
           
            System.gc();
           
            // Wait for a game to start
           preGameScreen.renderLoop(bufferStrategy);
            // Initialize new game params
           lives = 5;
            livesS = "5";
            worldX = 0;
            worldY = 50;

            while( lives > 0 )
            {
                  System.gc(); // ask for clean up where a GC pause is least likely to affect the game
                 gameOn = true;
                  // Main game loop
                 mainGameLoop.renderLoop( bufferStrategy );
                  // either no lives left or all levels completed
                 
                  // This logic seems out of place here - refactor
                 // set a state variable so it is clear why the loop above terminated
                 // either game is won, or all lives lost.
                 if( level.gotAllTreasures() )// player completed level
                 {
                        // TODO: go to next level unless this is the last one
                       break; // last level break out of game loop
                 }
                 
                  // Died...
                 System.out.println("Died at tick="+tick);
                  // player died
                 long deathTime = System.currentTimeMillis();
                  // death loop
                 while( true )
                  {
                        // TODO Death animation (oxymoron?)
                       if( System.currentTimeMillis() - deathTime > 3000 )
                              break;
                        Thread.yield();
                  }
                  // don't let FPS scaling spaz
                 fpsTick = tick;
                  tickTime = System.currentTimeMillis();
            } // lives remaining loop
           
            gameOverLoop.setGameOverMessage( lives > 0 ? "You Won!!!  (Press Space)"
                                                       : "GAME OVER (Press SPACE)" );

            // end of game idle screen
           gameOverLoop.renderLoop(bufferStrategy);
      }
     
      private RenderLoop mainGameLoop = new RenderLoop()
      {
            public boolean render( Graphics2D g )
            {
                  gameTick(); // do game logic
                 
                  g.clearRect(0,0,bounds.width,bounds.height);
                  // remember original screen coordinate system                        
                 AffineTransform overlaytrans = g.getTransform();
                             
                  // vector graphics look much better with antialiasing
                 g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                  // move origin to center of screen
                 g.translate(bounds.width/2, bounds.height/2);
                  // and remember this coordinate system
                 AffineTransform oldtrans = g.getTransform();
     
                  drawLevel(g);
                  // TODO draw enemies, exits, decorations, etc.
     
                  // restore origin to center of screen
                 g.setTransform( oldtrans );
                  drawShip(g);
     
                  // restore original coordinate system
                 g.setTransform( overlaytrans );
                  drawOverlays(g); // Draw score, lives remaining, level etc...
                 
                  return gameOn;
            }
      };
     
      // Game Over loop
     class GameOverLoop extends RenderLoop
      {
            public boolean render( Graphics2D g )
            {
                  g.clearRect(0,0,bounds.width,bounds.height);
                  g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                  // remember original screen coordinate system                        
                 AffineTransform overlaytrans = g.getTransform();
                  // move origin to center of screen
                 g.translate(bounds.width/2, bounds.height/2);

                  drawLevel(g);
                  // restore original coordinate system
                 g.setTransform( overlaytrans );
                  // Game Over Message
                 g.drawString(geMsg,300,200);

                  return !space;
            }
            public void setGameOverMessage( String msg )
            {
                  geMsg = msg;
            }
            private String geMsg;
      };
      private GameOverLoop gameOverLoop = new GameOverLoop();

Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #21 - Posted 2003-10-12 18:37:46 »

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  
      private RenderLoop preGameScreen = new RenderLoop()
      {
            // Waiting to start loop
           public boolean render( Graphics2D g )
            {
                  g.clearRect(0,0,bounds.width,bounds.height);
                  g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                  // remember original screen coordinate system                        
                 AffineTransform overlaytrans = g.getTransform();
                  // move origin to center of screen
                 g.translate(bounds.width/2, bounds.height/2);
                 
                  drawLevel( g );

                  // restore original coordinate system
                 g.setTransform( overlaytrans );
                 
                  g.drawString("Press SPACE to Start",300,200);
                       
                  return !space;
            }
      };

      private void gameTick()
      {
            int oldScore = score;
           
            controlShip();
            moveShip();
            // TODO Check if a line segment from old to new intersects with anything
           // currently just checks new position

            // Check for collisions
           // check key (treasure) collisions. all objects that are picked up
           // at this position will be placed in the treasureBag
           treasureBag.clear();
            if( level.collectTreasure( worldX, worldY, treasureBag) )
            {
                  // Level completed
                 // TODO: open door to next level
                 // For now just stop ship
                 shipX = 0;
                  shipY = 0;
                  shipVelX = 0;
                  shipVelY = 0;
                  gameOn = false; // and end the game loop
           }
           
            // Update score display and handle bonuses
           if( !treasureBag.isEmpty() )
            {
                  for( Iterator it = treasureBag.iterator(); it.hasNext(); )
                  {
                        score += ((Integer)it.next()).intValue();
                  }
                  // TODO play sound for treasure pickup
                 // (could use magnitude of change in score to choose the sound)
           }
            if( oldScore != score )
            {
                  // TODO check if score crossed special boundaries like earning a
                 // free life.
                 scoreS = String.valueOf(score);
            }
                       
            // Check map collisions (ship crashes)
           if( level.checkCollision( -worldX, -worldY ) )
            {
                  msg = "ouch";
                  // TODO  handle this properly
                 // for now reset position here (move to doGame after death anim)
                 worldX = 0;
                  worldY = 50;
                  shipX = 0;
                  shipY = 0;
                  shipVelX = 0;
                  shipVelY = 0;
                  shipRot = 0;
                  --lives;
                  gameOn = false;
                  livesS = String.valueOf( lives );
                  // TODO trigger death sound and death animation
                 // (should drop out of 'gameOn' loop for this)
           }
            else
            {
                  msg = null;      
            }

            // this should always be called for each render loop iteration            
           calcFpsAndGameClock();
           
            keyRot = ctick & 15;
      }
     
      private void calcFpsAndGameClock()
      {
            // FPS indicator
           long t = System.currentTimeMillis();
            if( t-tickTime >= 1000 )
            {
                  fps = ((tick-fpsTick)*1000.0/(t-tickTime));
                  fpsS = NumberFormat.getNumberInstance().format(fps)+" fps";
                  fpsTick = tick;
                  tickTime = t;
                  // adjust for frame rate - scale numbers relative to 30 fps
                 FAC = 1.0;
                  if( fps > 5 )
                        FAC = 30.0/fps;
            }

            // frame tick and frame rate corrected 'ctick' for anims
           tick++;
            ctick = (int)(tick * FAC);
      }
     
      /** apply controls to ship parameters */
      private void controlShip()
      {
            // calculate ship heading
           if( left )
            {
                  shipRot--;
                  shipAngle = FAC * shipRot * 0.5 / Math.PI;
            }
            else if( right )
            {
                  shipRot++;
                  shipAngle = FAC * shipRot * 0.5 / Math.PI;
            }
            // acceleration due to ships engine
           if( thrust )
            {
                  shipVelX += FAC * ACCEL * Math.sin(shipAngle);
                  shipVelY -= FAC * ACCEL * Math.cos(shipAngle);
            }
      }
     
      /** move ship - scaled by FAC */
      private void moveShip()
      {
            // acceleration due to gravity
           shipVelY += FAC * GRAVITY;
           
            // put a cap on the speed (vertical only, proper cap needs vector math)
           double terminalV = FAC * TERMINAL_VELOCITY;
            if( shipVelY > terminalV )
                  shipVelY = terminalV;
            else if( shipVelY < -terminalV )
                  shipVelY = -terminalV;

            // translation of ship for this iteration (floating point)
           shipX += FAC * shipVelX;
            shipY += FAC * shipVelY;
           
            // do movement (if we have moved at least an entire pixel)
           int dx = (int) shipX;
            int dy = (int) shipY;
            if( dx != 0)
            {
                  worldX -= dx; // adjust world position
                 shipX -= dx; // (allows fractional part to accumulate until it makes a difference)
           }
            if( dy != 0)
            {
                  worldY -= dy;
                  shipY -= dy;
            }
      }

Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #22 - Posted 2003-10-12 18:39:09 »

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  
      private void drawLevel(Graphics2D g)
      {
            level.renderBackground( g, worldX, worldY, ctick);
      }

      private void drawShip(Graphics2D g)
      {
            //(center of screen or maybe near edge if level can't scroll any further)
           // rotate ship
           g.rotate( shipAngle );
            g.fill( shipShape );
            if( thrust )
            {
                  g.setColor( Color.ORANGE );
                  g.fill( thrustShape );
                  g.setColor( Color.BLACK );
            }
      }

      private void drawOverlays( Graphics2D g )
      {
            // general message
           if( msg != null )
            {
                  g.drawString(msg,10,44);
            }
            // fps indicator
           g.drawString(fpsS,10,34);
            // Score and other stats
           g.drawString("Score:",460,34);
            g.drawString(scoreS, 500, 34);
     
            g.drawString("Lives:",360,34);
            g.drawString(livesS, 400, 34);
                             
            // position (mainly a debug thing)
           g.drawString(String.valueOf(worldX),500,44);
            g.drawString(String.valueOf(worldY),590,44);
      }
     
      private void computeRotatedKeyShapes()
      {
            // TODO pre-render the transformed key shapes
           for(int i = 0; i < 16; i++)
                  rotKeys[i] = AffineTransform.getRotateInstance( i * RF )
                        .createTransformedShape( keyShape );

      }
     
      private static DisplayMode getBestDisplayMode(GraphicsDevice device)
      {
            for (int x = 0; x < BEST_DISPLAY_MODES.length; x++)
            {
                  DisplayMode[] modes = device.getDisplayModes();
                  for (int i = 0; i < modes.length; i++)
                  {
                        if (modes[i].getWidth() == BEST_DISPLAY_MODES[x].getWidth()
                              && modes[i].getHeight() == BEST_DISPLAY_MODES[x].getHeight()
                              && modes[i].getBitDepth()
                                    == BEST_DISPLAY_MODES[x].getBitDepth())
                        {
                              return BEST_DISPLAY_MODES[x];
                        }
                  }
            }
            return null;
      }

      public static void chooseBestDisplayMode(GraphicsDevice device)
      {
            DisplayMode best = getBestDisplayMode(device);
            if (best != null)
            {
                  device.setDisplayMode(best);
            }
      }

      public static void main(String[] args) throws Exception
      {
            GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice device = env.getDefaultScreenDevice();
            try
            {
                  boolean fs = true;
                  int numBuffers = 2;
                  for(int i = 0; i < args.length; i++ )
                  {
                        if( args[i].equalsIgnoreCase("window") )
                              fs = false;
                  }
                  VectorCollector game = new VectorCollector(numBuffers, device, fs);
                  game.doGame();
            }
            finally
            {
                  device.setFullScreenWindow(null);
            }

            System.exit(0);
      }

Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #23 - Posted 2003-10-12 18:40:00 »

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  
      public void keyTyped(KeyEvent e)
      {
      }

      public void keyPressed(KeyEvent e)
      {
            switch( e.getKeyCode() )
            {
                  case KeyEvent.VK_UP:
                        thrust = true;
                        break;
                  case KeyEvent.VK_LEFT:
                        left = true;
                        break;
                  case KeyEvent.VK_RIGHT:
                        right = true;
                        break;
                  case KeyEvent.VK_SPACE:
                        worldX = 0;
                        worldY = 50;
                        shipX = 0;
                        shipY = 0;
                        shipVelX = 0;
                        shipVelY = 0;
                        space = true;
                        break;
                  case KeyEvent.VK_ESCAPE:
                        lives = 0;
                        gameOn = false;
            }
      }

      public void keyReleased(KeyEvent e)
      {
            switch( e.getKeyCode() )
            {
                  case KeyEvent.VK_UP:
                        thrust = false;
                        break;
                  case KeyEvent.VK_LEFT:
                        left = false;
                        break;
                  case KeyEvent.VK_RIGHT:
                        right = false;
                        break;
                  case KeyEvent.VK_SPACE:
                        space = false;
                        break;
            }
      }
}

interface VCLevel
{
      // called after loading a level
     public void initialize();
      // draw the level to 'g' with world position x,y at the origin
     public void renderBackground( Graphics2D g, int x, int y, int ctick );
      public boolean checkCollision( int x, int y );
      public boolean collectTreasure( int x, int y, Collection bag);
      public boolean gotAllTreasures();
}

class DefaultLevel implements VCLevel
{
      public void initialize()
      {
            assert px.length == py.length;
            final int zoom = 6;
            // useless variety - jiggle level
           for (int i = 0; i < px.length; i++)
            {
                  int x = px[i];
                  int y = py[i];
                  x += Math.random() * 10;
                  y += Math.random() * 10;
                  x *= zoom; // scale level
                 y *= zoom;
                  px[i] = x;
                  py[i] = y;
            }
            mapShape = new Polygon( px, py, px.length );
           
            levelKeys = new HashSet();
            for (int i = 0; i < keyX.length; i++)
            {
                  Point p = new Point(keyX[i]*zoom, keyY[i]*zoom);
                  levelKeys.add( p );
            }
      }

      public void renderBackground(Graphics2D g, int x, int y, int ctick)
      {
            // adjust for position within level
           g.translate( x, y );
            g.setColor(COLORS[ctick % COLORS.length]);
            g.fill( mapShape );
            g.setColor( Color.BLACK );
            g.draw( mapShape );

            // TODO pre-render the transformed key shapes
           Shape rotKey = VectorCollector.rotKeys[VectorCollector.keyRot];
            for (Iterator i = levelKeys.iterator(); i.hasNext(); )
            {
                  Point p = (Point) i.next();
                  if( onScreen( g, p.x, p.y) )
                  {
                        g.translate( p.x, p.y );
                        g.draw( rotKey );
                        g.translate( -p.x, -p.y );
                  }
            }

            g.translate( -x, -y);
      }
     
      public boolean gotAllTreasures()
      {
            return levelKeys.isEmpty();
      }

      public boolean checkCollision(int x, int y)
      {
            return mapShape.contains(x,y);
      }
      /** Handles treasure pickup
       * returns true if all treasures have been collected */

      public boolean collectTreasure( int x, int y, Collection bag)
      {
            for (Iterator i = levelKeys.iterator(); i.hasNext();)
            {
                  Point p = (Point) i.next();
                  // TODO: key array positions should be sorted so
                 // we can jump out of this loop early
                 int dx = (p.x + x);
                  if( dx > 8 || dx < -8)
                        continue; // out of range on x - check next key
                 // x in range, check Y
                 int dy = (p.y + y);
                  if( dy > 8 || dy < -8)
                        continue; // out of range on y - check next key
                 // y also in range - good enough for me - count the hit
                 i.remove(); // take the key out of the map for the next render pass
                 bag.add( tenPoints );// and give out some points
                 // TODO: place a keyCapture animation at point p to play for a few milliseconds
                 // before decaying away.
                 
                  // TODO: change this entirely to keep track of where the ship would be inserted
                 // into the array.. then it is constant time.. to check collision against next
                 // or previous key . (and also update ships virtual position in the array)
           }
            return levelKeys.isEmpty();
      }
      private static Integer tenPoints = new Integer(10);
     
      private boolean onScreen( Graphics2D g, int x, int y )
      {
            Rectangle clip = g.getClipBounds();
            return clip != null ? clip.contains(x,y) : true;
      }

      // need colors for an 'eerie glow'
     private static Color[] COLORS = new Color[16];
      static
      {
            for(int i = 0; i < COLORS.length/2; i++)
            {
                  COLORS[i] = new Color(0,180+i*6,i*7);
                  COLORS[COLORS.length-1-i] = new Color(0,180+i*6,i*7);
            }
      }
      // level polygon X
     private int [] px = new int [] { -80,-80,-40,-40, 80, 80, 70,70,60, 60, 50, 50, 40, 40, 30,30,-40,-40};
      // level polygon Y
     private int [] py = new int [] { -20, 20, 20, 10, 10,-20,-20,00,00,-20,-20,-10,-10,-20,-20,00, 00,-20};
      // treasure placement X
     private int [] keyX = new int [] {  45,-80,  0, 65 };
      // treasure placement Y
     private int [] keyY = new int [] { -15,-28, 15, -5 };
      private transient Shape mapShape;
      private transient Set levelKeys;

}

Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #24 - Posted 2003-10-12 18:43:41 »

There you go.  As you can see it is extremely simple with many areas to improve.  That is sort of the point.  I wanted a simple functional game that I could show evolving through a series of tutorials that make it better and better and maybe add a few key features.

Note that the simple level that is hardcoded has no boundary and gravity will pull you to negative infinity and it can be hard to find your way back..

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.

xsi3rr4x (38 views)
2014-04-15 18:08:23

BurntPizza (34 views)
2014-04-15 03:46:01

UprightPath (50 views)
2014-04-14 17:39:50

UprightPath (32 views)
2014-04-14 17:35:47

Porlus (49 views)
2014-04-14 15:48:38

tom_mai78101 (71 views)
2014-04-10 04:04:31

BurntPizza (130 views)
2014-04-08 23:06:04

tom_mai78101 (230 views)
2014-04-05 13:34:39

trollwarrior1 (193 views)
2014-04-04 12:06:45

CJLetsGame (200 views)
2014-04-01 02:16:10
List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30
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!