More regions..

Started by Slasher, Sun 14/06/2015 15:28:52

Previous topic - Next topic

Slasher

Hi,

is there a working ags version that gives more regions than 3.2.1?

cheers

Crimson Wizard

Not yet.
There is unstable version here, only for test, but I won't suggest using it for actual game: http://www.adventuregamestudio.co.uk/forums/index.php?topic=51349.0

Khris

If you told us what exactly you need them for, we could suggest a workaround.
In fact, simply painting the regions on a room background-sized sprite and checking color values at character coordinates for entering and leaving will basically increase the number of regions to 16 million.

Slasher

#3
Hi,

Khris:
QuoteIf you told us what exactly you need them for, we could suggest a workaround.
Board game using Addpoint's (destination squares - done) but also need to reference 'start' points (square of where player is - thinking of turning on/off bools option with regions). Moves can be from roll of the dice or card chosen from pack.

hope this explains what i am trying to do.


Khris


Slasher

Quote from: Khris on Sun 14/06/2015 21:52:48
Not really.

Adding a reference point to what square the player is on. After throwing the dice the player moves to appropriate destination square by way of WalkToPoint locations.

Code: ags

// A WalkToPoint destination
 player.WalkToPoint(EGlen, eBlock);


example:
Say player is on square 50 and throws a five he will go forward 5 squares to square 55 etc.

This is based on knowing what square player is on.


Snarky

#6
I'm not sure exactly what you're doing either, but I gather you want to use regions to represent squares on a game board?

In cases like this, it's usually better to represent the board in code (e.g. as a 2D array), and then just have some code to map the square to its position on the screen. (If it's a top-down view, that code should be very simple; if it's a perspective view it will be a little trickier, but you can probably use a hybrid region-for-x-coord/code-for-y-coord solution to avoid having to calculate 3D projections.)

Edit: Oh, I see. I was thinking a grid board, not a "move your marker along a path"-type board. In that case, I would get rid of the regions entirely: just have two arrays with the x- and y-coordinates of the walk-to points of each square, and a variable storing the player's current square.

Slasher

Early version of board with walkable area (player only moves (auto clockwise) once dice is thrown or by a card chosen):

MoonDog

I don't know if my idea is possible but maybe use objects instead of regions. You
Could maybe set it so that when character is colliding with object a and rolls a dice number
It then moves to object b. I don't know tho since I'm still new to this.

Snarky

No, I already explained how to do it. Get rid of all the regions, just do this:

First, (mentally) number all the squares from 0-41 (or however many you have). Then write some real simple code:

Code: ags
#define SQUARE_COUNT 42
int currentSquare;
int squareX[SQUARE_COUNT];
int squareY[SQUARE_COUNT];

// Call this probably from "player enters room before fade-in"
void initBoard()
{
  // Enter the coordinates of each square here:
  squareX[0] = 16; squareY[0] = 32;
  squareX[1] = 32; squareY[1] = 32;
  squareX[2] = 48; squareY[2] = 32;
  // ...
  // (This is the naive way; you can also calculate it based on h_gap and v_gap values, but let's keep it simple)
}

void movePlayer(int squaresToMove)
{
  // I'm not sure exactly how the little detours work, so I'm just assuming a linear (loop) board.
  // If choice of path is automatic you can code it here, if it's a player choice you should probably determine it outside of this function
  currentSquare = (currentSquare + squaresToMove) % SQUARE_COUNT; // The % is a modulo and makes the board wrap around, so e.g. square 45 = 3
  player.Walk(squareX[currentSquare],squareY[currentSquare]);
}

Slasher

Cheers Snarky,

it seems to work with my player.WalkToPoint after the dice is thrown...

Code: ags

player.Walk(squareX[currentSquare],squareY[currentSquare]);
player.WalkToPoint(EMordor, eBlock, eWalkableAreas);    


I will do some more testing and report back...

cheers mate ;)

Snarky

If that's meant to represent one move, it looks awfully redundant. What I'm proposing is that you stop using regions for the squares entirely, and therefore ditch WalkToPoint() along with them, replacing it with the Walk() call.

Slasher

I had to add:

Code: ags
if(currentSquare==21)


QuoteWhat I'm proposing is that you stop using regions for the squares entirely, and therefore ditch WalkToPoint() along with them, replacing it with the Walk() call.

You mean like if a 6 is thrown from square 21 then walk to square 27 for example?

also i have no regions..

EDIT
I now use this that seems to work and does away with the WalkToPoint(s):

example
Code: ags

