Turn- and tilebased Pirategame in AGS

Started by Matti, Thu 16/10/2008 12:09:41

Previous topic - Next topic

Matti

I am planning to make a game where you are a pirate, have your ship and go plunder other ships, trade in cities etc. It should be turnebased and every turn the player can move the ship from one area to another (I don't think they can be called tiles).

I could program that with Turbo Pascal (I'm not familiar with any other language), but there are several reasons why I'd prefer doing it with AGS. So my questions are:

1. Is it possible / Is AGS capable of such idea?
2. Would it be very difficult?
3. What would be the best way?

I have two major problems:

1. I don't know what the best way to move the ship is. I could create hotspots for every "area" and a certain place where the ship is placed. I could number all the areas to check where the ship can move to. Another thing (2nd screenshot) would be to make the areas rectangular and always place the ship in the middle. Then perhaps a keyboard control would be adequate. But then again there would be land areas where the ship isn't supposed to be.

2. I don't have the slightest idea how to make some sort of an algorithm to let the player choose between several maps without having to script the same things for every map.

Here are the screenshots. They're very rough sketches, so don't mind the look.






Any ideas? Tell me if AGS isn't the right choice to do something like that. And tell me too if this would be too circuitous and difficult to script.

RickJ

The obvious thing that comes to mid is to just make your little ship be the player character.   Draw the walkable areas on the map where the ship can go and just have it walk to where ever the walk (or sail) cursor is clicked.  If you want it to go to a specific spot then each grid can have a walk-to point.

Khris

At first I'll try to address your specific issues:

1. Definitely.
2. It'll be much work rather than difficult, especially because of you having programming experience.
3. See below for a few ideas.

Problems:
1. See below.
2. Every map is stored in some sort of database; the main game logic loads the level data, then handles everything. Depending on the implementation, the game will use a single room or one for each map.

Tiles (single, dynamically drawn room):
Do it like Colonization. The map is made of small tiles, the ship can move several per turn.
Advantage: the map is relatively easy to handle (ship moves right -> check tile (x+1:y) and move if water)

Your first screenshot (one room for each map):
Use a chessboard pattern of hotspots and regions (e.g. hotspots as columns, regions as rows). Thus, every area is represented by a single hotspot X-region Y-combination. Each level will need area data holding the adjacent water areas. Movement is done by clicking one of them.

Matti

Quote from: KhrisMUC on Thu 16/10/2008 14:40:05
Your first screenshot (one room for each map):
Use a chessboard pattern of hotspots and regions (e.g. hotspots as columns, regions as rows). Thus, every area is represented by a single hotspot X-region Y-combination. Each level will need area data holding the adjacent water areas. Movement is done by clicking one of them.

I'd favor the one room for each map idea over the one with the tiles. But could you expand your idea a bit? I don't quite understand how you imagine the hotspot-region-combination.

Khris

Draw the hotspots like this:


Then similarly, draw rows using regions.
Thus, say the player clicked hotspot 3 and region 2, you can exactly determine the area the player clicked (by looking up the pair in a little "database" set in every room).
(Of course hotspots and regions have to be drawn in a way that every combination occurs exactly once.)

Matti

Hey, thanks. That's a good idea.

I'll try it out and see if any further problems occure.

Matti

#6
Okay, I'm able to correctly move the ship now, checking what area the ship is in and what area is clicked. But I'm afraid my scripting idea isn't a very practical one and it will be a lot of work if I'm continuing it this way.

Here's my code for one map (room). I've given every area a certain number. When clicking on a hotspot the region is checked too. Then, when th ship is currently placed on a adjacent area it will move.

EDIT: This code just lets you move between 3 of the 40 areas (29, 30 and 36).

Code: ags

// room script file

int ship_place=30;

function room_RepExec()
{
if (ship_place==29) { cship.x=33;cship.y= 267; }  // Defining the exact ship coordinates, depending on the area it's on
if (ship_place==30) { cship.x=69;cship.y= 252; } 
if (ship_place==36) { cship.x=77;cship.y= 276; }
if (ship_place==37) { cship.x=131;cship.y= 269; }

}

function hHotspot1_AnyClick()
{
  if (Region.GetAtRoomXY(mouse.x, mouse.y) == region[1]){    // Area 29 is clicked
  
    if (ship_place==30 || ship_place==36){
      ship_place=29;
    }
  }
}

function hHotspot2_AnyClick()
{
  if (Region.GetAtRoomXY(mouse.x, mouse.y) == region[1]){
  
    if (ship_place==29 ||ship_place==30 || ship_place==37){   // Area 36 is clicked
      ship_place=36;
    }
  }
  if (Region.GetAtRoomXY(mouse.x, mouse.y) == region[2]){     // Area 30 is clicked
  
    if (ship_place==29 ||ship_place==36 || ship_place==37){
      ship_place=30;
    }
  }

}


If I have to do this for every ~40 areas per map I think I'm going insane..

Does anybody have an idea how to make the code shorter?

Khris

Look into two-dimensional arrays. There's a relatively simple way using a struct to get a[p].b[q] working:
Code: ags
// header 
struct twodim {
  int b[20];
};

// room script

twodim a[20];  // provides you with a twodimensional array with 400 elements, going from a[0].b[0] to a[19].b[19]


-put the area index into hotspot[p].region[q].
-now use another array: put the possible areas to move to into area[p].adjacent[q]
(you'd do this in a seperate function and call it in before fadein
also note that there's no way around this if you're using arbitrary shaped areas)

Code: ags
int check_click() {
  Hotspot*h = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
  Region*r = Region.GetAtRoomXY(mouse.x, mouse.y);   // adjust for scrolling rooms
  int clicked_area = hotspot[h.ID].region[r.ID];
  int i;
  while (i<10) {
    if (area[ship_place].adjacent[i] == clicked_area) return clicked_area;   // dirty ;)
    i++;
  }
  return 0;
}

// set every hotspot's OnClick to this function:
hotspot_AnyClick() {
  int new_area = check_click();
  if (new_area == 0) Display("You can't go there.");
  else {
    // move ship, etc.
  }
}

SMF spam blocked by CleanTalk