I did search for a solution, couldn't find anything. And I don't know if this counts as a beginner's question, but here goes. I'd like to design a maze-type area where, unless you have a specific item, if you move in any direction but down, it just loads one of, say, four random screens, and if you move down you end up right back at the start of the maze.
Then, if the player does have the specific item, either
a) you go straight to the end of the maze,
or
b) (preferably) you end up at the end of the maze only if you follow the instructions you are given as a result of obtaining the item.
Any hints?
I'm not sure about all the implimentation, but checking if the player has an item has been asked before. Read the manual: Character.InventoryQuantity (http://www.adventuregamestudio.co.uk/manual/Character.InventoryQuantity.htm).
Maybe something like:
// Player interacts with 'exit' hotspots in maze room
if (player.InventoryQuantity[iMap/ID] == 0) { // player doesn't have map
player.ChangeRoom(10+Random(3));
// Very basic, assumes the maze rooms are 10,11,12 and 13. Can change this as needed
// For the 'down' hotspot, this'll take the player back to the beginning.
}
else { // Player has map
// Whatever needs to happen if the player is following the instructions
}
What goes in the second condition depends on what the 'instructions' are - I'd guess using variables and/or player.PreviousRoom to track the players progress. If you use the first method, it'd just take you to the end of the maze.
Here's a short example game:
_maze.zip (http://www.2dadventure.com/ags/_maze.zip)
Check the top of the global script for the used mechanics.
The maze rooms have regions calling leave(dir);.
I managed to create a single room where you can only pass through if you go through it in the correct order. This single room simulates the action of four different rooms. This is kind of useful if you want to save space and make your game a teeny bit smaller.
The code is ripped right out of my game, so I didn't bother changing some of the x or y coordinates, and room numbers, etc. I also used global ints to keep track of whether the player went the right way, but you can replace the GetGlobalInt() with InventoryQuantity[] or whatever you need.
// room script file
#sectionstart room_a // DO NOT EDIT OR REMOVE THIS LINE
function room_a() {
// script for room: Walk off left screen edge
SetGlobalInt(5, 0); // reset number of correct turns because the player didn't go through correctly
cPlayer.ChangeRoom(21, 300, 170); // go to beginning
}
#sectionend room_a // DO NOT EDIT OR REMOVE THIS LINE
#sectionstart room_b // DO NOT EDIT OR REMOVE THIS LINE
function room_b() {
// script for room: Walk off right screen edge
if ((GetGlobalInt(5) != 1) && (GetGlobalInt(5) != 3)) { // this direction is not correct right now
FadeOut(10);
cPlayer.StopMoving()
cPlayer.x = 20;
cPlayer.y = 170; //place player on opposite side of room; gives the illusion of a new room
SetGlobalInt(5, 0); // wrong way, reset the number of correct turns
Wait(1);
FadeIn(10);
}
else if (GetGlobalInt(5) == 1) { //correct path
FadeOut(10);
cPlayer.StopMoving();
cPlayer.x = 20;
cPlayer.y = 170; //place player on opposite side of room; gives the illusion of a new room
SetGlobalInt(5, 2); // correct path
Wait(1);
FadeIn(10);
}
else if (GetGlobalInt(5) == 3) {
SetGlobalInt(5, 0); //reset correct path for next time player goes through the maze
cPlayer.ChangeRoom(23, 20, 170); // finished maze, go to next room
}
}
#sectionend room_b // DO NOT EDIT OR REMOVE THIS LINE
#sectionstart room_c // DO NOT EDIT OR REMOVE THIS LINE
function room_c() {
// script for room: Walk off bottom screen edge
if (GetGlobalInt(5) == 2) { // correct path
FadeOut(10);
cPlayer.StopMoving();
cPlayer.x = 150;
cPlayer.y = 80; //place player on opposite side of room; gives the illusion of a new room
SetGlobalInt(5, 3);
Wait(1);
FadeIn(10);
}
else { // not the correct path
FadeOut(10);
StopMoving(PLAYER);
character[PLAYER].x = 150;
character[PLAYER].y = 80; //place player on opposite side of room; gives the illusion of a new room
SetGlobalInt(5, 0); // reset number of correct turns
Wait(1);
FadeIn(10);
}
}
#sectionend room_c // DO NOT EDIT OR REMOVE THIS LINE
#sectionstart room_d // DO NOT EDIT OR REMOVE THIS LINE
function room_d() {
// script for room: Walk off top screen edge
if (GetGlobalInt(5) == 0) { //correct path
FadeOut(10);
cPlayer.StopMoving();
cPlayer.x = 160;
cPlayer.y = 220; //place player on opposite side of room; gives the illusion of a new room
SetGlobalInt(5, 1);
Wait(1);
FadeIn(10);
}
else { //not the correct path
FadeOut(10);
cPlayer.StopMoving();
cPlayer.x = 160;
cPlayer.y = 220; //place player on opposite side of room; gives the illusion of a new room
SetGlobalInt(5, 0);
Wait(1);
FadeIn(10);
}
}
#sectionend room_d // DO NOT EDIT OR REMOVE THIS LINE
Sorry if that's a bit long and hard to understand... This is my first time I've ever tried to help someone rather than asking for help myself. :P
For this particular maze, the player (cPlayer) needs to go North, East, South, East in order to pass through the maze. Hope this helps!
hummmm Maaaaaze :D
4 questions before giving a coherent answer :
1) How many rooms? for the maze itself.
2) Is it random or coherent (before having the map/object)?
3a) how many instructions into the map?
3b) Will this instruction will need the character to pass-by more than 1 time in each maze room (see 1).
There is many ways to do such. Is really relative to the kind of maze/solution you have. (otherwise you are going to re-do everything twice).
The easiest need as many rooms as instruction path - The more complex / but more efficient use binary numbers.
Since this has been dug out, a few comments:
NiksterG:
Your method is fine, but the execution is not ideal. A longer path would make the ifs become ever more complex and harder to read.
Changing the path would be a tiring hassle.
Another thing is that you've got (almost) identical blocks of code at five or six places in the script:
function nextroom(int x, int y, int gi) {
FadeOut(10);
cPlayer.x = x;
cPlayer.y = y;
SetGlobalInt(5, gi); // wrong way, reset the number of correct turns
Wait(1);
FadeIn(10);
}
Now simply use nextroom(60, 220, 0); and there you are.
'The way I've done it allows to use anything from one to 300 rooms, and changing the right path is as easy as changing "uluru" to "urlrulrululr" (going down always exits the maze, can be changed easily, too).
Here's the script I used:
String went;
String sol;
function set_strings() { // called in game_start
sol="uluru";
went="";
}
function check() {
if (went.CompareTo(sol)==0 && player.InventoryQuantity[iMap.ID]>0) return true;
return false;
}
function leave(Dir d) {
String s;
int x, y;
if (d==eDirDown) {
went="";
player.ChangeRoom(1, 160, 140);
return;
}
if (d==eDirUp) { s="u"; x=player.x; y=215; }
if (d==eDirLeft) { s="l"; x=260; y=140; }
if (d==eDirRight) { s="r"; x=60; y=135; }
went=went.Append(s);
way.Text=String.Format("Player went: %s", went); // update debug label
if (check()) {
Display("Yay! You've found the way out.");
QuitGame(0);
}
player.ChangeRoom(2+Random(3), x, y);
}
Exiting the rooms will call e.g. leave(eDirUp);