Java-Gaming.org Java4K winners: [ by our judges | by the community ]         
Featured games (67)
games approved by the League of Dukes
Games in Showcase (∞)
games submitted by our members



News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  Print  
  your turn / my turn logic  (Read 1821 times)
0 Members and 2 Guests are viewing this topic.
Offline EddieRich

JGO n00b
*

Posts: 21



« on: 2012-01-04 08:58:03 »

Hello everyone,

I am writing a simple abstract game in an attempt to learn java programming, and eventually Android apps. I have been a windows/C++/C# programmer for over 20 years, but I am new to java. I have a solid understanding of the language, threads, GUI, etc.

My question is, how do I implement the state machine logic for a game where there is an initial welcome screen, which switches to the game screen, and allows the user to make a move, then the computer, then the user, etc.

I'm looking for a tutorial that goes beyond "Hello World" or "How to start a background thread". I just can't seem to get my head around the state machine logic for a simple game like tic-tac-toe.

I'm hoping someone has a link to a tutorial for a "your turn/my turn" type of game.

Ed
Offline StonePickaxes

Full Member
**

Posts: 204
Medals: 3


Nathan Kramber


« Reply #1 on: 2012-01-04 09:07:42 »

What I did for my game I'm working on is I just have 2 booleans: inGame and inMainmenu, and I flip the values when I switch from menus to game, or vice-versa. In your main game loop, just put the logic for each one there (or use an interface and put the logic for each one in it's own class)

1  
2  
3  
4  
5  
while (running)
     while (inGame)
          //do game updates
    while (inMainMenu)
          //do menu stuff


I'm new to java too. I feel weird being the one giving advice for once x:

Check out my website!
Offline EddieRich

JGO n00b
*

Posts: 21



« Reply #2 on: 2012-01-04 09:22:44 »

I'm new to java too. I feel weird being the one giving advice for once x:

Don't feel weird, it's good advice, and appreciated.

I had considered a simple boolean flag to notify the computer player thread to actually make it's move.
For some reason that seems "amateur" to me, and I thought there might be some other, more elegant
solution that I had never seen before. But, sometimes the simplest solution is the best.
Games published by our own members! Go get 'em!
Offline StonePickaxes

Full Member
**

Posts: 204
Medals: 3


Nathan Kramber


« Reply #3 on: 2012-01-04 09:24:51 »

Maybe take a look at this http://www.ludumdare.com/compo/ludum-dare-22/?action=preview&uid=398

I think all the menus are handled in the Game class, but I'm not sure. That's notch's "Minicraft", and he's one of the best java developers.

Check out my website!
Online theagentd

JGO Wizard
****

Posts: 1393
Medals: 88



« Reply #4 on: 2012-01-04 10:26:45 »

You could use a state engine, which I believe is pretty much standard for this. I don't know how advanced your knowledge of Java is or anything, but it simplifies a lot of things and allow you to add as many different "states" as you want without having to change the main loop. It's pretty easy, but it relies heavily on object orientation, but as you have experience with C/C++ it should be a piece of cake.

Create a small State interface:
1  
2  
3  
4  
5  
package somewhere.meaningful;

public interface State{
    public void update();
}


Then create a class that implements this interface for each "state" in the game; main menu, playing, pause menu, options menu, ending credits, e.t.c.
1  
2  
3  
4  
5  
6  
7  
package somewhere.meaningful;

public class MainMenu implements State{
    public void update(){
        //Do main menu stuff
   }
}

1  
2  
3  
4  
5  
6  
7  
package somewhere.meaningful;

public class GameRunning implements State{
    public void update(){
        //Do game stuff
   }
}

E.t.c.

Your main class then looks something like this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
private State state; //Remember to set state to something in the constructor of the main class
private boolean running = true;

public void gameloop(){
    while(running){
        state.update();
    }
}

//Use this method to switch between states
public void setState(State state){
     this.state = state;
}

//Use this method to end the game
public void endGame(){
    running = false;
}


You also need to let each State keep a reference to the main class so they can actually access the setState() and endGame() functions.

There is no god.
Offline ReBirth

JGO Wizard
****

Posts: 1279
Medals: 19



« Reply #5 on: 2012-01-04 10:36:33 »

adding to above post, by using State interface you can share main objects like Graphics or sometimes keyEvent.

Follow me, your mastah, on TWITTAH!
Offline EddieRich

JGO n00b
*

Posts: 21



« Reply #6 on: 2012-01-04 11:45:52 »

