Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (109)
games submitted by our members
Games in WIP (536)
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  
  Slick2d turn based  (Read 2093 times)
0 Members and 1 Guest are viewing this topic.
Offline xproch13

Senior Newbie





« Posted 2012-07-23 19:33:21 »

Hi all,
I would like to develop small turn based game with slick2d but I cannot imagine a way how to do it in slick2d update() method. It is quite easy to develop own game loop for turn based game but how to do it in slick2d with its update/render methods? Any idea how to tell update() method to wait until something happens (keypress or player action taken)?
I have tried something like:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
   public void update(GameContainer container, StateBasedGame game, int delta)
         throws SlickException {
      boolean played = false;
     
      while (played == false) {
         Input input = container.getInput();
         if (input.isKeyDown(Input.KEY_RIGHT)) {
            container.resume();
            x = x + 32;
            played = true;
         }
      }

   }

But window got unresponsive and input never received my keypress.

I am quite new to slick2d so maybe it is just some misunderstanding of the basic library concepts on my end (very probably). Thank you.
Offline Vladiedoo
« Reply #1 - Posted 2012-07-23 19:37:32 »

Welcome to JGO  Grin.
You actually don't need to make a game loop with Slick2D, it takes care of it for you. Take a look at this link http://www.java-gaming.org/topics/slick2d-game-loop/26681/view.html

As for you game, this isn't an advanced way of doing it but you could do something along the lines of this.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
  private boolean enemyAI = false;
  private boolean player = true;

  public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
     Input input = gc.getInput();
     if (gc.hasFocus() == true){
        if (enemyAI == true){
           // Change stuff
          player ^= true;
           enemyAI ^= true;
        }
        if (player == true){
           // Change stuff
          player ^= true;
           enemyAI ^= true;
        }
     }
  }
Offline xproch13

Senior Newbie





« Reply #2 - Posted 2012-07-23 20:12:56 »

Thanks for reply. Yes, I know that slick2d takes care of update. However it does not seem to be suitable for turn based game (I press some key, slicks move my character, then some NPC tooks his turn, other NPC till my turn starts again)....I mean I cannot put my game logic to update() method because it runs too fast. In other words update would process many turns on "single" key press and thats not what you want in turn based games. However I kind of solved it by putting game logic to overriden keyPressed(int, char) method....hope it will work.
And there comes another question....I need custom keyrepeat intervals. How can this be achieved since "public void enableKeyRepeat(int initial,
int interval) is deprecated and does not seem to work? Sad
Thanks again.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Vladiedoo
« Reply #3 - Posted 2012-07-23 20:16:21 »

