Reputation: 883
I am here today with a more design/conceptual doubt on how to approach a certain class scenario I'm planning to code.
Here's the deal, I am to implement a class Monster, which will hold most of the data related to kinds of monster existent in my game, but it will not hold effective data, in fact, what I want to store here are range of possible values, so when I actually create a monster object, it will have it's attributes within the range for the race/kind of the monster encountered.
Exemplifying: I will have different types of monster, Rat, Spider, Snake, Wolf. Each of this species will roll attributes within certain ranges:
Rat: Attack [5,9], Defense [3,5]
Spider: Attack [6,11], Defense [4,5]
...
I would like to have these data on a JSON object in my js file, from which I would then load its data and prepare to create the monster object on encounter taking this values into consideration.
What is troubling me is the design I should make for this to happen. I would say that a good way to make reference to the types of monsters would be something like, Monster.Rat, Monster.Spider, and call their constructor when the encounter happens: Monster.Spider() -> Would give me a monster object with random attributes within a spider range.
Also some point in time I would like to create specific areas for finding specific types of monsters, and I fail to see clearly how I would do that in a simple way, without making the code hard to read.
I did something like this a couple months ago, using Swift, and the approach I made was having a class method on monster for every type of monster I wanted, but this was hard to maintain, since if I wanted to change the way monsters were created I would have to change all the methods, also add a new method for every new type of monster desired.
What do you think would be the best way to handle the design of a game like that? I know I don't want to create new classes extending Monster for every new type of monster I have, as that feels terribly wrong and bad design to me.
Thanks for your time, I'll keep this post updated with whatever interesting piece of information I find.
Upvotes: 0
Views: 286
Reputation: 1117
EDIT: I've made a couple of improvements to this script for you, too - just to highlight what can be done:
var Monster = {
monsters: {
rat: {
attack: [5, 9],
defense: [3, 5],
health: [5, 10],
title: "Rat"
},
spider: {
attack: [6, 11],
defense: [4, 5],
health: [4, 6],
title: "Spider"
}
},
create: function(type) {
// choose type at random if not specified
if(typeof type !== "string") {
var keys = [ ];
for(var key in this.monsters) {
if(this.monsters.hasOwnProperty(key)) {
keys.push(key);
}
}
type = keys[Math.floor(Math.random() * keys.length)];
}
// check if given monster type exists
if(typeof this.monsters[type] === "undefined") {
throw new TypeError('invalid monster type "' + type + '"');
}
var monster = { };
/*
* This allows you to add new attributes and not have to change any
* of this code, except the attributes object for each monster.
*/
for(var attribute in this.monsters[type]) {
if(this.monsters[type].hasOwnProperty(attribute)) {
var a = this.monsters[type][attribute];
if(typeof a == "object") {
a = Math.floor(Math.random() * (a[1] - a[0] + 1) + a[0]);
}
monster[attribute] = a;
}
}
return monster;
}
};
console.log(Monster.create('rat'));
console.log(Monster.create('spider'));
console.log(Monster.create());
This is what I'd do, this is nice and simple, and allows easy adding of monsters and attributes in future:
var Monster = {
monsters: {
rat: {
attack: [5, 9],
defense: [3, 5],
},
spider: {
attack: [6, 11],
defense: [4, 5]
}
},
create: function(type) {
// check if given monster type exists
if(typeof this.monsters[type] === "undefined") {
throw new TypeError('invalid monster type "' + type + '"');
}
var monster = { };
/*
* This allows you to add new attributes and not have to change any
* of this code, except the attributes object for each monster.
*/
for(var attribute in this.monsters[type]) {
if(this.monsters[type].hasOwnProperty(attribute)) {
var a = this.monsters[type][attribute];
monster[attribute] = Math.floor(Math.random() * (a[1] - a[0] + 1) + a[0]);
}
}
return monster;
}
};
console.log(Monster.create('rat'));
console.log(Monster.create('spider'));
Upvotes: 3