How to remember a room has been cleared? AS3,FP - actionscript-3

I have am new to AS3 and coding in general so this is why I am asking this question. I am trying to make a like semi-proceduraly generated dungeon crawler sort of thing like binding of isaac using flashbuilder and flashpunk.
but this has left me with a problem; I have figured out two ways to do the rooms. Either I can spawn all the rooms at once and have the players move between them using a door entity to block progress or I can load a new world that contains the room inside it and nothing else using FP.world = new world. But this gives me two problems so basically this is the main thing I want to know.
I want the world to remember what was in it and what was killed even if I enter a new world. E.g. right now if I enter a new world it will load that world up fresh and then if I kill all the enemies and leave and then re enter it will just spawn all the enemies again. I need to know how to get that room to remember it has been cleared of enemies.
Is there anyway to do this?

I'm not familiar with FP, so I cannot tell if FP allows to save room states. You better check the documentation, but if it doesn't help, you can do the following:
Find a way to get the room unique ID somehow. It could be anything - a coordinate, a number, a name, an object, etc. Just be sure it is unique. Once you have it, proceed.
The next mandatory thing you need is a way to get and set the room state. I.e. after getting state you can know that there are three goblins in a room. And setting state would be like "remove all and put these three goblins in this room". These requirements are natural as you are going to read and write the room's content anyway. Once you have it, the rest is easy.
Choose how you will keep the state. Let's say, an Object like {goblins:3, chest:1}. If you kill one goblin, it will become { goblins:2, chest:1 }. If you want to remember just the rooms that are FULLY cleared, then you simply need a boolean variable (true/false) as a state object.
You can store the state Object in a Dictionary as a key-value pair where key is the room's unique ID.
var visited_rooms:Dictionary = new Dictionary();
var roomID = ... // unique room id
var savedState:Object = { goblins:3, chest:1 } // read room state somehow
visited_rooms[roomID] = savedState;
Now, upon leaving the room, you get the state info and put it in the Dictionary.
Once you enter this room again, just check if its unique ID is present in the Dictionary and restore the state if so:
var roomID = ... // unique room id
if (roomID in visited_rooms) {
var savedState:Object = visited_rooms[roomID];
room.setState(savedState);
}
That's basically all.

Related

Return State ID from Containing County Event

I have a topojson map that has both county and state data in json format. There are no actual names for the states, but the states do each have a unique id. I would like to find a way to return the id of a state if the user clicks on one of its containing counties.
The trouble is I cannot seem to be able to access the state ids in the json when I set up my click event listener. I have sliced and diced the json data every which way, but I keep going in circles. Is it possible to have asymmetric information within the json file? I feel like the state ids are in a black box when working with the containing counties.
Let me know if anything comes to mind. I have a fully functional minimalist example here, where I am trying to return a console log of the state id based on user click.
Note: I would prefer to avoid point in polygon solutions for complexity reasons.
Seems your json file ships with FIPS county code. That means that first two digits of county code are in fact the state code. So Math.floor(county.id / 1000) is what you‘re looking for in the end.

AS3: how to pass by "object"