To fix
Quote
In other words update would process many turns on "single" key press and thats not what you want in turn based games.
change
1  
if (input.isKeyDown(Input.KEY_RIGHT)) {
to
1  
if (input.isKeyPressed(Input.KEY_RIGHT)) {

To fix
Quote
However it does not seem to be suitable for turn based game (I press some key, slicks move my character, then some NPC tooks his turn, other NPC till my turn starts again)....I mean I cannot put my game logic to update() method because it runs too fast.
Slick2D is an amazing engine, a turn based game can easily be achieved with it if you code the correct logic into it. I'm not a very good programmer yet so I can't give you a straight answer for the game logic on a turn based game (it also depends heavily on what kind of turn based game it will be) but it's very do-able.

To fix
Quote
And there comes another question....I need custom keyrepeat intervals. How can this be achieved since "public void enableKeyRepeat(int initial,
int interval) is deprecated and does not seem to work?
enableKeyRepeat(int initial, int interval) is indeed Deprecated. But if you look at this link http://slick.cokeandcode.com/javadoc/org/newdawn/slick/Input.html you can see that enableKeyRepeat() still works but I'm not sure how to use it, I'll do some research on that.
Offline jonjava
« Reply #4 - Posted 2012-07-23 20:49:12 »

Different States?

1  
2  
3  
public final int START_SCREEN;
public final int GAME_ROOM;
public final int BATTLE;

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
update() {

   keyboardCheck();
   mouseCheck();

   switch (state) {
      case START_SCREEN: break;
      case GAME_ROOM: break;
      case BATTLE:
         if (turn == 1) { /* do stuff */ }
   }
}


Would that work?

Offline Vladiedoo
« Reply #5 - Posted 2012-07-23 20:59:42 »

If you want to make different states Slick2D already has a StateBasedGame you can extend  Cheesy.
Have your main class look like this https://bitbucket.org/kevglass/slick/src/development/trunk/Slick/src/org/newdawn/slick/tests/StateBasedTest.java

Then you should make three classes called TestState1, TestState2, and TestState3. But for your case you can change the code and class names to START, GAME, and BATTLE. Those three classes will each extend StateBasedGame, so each of those three classes will have a init(), update(), and render(). To switch between states you call this in the update method for example
1  
2  
3  
4  
5  
      if (input.isKeyPressed(Input.KEY_ESCAPE)) {
         PsionicEntrance.PREVIOUSSTATE = PsionicEntrance.CREDITS;
         PsionicEntrance.CURRENTSTATE = PsionicEntrance.MENU;
         sbg.enterState(PsionicEntrance.MENU);
      }

That's how I exit out of my credits screen to my main menu. PsionicEntrance is my main class and it contains static IDs of all the classes. Ah right I forgot to mention, your three classes will also need this code at the end.
1  
2  
3  
   public int getID() {
      return PsionicEntrance.CREDITS;
   }

My main class then contains this code
1  
   public static final int CREDITS = 5;// Credits screen

If this was poorly explained I can modify this post  Grin.
Offline xproch13

Senior Newbie





« Reply #6 - Posted 2012-07-23 21:17:48 »

Different States?

1  
2  
3  
public final int START_SCREEN;
public final int GAME_ROOM;
public final int BATTLE;

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
update() {

   keyboardCheck();
   mouseCheck();

   switch (state) {
      case START_SCREEN: break;
      case GAME_ROOM: break;
      case BATTLE:
         if (turn == 1) { /* do stuff */ }
   }
}


Would that work?

I am already using StateBasedGame superclass in my project but it is good for menus, etc. (I can imagine using it for switching levels if count is limited) but probably not for game logic.
I would also like to separate key controls from game update (to avoid loong if/else/switch statements in the main update method) so I will probably put it to different class implementing one of the InputListeners (maybe to hero class or to seperate one and use composition...need to think about it). We will see what turns out to be the best way Smiley
Thanks for suggestions.
Offline MashedPotatoe

Senior Newbie





« Reply #7 - Posted 2012-07-27 05:35:45 »

change
1  
if (input.isKeyDown(Input.KEY_RIGHT)) {
to
1  
if (input.isKeyPressed(Input.KEY_RIGHT)) {


This is the easiest way to achieve it, although actions only occur after the key has been released again.

Another way would be to block the input for a certain time after an action has been processed. For example:
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  
private int timeToBlock = 100;
private int time = 0;
private boolean played = false;

public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {

  Input input = gc.getInput();
 
  if (time == 0 && played == false) {
    if (input.isKeyDown(Input.KEY_RIGHT)) {
            container.resume();
            x = x + 32;
            played = true;
            time += delta;
     }
  } else if (time > 0 && time < timeToBlock) {
      time += delta;
  } else if (time >= timeToBlock) {
      time = 0;
  }

  if (played == true) {
    //process AI stuff
   played = false;
  }


Certainly not the most beautiful piece of code but it does it's job. Input is processed when it's the player's turn and no action has been performed for a given time (timeToBlock).
When you press a key, the action is processed, the AI can do it's stuff and the timer starts. When the time limit has been reached input is "unlocked" again.

Offline UprightPath
« Reply #8 - Posted 2012-07-27 06:29:48 »

Personally, I'd go about it a different way. I mean, yes using flags will work, but they're... Inelegant. Cheesy

Anyway, I'd honestly make the turn-based control into something of a state machine in its own rights. A very basic one, but one none the less.

Here's a snippet of how it'd do it.

It also allows you to add other effects to the turn-based list. Basically, you register a 'State' with the Context, and the context will keep calling 'actionPerformed()' on the state until it sets its 'actionPerformed' to true. At that point, it'll move that state to the end of the list, then start doing the same on the next state. Probably using the wrong term for doing it this way, but... Anyway, it allows you to add a variable number of entities/effects that have to work in the turn based manner.

Offline xproch13

Senior Newbie





« Reply #9 - Posted 2012-07-27 15:35:07 »

Thanks, this one looks like really solid design. Now, I have some testing implementation of flag-based turns and it seems to be working fine....we will see how it works with more features added. If it does not work well, I will definitely move to your state based design...
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #10 - Posted 2012-07-27 18:02:31 »

If you want the game loop to be slower, you could add up the delta time and only execute a block once the delta has built up enough. I wouldn't advise that you do this for turn-based gameplay though. It's rather if you want something executing at a specific pace, like animation.


Offline MashedPotatoe

Senior Newbie





« Reply #11 - Posted 2012-07-27 21:00:55 »

I have two questions about UprightPath's paste-bin code:

Is there any benefit in using something like that over a simple enhanced for loop through ArrayList<Entity>?

And is an ArrayList "fit" to be used as a queue(cutting the first element and putting it at the back)? I realize that thinking about the most efficient container can lead to long discussion and is most of the time only noticeable at very high number of elements, so take this question with a grain of salt.

My game is turn based, too, so I have a genuine interest in what needs tweaking/changing in my code.
Offline sproingie

JGO Kernel


Medals: 202



« Reply #12 - Posted 2012-07-27 21:05:40 »

An ArrayList is not ideal as a queue because it will have to shift the whole array either on every put or on every get.  You can maintain a ringbuffer yourself to avoid that, but an easier route would be to just use an ArrayDeque instead

Offline UprightPath
« Reply #13 - Posted 2012-07-27 22:57:31 »

Yeah, thinking about it using an ArrayList isn't the best, as was said. I just used that because it was the first thing that came to mind (Next to using a LinkedList, which would have performed the task rather admirably, since you shouldn't have to worry too much about its performance since changes would only happen during certain steps).

Is there any benefit in using something like that over a simple enhanced for loop through ArrayList<Entity>?
I did it like that for the express reason of allowing you to turn the TurnState into another state machine that would allow you to display different state information based on what's happening. Basically, it keeps returning to whatever the current 'Entity State' is until that state says it's done with its job.

If you turn the Entity's TurnState into another state machine itself, you can make it so that your player's entity is constrained by a set of states/actions it can perform. Think like the older Turn based RPGs where your character can move then make an action. This is modeled fairly well as a state machine.

Further, you can use this method to allow different 'stages' of your AI's decisions to be spread out across multiple frames.

Offline Jimmt
« League of Dukes »

JGO Kernel


Medals: 128
Projects: 4
Exp: 3 years



« Reply #14 - Posted 2012-07-27 23:16:09 »

Welcome to JGO  Grin.
You actually don't need to make a game loop with Slick2D, it takes care of it for you. Take a look at this link http://www.java-gaming.org/topics/slick2d-game-loop/26681/view.html

As for you game, this isn't an advanced way of doing it but you could do something along the lines of this.
Wait, Slick2D has a built-in game loop? Maybe I should try it...
Offline UprightPath
« Reply #15 - Posted 2012-07-27 23:17:52 »

The use of the GameState and all of that jazz provides you with a fairly well written game loop, which you can then adjust the FPS max on and the like.

I used it for a bit of stuff and it did take a lot of the work out of getting it to trigger right. :3

Offline MashedPotatoe

Senior Newbie





« Reply #16 - Posted 2012-07-28 00:04:57 »

Maybe I just needed some time to let it sink in but now your state based system - or some sort of it anyway - seems like the way to go.

Makes multiple actions like looking around or talking to another entity much easier without having to use flags for everything. The more I think about it, the better it gets  Wink
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.

CogWheelz (18 views)
2014-07-30 21:08:39

Riven (26 views)
2014-07-29 18:09:19

Riven (15 views)
2014-07-29 18:08:52

Dwinin (13 views)
2014-07-29 10:59:34

E.R. Fleming (34 views)
2014-07-29 03:07:13

E.R. Fleming (12 views)
2014-07-29 03:06:25

pw (43 views)
2014-07-24 01:59:36

Riven (44 views)
2014-07-23 21:16:32

Riven (30 views)
2014-07-23 21:07:15

Riven (31 views)
2014-07-23 20:56:16
List of Learning Resources
by SilverTiger
2014-07-31 18:29:50

List of Learning Resources
by SilverTiger
2014-07-31 18:26:06

List of Learning Resources
by SilverTiger
2014-07-31 13:54:12

HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54
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!