[Java] concept of a Turn based system (WIP)

A place for tutorials on how to get the most out of Flash

[Java] concept of a Turn based system (WIP)

Postby BlueLight » Sun May 19, 2013 10:27 am

Sorry, but grammar still needs work.


I make the assumption you know how to program in java but if you program in some other language then the concept should be very similar but milage may vary based on your API. I am making available my self made library for game development. It is likely going to help if you have the files. There are about 8 files in the spoiler i suggest you have on hand.

Items you might need before we start.
Spoiler (click to show/hide):

Here is a library I'm working on for game development but be warned it's very basic.
BIP.zip
(4.04 KiB) Downloaded 259 times


here is the main class for the program i made. Might help if you use this.
Code: Select All Code
import java.awt.List;
import java.util.ArrayList;

import BIP.EntityInterface;
import BIP.EntityList;
import BIP.TurnController;

//writen by Jordan C.D.

public class Main_TurnTest {
   public static gui gui = new gui();
   public static EntityList entityList = new EntityList(); // The list are for, entities that will be used in turn system.
   public static TurnController trunController; // This object is used to control the turns.
   
   public static void main(String[] args){
      
      //These are the list. I'm using a entity list because it already has a "EntityInterface" required for a object to be added and this is what it was designed for.
      ArrayList<EntityInterface> exclusionList = new EntityList();
      
      //Both BlueSlimes are a sub class of Entity but wont be added to the exclusion List.
      BlueSlime monster1 = new BlueSlime();
      BlueSlime monster2 = new BlueSlime();
      
      //Players are a sub class of Entity but will be added to the exclusion List.
      Player p = new Player();
      System.out.println(p.toString());
      //These are being added to entityList
      entityList.add(monster1);
      entityList.add(monster2);
      entityList.add(p);
      
      
      //These objects are items that will be excluded from normal actions when turnController runs turn manager.
      exclusionList.add(p);
      
      //creating the trunController
      trunController = new TurnTestController(entityList, exclusionList);
      trunController.turnOn();
   }
}



Here is the code i use to control my turns for my tech demo.
Code: Select All Code
import java.util.ArrayList;

import BIP.EntityInterface;
import BIP.EntityList;
import BIP.TurnController;


public class TurnTestController extends TurnController {

   public TurnTestController(
         EntityList//<EntityInterface>
         entityList,
         ArrayList<EntityInterface> list) {
      super(entityList, list);
      // TODO Auto-generated constructor stub
   }

   //returns the size of the entityList. Doesn't need to be in this class.
   protected int getEntityListSize() {
      // TODO Auto-generated method stub
      return this.entityList.size();
   }

   //normal routine for handling the average entity.
   protected void runNormalRoutine() {
      System.out.println("Normal routine ran.");
      this.getCurrentEntity().runAICommand();
   }

   //normal routine for handling the player entities.
   protected void runPlayerRoutine() {
      System.out.println("player routine ran.");
      this.getCurrentEntity().runAICommand();   
   }

}

GUI i had my IDE create. This will be how we test the turn system.
Code: Select All Code
import java.awt.BorderLayout;


public class gui extends JFrame {

   private JPanel contentPane;

   /*public static void main(String[] args) {
      EventQueue.invokeLater(new Runnable() {
         public void run() {
            try {
               gui frame = new gui();
               frame.setVisible(true);
            } catch (Exception e) {
               e.printStackTrace();
            }
         }
      });
   }*/

   /**
    * Create the frame.
    */
   public gui() {
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setBounds(100, 100, 450, 300);
      contentPane = new JPanel();
      contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
      contentPane.setLayout(new BorderLayout(0, 0));
      setContentPane(contentPane);
      
      JButton btnTest = new JButton("TEST");
      btnTest.addActionListener(new action());
      contentPane.add(btnTest, BorderLayout.CENTER);
      this.setVisible(true);
   }

   private class action implements ActionListener {
      
      public void actionPerformed(ActionEvent e) {
         Player p = (Player)Main_TurnTest.trunController.getCurrentEntity();
         p.turnActiveOff();
         
      }
   }
}




So one of the problems i found was while programming my games is how to get the AI to interact with the player and the world. Less about programming the AI itself and more how to get them to at least drool on the floor in turns with the player. The idea is to make the player think he's the smartest person in the room.

The concept for doing a turn system is to use in your monsters, party members and player; a base class. I always call my base class Entity. You follow up that by using something like a arraylist and adding your based class as the generic type.
Spoiler (click to show/hide):

