mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2026-02-04 17:41:23 +01:00
sparse array implementation with reduced updates
This commit is contained in:
parent
5600c06381
commit
21710bc426
3 changed files with 90 additions and 31 deletions
|
|
@ -65,33 +65,41 @@ window.Ice = (function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new iceberg (manual editing)
|
|
||||||
function addIceberg(cellId, size) {
|
function addIceberg(cellId, size) {
|
||||||
const [cx, cy] = grid.points[cellId];
|
const [cx, cy] = grid.points[cellId];
|
||||||
const points = getGridPolygon(cellId).map(([x, y]) => [
|
const points = getGridPolygon(cellId).map(([x, y]) => [
|
||||||
rn(lerp(cx, x, size), 2),
|
rn(lerp(cx, x, size), 2),
|
||||||
rn(lerp(cy, y, size), 2)
|
rn(lerp(cy, y, size), 2)
|
||||||
]);
|
]);
|
||||||
|
//here we use the lose equality to find the first undefined or empty or null slot
|
||||||
pack.ice.icebergs.push({
|
const nextIndex = pack.ice.icebergs.findIndex(iceberg => iceberg == undefined);
|
||||||
cellId,
|
if (nextIndex !== -1) {
|
||||||
size,
|
pack.ice.icebergs[nextIndex] = {
|
||||||
points
|
cellId,
|
||||||
});
|
size,
|
||||||
|
points
|
||||||
return pack.ice.icebergs.length - 1; // return index
|
};
|
||||||
}
|
redrawIceberg(nextIndex);
|
||||||
|
} else {
|
||||||
// Remove ice element by index
|
pack.ice.icebergs.push({
|
||||||
function removeIce(type, index) {
|
cellId,
|
||||||
if (type === "glacier" && pack.ice.glaciers[index]) {
|
size,
|
||||||
pack.ice.glaciers.splice(index, 1);
|
points
|
||||||
} else if (type === "iceberg" && pack.ice.icebergs[index]) {
|
});
|
||||||
pack.ice.icebergs.splice(index, 1);
|
redrawIceberg(pack.ice.icebergs.length - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeIce(type, index) {
|
||||||
|
if (type === "glacier" && pack.ice.glaciers[index]) {
|
||||||
|
delete pack.ice.glaciers[index];
|
||||||
|
redrawGlacier(index);
|
||||||
|
} else if (type === "iceberg" && pack.ice.icebergs[index]) {
|
||||||
|
delete pack.ice.icebergs[index];
|
||||||
|
redrawIceberg(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update iceberg points and size
|
|
||||||
function updateIceberg(index, points, size) {
|
function updateIceberg(index, points, size) {
|
||||||
if (pack.ice.icebergs[index]) {
|
if (pack.ice.icebergs[index]) {
|
||||||
pack.ice.icebergs[index].points = points;
|
pack.ice.icebergs[index].points = points;
|
||||||
|
|
@ -99,7 +107,6 @@ window.Ice = (function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Randomize iceberg shape
|
|
||||||
function randomizeIcebergShape(index) {
|
function randomizeIcebergShape(index) {
|
||||||
const iceberg = pack.ice.icebergs[index];
|
const iceberg = pack.ice.icebergs[index];
|
||||||
if (!iceberg) return;
|
if (!iceberg) return;
|
||||||
|
|
@ -120,7 +127,6 @@ window.Ice = (function () {
|
||||||
iceberg.points = points;
|
iceberg.points = points;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change iceberg size and recalculate points
|
|
||||||
function changeIcebergSize(index, newSize) {
|
function changeIcebergSize(index, newSize) {
|
||||||
const iceberg = pack.ice.icebergs[index];
|
const iceberg = pack.ice.icebergs[index];
|
||||||
if (!iceberg) return;
|
if (!iceberg) return;
|
||||||
|
|
@ -129,7 +135,6 @@ window.Ice = (function () {
|
||||||
const [cx, cy] = grid.points[cellId];
|
const [cx, cy] = grid.points[cellId];
|
||||||
const oldSize = iceberg.size;
|
const oldSize = iceberg.size;
|
||||||
|
|
||||||
// Recalculate points based on new size
|
|
||||||
const flat = iceberg.points.flat();
|
const flat = iceberg.points.flat();
|
||||||
const pairs = [];
|
const pairs = [];
|
||||||
while (flat.length) pairs.push(flat.splice(0, 2));
|
while (flat.length) pairs.push(flat.splice(0, 2));
|
||||||
|
|
@ -143,7 +148,6 @@ window.Ice = (function () {
|
||||||
iceberg.size = newSize;
|
iceberg.size = newSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all ice data
|
|
||||||
function getData() {
|
function getData() {
|
||||||
return pack.ice;
|
return pack.ice;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,17 +11,73 @@ function drawIce() {
|
||||||
|
|
||||||
// Draw glaciers
|
// Draw glaciers
|
||||||
pack.ice.glaciers.forEach((glacier, index) => {
|
pack.ice.glaciers.forEach((glacier, index) => {
|
||||||
html += `<polygon points="${glacier.points}" type="iceShield" data-index="${index}" ${glacier.offset ? `transform="translate(${glacier.offset[0]},${glacier.offset[1]})"` : ""} class="glacier"/>`;
|
html += getGlacierHtml(glacier, index);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Draw icebergs
|
// Draw icebergs
|
||||||
pack.ice.icebergs.forEach((iceberg, index) => {
|
pack.ice.icebergs.forEach((iceberg, index) => {
|
||||||
html += `<polygon points="${iceberg.points}" cell="${iceberg.cellId}" size="${iceberg.size}" data-index="${index}" ${iceberg.offset ? `transform="translate(${iceberg.offset[0]},${iceberg.offset[1]})"` : ""} class="iceberg"/>`;
|
html += getIcebergHtml(iceberg, index);
|
||||||
});
|
});
|
||||||
|
|
||||||
ice.html(html);
|
ice.html(html);
|
||||||
|
|
||||||
TIME && console.timeEnd("drawIce");
|
TIME && console.timeEnd("drawIce");
|
||||||
|
|
||||||
|
function getGlacierHtml(glacier, index) {
|
||||||
|
return `<polygon points="${glacier.points}" type="iceShield" data-index="${index}" ${glacier.offset ? `transform="translate(${glacier.offset[0]},${glacier.offset[1]})"` : ""} class="glacier"/>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getIcebergHtml(iceberg, index) {
|
||||||
|
return `<polygon points="${iceberg.points}" cell="${iceberg.cellId}" size="${iceberg.size}" data-index="${index}" ${iceberg.offset ? `transform="translate(${iceberg.offset[0]},${iceberg.offset[1]})"` : ""} class="iceberg"/>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function redrawIceberg(index) {
|
||||||
|
TIME && console.time("redrawIceberg");
|
||||||
|
const iceberg = pack.ice.icebergs[index];
|
||||||
|
let el = ice.selectAll(`.iceberg[data-index="${index}"]`);
|
||||||
|
if (!iceberg && !el.empty()) {
|
||||||
|
el.remove();
|
||||||
|
} else {
|
||||||
|
if (el.empty()) {
|
||||||
|
// Create new element if it doesn't exist
|
||||||
|
const polygon = getIcebergHtml(iceberg, index);
|
||||||
|
ice.node().insertAdjacentHTML("beforeend", polygon);
|
||||||
|
el = ice.selectAll(`.iceberg[data-index="${index}"]`);
|
||||||
|
}
|
||||||
|
el.attr("points", iceberg.points);
|
||||||
|
el.attr("size", iceberg.size);
|
||||||
|
el.attr("cell", iceberg.cellId);
|
||||||
|
el.attr("transform", iceberg.offset ? `translate(${iceberg.offset[0]},${iceberg.offset[1]})` : null);
|
||||||
|
}
|
||||||
|
TIME && console.timeEnd("redrawIceberg");
|
||||||
|
|
||||||
|
function getIcebergHtml(iceberg, index) {
|
||||||
|
return `<polygon points="${iceberg.points}" cell="${iceberg.cellId}" size="${iceberg.size}" data-index="${index}" ${iceberg.offset ? `transform="translate(${iceberg.offset[0]},${iceberg.offset[1]})"` : ""} class="iceberg"/>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function redrawGlacier(index) {
|
||||||
|
TIME && console.time("redrawGlacier");
|
||||||
|
const glacier = pack.ice.glaciers[index];
|
||||||
|
let el = ice.selectAll(`.glacier[data-index="${index}"]`);
|
||||||
|
if (!glacier && !el.empty()) {
|
||||||
|
el.remove();
|
||||||
|
} else {
|
||||||
|
if (el.empty()) {
|
||||||
|
// Create new element if it doesn't exist
|
||||||
|
const polygon = getGlacierHtml(glacier, index);
|
||||||
|
ice.node().insertAdjacentHTML("beforeend", polygon);
|
||||||
|
el = ice.selectAll(`.glacier[data-index="${index}"]`);
|
||||||
|
}
|
||||||
|
el.attr("points", glacier.points);
|
||||||
|
el.attr("transform", glacier.offset ? `translate(${glacier.offset[0]},${glacier.offset[1]})` : null);
|
||||||
|
}
|
||||||
|
TIME && console.timeEnd("redrawGlacier");
|
||||||
|
|
||||||
|
function getGlacierHtml(glacier, index) {
|
||||||
|
return `<polygon points="${glacier.points}" type="iceShield" data-index="${index}" ${glacier.offset ? `transform="translate(${glacier.offset[0]},${glacier.offset[1]})"` : ""} class="glacier"/>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-render ice layer from data model
|
// Re-render ice layer from data model
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ function editIce() {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!modules.editIce) {
|
if (!modules.editIce) {
|
||||||
modules.editIce = {currentIndex: index};
|
modules.editIce = {currentIndex: index, isGlacier: isGlacier};
|
||||||
// add listeners
|
// add listeners
|
||||||
document.getElementById("iceEditStyle").addEventListener("click", () => editStyle("ice"));
|
document.getElementById("iceEditStyle").addEventListener("click", () => editStyle("ice"));
|
||||||
document.getElementById("iceRandomize").addEventListener("click", randomizeShape);
|
document.getElementById("iceRandomize").addEventListener("click", randomizeShape);
|
||||||
|
|
@ -32,19 +32,20 @@ function editIce() {
|
||||||
document.getElementById("iceRemove").addEventListener("click", removeIce);
|
document.getElementById("iceRemove").addEventListener("click", removeIce);
|
||||||
}
|
}
|
||||||
modules.editIce.currentIndex = index;
|
modules.editIce.currentIndex = index;
|
||||||
|
modules.editIce.isGlacier = isGlacier;
|
||||||
|
|
||||||
|
|
||||||
function randomizeShape() {
|
function randomizeShape() {
|
||||||
const idx = modules.editIce.currentIndex;
|
const idx = modules.editIce.currentIndex;
|
||||||
Ice.randomizeIcebergShape(idx);
|
Ice.randomizeIcebergShape(idx);
|
||||||
redrawIce();
|
redrawIceberg(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeSize() {
|
function changeSize() {
|
||||||
const newSize = +this.value;
|
const newSize = +this.value;
|
||||||
const idx = modules.editIce.currentIndex;
|
const idx = modules.editIce.currentIndex;
|
||||||
Ice.changeIcebergSize(idx, newSize);
|
Ice.changeIcebergSize(idx, newSize);
|
||||||
redrawIce();
|
redrawIceberg(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleAdd() {
|
function toggleAdd() {
|
||||||
|
|
@ -64,13 +65,12 @@ function editIce() {
|
||||||
const size = +document.getElementById("iceSize")?.value || 1;
|
const size = +document.getElementById("iceSize")?.value || 1;
|
||||||
|
|
||||||
Ice.addIceberg(i, size);
|
Ice.addIceberg(i, size);
|
||||||
redrawIce();
|
|
||||||
|
|
||||||
if (d3.event.shiftKey === false) toggleAdd();
|
if (d3.event.shiftKey === false) toggleAdd();
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeIce() {
|
function removeIce() {
|
||||||
const type = isGlacier ? "Glacier" : "Iceberg";
|
const type = modules.editIce.isGlacier ? "Glacier" : "Iceberg";
|
||||||
alertMessage.innerHTML = /* html */ `Are you sure you want to remove the ${type}?`;
|
alertMessage.innerHTML = /* html */ `Are you sure you want to remove the ${type}?`;
|
||||||
$("#alert").dialog({
|
$("#alert").dialog({
|
||||||
resizable: false,
|
resizable: false,
|
||||||
|
|
@ -78,8 +78,7 @@ function editIce() {
|
||||||
buttons: {
|
buttons: {
|
||||||
Remove: function () {
|
Remove: function () {
|
||||||
$(this).dialog("close");
|
$(this).dialog("close");
|
||||||
Ice.removeIce(isGlacier ? "glacier" : "iceberg", index);
|
Ice.removeIce(type.toLowerCase(), modules.editIce.currentIndex);
|
||||||
redrawIce();
|
|
||||||
$("#iceEditor").dialog("close");
|
$("#iceEditor").dialog("close");
|
||||||
},
|
},
|
||||||
Cancel: function () {
|
Cancel: function () {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue