xxxxxxxxxx
275
let AMT_THINGS = 1100;
let GRID_SIZE = 20; // Size of each grid cell
let SHOW_TEXT = true;
let LOW_RES = false; // Set to true for low-res fallback
let names = ["thing", "thing2", "thing", "thing4", "thing5", "longthingname"];
let inventory = [];
let btn_sort;
let slider_columns;
let checkbox_sortOnChange;
let offsetX = 0;
let offsetY = 0;
let isPanning = false;
let startPanX, startPanY;
let maxItemWidth;
let defaultColumns;
let prevColumns;
let totalInventoryHeight = 0;
function setup() {
createCanvas(800, 600);
// Create GUI elements
btn_sort = createButton("Sort Inventory");
btn_sort.position(20, height + 20);
btn_sort.mousePressed(sortInventory);
slider_columns = createSlider(1, 100, 1);
slider_columns.position(150, height + 20);
slider_columns.style('width', '200px');
slider_columns.input(onColumnSliderChange);
checkbox_sortOnChange = createCheckbox('Sort on Change Width', false);
checkbox_sortOnChange.position(370, height + 20);
// Create InvObject items and generate textures
for (let i = 0; i < AMT_THINGS; i++) {
let o = new InvObject(names[i % names.length]);
o.generateTexture();
inventory.push(o);
}
// Calculate K (maximum item width)
maxItemWidth = Math.max(inventory.map(item => item.gridW));
defaultColumns = 4 * maxItemWidth;
slider_columns.value(defaultColumns);
prevColumns = defaultColumns;
// Initially arrange the inventory
arrangeInventory();
}
function draw() {
background(251);
// Apply vertical offset for scrolling
push();
translate(offsetX, offsetY);
displayInventory();
pop();
// Draw scroll bar if needed
drawScrollBar();
}
function displayInventory() {
for (const box of inventory) {
// Use the pre-generated texture
if (box.texture) {
image(
box.texture,
box.x * GRID_SIZE,
box.y * GRID_SIZE,
box.gridW * GRID_SIZE,
box.gridH * GRID_SIZE
);
} else {
// Fallback to a colored rectangle
fill(box.color);
rect(
box.x * GRID_SIZE,
box.y * GRID_SIZE,
box.gridW * GRID_SIZE,
box.gridH * GRID_SIZE
);
}
if (SHOW_TEXT) {
fill(0);
text(
box.name,
box.x * GRID_SIZE,
box.y * GRID_SIZE - box.gridH * GRID_SIZE
);
}
}
}
function mouseWheel(event) {
// Adjust vertical offset for scrolling
offsetY -= event.delta;
// Constrain scrolling to the bounds of the inventory
offsetY = constrain(
offsetY,
height - totalInventoryHeight - 50, // -50 for some padding
0
);
return false; // Prevent default behavior
}
function mousePressed() {
isPanning = true;
startPanX = mouseX - offsetX;
startPanY = mouseY - offsetY;
}
function mouseDragged() {
if (isPanning) {
offsetX = mouseX - startPanX;
// Horizontal panning only
// offsetY = mouseY - startPanY;
// Optional: Constrain offsetX if needed
}
}
function mouseReleased() {
isPanning = false;
}
function onColumnSliderChange() {
let columns = slider_columns.value();
if (columns < prevColumns) {
// Columns decreased, rearrange inventory
if (checkbox_sortOnChange.checked()) {
sortInventory();
} else {
arrangeInventory();
}
} else {
// Columns increased, keep relative positions
adjustInventoryForIncreasedColumns(prevColumns, columns);
}
prevColumns = columns;
}
function sortInventory() {
// Sort items based on their area (could be any sorting criteria)
inventory.sort((a, b) => b.gridW * b.gridH - a.gridW * a.gridH);
arrangeInventory();
}
function arrangeInventory() {
let columns = slider_columns.value();
let x = 0;
let y = 0;
let maxRowHeight = 0;
for (const box of inventory) {
if (x + box.gridW > columns) {
// Move to next row
x = 0;
y += maxRowHeight;
maxRowHeight = 0;
}
box.x = x;
box.y = y;
x += box.gridW;
maxRowHeight = max(maxRowHeight, box.gridH);
}
// Calculate total inventory height
totalInventoryHeight = (y + maxRowHeight) * GRID_SIZE;
// Reset vertical offset if needed
offsetY = constrain(offsetY, height - totalInventoryHeight - 50, 0);
}
function adjustInventoryForIncreasedColumns(oldColumns, newColumns) {
// Adjust positions for increased columns without rearranging
for (const box of inventory) {
if (box.x + box.gridW > oldColumns) {
// Move item to next row if it was previously wrapped
box.x = box.x % oldColumns;
box.y -= floor(box.x / oldColumns) * box.gridH;
}
// No further adjustment needed as we are increasing columns
}
// Recalculate positions
arrangeInventoryPositionsOnly(newColumns);
}
function arrangeInventoryPositionsOnly(columns) {
let x = 0;
let y = 0;
let maxRowHeight = 0;
for (const box of inventory) {
if (x + box.gridW > columns) {
// Move to next row
x = 0;
y += maxRowHeight;
maxRowHeight = 0;
}
box.x = x;
box.y = y;
x += box.gridW;
maxRowHeight = max(maxRowHeight, box.gridH);
}
// Calculate total inventory height
totalInventoryHeight = (y + maxRowHeight) * GRID_SIZE;
// Reset vertical offset if needed
offsetY = constrain(offsetY, height - totalInventoryHeight - 50, 0);
}
function drawScrollBar() {
if (totalInventoryHeight > height) {
let scrollbarHeight = map(height, 0, totalInventoryHeight, height, 20);
let scrollbarY = map(-offsetY, 0, totalInventoryHeight - height, 0, height - scrollbarHeight);
fill(200);
rect(width - 20, scrollbarY, 15, scrollbarHeight);
}
}
class InvObject {
constructor(name) {
this.name = name;
// Item dimensions in grid units (integers)
this.gridW = floor(random(1, 5)); // Width in grid cells
this.gridH = floor(random(1, 5)); // Height in grid cells
this.x = 0; // Grid position x
this.y = 0; // Grid position y
this.texture = null;
this.color = color(random(255), random(255), random(255));
}
generateTexture() {
// Decide texture resolution based on LOW_RES flag
let texWidth = this.gridW * GRID_SIZE;
let texHeight = this.gridH * GRID_SIZE;
if (LOW_RES) {
texWidth /= 2;
texHeight /= 2;
}
// Create a graphics buffer
this.texture = createGraphics(texWidth, texHeight);
// Draw random shapes or patterns
this.texture.background(random(255), random(255), random(255));
for (let i = 0; i < 10; i++) {
this.texture.fill(random(255), random(255), random(255), 100);
this.texture.noStroke();
this.texture.ellipse(
random(texWidth),
random(texHeight),
random(10, texWidth / 2)
);
}
}
}