Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (488)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (553)
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  
  Roguelike turns  (Read 2281 times)
0 Members and 1 Guest are viewing this topic.
Offline RylandAlmanza

Junior Member


Medals: 3



« Posted 2012-03-12 22:51:58 »

So, I've been making a roguelike for a while, and I've just recently started thinking about the turn system. Right now, I have a very simple system. Every entity has a step() method. Every time a key is pressed, first the player's step method is called, then I loop through the enemies and npc's and call their step methods. This has worked fine so far, but it's a bit limited.

For example: Let's say we want the player to fire an arrow, and then every other entity waits until the arrow has hit something. This would not work with my system, because the enemies step right after the player steps. The other entities would step right as the arrow is fired, instead of waiting for it to hit something.

So, does anyone know of a method for timing a roguelike that is better than mine, but not too complex? Thanks!
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #1 - Posted 2012-03-12 23:04:24 »

I have all creatures return an Action that then get's processed. Only once it's done does that creature's turn finish and I begin the next one. Something like:

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  
interface Creature
{
  public Action takeTurn();
}

interface Action
{
  public void update();
  public boolean isFinished();
}

class Map
{
  public void update()
  {
    switch (state)
    {
      TAKE_TURN:
         action = creature.takeTurn()
      PERFORM_ACTION:
         action.update();
         if action.isFinished()
           creature = getNextCreature()
           state = TAKE_TURN
     }
  }


One of the nice things is that most of the logic goes in the action, so it can be shared between player, npc and enemies easily. Shooting an arrow would be in a ShootArrowAction, and once it's created it works the same regardless of who actually shot it.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline sproingie

JGO Kernel


Medals: 202



« Reply #2 - Posted 2012-03-12 23:50:01 »

I'm not sure why the firing action isn't resolved in the player's step()?  Is the arrow a separate entity?  If so, then you probably need to prioritize the arrow's step() before anyone else.  If you want to animate the arrow in steps, you should think of animation steps as separate from the simulation steps.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline KrazyTheFox

Innocent Bystander





« Reply #3 - Posted 2012-03-13 14:37:44 »

I've adapted the following for use in my roguelike and am liking it quite a bit: http://roguebasin.roguelikedevelopment.org/index.php/A_simple_turn_scheduling_system_--_Python_implementation

It essentially keeps a list of which events occur on each tick. When advanceTime() is called (For example, when the player moves, he might call advanceTime(5)), it cycles through each tick and calls whatever AI or Events need updating until it reaches the new tick. Unfortunately I need to leave for class now, but this should hopefully help point you in the right direction when creating your system.

I'm sure that there's improvements to be made here, as I've only been learning Java for a couple of months now, so just remember that this is probably not as well written as it could be.

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  
package net.krazyweb.dungeoncrawler;

import java.util.ArrayList;
import java.util.HashMap;

import net.krazyweb.dungeoncrawler.entity.LivingEntity;
import net.krazyweb.dungeoncrawler.entity.livingentities.Player;
import net.krazyweb.dungeoncrawler.event.Event;

public class Ticker {
   
   private long ticks;
   
   private HashMap<Long, ArrayList<LivingEntity>> schedule;
   private HashMap<Long, ArrayList<Event>> eventSchedule;
   
   public Ticker(long ticks) {
      this.ticks = ticks;
      this.schedule = new HashMap<Long, ArrayList<LivingEntity>>();
      this.eventSchedule = new HashMap<Long, ArrayList<Event>>();
   }
   
   public void advanceTime(int time) {
      for (int t = 0; t < time; t++) {
         
         ticks += 1;
         
         if (schedule.containsKey(ticks)) {
            for (int e = 0; e < schedule.get(ticks).size(); e++) {
               LivingEntity entity = schedule.get(ticks).get(e);
               if (!(entity instanceof Player))
                  entity.ai.action(entity);
            }
         }

         if (eventSchedule.containsKey(ticks)) {
            for (int e = 0; e < eventSchedule.get(ticks).size(); e++) {
               Event event = eventSchedule.get(ticks).get(e);
               event.action();
            }
         }
         
      }
   }
   
   public long scheduleTurn(int interval, LivingEntity entity) {
     
      if (!schedule.containsKey(ticks + interval)) {
         schedule.put((ticks + interval), new ArrayList<LivingEntity>());
         schedule.get(ticks + interval).add(entity);
      } else {
         schedule.get(ticks + interval).add(entity);
      }
     
      return ticks + interval;
     
   }
   
   public long scheduleEvent(int interval, Event event) {
     
      if (!eventSchedule.containsKey(ticks + interval)) {
         eventSchedule.put((ticks + interval), new ArrayList<Event>());
         eventSchedule.get(ticks + interval).add(event);
      } else {
         eventSchedule.get(ticks + interval).add(event);
      }
     
      return ticks + interval;
     
   }
   
   public void unScheduleTurn(long nextMoveTick, LivingEntity entity) {
     
      if (schedule.containsKey(nextMoveTick)) {
         schedule.get(nextMoveTick).remove(entity);
      }
     
   }
   
   public void unScheduleEvent(long nextMoveTick, Event event) {
     
      if (eventSchedule.containsKey(nextMoveTick)) {
         eventSchedule.get(nextMoveTick).remove(event);
      }
     
   }
   
   public void scheduleTurnLoad(long tickToAdd, LivingEntity entity) {
     
      if (!schedule.containsKey(tickToAdd)) {
         schedule.put((tickToAdd), new ArrayList<LivingEntity>());
         schedule.get(tickToAdd).add(entity);
      } else {
         schedule.get(tickToAdd).add(entity);
      }
     
   }
   
   public long getTicks() {
      return ticks;
   }
   
}
Offline Archibald

Junior Member


Projects: 1



« Reply #4 - Posted 2012-03-13 19:39:42 »

You don't put missiles in the same system as player/monster turns in roguelikes (althrough it would be logical if you were making RPG). Missiles are instant things, these are part of display system, not game logic system. Players/monsters do their things. When one of the actions is fire a missile, you stop the execution of player turns (actually you don't have to stop anything since roguelikes are turn based) and display animation of missile moving around. When all animations are finished the player is allowed to press next button.

Also note that things will get hairy if you have various speed of monsters. In such case the typical solution is to move the entity (monster/player) with the highest remaining speed, when none of the entites have enough speed to move the speed is replenished by the base speed.
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.

TehJavaDev (17 views)
2014-08-28 18:26:30

CopyableCougar4 (26 views)
2014-08-22 19:31:30

atombrot (39 views)
2014-08-19 09:29:53

Tekkerue (36 views)
2014-08-16 06:45:27

Tekkerue (33 views)
2014-08-16 06:22:17

Tekkerue (22 views)
2014-08-16 06:20:21

Tekkerue (33 views)
2014-08-16 06:12:11

Rayexar (68 views)
2014-08-11 02:49:23

BurntPizza (45 views)
2014-08-09 21:09:32

BurntPizza (36 views)
2014-08-08 02:01:56
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

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

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!