RMMZ Adding properties to all existing and potential elements in array using prototype or similar? Adding objects to array.

bishiba

Adept
Veteran
Joined
Apr 6, 2016
Messages
183
Reaction score
51
First Language
Swedish
Primarily Uses
N/A
So I just spent the last three hours setting this up, I thought I tried it, I thought it worked. But now, that I've done it with most of my code I realize that it doesn't work...

JavaScript:
BISH.ship = [];
BISH.ship.prototype = Object.prototype;
BISH.ship.prototype.actor;
BISH.ship.prototype.id;
BISH.ship.prototype.picId;
BISH.ship.prototype.name;
BISH.ship.prototype.skin;

I wanted to be able to add BISH.ship[x] and then use this.ship[x].actor...
But I've noticed I'm just getting "prototype" as an index and then the prototype contains the objects.
Here is the full object before adding anything to the array.
1627084320200.png

This is the object with ship[1] set to 42. Along with what BISH.ship[1] returns/contains and what autocompletes appear, without any of the objects I thought I was adding :(
1627084399116.png

Is there anything I can do to fix it except turning it into a function and looping it for each new index?

Best regards!
 
Last edited:

bishiba

Adept
Veteran
Joined
Apr 6, 2016
Messages
183
Reaction score
51
First Language
Swedish
Primarily Uses
N/A
Bumpy, you don't need to be an expert, any input, even if it is a guess I'll be so grateful :)

Currently just using the below, it works perfectly I think, just that I need to run the function everytime I create a new element. But I'll leave this thread open in the hopes that someone can explain if the first idea is doable.

JavaScript:
function BISH.ship.applyTraits(activeShip) {
    //Base stats
    activeShip.actor;
    activeShip.id;
    activeShip.picId;
    activeShip.name;
    activeShip.skin;

    //Coords
    activeShip.x;
    activeShip.y;
    activeShip.angle;

    //Attributes
    activeShip.maxCargo;
    activeShip.cargo;
    activeShip.passengers;
    activeShip.seats;
    activeShip.fuel;
    activeShip.fuelEfficacy;
    activeShip.speed;
    activeShip.hull;
    activeShip.hardpoints;
    activeShip.size;
}
 
Last edited:

Nolonar

Veteran
Veteran
Joined
Feb 18, 2018
Messages
274
Reaction score
377
First Language
French, German
Primarily Uses
RMMZ
If I understand correctly, you want BISH.ship to be an array of actors (?), or at least an array of something that contains an actor, an id, a picId, a name, and a skin. Let's say it's an array of actors to keep things simple.

The problem is that you've made an array that is also an actor, and are adding numbers to it. I think that's what's confusing you. In fact, I think your current code might be more complicated than necessary. For example:
JavaScript:
BISH.ship = [];
is plenty enough for your purpose (as far as I can tell from your code).

And instead of adding the number 42 to your ship, the following might be closer to what you need:
JavaScript:
BISH.ship[1] = {
    actor: /* actor here */,
    id: 42,
    picId: //etc.
};

