Reputation: 5
I'm not really expert on OOP and as3 now. I'm making inventory system that will handle this things:
*when player collide with an "item", it will get it and send to the inventory array, etc...
here is the Player class constructor
as you can see i write item's instance name manually: "silver_key"
public function Player(player:MovieClip,loot:MovieClip,place:MovieClip)
{
// constructor code
_player = player;
silver_key = loot;//the item
_inventory = new InventorySystem(place);//InventorySystem Class
_player.addEventListener(Event.ENTER_FRAME,on_enter_frame);
addEventListener(EventDemo.EVENT_DEFAULT,onEvent);//custom event listener
}
This is the functions relative to it:
private function on_enter_frame(e:Event):void
if (_player.hitTestObject(silver_key))//check collision between player and item
{
dispatchEvent(new EventDemo(EventDemo.EVENT_DEFAULT));
}
private function onEvent(e:EventDemo)
{
_inventory.getitem(_loot);//function use in InventorySystem for array.push
removeEventListener(EventDemo.EVENT_DEFAULT,onEvent);//removes the listener when the item was sent to array
}
now my question is how can i be able to create a lot of items without manually writing their instance name. Thanks.
ps: if you still can't understand please comment.
Upvotes: 0
Views: 2152
Reputation: 2558
To put it simply:
object["string_name"] = value
For a more thorough explanation, read on...
You need explicit names for each item, but you want to dynamically define those items without knowledge of what it could be. You can store this in a number of ways, but a basic Array or Object should work fine.
It looks like you were creating a movieclip to represent the player. As a class, the instantiation of the player class could itself be that movieclip, but be aware that MovieClips carry a lot of timeline baggage that can slow you down. For a more succinct/lightweight player class, extend Sprite and write your own properties/methods.
For example, let's imagine this is what a Silver Key object looks like:
item:Object = {
"name":"Silver Key",
"count":1,
"weight":3,
"icon":"silver_key.jpg"
}
In one object, we can define a name property to be whatever we want that type of item to be, as well as other pertinent properties that describe that item. Now, all we need to do is keep a list of saved items in the player class itself.
Player Class
package {
public dynamic class Player extends Sprite {
import flash.events.*;
import flash.display.*;
public var inventory:Object = {};
public function Player() {
addEventListener(Event.ENTER_FRAME, tick);
}
public function tick(e:Event):void {
// ENTER_FRAME stuff
}
public function loot(item:Object) {
if (inventory.hasOwnProperty(item.name)) {
inventory.item.count++
trace("You now have " + inventory.item.count + " " + item.name + "'s!");
} else {
inventory[item.name] = item;
trace("You have picked up a " + item.name)
}
}
public function drop(item:Object) {
if (inventory.hasOwnProperty(item.name)) {
inventory.item.count--
if (inventory.item.count == 0) {
trace("You no longer have " + item.name);
delete(inventory[item.name]);
} else {
trace("You now have one less " + item.name + ".");
}
}
}
}
}
Example Implementation
var player:Player = new Player();
player.loot(item);
// traces "You picked up a Silver Key"
player.drop(item);
// traces "You no longer have Silver Key"
This is a simple way of doing it, and truthfully, you may want to expand on it with your own item & inventory classes, as well as data sanitization/checking to prevent a corrupted inventory.
Update: "More than likely, you'll create a prototype of each item."
Here's what one could look like.
package {
public class ItemDefinition extends Object {
public var name:String = "Unnamed Item";
public var count:int = 1;
public var weight:int = 0;
public var icon:String = "unnamed.jpg";
public function ItemDefinition(Properties:Object) {
// By passing in an object, we can define only the properties we want to change.
for (var Name:String in Properties) {
// Only property names that match will overwrite the defaults.
if (this.hasOwnProperty(Name)) {
this[Name] = Properties[Name]
}
}
}
}
}
What's cool about this, is that we can define any number of properties and in any order without fear of adding a bogus value that could mess us up later. Furthermore, if we want to add a new property to what defines a Item, just add it as a public var at the top.
Next, we might define all of our items once at the top of our document, using a new ItemDefinition object.
var itemDefinitions:Object = {
'Silver Key':new Item({name:"Silver Key", icon:"silver_key.jpg", weight:3}),
'Gold Key':new Item({weight:10, name:"Gold Key", icon:"gold_key.jpg"}),
'Iron Key':new Item({icon:"iron_key.jpg", weight:2, name:"Iron Key"})
}
function populateItems(itemName:String, count:int = 20) {
if (itemDefinitions.hasOwnProperty(itemName)) {
for (var i:int = 0; i < count; i++) {
var item:MovieClip = new MovieClip();
item.x = randomNumber(0, this.loaderInfo.width);
item.y = randomNumber(0, this.loaderInfo.height);
item["itemDefinition"] = itemName;
}
} else {
trace(itemName + " is an invalid item.");
}
}
function randomNumber(low:Number=0, high:Number=1):Number {
/* Returns a random number between the low and high values given. */
return Math.floor(Math.random() * (1+high-low)) + low;
}
As you can see, I've added a couple helper functions to spit out those extra items on screen (randomly). Obviously, we'd need to have an addChild, and image loading, but that's really something you should implement.
Finally, we'll revise our loot call to pass the itemDefinition...
player.loot(itemDefinitions[item.itemDefinition]);
removeChild(item);
Worlds of possibilities. You'll likely make something far more robust which addresses the needs of your game, so this is only one way you might do it.
Upvotes: 1