I think I finally have my "head around it" now. That is the type of solution I was looking for.
I'll have to add some thread sync, but I think I'm off and running again.

Thank you everyone for your quick answers.

Ed
Online theagentd

JGO Wizard
****

Posts: 1393
Medals: 88



« Reply #7 on: 2012-01-04 11:51:55 »

Have fun!  Grin

There is no god.
Offline Gingerious

JGO n00b
*

Posts: 26
Medals: 2



« Reply #8 on: 2012-02-06 17:21:26 »

Should each state implement its own key listener, or is that a bad idea?
Offline UprightPath

Full Member
**

Posts: 214
Medals: 9



« Reply #9 on: 2012-02-06 23:21:02 »

Should each state implement its own key listener, or is that a bad idea?

Probably not. They can, but it's probably not the best idea.

A better idea would be to have a key listener that forwards commands to your state, and allow the state to handle it some how. This doesn't mean the state itself has just that some member there should perform the logic.

Otherwise, you'll have to be adding/removing listeners all of the time to make sure that each state only receives the keystrokes when they're the active one.

I am filled with despair... About how far people think about ideas they propose, about the state of my teams in classes when people do not understand what an assumption is...
Games published by our own members! Go get 'em!
Offline gbeebe

Full Member
**

Posts: 145
Medals: 5



« Reply #10 on: 2012-02-07 00:15:54 »

My solution to listeners was to have the main class handle the actual "listening" and then sending the event to the current State.
My State interface:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
public interface State {
      public void next(Graphics g);   //I'm not allowed to call it Update for some reason  :(
     public void mouseClicked(MouseEvent evt);
      public void mouseEntered(MouseEvent evt);
      public void mouseExited(MouseEvent evt);
      public void mousePressed(MouseEvent evt);
      public void mouseReleased(MouseEvent evt);
      public void mouseDragged(MouseEvent evt);
      public void mouseWheelMoved(MouseWheelEvent evt);
      public void mouseMoved(MouseEvent evt);
      public void keyPressed(KeyEvent evt);
      public void keyReleased(KeyEvent evt);
      public void keyTyped(KeyEvent evt);
     
   }

Then my main class has the listeners and simply forwards the event; my keyPressed event in the main Class:
1  
2  
3  
4  
@Override
   public void keyPressed(KeyEvent evt) {
      state.keyPressed(evt);
   }


You can set state to be any class implementing State.  I am passing 'this' to my classes when creating them, and they set it to an internal variable of the main class called 'me'  Then I can change state by doing a me.state = ...  I do not have my main class implement State, the examples probably do so to make sure you have all the procedures necessary.  Or maybe there's another reason, I dunno.
Online theagentd

JGO Wizard
****

Posts: 1393
Medals: 88



« Reply #11 on: 2012-02-07 05:32:24 »

1  
2  
3  
4  
    public interface State extends KeyListener, MouseListener, MouseMotionListener{
        public void next(Graphics g);   //I'm not allowed to call it Update for some reason  :(
       //Probably because of a collision with the built in function in Swing with the same name
   }

And then just register the current state as a listener and you won't have to pass events through to the current state in your state handling code.  Wink

There is no god.
Offline Waterwolf

JGO n00b
*

Posts: 36
Medals: 2



« Reply #12 on: 2012-02-07 06:18:29 »

1  
2  
3  
4  
    public interface State extends KeyListener, MouseListener, MouseMotionListener{
        public void next(Graphics g);   //I'm not allowed to call it Update for some reason  :(
       //Probably because of a collision with the built in function in Swing with the same name
   }

And then just register the current state as a listener and you won't have to pass events through to the current state in your state handling code.  Wink

Whaaat. I didn't know interfaces can extend multiple interfaces. Life quality improved!
Online theagentd

JGO Wizard
****

Posts: 1393
Medals: 88



« Reply #13 on: 2012-02-07 06:35:30 »

I was just as surprised as you were when I noticed it but it does make sense though. Name and argument collisions don't matter because there's no actual implementation of them, the "blueprints" just happened match up.

There is no god.
Offline Gingerious

JGO n00b
*

Posts: 26
Medals: 2



« Reply #14 on: 2012-02-07 10:24:44 »

1  
2  
3  
4  
    public interface State extends KeyListener, MouseListener, MouseMotionListener{
        public void next(Graphics g);   //I'm not allowed to call it Update for some reason  :(
       //Probably because of a collision with the built in function in Swing with the same name
   }