Although instead of setting the array's index directly, I'd recommend using BISH.ship.push({ actor: /* etc. */ }) instead. The Array.push() function adds whatever you're giving it to the end of the array. It's better than setting the index directly, because you might overwrite an existing object, which may not be what you want (at least not when you're adding to an array).
 

Anyone

Veteran
Veteran
Joined
Aug 24, 2019
Messages
257
Reaction score
353
First Language
German
Primarily Uses
RMMV
The code looks weird. Are you trying to create a prototype from which to create multiple ships, or are you trying to create a single ship?

Instead of using prototype, I'd use class to create a blueprint for ships:
JavaScript:
class BISH_Ship {
    constructor(shipData) {
        this.initialize(shipData);
    }
    
    initialize(shipData) {
        Object.assign(this, shipData);
    }
}

You can use this to create a new BISH_Ship by sending an object to its constructor and plucking off whatever values you want to assign.
e.g.
JavaScript:
const myShip = {actor: "Mel", id: 5, picId: 7, name: "The Holly Wolly", skin: "Battleship"}
const newShip = new BISH_Ship(myShip);

You can use this to add methods, functions and default properties to the ship, while importing specific data (actor, etc.) from another object.

If you just want a single ship entity, you can just create it as an object.
JavaScript:
const myShip = {actor: "Mel",
                id: 5, picId: 7,
                name: "The Holly Wolly",
                skin: "Battleship"};

If you want to be able to create multiple ships, go with the class, if you want a single ship, just create it as object. You can attach functions to an object to be used as methods, too.
 

bishiba

Adept
Veteran
Joined
Apr 6, 2016
Messages
183
Reaction score
51
First Language
Swedish
Primarily Uses
N/A
If I understand correctly, you want BISH.ship to be an array of actors (?), or at least an array of something that contains an actor, an id, a picId, a name, and a skin. Let's say it's an array of actors to keep things simple.

The problem is that you've made an array that is also an actor, and are adding numbers to it. I think that's what's confusing you. In fact, I think your current code might be more complicated than necessary. For example:
JavaScript:
BISH.ship = [];
is plenty enough for your purpose (as far as I can tell from your code).

And instead of adding the number 42 to your ship, the following might be closer to what you need:
JavaScript:
BISH.ship[1] = {
    actor: /* actor here */,
    id: 42,
    picId: //etc.
};

Although instead of setting the array's index directly, I'd recommend using BISH.ship.push({ actor: /* etc. */ }) instead. The Array.push() function adds whatever you're giving it to the end of the array. It's better than setting the index directly, because you might overwrite an existing object, which may not be what you want (at least not when you're adding to an array).
Ah, I guess showing the "actor" thing was not very good since it caused confusion. I am using it to sneakily get information for different things. The actor itself is never actually used.

Also, the "42" is irrelevant and was only there to showcase that even though the ship[1] has been assigned a value it does not have access to all the attributes of the prototype. I used 42 as a reference to the Hitchhikers guide to the galaxy.

The array.push does not work well in this situation, that's because some array will have empty indexes up until a certain value. Reasons for this is that the index is set to whatever index the built in picture function picture has. So if the picture has a pictureId of 31, then the ship index will be 31. Even if it is the first ship. The first indexes of pictures are used for planets. There are certainly other ways to do it though, but I am trying to implement quite a lot of the base engine into what I am making so I am trying to make my code apply to how the RPG maker engine handles certain functions and objects.

Seems that I've done a poor job explaining and showcasing what I am requesting... Probably since I first started learning java about 3 months ago and since then have been trying to learn javascript. It'll get better as I keep getting so much help from our forum! :)

======================================================

The code looks weird. Are you trying to create a prototype from which to create multiple ships, or are you trying to create a single ship?

Instead of using prototype, I'd use class to create a blueprint for ships:
JavaScript:
class BISH_Ship {
    constructor(shipData) {
        this.initialize(shipData);
    }
   
    initialize(shipData) {
        Object.assign(this, shipData);
    }
}

You can use this to create a new BISH_Ship by sending an object to its constructor and plucking off whatever values you want to assign.
e.g.
JavaScript:
const myShip = {actor: "Mel", id: 5, picId: 7, name: "The Holly Wolly", skin: "Battleship"}
const newShip = new BISH_Ship(myShip);

You can use this to add methods, functions and default properties to the ship, while importing specific data (actor, etc.) from another object.

If you just want a single ship entity, you can just create it as an object.
JavaScript:
const myShip = {actor: "Mel",
                id: 5, picId: 7,
                name: "The Holly Wolly",
                skin: "Battleship"};

If you want to be able to create multiple ships, go with the class, if you want a single ship, just create it as object. You can attach functions to an object to be used as methods, too.
Yes, I wanted to start using a constructor in that way as well. But since I still don't understand exactly how it works well enough yet and because I had already made a lot of code utilizing arrays I didn't want to correct all of it by changing it to functions. I did learn from the way the source code of the engine is made how to use constructor in that way during this project.

===============================================

It will be very difficult to explain exactly what I am trying to do. But I have since then changed the way I handle this issue and the post is still up as unsolved since I am interested in seeing wheter or not it is possible to do what I am requesting. The current code for creating a ship looks like this, I think it works rather fine. If there is any instant improvements you see that be great, but please don't put any effort into it. Just showing the way I am currently doing it. There is a lot of redundancies in the current code though.

JavaScript:
BISH.createShip = function(id, startingPlanet) {
    this.ship[id] = {};
    activeShip = this.ship[id];
    this.applyTraits(activeShip);
    this.pilotedShip = activeShip;
    activeShip.dockedObject = startingPlanet;
    activeShip.actor = $gameActors.actor(id);
    activeShip.shipItem = $dataWeapons[activeShip.actor._equips[0]._itemId];
    activeShip.meta = activeShip.shipItem.meta;
    activeShip.topViewSrcPath = this.getShipSrcPath(activeShip);
    console.log(activeShip.topViewSrcPath);
    activeShip.id = id;
    activeShip.picId = activeShip.id + this.pictureShipIndexStart;
    activeShip.x = startingPlanet.x;
    activeShip.y = startingPlanet.y;
    activeShip.coords = this.getObjectCoords(activeShip);
    $gameScreen.showPicture(activeShip.picId, activeShip.topViewSrcPath, 1, activeShip.x, activeShip.y, 100, 100, 255, 0);
    activeShip.picture = $gameScreen.picture(activeShip.picId);
    Picture[activeShip.picId] = activeShip.picture;
    activeShip.picture._shipId = activeShip.id;
    activeShip.picture._pictureId = activeShip.picId;
    this.setShipSpeed(activeShip, 6);
    activeShip.fuelEfficacy = 1;
    $gameActors.actor(1)._name = BISH.Names.getRandomShipName();
    $gameScreen.picture(activeShip.picId).mzkp_commonEventId = 51;
}
 

Anyone

Veteran
Veteran
Joined
Aug 24, 2019
Messages
257
Reaction score
353
First Language
German
Primarily Uses
RMMV
Ah, I guess showing the "actor" thing was not very good since it caused confusion. I am using it to sneakily get information for different things. The actor itself is never actually used.

Also, the "42" is irrelevant and was only there to showcase that even though the ship[1] has been assigned a value it does not have access to all the attributes of the prototype. I used 42 as a reference to the Hitchhikers guide to the galaxy.

The array.push does not work well in this situation, that's because some array will have empty indexes up until a certain value. Reasons for this is that the index is set to whatever index the built in picture function picture has. So if the picture has a pictureId of 31, then the ship index will be 31. Even if it is the first ship. The first indexes of pictures are used for planets. There are certainly other ways to do it though, but I am trying to implement quite a lot of the base engine into what I am making so I am trying to make my code apply to how the RPG maker engine handles certain functions and objects.

Seems that I've done a poor job explaining and showcasing what I am requesting... Probably since I first started learning java about 3 months ago and since then have been trying to learn javascript. It'll get better as I keep getting so much help from our forum! :)

