Hormiguero con jQuery (parte 2)

En esta nueva entrega añado la funcionalidad de que haya paredes (celdas naranjas) dentro del hormiguero, al igual que con el resto de celdas, las hormigas esquivan dichas paredes:



Código HTML:

<!doctype html>
<html>
<head>
<link rel="stylesheet" href="anthill-2.css"/>
<script src="jquery.min_.1.10.1.js"></script>
<script src="anthill-2.js"></script>
</head>
<body>
<div class="anthill" width="50" height="30" cell="15"></div>
</body>
</html>

Código CSS:

.anthill {
background-color: black;
position: relative;
}

.cell {
position: absolute;
}

.ant {
background-color: blue;
}

.grub {
background-color: white;
}

.wall {
background-color: orange;
}

Código JS:

// Enumeration of cell types.
var Cell = {
Empty: 0,
Wall: 1,
Ant: 2,
Grub: 3
}
// Hash to store all the needed data structures to store an anthill.
var theAnthill = {};

// Return a free position in the array.
function FreePosition(cells) {
var position = {x: 0, y: 0};
do {
// Calculate a random position in the anthill.
position.y = Math.floor(Math.random() * cells.length);
position.x = Math.floor(Math.random() * cells[position.y].length);
// Loop until a free position is found.
} while (cells[position.y][position.x] != Cell.Empty);
return position;
}

function FillCell(anthill, position, elements, cellClass, cellType) {
// Create a new div with the needed CSS class.
var element = $(document.createElement("div"));
element.addClass("cell " + cellClass);
// Set the element dimensions & position.
element.css({"width": ("" + anthill.cell + "px"),
"height": ("" + anthill.cell + "px"),
"left": ("" + (position.x * anthill.cell) + "px"),
"top": ("" + (position.y * anthill.cell) + "px")});
// Add the element to the anthill.
anthill.div.append(element);
// Add it to the elements array.
elements.push({position: position, element: element});
// Set the cell as busy.
anthill.cells[position.y][position.x] = cellType;
}

// Fill an array of elements.
function FillCells(countOfElements, anthill, elements, cellType, cellClass) {
for (var i = 0; i < countOfElements; i++) {
// Get a free position in the anthill.
var position = FreePosition(anthill.cells);
// Fill the cell type.
FillCell(anthill, position, elements, cellClass, cellType);
}
}

// Move a position in a toroide anthill world with a direction.
function MovePosition(anthill, position, direction) {
// Calculate a new position based on the direction.
var newPosition = {x: position.x + direction.incX,
y: position.y + direction.incY};
// Make the movement in a toroide world.
if (newPosition.x < 0) {
newPosition.x = anthill.width - 1;
} else if (newPosition.x >= anthill.width) {
newPosition.x = 0;
}
if (newPosition.y < 0) {
newPosition.y = anthill.height - 1;
} else if (newPosition.y >= anthill.height) {
newPosition.y = 0;
}
return newPosition;
}

// Fill the anthill with walls.
function FillWalls(countOfWalls, anthill) {
var maxLength = anthill.cells.length;
maxLength = (anthill.cells[0].length < maxLength) ? anthill.cells[0].length : maxLength;
maxLength /= 3;
var minLength = maxLength / 5;
for (var leftLength = countOfWalls; leftLength >= 0; ) {
// Calculate wall length.
var length = Math.floor(Math.random() * (maxLength - minLength)) + minLength;
// Decrement the wall left length.
leftLength -= length;
// Get a free position in the anthill.
var position = FreePosition(anthill.cells);
// Calculate a direction to create the wall along to.
var direction = {incX: Math.floor(Math.random() * 2), incY: 0};
direction.incY = (direction.incX == 0) ? 1 : 0;
console.log("Direction: [" + direction.incX + ", " + direction.incY + "]");
// Create as many walls as needed by the length.
for (var i = 0; i < length; i++) {
// Fill the cell with a wall.
FillCell(anthill, position, anthill.walls, "wall", Cell.Wall);
console.log("Wall " + i + " created on [" + position.x + ", " + position.y + "]");
console.log("direction: [" + direction.incX + ", " + direction.incY + "]");
// Move the position.
position = MovePosition(anthill, position, direction);
}
}
}