if(oDice.Frame >=0) // after dice has rolled.
 {
 cGandolf.SayAt(cGandolf.x+9, cGandolf. y-100, 500, "You have thrown a one. You may proceed on.");
 oTumbler.Move(oTumbler.X, oTumbler.Y+40, 2, eBlock, eAnywhere);
 
 if(currentSquare==21)
 player.Walk(squareX[currentSquare],squareY[currentSquare]);
 player.Walk(squareX[0], eBlock); 
   
 roll=false;

}
// etc etc


it will mean tons of scripting as there are 29 squares.

unless of course you question it (nod)

cheers, it's getting there.....



Snarky

#13
No. I don't even understand what you're trying to do here. Why do you need a special test for (currentSquare==21)? Why do you first walk to (squareX[currentSquare],squareY[currentSquare]), and then to some other, completely unrelated coordinate?

Also, this call is wrong:

Code: ags
player.Walk(squareX[0], eBlock);


You always need two coordinates for the .Walk() function. This only works by interpreting the eBlock enum as a coordinate (probably 0 or 1). Also, you haven't indented correctly, so it's unclear whether you mean both or only one of the Walk() lines to be conditional on the currentSquare==21 test.

.
.
.

You're making this way more complicated than it needs to be. It's really quite simple:

-The player is standing on currentSquare (any number from 0 to SQUARE_COUNT-1)
-You throw a die or draw a card or whatever, which tells you how many squares the player moves
-You take currentSquare + that value to get the ID of the square the player should move to, modulo SQUARE_COUNT so that it loops around
-If, in some cases, the player should move to a different square than this calculation suggests (one of the detours on the board), you program that in as a special case
-You set currentSquare to the new value
-You tell the player to walk to the coordinates of the new currentSquare, i.e. (squareX[currentSquare],squareY[currentSquare])

Is there any step of this you don't understand?

Slasher

Here is the basic board with numbers for reference:


Code: ags

 //ROOM LOAD
