Hello and welcome to our community! Is this your first visit?
Enjoy an ad free experience by logging in. Not a member yet? Register.

# Thread: Simple Simulation in JS and HTML

1. ## Simple Simulation in JS and HTML

I've been given the challenge of creating a simple simulation in Javascript and html. Here are the criteria:

- A bunny occupies a meadow that is 30 units wide and 30 units long.
- The bunny has a limited amount of energy. 1000 units to start.
- The bunny can only move one spatial unit per unit time. Each movement may be in any direction.
- Each time the bunny moves, it spends 1 unit of energy.
- The meadow is bathed by sunlight, and the soil is fertile and rich. Plants grow in the meadow. These plants can be eaten by the bunny. Each plant boosts the energy of the bunny by ten units. When the plant is eaten by the bunny, it should no longer be present in the meadow.
- Plants grow at random in the meadow.
- Plants boost the bunny's energy by 10 units
- No two plants may occupy the same space in the meadow.

So far, I have the bunny moving properly and its energy adjusting properly, but I can's seem to figure out how to visually add plants to the meadow. My current code is below:

HTML:
Code:
```<div id="energyFeedback" style="width:300px; height:10px; border:1px solid #666;">
<div id="energyFeedbackBar" style="width:100%; background-color:#999; height:100%;"></div></div>
<div id="gameContainer" style="position:absolute; top:30px;">
<div id="meadow" style="width:300px; height:300px; background-color:#957E52; position:absolute; left:0px; top:0px;">
<div id="bunny" style="position:absolute; height:10px; width:10px; background-color:#FCC;"></div>
</div>
</div>```
JS:
Code:
```//The bunny will start in the center of the meadow... therefore 15units in x & 15units in y directions
var bunny = {name: "Bunny", x: 15, y: 15, energy: 1000};
//as plants are created, they will get pushed into this array:
var allPlants = [];

//Graphic stuff
// Create a reference to the HTML element on screen so that you can move it around
bunny.graphic = document.getElementById('bunny');
energyFeedbackBar.graphic = document.getElementById('energyFeedbackBar');

//growthFactor will determine how likely a plant is to grow. Modify this value to answer the question above.
var growthFactor = 0.5;

//make a list of directions of travel for our Bunny
var directions = [
n = {x: 0, y: -1, name: "North"},
e = {x: 1, y: 0, name: "East"},
s = {x: 0, y: 1, name: "South"},
w = {x: -1, y: 0, name: "West"},];

//setInterval will make the program run every 100ms (in this case)
var int = setInterval(Simulation,100);

//intervalCount will keep track of our units of time expended
var intervalCount = 0;

//clear the interval (once the angriest bunny has been determined)
function stopInt() {
clearInterval(int);
};

//this function gives a random element from an array (directions in our case)
function randomElement(_array) {
if (_array.length == 0)
throw new Error("The array is empty.");
return _array[Math.floor(Math.random() * _array.length)];
};

//the moveBunny function will take the bunny and and move it in a random direction
function moveBunny() {
// if the bunny is still alive...
if (bunny.energy > 0) {
//choose a random direction by running our "directions" array through our randomElement function.
var directionOfMovement = randomElement(directions);
//the bunny's position is changed by adding a random value to his x and y coordinates
var newPosX = bunny.x + directionOfMovement.x;
var newPosY = bunny.y + directionOfMovement.y;
//we must constrain the bunny's movement to within the 30 by 30 meadow
if (newPosX < 0 || newPosX > 30) {
//basically, if the bunny lands beyond 30px or before 0px in the x or y directions,
//	their value gets reset to the min or max distances.
if (newPosX > 30) {
bunny.x = 30;
}
else {
bunny.x = 0;
}
}
//If they fall within the meadow, the bunny's x and y value are now updated to the new value.
else {
bunny.x = newPosX;
}
if (newPosY < 0 || newPosY > 30) {
if (newPosY > 30) {
bunny.y = 30;
}
else {
bunny.y = 0;
}
}
else {
bunny.y = newPosY;
}
}
else{
stopInt();
};
//move bunny graphically on the browser.
bunny.graphic.style.left = (bunny.x * 10) + 'px';
bunny.graphic.style.top = (bunny.y * 10) + 'px';
console.log(bunny.name + " moved to x: " + bunny.x + ", y: " + bunny.y + ", " + directionOfMovement.name);
//bunny's health is reduced by 1 unit per movement.
bunny.energy -= 1;
//represent this graphically in the browser by adjusting the width of the energyFeedbackBar to represent the bunny's current energy level.
energyFeedbackBar.graphic.style.width = (bunny.energy/10)*3;
console.log(bunny.name + " has " + bunny.energy + " units of energy left.");
};

function createPlant() {
//*********************************Here is where the problem begins...***********************************
//the plant needs to appear on the screen as a small green square (approx 5 by 5px) within the 30 by 30px meadow.
//Every plant created must be pushed onto the array 'allPlants' so that it can be compared to the position of the bunny.
//I thought that maybe divs could be dynamically generated but I'm not sure if this is the most effective way, or if I'm even doing this properly. I tried this below:

/*var plant = document.createElement("div");
plant.id = "plant" + intervalCount;
plant.style.x = Math.floor(Math.random()*30) + "px";
plant.style.y = Math.floor(Math.random()*30) + "px";
plant.style.width = 5 + "px";
plant.style.height = 5 + "px";
plant.style.background = "#090";
document.documentElement.appendChild(plant);
console.log("plant created at x: " + plant.x +" and y: " + plant.y);*/
};

//Simulation will determine whether a plant grows,
//...moves the bunny
//... and compares the position of the bunny to the position of all the plants.
function Simulation(){
//To keep track of time, add to the intervalCount
intervalCount++;
//state time in the console
console.log("Time: " + intervalCount +" units");
//grow a plant randomly (dependant on the growth factor)
if (Math.random() < growthFactor) {
createPlant();
}
//move the bunny
moveBunny();
// Compare bunny's position to the plants' positions, if there are plants.
if (allPlants.length >= 1) {
for (var j = 0; j < allPlants.length; j++) {
// compare x and y co-ordinates
if (bunny.x == allPlants[j].x && bunny.y == allPlants[j].y) {
console.log("The bunny ate a plant!");
//increase bunny's energy
bunny.energy = bunny.energy + 10;

// *********Here the plant must also be removed from allPlants and removed visually from the meadow***********
};
};
};
};```
Any help with this generation of plants would be appreciated!