I was actually looking for a way to pass by reference in AS3 but then it seemed that adobe and lots of people's understanding of pass by reference is different from what I have been taught at the university. I was taught java was pass by value and C++ allowed pass by reference.
I'm not trying to argue what pass by value and reference are. I just want to explain why I'm using pass by object in the question...
Back to the question, I would like to do something like:
public function swapCard(cardA:Cards, cardB:Cards) {
var temp:Cards = cardA;
cardA = cardB;
cardB = temp;
}
...
swapCard(c1, c2);
EDIT: adding two examples on how I'm using the swapCard function
1) in the process of swaping a card between player1 and player2's hand
swapCard(player1.hand[s], player2.hand[t]);
2) in the process of swaping a card between player1's hand and deck
swapCard(player1.hand[s], player1.deck[rand]);
In C++, we only need to add a symbol before the parameters to make it work (and we call THIS pass by reference). But in AS3, cardA and cardB are just pointers to the formal parameters. Here in the function, changing the pointers does not do anything to the formal parameters :(
I have been searching for hours but I couldn't find a way to without knowing all the properties of the Cards.
If I have to change the properties of the cards one by one then maybe I should change swapCard to a static function in class Cards? (because I don't want to expose everything to another class) I'm not sure if this is a good practice either. This is like adding a swap_cars function into class Cars. If I let this happen, what will be next? Wash car, lend car, rent car... I really want to keep the Cards class clean and holds only the details of the card. Is there a possible way to do this properly in AS3?
The kind of swap function that you're trying to implement is not possible in AS3. The input parameters are references to the input objects but the references themselves are passed by value. This means that inside the function you can change the cardA and cardB but those changes will not be visible outside the function.
Edit: I added this portion after you edited your question with sample usage.
It seems like you're trying to swap two objects in 2 different arrays at given array positions in each - you can create a function for this in AS3 but not the way you attempted.
One possible implementation is to pass the arrays themselves and the positions that you're trying to exchange; something like this:
// Assumes arrays and indices are correct.
public function SwapCards(playerHand:Array, playerCardIndex:int,
playerDeck:Array, playerDeckIndex:int):void
{
var tempCard:Card = playerHand[playerHandIndex];
playerHand[playerHandIndex] = playerDeck[playerDeckIndex];
playerDeck[playerDeckIndex] = tempCard;
}
Note that you still exchange references and the arrays themselves are still passed by reference (and the array references are passed by value - you could, if you wanted, change the arrays to new arrays inside this function but you wouldn't see new arrays outside). However, because the array parameters refer to the same arrays inside and outside the function, you can make changes to the contents of the array (or other array properties) and those changes will be visible outside.
This solution is faster than cloning the card because that involves allocating memory for a new Card instance (which is expensive) and that temporary instance will also have to be freed by the garbage collector (which is also expensive).
You mentioned in a comment that you pass cards down to lower levels of code - if you don't have a back reference to the arrays (and the positions of the cards), you will not be able to easily swap cards - in AS3, all input parameters are copies (either the copy of the value for primitive types or the copy of the reference for complex objects - changes to the input parameters in a function will not be visible outside).
EDIT: renaming the function from clone to copyFrom as pointed out by aaron. Seems like clone is supposed to be used as objA = objB.clone()
At this point, I'm adding a copyFrom() function in the Cards class such that
var temp:Cards = new Cards(...);
var a:Cards = new Cards(...);
...
temp.copyFrom(a);
...
temp will be copying everything from a.
public function swapCard(cardA:Cards, cardB:Cards) {
var temp:Cards = new Cards();
temp.copyFrom(cardA);
cardA.copyFrom(cardB);
cardB.copyFrom(temp);
}
I will wait for a week or so to see if there are any other options
You have some good answers already, but based on the comments back-and-forth with me, here's my suggestion (I use "left" and "right" naming because it helps me visualize, but it doesn't matter):
function swapCard(leftCards:Array, leftCard:Card, rightCards:Array, rightCard:Card):void {
var leftIndex:int = leftCards.indexOf(leftCard);
var rightIndex:int = rightCards.indexOf(rightCard);
leftCards[leftIndex] = rightCard;
rightCards[rightIndex] = leftCard;
}
Now you can swap the cards in the two examples you posted like this:
swapCard(player1.hand, player1.hand[s], player2.hand, player2.hand[t]);
swapCard(player1.hand, player1.hand[s], player1.deck, player1.deck[rand]);
However, note that while this swaps the cards in the arrays, it does not swap direct references to the cards in those arrays. In other words:
var a:Card = player1.hand[0];
var b:Card = player2.hand[0];
swapCard(player1.hand, a, player2.hand, b);
// does not change the references a and b, they still refer to the same card
a == player2.hand[0];
a != player1.hand[0];
b == player1.hand[0];
b != player2.hand[0];
Typically, this sort of thing is handled by dispatching a "changed" event so that any code that cares about the state of a player's hand array will know to re-evaluate the state of the hand.
There's a deep misunderstanding going on here. The question is about object reference but the PO is not trying to swap any Object reference at all.
The problem comes from the fact that the PO does not understand the difference between variable and objects. He's trying to swap variable/object reference which is not dynamically possible of course. He wants with a function to make the variable holding a reference to Object A, swap its object reference with another variable. Since Objects can be passed around but not variables (since they are just holders (not pointers)) the task is not possible without a direct use of the given variable.
To resume:
variables are not Objects!
variables hold a reference to an object.
variables cannot be passed in function or referenced in functions because THEY ARE NOT OBJECTS.

How do you use the CustomRoomData on Appwarps with cocos2d-x

Just started coding with Appwarps and I'm running into an issue. I have a lobby built that shows live rooms, but I really do not want to show the rooms for matches that have already started. I figured I would use
void Client::setCustomRoomData(std::string roomId, std::string customData)
But I have some doubts on how to use it. Once the game starts, I plan on sending
SetCustomRoomData(roomId, "Closed");
to notify the server that open seating is now closed. However, when I check the room properties on another device when it calls
void CCAppwarpDelegate::onGetLiveRoomInfoDone(AppWarp::liveroom revent)
{
CCLog("CustomData=%s",revent.customData.c_str());
...
it returns blank. What am I missing here? Besides the code not working, what really makes me question myself is that I don't understand the mechanics of the properties. How do you have multiple custom properties since you aren't assigning it any kind of index...or do room only have a single custom property at any given time?
You don't need to use customData and instead use only room properties. Room properties is a set of key/value pairs that you can associate with a room.
I recommend you read the following link
http://appwarp.shephertz.com/game-development-center/matchmaking-basic-concept/
So the flow is as follows -
you first create the room using the createRoom API and pass a
properties dictionary containing <"closed", "false">.
Then once the game is active, you use updateRoomProperties API
on the room and pass <"closed", "true"> to the API.
Then when you want to show the list you should use
getRoomWithProperties and pass <"closed", "false">. This will get
you a list of rooms that are not yet "closed".

Saving and Loading progress in action script 3

I've looked everywhere for this answer..but I am not quite sure on how to do it exactly...
I am making a Flash Game using Flash AS3...
I need options where user can save and load their progress..
can somebody give a step by step on how to do this please? I am very new to actionscript...
usually other tuts shows u how to save certain variables
Cookies!
Lucky us it's very simple. Unlucky us it's not obvious how it's done:
// have that referenced all the time:
var cookies: SharedObject = SharedObject.getLocal("myGameData");
// start saving
cookies.data.progress = 50;
cookies.data.lives = 5;
cookies.data.anyRandomVariable = "my name or something";
cookies.flush();
// now it's saved
// start loading
var progress: Number = cookies.data.progress;
var lives: int = cookies.data.lives = 5;
var anyRandomBlah: String = cookies.data.anyRandomVariable;
// now it's loaded
(following the comments above...)
Yes, pretty much along those lines. I was asking questions to try to get you to see that you do actually have variables/data which you'd save. =b
If you want to save in the middle of the level, it is up to you... I don't know how you've designed your game, but basically you can write the saving code to trigger whenever you want based on any conditions you want.
For saving in the middle of levels, since you are handling the saving and loading you could try having a value like level "7.5" or whatever notation you want to indicate a level that is partway done. Or just use whole numbers like 750 and treat it as a percentage (level 7 at 50% done). And so forth. It's up to you.
A very similar question has been asked how to save a current frame value using a SharedObject. In your case, replace 'current frame' with whatever values you want to save:
Actionscript 3 saving currentframe location to local hard drive?

Monotouch Dialog Json, EntryElement use EntryEnded Event

I need to use MTD with Json to dinamycally create forms, but also i need to check the user input:
Some fields may only accept numbers, and some other have a fixed length etc.
This can be done with an action that checks every EntryElement value against the specified conditions, and then using some messaging to tell the user about the necessary corrections.
If we have a low number of fields this is Ok, but when one has more than 50 fields then this turn out to be very awkward in terms of usability. The ideal solution would be to notify the user about corrections, in the moment the user ends typing in the EntryElement
Now MTD provides some sort of mechanism to do this:
JsonElement jsonElement;
jsonElement = JsonObject.Load("file.json");
((EntryElement) jsonElement["field_1"]).EntryEnded = delegate { doSomething();};
Provided that "field_1" is an EntryElement marked with the id attribute with "field_1" value
The above code works as expected, ie: When i change the focus to another part, the EntryEnded event activates. Now for the million dollar question:
How do i know to which EntryElement does the Event correspond? or in other words. How do i get the ID of the EntryElement when calling the Event?
If none of the above is possible which would be suitable solution?
Thanks in advance for any leads,
Found a way to do it:
((EntryElement)jsonElement ["field_1"]).EntryEnded += (object sender, EventArgs e ) =>
{
NSIndexPath pt = ((EntryElement)sender).IndexPath;
Console.WriteLine("section: "+pt.Section+" row: "+pt.Row);
};
This little thing will print the Section and the Row of the EntryElement that received
the EntryEnded event. This is not exactly as getting the id, but at least now i have information about its location, and from this i can get a lot more info (specially if i took care to save it somewhere else)
This is probably a basic trick, but i didn`t found it anywhere else!