And then just register the current state as a listener and you won't have to pass events through to the current state in your state handling code.  Wink



EDIT: Also, I'm assuming this, but it makes the most sense to me:

I have a canvas that I'm adding my listeners to.  When you say register, then when we change states, we'll have to remove the current state's listeners from the canvas, change the state, then add the new state's listeners to the canvas, right?
Offline gbeebe

Full Member
**

Posts: 145
Medals: 5



« Reply #15 on: 2012-02-07 13:10:10 »

My way doesn't change listeners.  The main class handles the listening and forwards the events to the current state.  I just thought it was easier this way.
Online theagentd

JGO Wizard
****

Posts: 1393
Medals: 88



« Reply #16 on: 2012-02-07 22:25:20 »

@Gingerious and Gbeebe:
Yeah, the idea is to do something like this:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
public void changeState(State newState){
    if(currentState != null){
        canvas.removeKeyListener(currentState);
        canvas.removeMouseListener(currentState);
        canvas.removeMouseMotionListener(currentState);
    }

    currentState = newState;
    canvas.addKeyListener(currentState);
    canvas.addMouseListener(currentState);
    canvas.addMouseMotionListener(currentState);
}

There is no god.
Offline ReBirth

JGO Wizard
****

Posts: 1279
Medals: 19



« Reply #17 on: 2012-02-08 07:13:15 »

My way doesn't change listeners.  The main class handles the listening and forwards the events to the current state.  I just thought it was easier this way.
that's what I do everytime and work fine.

Follow me, your mastah, on TWITTAH!
Online theagentd

JGO Wizard
****

Posts: 1393
Medals: 88



« Reply #18 on: 2012-02-08 09:47:37 »

My way doesn't change listeners.  The main class handles the listening and forwards the events to the current state.  I just thought it was easier this way.
that's what I do everytime and work fine.
Lot's of things work fine, but that doesn't mean they're optimal or even close to efficient and/or flexible...  Wink

There is no god.
Offline ReBirth

JGO Wizard
****

Posts: 1279
Medals: 19



« Reply #19 on: 2012-02-08 09:57:20 »

@theagentd
and not mention about reuseable, extendable and readable Wink Kev said make it run first.

Follow me, your mastah, on TWITTAH!
Offline Gingerious

JGO n00b
*

Posts: 26
Medals: 2



« Reply #20 on: 2012-02-08 16:24:22 »

Srsly gais, this is really helpful.  Also, this implementation seems like it would make sense to have a state manager class. in between the various states and the game class that holds the changeState(State state) method.
Offline antelopeDJ

JGO n00b
*

Posts: 49


Java Developer on the Weekends!


« Reply #21 on: 2012-02-13 12:15:42 »

You could use a state engine, which I believe is pretty much standard for this. I don't know how advanced your knowledge of Java is or anything, but it simplifies a lot of things and allow you to add as many different "states" as you want without having to change the main loop. It's pretty easy, but it relies heavily on object orientation, but as you have experience with C/C++ it should be a piece of cake.

Create a small State interface:
1  
2  
3  
4  
5  
package somewhere.meaningful;

public interface State{
    public void update();
}


Then create a class that implements this interface for each "state" in the game; main menu, playing, pause menu, options menu, ending credits, e.t.c.
1  
2  
3  
4  
5  
6  
7  
package somewhere.meaningful;

public class MainMenu implements State{
    public void update(){
        //Do main menu stuff
   }
}

1  
2  
3  
4  
5  
6  
7  
package somewhere.meaningful;

public class GameRunning implements State{
    public void update(){
        //Do game stuff
   }
}

E.t.c.

Your main class then looks something like this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
private State state; //Remember to set state to something in the constructor of the main class
private boolean running = true;

public void gameloop(){
    while(running){
        state.update();
    }
}

//Use this method to switch between states
public void setState(State state){
     this.state = state;
}

//Use this method to end the game
public void endGame(){
    running = false;
}


You also need to let each State keep a reference to the main class so they can actually access the setState() and endGame() functions.

Thanks for providing this! It was really helpful, and let me complete a project quicker.
Offline Blackout

JGO n00b
*

Posts: 10



« Reply #22 on: 2012-02-15 17:43:29 »

I think this is called a turn system and I believe you can just control the player's turns with booleans.
I've actually made a Battleship recently and i've implemented a turn system inside of it.
If you wanna see the code, just give me a message. xD
Pages: [1]
  Print  
 
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.16 | SMF © 2011, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.081 seconds with 20 queries.