For a example of this, go into the bip folder i gave you and open these 3 files. abstarctEntity, EntityInterface, and EntityList.
EntityList is a carbon copy of arraylist except only objects that are type EntityInterface can be added to it. However abstractEntity implements EntityInterface so you can add it to a EntityList. You'll just only be able to use methods that are in EntityInterface. Any class that extends abstractEntity may also be added to the EntityList.

Now that we have an arraylist to use, we're going to make a loop that will go through the arraylist objects and run are AI command. Here would be a example assuming that your base class has a public method called "runAICommand();"

Code: Select All Code
public void turnManagement(){
      while(keepActive){
         this.getCurrentEntity().runAICommand();
      }
      System.out.println("turrnManagement has been turned offline.");
   }

Now here's a problem with the loop. This loop will go until the end of time, and wont stop to allow the player to move. the way around that is either make your Player class smart enough to pause this loop somehow or the make the loop itself smart enough.
My solution is to do both and be silly about it. Now this next example i'm taking directly from my bip library and the file name is TurnController.

Code: Select All Code
   public void turnManagement(){
      while(keepActive){

         boolean i = this.testObjectForTurnManger.contains(getCurrentEntity()); //
         
         if(!i){runNormalRoutine();}
         else  {runPlayerRoutine();}
      }
      System.out.println("turrnManagement has been turned offline.");
   }

Spoiler (click to show/hide):

Code: Select All Code
boolean i = this.testObjectForTurnManger.contains(getCurrentEntity());

So in my Bip library turn manager class, i use 2 array list. One contains all the entities that will be handled and the other contains the entities that have exceptions to how they will be handled. The getCurrentEntity(); method returns the object of the current entity and then i check the array with all the entities that will have exceptions has the current entity inside of it. If the entity is in both list, then I is true. If it's not in both list than I is false. If it's not in the main array, the entity will never be called by this loop.

runNormalRoutine(); & runPlayerRoutine(); are both abstract methods that require you to extend the TurnController class and initialize. their methods that allow you to determine what action you do with normal entities and what you do with player entities. You don't have to use these methods as my first loop should show.
in my program i basically just have this.getCurrentEntity().runAICommand(); in both runNormalRoutine(); & runPlayerRoutine(); but i also have a system.out.println message that is different for each.


What really need to do however is to pause the loop using the player class. There are two ways i've figured out how to do this and it really depends how you the player to control the game. The first way is if i you have a console based game. The simplest way is to just do this.
Code: Select All Code
   public void runAICommand() {
         Scanner scan = new Scanner(System.in);
              System.out.println(scan.nextInt());
      }


the method scan.nextInt() will wait until the user inputs a values. Just follow that up with some if statements and that's one way of dealing with turns.
Be warned that nextInt() will only work if you the user inputs a integer. However if you want to make this solution work for your needs, than i suggest you read the JAVA API on the class. http://docs.oracle.com/javase/6/docs/api/

Now lets say we have a GUI. We can't just use scanner like we just did. This solution is a bit more of a hack and is a waste of resources but it works for me.
Assume we have a instants variable that is "boolean active = true;".
Code: Select All Code
public void runAICommand() {
      //we're going to need this boolen to be true for the while loop.
      active = true;
      //give information about game state in console.
      System.out.println("Game waiting for player command");
      while(active){
         //must have some statement inside the loop or the loop will never end. Reasons: Unknown.
         System.out.print(""); // println must not have any other value other than a empty string or the console will clear all text after a few seconds.
      } // pause the game, the brute force method.
      
      //tells the users that the game is no longer paused
      System.out.println("Game got player command");
      
      // what the player does.
      System.out.print("{Players uses normal attack.}");
   }
   
   public void turnActiveOff(){
      //changes the active boolean to false to turn off the while loops that would be running in "runAICommand();" method.
      this.active = false;
      }

Basically with this all you have to do is make the action listener in your GUI find this object and use the turnActiveOff(). then when the loop in the loop object runs again, it will notice the active boolean is false and wont run again. If you want a example, in the first spoiler box, there is a class called gui , the action lister does this exact thing.

I assume you have a system set up to move the player object around already. What i did in my last game was make a AI class for entities, and then made a player AI. I put the player AI in the GUI as a instance variable and also in the player object. Then, when i wanted to move my character i could just send the commands to the AI and it would move the player. You could use the same concept here.
User avatar
BlueLight
Gangs n' Whores Developer
 
Joined: Sat Jun 04, 2011 8:23 am

Return to Tutorials



Who is online

Users browsing this forum: No registered users