• Can you describe a little more what the exact problem you're having is? (ex: are your plants not displaying, are they getting placed incorrectly...)

At a quick glance, I notice two issues:

1. You should be able to use document.appendChild instead of document.documentElement.appendChild
2. Your plant needs to have the "position: absolute" style attached to it.

This sounds like a fun assignment. I'd love to see your full source so I can run it and watch the bunny.

• Hi, thanks for your response!

My problem is that my plants do not show up at all. Specifically I'm getting an error in the console that says: HIERARCHY_REQUEST_ERR: DOM Exception 3: A Node was inserted somewhere it doesn't belong.

I've taken your suggestions and made the following changes to my createPlant script:

Code:
```function createPlant() {
var plant = document.createElement("div");
plant.id = "plant" + intervalCount;

var xValue = Math.floor(Math.random()*30);
plant.style.x = xValue + "px";

var yValue = Math.floor(Math.random()*30);
plant.style.y = yValue + "px";

plant.style.width = 5 + "px";
plant.style.height = 5 + "px";
plant.style.background = "#090";
plant.style.position = "absolute";
document.appendChild(plant);

console.log("plant created at x: " + xValue +" and y: " + yValue);

//push coordinates onto allPlants array
allPlants.push({x: xValue, y: yValue});
};```
I'd be more than happy to post once it all works!

• document.appendChild(plant);

adds the plant to the end of the document after the </body> where it isn't allowed.

You need to specify the parent element that you want to append into the end of when using appendChild()

• Thank you! that fixed the error! All of my code works now though my plants are still invisible! The file can be accessed here:

http://bmc.erin.utoronto.ca/~andrea/..._20120122.html

Turn on your console log to see what's going on a bit better. Now I just need to figure out the html bit to represent the plants visually!

• Well, no wonder you can't see the plants. Look at the style you gave them:
Code:
`style="width: 5px; height: 5px; background: none repeat scroll 0% 0% rgb(102, 204, 51); position: absolute;">`
background: none
[/code]
means that none of the rest of the specification there matters. The will *NOT* have any background and so are invisible.

Try something like:
Code:
`style="width: 5px; height: 5px; background-color: lime; position: absolute;">`
Bit while you are at it, stop using an inline style.

Do this:
Code:
```<style type="text/css">
div.plant { width: 5px; height: 5px; background-color: lime; position: absolute; }
</style>```
and then you can just do
Code:
`<div class="plant" style="left: xxxpx; top: yyypx;">`
As it is now, all your plants are in the same place on the screen: the top left corner, since you never give them either a top or left position.

• Oh, and when the bunny eats a plant, just change it via `style.backgroundColor='black';` perhaps.

• Thank you Old Pendant! Everything works now!

•

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•