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 (576)
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  
  your turn / my turn logic  (Read 5085 times)
0 Members and 1 Guest are viewing this topic.
Offline EddieRich

Senior Newbie





« Posted 2012-01-04 13: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

JGO Coder


Medals: 4
Projects: 2


Nathan Kramber


« Reply #1 - Posted 2012-01-04 14: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

Senior Newbie





« Reply #2 - Posted 2012-01-04 14: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! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline StonePickaxes

JGO Coder


Medals: 4
Projects: 2


Nathan Kramber


« Reply #3 - Posted 2012-01-04 14: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!
Offline theagentd
« Reply #4 - Posted 2012-01-04 15: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.

Myomyomyo.
Offline ReBirth
« Reply #5 - Posted 2012-01-04 15:36:33 »

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

Offline EddieRich

Senior Newbie





« Reply #6 - Posted 2012-01-04 16: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
Offline theagentd
« Reply #7 - Posted 2012-01-04 16:51:55 »

Have fun!  Grin

Myomyomyo.
Offline Gingerious

Junior Duke


Medals: 2



« Reply #8 - Posted 2012-02-06 22:21:26 »

Should each state implement its own key listener, or is that a bad idea?
Offline UprightPath
« Reply #9 - Posted 2012-02-07 04: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.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline gbeebe
« Reply #10 - Posted 2012-02-07 05: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.
Offline theagentd
« Reply #11 - Posted 2012-02-07 10: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

Myomyomyo.
Offline Waterwolf

Junior Duke


Medals: 3



« Reply #12 - Posted 2012-02-07 11: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!
Offline theagentd
« Reply #13 - Posted 2012-02-07 11: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.

Myomyomyo.
Offline Gingerious

Junior Duke


Medals: 2



« Reply #14 - Posted 2012-02-07 15: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
« Reply #15 - Posted 2012-02-07 18: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.
Offline theagentd
« Reply #16 - Posted 2012-02-08 03: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);
}

Myomyomyo.
Offline ReBirth
« Reply #17 - Posted 2012-02-08 12: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.

Offline theagentd
« Reply #18 - Posted 2012-02-08 14: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

Myomyomyo.
Offline ReBirth
« Reply #19 - Posted 2012-02-08 14:57:20 »

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

Offline Gingerious

Junior Duke


Medals: 2



« Reply #20 - Posted 2012-02-08 21: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

Junior Duke


Projects: 2


Java Developer on the Weekends!


« Reply #21 - Posted 2012-02-13 17: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

Senior Newbie





« Reply #22 - Posted 2012-02-15 22: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]
  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.

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

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

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

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

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

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

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

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

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

BurntPizza (82 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!