// Change the direction of an ant.
function ChangeDirection(direction) {
do {
direction.incX = Math.floor(Math.random() * 3) - 1;
direction.incY = Math.floor(Math.random() * 3) - 1;
} while ((direction.incX == 0) && (direction.incY == 0));
}

// Move an ant inside the anthill.
function ChangeAntPosition(ant, anthill) {
// Calculate a new position based on the ant direction.
newPosition = MovePosition(anthill, ant.position, ant.direction);
// Check if the new position is free.
if (anthill.cells[newPosition.y][newPosition.x] == Cell.Empty) {
// Empty the previous cell, and fill the new position.
anthill.cells[ant.position.y][ant.position.x] = Cell.Empty;
anthill.cells[newPosition.y][newPosition.x] = Cell.Ant;
// Change the ant position.
ant.position = newPosition;
ant.element.css({"left": ("" + (newPosition.x * anthill.cell) + "px"),
"top": ("" + (newPosition.y * anthill.cell) + "px")});
} else {
// The new position is busy, change the ant direction (& don't move it).
ChangeDirection(ant.direction);
}
}

$(document).ready(function() {
$(".anthill").each(function() {
// Get the DIV element.
theAnthill.div = $(this);
// Get DIV attributes.
theAnthill.width = theAnthill.div.attr("width") || 50;
theAnthill.height = theAnthill.div.attr("height") || 30;
theAnthill.cell = theAnthill.div.attr("cell") || 15;
// Protect DIV attribute values.
theAnthill.width = (theAnthill.width < 10) ? 10 : theAnthill.width;
theAnthill.width = (theAnthill.width > 100) ? 100 : theAnthill.width;
theAnthill.height = (theAnthill.height < 10) ? 10 : theAnthill.height;
theAnthill.height = (theAnthill.height > 100) ? 100 : theAnthill.height;
theAnthill.cell = (theAnthill.cell < 1) ? 1 : theAnthill.cell;
theAnthill.cell = (theAnthill.cell > 100) ? 100 : theAnthill.cell;
// Set DIV dimensions.
theAnthill.div.css({"width": ("" + (theAnthill.width * theAnthill.cell) + "px"),
"height": ("" + (theAnthill.height * theAnthill.cell) + "px")});
// Fill the cells array.
theAnthill.cells = [];
for (var y = 0; y < theAnthill.height; y++) {
theAnthill.cells[y] = [];
for (var x = 0; x < theAnthill.width; x++) {
theAnthill.cells[y][x] = Cell.Empty;
}
}
// Calculate how many cell types we should generate.
var countOfWalls = (theAnthill.width * theAnthill.height) * 0.1;
var countOfAnts = (theAnthill.width * theAnthill.height) * 0.01;
var countOfGrubs = (theAnthill.width * theAnthill.height) * 0.07;
// Fill the walls array.
theAnthill.walls = [];
FillWalls(countOfWalls, theAnthill);
// Fill the ants array.
theAnthill.ants = [];
FillCells(countOfAnts, theAnthill, theAnthill.ants, Cell.Ant, "ant");
for (var i = 0; i < theAnthill.ants.length; i++) {
theAnthill.ants[i].direction = {};
ChangeDirection(theAnthill.ants[i].direction);
}
// Fill the grubs array.
theAnthill.grubs = [];
FillCells(countOfGrubs, theAnthill, theAnthill.grubs, Cell.Grub, "grub");
});
});

window.setInterval(function() {
// Loop along all the ants.
for (var i = 0; i < theAnthill.ants.length; i++) {
var ant = theAnthill.ants[i];
// Change the direction of the ant 1 of 20 times.
if (Math.floor(Math.random() * 20) == 0) {
ChangeDirection(ant.direction);
}
// Move the ant.
ChangeAntPosition(ant, theAnthill);
}
},100); // 100ms period.

A continuación os dejo los enlaces al código fuente:

3 comentarios

  1. hcg weight loss north carolina

    Hormiguero con jQuery (parte 2) « OCIO y TECnología

  2. legal advisors

    Hormiguero con jQuery (parte 2) « OCIO y TECnología

  3. athletic shoes

    Hormiguero con jQuery (parte 2) « OCIO y TECnología

Deja un comentario