======================================================


Yes, I wanted to start using a constructor in that way as well. But since I still don't understand exactly how it works well enough yet and because I had already made a lot of code utilizing arrays I didn't want to correct all of it by changing it to functions. I did learn from the way the source code of the engine is made how to use constructor in that way during this project.

===============================================

It will be very difficult to explain exactly what I am trying to do. But I have since then changed the way I handle this issue and the post is still up as unsolved since I am interested in seeing wheter or not it is possible to do what I am requesting. The current code for creating a ship looks like this, I think it works rather fine. If there is any instant improvements you see that be great, but please don't put any effort into it. Just showing the way I am currently doing it. There is a lot of redundancies in the current code though.

JavaScript:
BISH.createShip = function(id, startingPlanet) {
    this.ship[id] = {};
    activeShip = this.ship[id];
    this.applyTraits(activeShip);
    this.pilotedShip = activeShip;
    activeShip.dockedObject = startingPlanet;
    activeShip.actor = $gameActors.actor(id);
    activeShip.shipItem = $dataWeapons[activeShip.actor._equips[0]._itemId];
    activeShip.meta = activeShip.shipItem.meta;
    activeShip.topViewSrcPath = this.getShipSrcPath(activeShip);
    console.log(activeShip.topViewSrcPath);
    activeShip.id = id;
    activeShip.picId = activeShip.id + this.pictureShipIndexStart;
    activeShip.x = startingPlanet.x;
    activeShip.y = startingPlanet.y;
    activeShip.coords = this.getObjectCoords(activeShip);
    $gameScreen.showPicture(activeShip.picId, activeShip.topViewSrcPath, 1, activeShip.x, activeShip.y, 100, 100, 255, 0);
    activeShip.picture = $gameScreen.picture(activeShip.picId);
    Picture[activeShip.picId] = activeShip.picture;
    activeShip.picture._shipId = activeShip.id;
    activeShip.picture._pictureId = activeShip.picId;
    this.setShipSpeed(activeShip, 6);
    activeShip.fuelEfficacy = 1;
    $gameActors.actor(1)._name = BISH.Names.getRandomShipName();
    $gameScreen.picture(activeShip.picId).mzkp_commonEventId = 51;
}
I'd suggest you refactor that code. There's a lot of redundencies & you're doing way, way too much in a single function.
It may currently work "kind of" but you're going to revisit that code at some point in the future. The easier it is to read, the better.