void initBoard()
{
  squareX[0] = 50; squareY[0] = 470;
  squareX[1] = 50; squareY[1] = 368;
  squareX[2] = 50; squareY[2] = 268;
  squareX[3] = 132; squareY[3] = 368;
  squareX[4] = 50; squareY[4] = 180;
  squareX[5] = 136; squareY[5] = 173;
  squareX[6] = 225; squareY[6] = 173;
  squareX[7] = 225; squareY[7] = 249;
  squareX[8] = 314; squareY[8] = 173;
  squareX[9] = 396; squareY[9] = 173;
  squareX[10] = 485; squareY[10] = 173;
  squareX[11] = 575; squareY[11] = 173;
  squareX[12] = 575; squareY[12] = 237;
  squareX[13] = 658; squareY[13] = 173;
  squareX[14] = 744; squareY[14] = 173;
  squareX[15] = 744; squareY[15] = 267;
  squareX[16] = 748; squareY[16] = 254;
  squareX[17] = 748; squareY[17] = 265;
  squareX[18] = 225; squareY[18] = 468;
  squareX[19] = 225; squareY[19] = 468;
  squareX[20] = 225; squareY[20] = 468;
  squareX[21] = 225; squareY[21] = 468;
  squareX[22] = 225; squareY[22] = 468;
  squareX[23] = 225; squareY[23] = 468;
  squareX[24] = 225; squareY[24] = 468;
  squareX[25] = 225; squareY[25] = 468;
  squareX[26] = 225; squareY[26] = 468;
  squareX[27] = 225; squareY[27] = 468;
  squareX[28] = 225; squareY[28] = 468;



Code: ags


// After throwing dice

 if(oDice.Frame >=0){
 
 cGandolf.SayAt(cGandolf.x+9, cGandolf. y-100, 500, "you have rolled a one.");
 oTumbler.Move(oTumbler.X, oTumbler.Y+40, 2, eBlock, eAnywhere);
 
 if(currentSquare ==0){
 cHobbit.Walk(squareX[5], squareY[5], eBlock, eWalkableAreas);

// etc etc


At the moment the player moves to the same square whatever walk square is... there is plenty of walkable area.



Snarky

#15
You've forgotten to do the bit where you actually add the result of the die-roll to the currentSquare:

Code: ags

String number[7];

// Call this up front, along with initBoard()
void initNumbers();
{
  number[0] = "zero";    // Unused, but makes it easier to map from int to string
  number[1] = "one";
  number[2] = "two";
  number[3] = "three";
  number[4] = "four";
  number[5] = "five";
  number[6] = "six";
}

{
  // ...
  int dieRoll = Random(5)+1;  // roll the die
  // Display rolling die ...

  // Once the die has settled down

  // Display some stuff:
  oGandolf.SayAt(cGandolf.x+9, cGandolf.y - 100, 500, String.Format("You have rolled a %s.", number[dieRoll]));
  oTumbler.Move(oTumbler.X, oTumbler.Y+40, 2, eBlock, eAnywhere);

  // Go to the square you landed on:
  currentSquare = (currentSquare + dieRoll) % SQUARE_COUNT;
  cHobbit.Walk(squareX[currentSquare], squareY[currentSquare]);
}

xil

Edit: Snarky beat me to it :)

Slasher I think you missed a key part of Snarky's code:

Code: ags

void movePlayer(int squaresToMove)
{
  // I'm not sure exactly how the little detours work, so I'm just assuming a linear (loop) board.
  // If choice of path is automatic you can code it here, if it's a player choice you should probably determine it outside of this function
  currentSquare = (currentSquare + squaresToMove) % SQUARE_COUNT; // The % is a modulo and makes the board wrap around, so e.g. square 45 = 3
  player.Walk(squareX[currentSquare],squareY[currentSquare]);
}


After throwing the dice you should not be checking currentSquare, that is updated automatically.

You need to set currentSquare to 1 at the start of the game and you also need a variable for the total number of squares.

Then when you throw the dice the code will grab the currentSquare, add the dice amount to that number, check the X and Y coords based off of the new square and move the player to those coordinates.

To try to merge Snarky's and your code you could perhaps do:

Code: ags

#define SQUARE_COUNT 42
int currentSquare = 1;

// After throwing dice
 
 if(oDice.Frame >=0){
 
 cGandolf.SayAt(cGandolf.x+9, cGandolf. y-100, 500, "you have rolled a one.");
 oTumbler.Move(oTumbler.X, oTumbler.Y+40, 2, eBlock, eAnywhere);
 
 currentSquare = (currentSquare + oDice.Frame) % SQUARE_COUNT; // you might need to convert oDice.Frame to an integer?
 cHobbit.Walk(squareX[currentSquare], squareY[currentSquare], eBlock, eWalkableAreas);
 
// etc etc


The hardest part to understand is the % SQAURE_COUNT - you need to do this because if the player is on square 39 and they roll a 5, you don't want the code trying to send them to square 44, you want the system to get the number 44 and then do the calculation: 44 % 42 - the outcome of this calculation is 2. So the player will loops round the board and go to square 2.
Calico Reverie - Independent Game Development, Pixel Art & Other Stuff
Games: Mi - Starlit Grave - IAMJASON - Aractaur - blind to siberia - Wrong Channel - Memoriae - Point Of No Return

Snarky

Yup. I should also add that the code assumes your squares are numbered starting from 0, not from 1, because that makes the modulo calculation and the mapping to arrays easier.

Slasher

cheers guys, that should keep me busy for a while (nod)

muchos gracious (laugh)

Slasher

hi guys,

error

one of the string arguments supplied was not a string...
Code: ags

 cGandolf.SayAt(cGandolf.x+9, cGandolf.y -100, 500, String.Format("You have rolled a %s.", number[dieRoll]));

//FULL script
 if(oDice.Frame ==0){
   
 cGandolf.SayAt(cGandolf.x+9, cGandolf.y - 100, 500, String.Format("You have rolled a %s.", number[dieRoll]));
 oTumbler.Move(oTumbler.X, oTumbler.Y+40, 2, eBlock, eAnywhere);
 currentSquare = (currentSquare + dieRoll) % SQUARE_COUNT;
 cHobbit.Walk(squareX[currentSquare], squareY[currentSquare]);

// Repeats for all dice numbers thrown


ok... first off you click a tumbler and it shakes. meanwhile dice is animating underneath. click tumbler again and dice stops animating. the tumbler rises to reveal dice and the player moves accordingly.

i think i have all the scripts in correctly....



Khris

I assume that number[dieRoll] is an int, not a String? In that case you need to use %d, not %s.

Snarky

In the code snippet I provided it's a String:

Code: ags
String number[7];
 
// Call this up front, along with initBoard()
void initNumbers();
{
  number[0] = "zero";    // Unused, but makes it easier to map from int to string
  number[1] = "one";
  number[2] = "two";
  number[3] = "three";
  number[4] = "four";
  number[5] = "five";
  number[6] = "six";
}


(Possibly it would be better practice to use Hungarian notation or a suffix to indicate the data type here, since it's potentially confusing.)

Are you doing that, slasher, and making sure you're actually running initNumbers() ahead of time so the values aren't null?

Slasher

Ok,

i'm going to bite the bullet and get ready for rear buckshots (laugh)

here is all my code it gives string argument is not a string:

Code: ags

//top of room script

bool roll=false;
bool throw=true;

#define SQUARE_COUNT 28
int currentSquare;
int squareX[SQUARE_COUNT];
int squareY[SQUARE_COUNT];



function room_Load()
{
  currentSquare=1;
  gStatusline.Clickable=false;
  cGandolf.Clickable=false;
  cGandolf.Baseline=0;
  cHobbit.Loop=3;
  game.speech_text_align=eAlignLeft;
  oDice.SetView(6);
  oDice.Animate(0, 4, eRepeat, eNoBlock);

} 
  void initBoard()
{
  // From square 1

  squareX[0] = 50; squareY[0] = 470;
  squareX[1] = 50; squareY[1] = 379;
  squareX[2] = 136; squareY[2]=368;
  squareX[3] = 50; squareY[3] = 268;
  squareX[4] = 50; squareY[4] = 173;
  squareX[5] = 136; squareY[5] = 173;
  squareX[6] = 225; squareY[6] = 173;
  squareX[7] = 225; squareY[7] = 255;
  squareX[8] = 314; squareY[8] = 173;
  squareX[9] = 396; squareY[9] = 173;
  squareX[10] = 485; squareY[10] = 173;
  squareX[11] = 575; squareY[11] = 173;
  squareX[12] = 575; squareY[12] = 237; 
  squareX[13] = 658; squareY[13] = 173;
  squareX[14] = 744; squareY[14] = 173;
  squareX[15] = 744; squareY[15] = 265; 
  squareX[16] = 744; squareY[16] = 355;
  squareX[17] = 744; squareY[17] = 254; 
  squareX[18] = 744; squareY[18] = 371; 
  squareX[19] = 672; squareY[19] = 382; 
  squareX[20] = 678; squareY[20] = 457; 
  squareX[21] = 744; squareY[21] = 457; 
  squareX[22] = 586; squareY[22] = 457;
  squareX[23] = 494; squareY[23] = 457; 
  squareX[24] = 494; squareY[24] = 438; 
  squareX[25] = 415; squareY[25] = 457; 
  squareX[26] = 322; squareY[26] = 457;
  squareX[27] = 322; squareY[27] = 376; 
  squareX[28] = 278; squareY[28] = 376; 

}
 void movePlayer(int squaresToMove)
{
 
 currentSquare = (currentSquare + squaresToMove) % SQUARE_COUNT;
 player.Walk(squareX[currentSquare],squareY[currentSquare]);
 }
String number[7];

void initNumbers()
{
  number[0] = "zero";    
  number[1] = "one";
  number[2] = "two";
  number[3] = "three";
  number[4] = "four";
  number[5] = "five";
  number[6] = "six";
}

function oTumbler_Interact()
{
  int dieRoll = Random(5)+1; 

if(roll==false && throw==true){

  oTumbler.SetView(6);
  oTumbler.Animate(1, 1, eRepeat, eNoBlock);
  oDice.SetView(6);
  oDice.Animate(0, 1, eRepeat, eNoBlock);
  roll=true;

} 
 else if(roll==true && throw==true){
 oDice.StopAnimating();
 oTumbler.StopAnimating();
 Wait(10);
 oTumbler.Move(oTumbler.X, oTumbler.Y-40, 2, eBlock, eAnywhere);
 Wait(20);



if(oDice.Frame ==0){
   

 cGandolf.SayAt(cGandolf.x+9, cGandolf.y - 100, 500, String.Format("You have rolled a %s.", number[dieRoll]));
 oTumbler.Move(oTumbler.X, oTumbler.Y+40, 2, eBlock, eAnywhere);
 currentSquare = (currentSquare + oDice.Frame) % SQUARE_COUNT; // you might need to convert oDice.Frame to an integer?
 cHobbit.Walk(squareX[currentSquare], squareY[currentSquare], eBlock, eAnywhere);   
   
// etc etc through all the dice numbers

// It could be to do with the way i use odice frame to add event, possibly.....



Well. there you have it... :-[





Snarky

#23
OK, great. I see a few problems:

-The direct cause of the crash is, I think, that you haven't initialized the number[] array by calling initNumbers(); this is what I asked you in the last post
-You've mixed different versions of the snippets we've given you, with duplication and unused code. This can be simplified
-You're using a different method to roll the die, so you don't need the Random() call.
-You really don't want (or need!) to write six different cases, one for each number on the die. It's very simple to have the same code for all of them, and that's part of what the snippets we gave you were for
-You really need to learn how to indent. By not doing it consistently you create a lot of confusion and possibility of bugs

Here's a cleaned-up, hopefully fixed version of the code:

Code: ags

//top of room script

bool roll=false;
bool throw=true;    // You're never actually setting this value to anything other than true, so it's redundant

#define SQUARE_COUNT 28
int currentSquare;
int squareX[SQUARE_COUNT];
int squareY[SQUARE_COUNT];
String numberString[7];

void initNumbers()
{
  numberString[0] = "zero";    
  numberString[1] = "one";
  numberString[2] = "two";
  numberString[3] = "three";
  numberString[4] = "four";
  numberString[5] = "five";
  numberString[6] = "six";
}

void initBoard()
{
  // From square 1

  squareX[0] = 50; squareY[0] = 470;
  squareX[1] = 50; squareY[1] = 379;
  squareX[2] = 136; squareY[2]=368;
  squareX[3] = 50; squareY[3] = 268;
  squareX[4] = 50; squareY[4] = 173;
  squareX[5] = 136; squareY[5] = 173;
  squareX[6] = 225; squareY[6] = 173;
  squareX[7] = 225; squareY[7] = 255;
  squareX[8] = 314; squareY[8] = 173;
  squareX[9] = 396; squareY[9] = 173;
  squareX[10] = 485; squareY[10] = 173;
  squareX[11] = 575; squareY[11] = 173;
  squareX[12] = 575; squareY[12] = 237; 
  squareX[13] = 658; squareY[13] = 173;
  squareX[14] = 744; squareY[14] = 173;
  squareX[15] = 744; squareY[15] = 265; 
  squareX[16] = 744; squareY[16] = 355;
  squareX[17] = 744; squareY[17] = 254; 
  squareX[18] = 744; squareY[18] = 371; 
  squareX[19] = 672; squareY[19] = 382; 
  squareX[20] = 678; squareY[20] = 457; 
  squareX[21] = 744; squareY[21] = 457; 
  squareX[22] = 586; squareY[22] = 457;
  squareX[23] = 494; squareY[23] = 457; 
  squareX[24] = 494; squareY[24] = 438; 
  squareX[25] = 415; squareY[25] = 457; 
  squareX[26] = 322; squareY[26] = 457;
  squareX[27] = 322; squareY[27] = 376; 
  squareX[28] = 278; squareY[28] = 376; 
}

function room_Load()
{
  initBoard();        // ADDED!
  initNumbers();      // ADDED!
  currentSquare=0;    // CHANGED!
  gStatusline.Clickable=false;
  cGandolf.Clickable=false;
  cGandolf.Baseline=0;
  cHobbit.Loop=3;
  game.speech_text_align=eAlignLeft;
  oDice.SetView(6);
  oDice.Animate(0, 4, eRepeat, eNoBlock);
}

void movePlayer(int squaresToMove)
{
  currentSquare = (currentSquare + squaresToMove) % SQUARE_COUNT;
  cHobbit.Walk(squareX[currentSquare],squareY[currentSquare]);
}

function oTumbler_Interact()
{
  if(roll==false && throw==true)
  {
    oTumbler.SetView(6);
    oTumbler.Animate(1, 1, eRepeat, eNoBlock);
    oDice.SetView(6);
    oDice.Animate(0, 1, eRepeat, eNoBlock);
    roll=true;
  }
  else if(roll==true && throw==true)
  {
    oDice.StopAnimating();
    oTumbler.StopAnimating();
    Wait(10);
    oTumbler.Move(oTumbler.X, oTumbler.Y-40, 2, eBlock, eAnywhere);
    Wait(20);

    cGandolf.SayAt(cGandolf.x+9, cGandolf.y - 100, 500, String.Format("You have rolled a %s.", numberString[oDice.Frame + 1]));
    oTumbler.Move(oTumbler.X, oTumbler.Y+40, 2, eBlock, eAnywhere);
    movePlayer(oDice.Frame + 1);
  }
}


I also feel the need to point out that if this is meant to be a Hobbit game, the name of the wizard is Gandalf, not Gandolf.

Slasher

Cheers Snarky it's almost on the button except re-animating the tumbler, i can do this...

also i need to tweak the initBoard squareX 's and squareY 's.

So, all in all a success (nod)

Oh, yes: Gandalf...

thanks so much Snarky (nod)

back to testing....let you know..

cheers


SMF spam blocked by CleanTalk