I am writing a text based game where I want users to be able to manipulate any item.
I want the user to be able to say, for example, "I throw the bottle of oil at the monster."
Now when this happens [throw] will be an action, [bottle of oil] is an inventory item with the property [contains oil], and the monster will be the nearest monster in the room unless specified further.
Code needs to analyze the various properties of all these things and then pick actions that cause those things to interact.
When i write the Game story code it will be like follows
*room.darkroom.1 "wake up" [...] everything appears blurry, the voice sounds strange as if echoing down a long tunnel. From what you can see you can tell [you are in a dark room] your vision blurs from white to dark. [pc is inside very dark room. Inside this room everything is hidden in darkness. The northern wall has a locked thick wooden door. the southern wall has a barrel full of oil containing a bottle of oil. In the eastern side of the room are 2 medium sized crates one crate contains flint and rusty dagger. In the western side of the room a [small window] */room.darkroom.1
The script will take all those words and apply properties to them randomizing certain elements that are left unstated. So if you then say "chair" it will go to the chair properties and randomly assign unstated properties. One property of chair will be material. If its not stated that its an oak chair then the script should pick from any of the material properties and assign them. This new chair will pick up a few properties and be saved for future reference on the database with all properties.
Another property would be an action. A chair would not necessarily have an action .. but it might break. The script needs to know if the chair is breakable. But I am thinking that could be nested into another property like [toughness].
Many things will have many of the same properties: chair, night stand, table would all be similar in many ways. But they would also have different outcomes depending on the actions applied to them.
How do I specify for instance when "broken" contains chair legs and scrap material? The chair legs and the scrap material would both need to inherit the properties of the chair that was destroyed, such as oak / flammable / breakable. Obviously, as stated before, it might not have to inherit flammable or breakable if oak is the part that holds that value.
I want to make it easy to access the array that stores properties and that might include a script that effects behavior and descriptions of things.
I started to just create a keyed array which would be looped through... But now I am thinking that I should utilize the object based element of JavaScript.
Here is what i have started to do but I stopped right away:
var language = {
// key currentmodifyers possible modifyers action/condition description of item
item: ";medium,material;;its a thing thats not a person",
chair: "item,chair_Legs;;pile_of.#scraps.collection.chairlegx3/broken,#[chair ]scraps/destroyed; and someone could sit on it. ",
chair_leg:"item,blunt,light,"
}
I have so many definitions to write so it would be a shame to start writing it all and then have to do it over when I discover the best way.
I am looking at various ways to build objects in JavaScript, but would like the best way from someone experienced.
Understanding the complexity of my problem, what is the best way to store and apply properties?
There are actually two good thoughts in your question:
But now I am thinking that I should utilize the object based element of JavaScript.
You definitely need to use objects instead of arrays, the OOP ideas can be directly applied to your descriptions.
Some objects are composed of smaller parts (the "composition" in OOP) and some inherit properties of other objects (the "inheritance").
So you could have some base Item class which defines basic operations and properties for all objects (like they have different properties and can do some things).
Then you can add objects like StaticItem (will be base for chairs, night stands, etc) and LiveBeeing (monsters, etc).
And now you can actually create the Chair (pseudocode):
StaticItem extends Item
this.material = oak // oak is an object of OakMaterial
// is this static item flamable?
this.isFlamable = function() {
// we "redirect" flamability detection to the material
return this.material.flamable();
}
Chair extends Static
// break this chair!
this.break = function() {
// when it is broken we return a HeapOfCrap, it is a
// Static subclass which contains some sub-items
// In this case the heap contains 4 chair legs of the
// same material as the chair
return HeapOfCrap([
new ChairLeg(this.material), new ChairLeg(this.material),
new ChairLeg(this.material), new ChairLeg(this.material)
])
}
And so on, you need to plan you object structure carefully and there is a good field to apply some of the design patterns.
The example above is just what came in my mind immediately, while actual design should take much more time and thinking.
The second good thought in your question is about the huge amount of work:
I have so many definitions to write so it would be a shame to start writing it all and then have to do it over when I discover the best way.
You absolutely right here, would you select to use objects or arrays, or anything else - don't try to describe all your game right away.
Select few basic elements, like "Room", "Door", "Chair", "Monster", "Player" and try to code the minimal game with only these elements.
Play with the structure to find the good design and once you are sure it is good - go on and add more elements to the game.
Related
I am working to reduce size of an Equirectangular map, losslessly. Upon optimizing the SVG images with use of an online tool I am unsure whether any of the shapes overlap (hereby in this state of matter asserting a reality that is either conflicting or less relevant). Regardless of any one of the processing methods which applies to this image, I am simply assuming that multiplicity of straight(ened) lines among coordinates on the given map are best optimized with use of polynomial functions, composites and/or derivates thereof (such as splines or bezier curves, as defined with XML/SVG).
I am looking for a list of mathematical methods to use -- in order to figure out points where any of the neighbouring SVG polygons overlap. I expect to transform shapes upon discovering the most proper mathematics, so that two polynoms of any two shapes on map will only intersect in one point, at most (most likely so). In other words, any intersection will not exceed an area of zero and will match properties of either a zero-dimensional object (a point), or an infinite and limited series thereof (a line).
// See me write best code, because this is like the yellow cake topping of global standards
Import {
Uniform_Resource_Identifier as URI,
Uniform_Resource_Locator as URL
} from "#jsonion/RegularExpressions://wikipedia/en";
Import {
QualifiedName as QName
} from "#jsonion://www.w3.org/2001/tag/doc/qnameids"
Import {
Optional as Opt
} from "#jsonion://github.com/aldeed/simpl-schema"
Import { parseType, evaluateArgs, oneOf } from "jsonion/lib"
//
// Behind the scenes is a seamless SVGn archive of ```js onion ˙˙˙ sliced domesticated codebase from the interwebs
// … the sky's an umbrella term to everything we know & it comes in the shape of thy heartest sun -- there really is no end to it
//
// Look, a meteor shower surrounds a light source and its satellite
// .* //
var jsonion = {
loadRes: function (args, inputSchema = {
expr: "loadResource",
__location: {
uri: [URI, QName, oneOf],
href: [URL],
...oneOf
},
mirror: [URL, Opt]
})
{
/* … */
return ( var err = evaluateArgs( args, inputSchema )
? err.push("Li{B")
: "undefined" // … brb, get me a postMessage() method native to foreignObject
},
findMeOverlappingShapes: ( args = {
asd: "sdf",
foo: "bar"
}) =>
{
}
}
May I kindly request for this favour -- so to compile a JS fiddle or a Git commit which I can recall with ease of mind and think about, even while I do seemingly unrelated stuff (ie. slicing onions for a vegan pizza).
Can you please forward to me some of the fine online sources, whether be it aligned with any or all of the following... one that you would cite yourself; one with a good example (and corridors to lead through gaps of interlaced but distinct knowledge bodies); one that you expect to stay online and maintained for the longer period of time (with a disambiguation protocol for future reference)
I don't spell out mathematics as much as I do web coding, so thank you all so much!
PS, I will share my recipe for a cheese pizza topping which doesn't boil in a heated oven, embedded in the forementioned code pen/snippet, as promised
… that's a fully vegan or an ovo-vegetarian recipe, but of course I'll choose one of these types only after I study and understand sources in reference
I seem to be stuck at a probably idiotic problem but I can't figure it out...
There are classes for a Player, an Army, and a Unit.
The Player object contains several armies, which in turn contain several units.
I add a player like so: let player1 = new Player()
I add armies within the player object like: this.armies.push(new Army())
I add the units within the army object like: this.units.push(new Unit(data)) - data being an object, containing the unit's base stats.
This all works fine.
Now – when I try to change a stat of a single warrior unit (for example player1.armies[0].units[0].hp -= 2), it also changes the stats of each other warrior unit in all armies of player1.
How can I select a specific warrior unit by index within a specific army of player1?
Thanks in advance,
Simon
I am trying to create an HTML page that outputs random Mark Twain quotes. I have the function and quotes array set up in a separate (linked) Javascript file. For whatever reason, I can't get the output to show up on the HTML document.
*Edit to add: My apologies for not doing better research & finding that case sensitivity matters in cases like these. I'm a newbie :)
Here is my Javascript code.
// Quotes
var quotes = [
["The size of a misfortune is not determinable by an outsider's measurement of it but only by the measurements applied to it by the person specially affected by it. The king's lost crown is a vast matter to the king but of no consequence to the child. The lost toy is a great matter to the child but in the king's eyes it is not a thing to break the heart about."],
["Trivial Americans go to Paris when they die."],
["There isn't time -- so brief is life -- for bickerings, apologies, heartburnings, callings to account. There is only time for loving -- & but an instant, so to speak, for that."],
["Thunder is good, thunder is impressive; but it is lightning that does the work."],
["Everyone is a moon, and has a dark side which he never shows to anybody."]
];
// Generate a random number from the array
function random_item(quotes) {
return quotes[math.floor(math.random()*quotes.length)];
}
Here is my HTML code with the output that isn't working. I'm not including the full thing because this is the only relevant part.
<div id="quotes">
<script>
document.write(random_item(quotes));
</script>
</div>
If it were working, each time the page is visited/refreshed, one of the quotes should display at random. They won't show up at all though.
you have a typo with the Math object.
And consider avoiding putting script inside div
// Quotes
var quotes = [
["The size of a misfortune is not determinable by an outsider's measurement of it but only by the measurements applied to it by the person specially affected by it. The king's lost crown is a vast matter to the king but of no consequence to the child. The lost toy is a great matter to the child but in the king's eyes it is not a thing to break the heart about."],
["Trivial Americans go to Paris when they die."],
["There isn't time -- so brief is life -- for bickerings, apologies, heartburnings, callings to account. There is only time for loving -- & but an instant, so to speak, for that."],
["Thunder is good, thunder is impressive; but it is lightning that does the work."],
["Everyone is a moon, and has a dark side which he never shows to anybody."]
];
// Generate a random number from the array
function random_item(quotes) {
return quotes[Math.floor(Math.random()*quotes.length)];
}
document.querySelector('#quotes').innerText = random_item(quotes); // use instead of document.write
<div id="quotes">
</div>
A few months ago I made a small terrain generator, like Minecraft, for a school project.
The way I did this was by using multiple chunks. Each chunk contained a 3-dimensional array that stored the blocks.
Every position in this array corresponded with the position of the block it contained.
blocks[x, y, z] = new Block();
Now I would like to add different sizes if blocks. However, I can't do that with the way I am storing the blocks right now, because bigger blocks would have to be spread over multiple positions in the 3-dimensional array.
An example of a game with different sizes of blocks (and different shapes) is LEGO Worlds. How does a game like this store all these little blocks?
I hope someone can help me with this.
The language I am using is Javascript in combination with WebGL.
Thanks in advance!
In my experience there are a few different ways of tackling an issue like this, but the one I'd recommend would depend on the amount of time you have to work on this and the scope (how big) you wanted to make this game.
Your Current Approach
At the moment I think your using what most people would consider the most straightforward approach by storing the voxels in a 3D grid
[Source].
But two problems you seem to be having is that there isn't an obvious way to create blocks that are bigger then 1x1 and that a 3D grid for a world space is fairly inefficient in terms of memory usage (As for an array you have to have memory allocated for every cell, including empty space. JavaScript is no different).
An Alternative Approach
An alternative to using a 3D array would be to instead use a different data structure, the full name being a sparse voxel octree.
This to put it simply is a tree data structure that works by subdividing an area of space until everything has been stored.
The 2D form of this where a square sub divides into four smaller quadrants is called a quad tree and likewise a 3D equivalent divides into eight quadrants, called an octree. This approach is generally preferable when possible as its much more efficient because the trees only occupy more memory when its absolutely essential and they can also be packed into a 1D array (Technically a 3D array can be too).
A common tactic used with quad/octrees in some block based games is to take a region of the same kind of voxel that fit into one larger quadrant of the tree is to simply stop sub division there, as there's no reason to go deeper if all the data is the same.
The other optimization they can make is called sparse where regions of empty space (air) are simply deleted since empty space doesn't do anything special and its location can be inferred.
[SVO Source]
[Z Order Curve Source]
Recommended Approach
Unless you have a few months to complete your game and you're at university I seriously wouldn't recommend an SVO (Though reading up about could impress any teachers you have). Instead I'd recommend taking the same approach that Minecraft appears to visibly has. E.G. A door is 1X2 but blocks can only be 1x1, then just make it two blocks.
In the example of a door you would have four unique blocks in total, two for the upper and lower half, and two variations of each being opened or closed.
E.G.
var cubeProgram; // shader program
var cubeVBO; // vertex buffer (I recommend combining vertex & UV coords)
var gl; // rendering context
// Preset list of block ID's
var BLOCK_TYPES = {
DOOR_LOWER_OPEN: 0,
DOOR_UPPER_OPEN: 1,
DOOR_LOWER_CLOSED: 2,
DOOR_UPPER_CLOSED: 3,
}
var BLOCK_MESHES = {
GENERIC_VBO: null,
DOOR_UPPER_VBO: null
DOOR_LOWER_VBO: null
}
// Declare a Door class using ES6 syntax
class Door {
// Assume X & Y are the lower half of the door
constructor(x,y,map) {
if (y - 1 > -1) {
console.error("Error: Top half of the door goes outside the map");
return;
}
this.x = x;
this.y = y;
map[x][y ] = BLOCK_TYPES.DOOR_LOWER_OPEN;
map[x][y-1] = BLOCK_TYPES.DOOR_UPPER_OPEN;
}
}
I am trying to generate a random level for my silly game. The game consists of having laser/detector pairs around a square field of possible mirrors. Like this:
/*
LLLLLLLLLL
LmmmmmmmmL
LmmmmmmmmL
LmmmmmmmmL
LLLLLLLLLL
*/
Now, I have an algorithm which generates a level, quite poorly, by relying on random placement, and rejecting bad positions. This is not very fast, and does not really generate the kind of fields I'd like to have. Please feel free to try it out at http://cmouse.desteem.org/laser/
Any suggestions are welcome.
The current algorithm looks something like this:
function createLevel:
for i=0 to mirrors:
mirrorLocation = pickRandomPosition
mirrorType = pickRandomType
if (verifyPosition(mirrorLocation, mirrorType)):
i = i - 1
next
else:
storeMirror(mirrorLocation, mirrorType)
In verifyPosition, we test the mirror that it reaches a laser in all four directions, in hope of avoiding undetectedable mirrors. It is somewhat boring code, so I omit it here.
One way to make sure it's not trying multiple fields more than once is to iterate over the fields and put a mirror or not based on some probability. The probability to put a mirror should be #mirros / #fields, so that the expected number of mirrors is #mirrors at the end.