I'm not sure why you're using some things, e.g. why use an array to contain a single ship? If you were planning to use multiple ships, wouldn't it make more sense to push new ships into an array?

I'm also uncertain what your "this" reference is, since you seem to be drawing on methods that are attached to the parent objects, but there's no clear way of knowing what parent object that is?
Are you calling the createShip function from a Ship Controller class called BISH? Or is that the main ship and you're calling it from a ship object?

If I were to create a ship plugin, I'd probably create a ShipList Class, which contains the data of all ships & methods to control them, e.g.
JavaScript:
class $ShipList {
    constructor() {
        this.initialize();
    }
    
    initialize() {
        this.currentShips = [];
        this.graveyardShips = [];
    }
    
    addShipToList(ship) {
        this.currentShips.push(ship);
    }
    
    removeShipFromList(shipListIndex) {
        this.graveyardShips.push(this.currentShips[shipListIndex])
        this.currentShips.splice(shipListIndex, 1);
    }
}
$ShipList = new $ShipList();

That way, I can just send the Ship object after creation into the array of current ships to keep track of all ships that exist in one place. And I can even keep track of ships that were destroyed, by having a graveyard for them.

I'd create another class like the one shown earlier to serve as blueprint for all ships, to initialize them with everything all ships have in common.

I'd ensure that I encapsulate every single seperate action in a function, so that instead of having to read a lot of code, I can instead read functions that tell me what I'm doing here. And then I can look into those functions to see how I'm doing what the function says I'm doing.
 

bishiba

Adept
Veteran
Joined
Apr 6, 2016
Messages
183
Reaction score
51
First Language
Swedish
Primarily Uses
N/A
I'd suggest you refactor that code. There's a lot of redundencies & you're doing way, way too much in a single function.
It may currently work "kind of" but you're going to revisit that code at some point in the future. The easier it is to read, the better.

I'm not sure why you're using some things, e.g. why use an array to contain a single ship? If you were planning to use multiple ships, wouldn't it make more sense to push new ships into an array?

I'm also uncertain what your "this" reference is, since you seem to be drawing on methods that are attached to the parent objects, but there's no clear way of knowing what parent object that is?
Are you calling the createShip function from a Ship Controller class called BISH? Or is that the main ship and you're calling it from a ship object?

If I were to create a ship plugin, I'd probably create a ShipList Class, which contains the data of all ships & methods to control them, e.g.
JavaScript:
class $ShipList {
    constructor() {
        this.initialize();
    }
   
    initialize() {
        this.currentShips = [];
        this.graveyardShips = [];
    }
   
    addShipToList(ship) {
        this.currentShips.push(ship);
    }
   
    removeShipFromList(shipListIndex) {
        this.graveyardShips.push(this.currentShips[shipListIndex])
        this.currentShips.splice(shipListIndex, 1);
    }
}
$ShipList = new $ShipList();

That way, I can just send the Ship object after creation into the array of current ships to keep track of all ships that exist in one place. And I can even keep track of ships that were destroyed, by having a graveyard for them.

I'd create another class like the one shown earlier to serve as blueprint for all ships, to initialize them with everything all ships have in common.

I'd ensure that I encapsulate every single seperate action in a function, so that instead of having to read a lot of code, I can instead read functions that tell me what I'm doing here. And then I can look into those functions to see how I'm doing what the function says I'm doing.
I'll revisit this topic at a later date when I buy MZ, I used the free version for the game jam :p

But yes, what you say make sense. The biggest issue is that it's like a deep dive into the world of programming and I'm just now learning how these steps would work. And I think I joined the game jam when it was 8 days left and I tried to push something out in that time, and I think I was about 5 hours from being completely done before the deadline hit. So then I decided to expand the concept just for fun. But at that time there was already a lot of code that was hastily put together, and I started to optimize it. Bringing it down from about 1500 lines to about 900.

If you want me to explain further on the topic of what I wanted that would be great, but that would be better done through a discord call or similar. Because to be honest, there is no way I'll be able to explain my goals through text and then actually be understood at this point :p

But I really appreciate your effort into this, I really do and I keep this in mind constantly and I constantly try to improve my future coding.

Best regards to both of you who has been active in this thread :)
 

Anyone

Veteran
Veteran
Joined
Aug 24, 2019
Messages
257
Reaction score
353
First Language
German
Primarily Uses
RMMV
I'll revisit this topic at a later date when I buy MZ, I used the free version for the game jam :p

But yes, what you say make sense. The biggest issue is that it's like a deep dive into the world of programming and I'm just now learning how these steps would work. And I think I joined the game jam when it was 8 days left and I tried to push something out in that time, and I think I was about 5 hours from being completely done before the deadline hit. So then I decided to expand the concept just for fun. But at that time there was already a lot of code that was hastily put together, and I started to optimize it. Bringing it down from about 1500 lines to about 900.

If you want me to explain further on the topic of what I wanted that would be great, but that would be better done through a discord call or similar. Because to be honest, there is no way I'll be able to explain my goals through text and then actually be understood at this point :p

But I really appreciate your effort into this, I really do and I keep this in mind constantly and I constantly try to improve my future coding.

Best regards to both of you who has been active in this thread :)
Yeah, deadlines can cause code to be a bit messy.

It's probably worth it to do the deep dive, though, if you're really interested in programming custom functionality into MV/MZ.
I went through that about 1 1/2 years to 2 years ago, and everything's a lot easier now. Once you establish a certain foundation (e.g. understanding how JS passes arguments as values, except for Arrays and Objects), you become much more comfortable with knowing the tools at your disposal and you can start making habits of things that'll make it a lot easier to work with & improve your own code (e.g. scoping things in functions, so every function has a clear purpose and you can literally read what's being done without analyzing the code).

Good luck with your project, if you have a specific question you need help with, feel free to PM me.
 

Latest Threads

Latest Posts

Latest Profile Posts

So got my hearing tested to see if it was the cause of my mishearing what people say. Test showed no problems but talked with the doctor about anxiety and ADHD causing hearing issues and she agreed and also added that some people hear things differently. With my anxiety cause I am in fight or flight I pay attention to all the sounds in the area so body knows when react. Can't pay attention to one source.
Welp, people are trying to quit my team because I can't code. Where's the dancing blob emoji when I need it?

Forum statistics

Threads
116,053
Messages
1,095,328
Members
151,409
Latest member
naj
Top