🔨 KICKSTARTER DEMO 99% - Tools (63), Blacksmith (8), Repair UI (6), Ivan NPC (5)
- Generated ALL 63 tool sprites (10 types × 6 tiers + 3 extras) - Completed Blacksmith Building sprites (8/8) - Completed Repair Bench UI (6/6) - Generated Ivan Blacksmith NPC sprites with master reference (5/6) - Confirmed NPC eye style: friendly NPCs have red eyes WITH pupils - Total: 112 production-ready sprites in 30min session - Demo launch ready, only organization remaining
This commit is contained in:
337
tools/asset_browser.html
Normal file
337
tools/asset_browser.html
Normal file
@@ -0,0 +1,337 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>🎨 NovaFarma Asset Browser</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
background: #1a1a1a;
|
||||
color: #fff;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
padding: 30px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
border-radius: 15px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
font-size: 2.5em;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.filters {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
margin-bottom: 30px;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.filter-btn {
|
||||
padding: 12px 24px;
|
||||
background: #2d2d2d;
|
||||
border: 2px solid #444;
|
||||
border-radius: 25px;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.filter-btn:hover {
|
||||
background: #667eea;
|
||||
border-color: #667eea;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.filter-btn.active {
|
||||
background: #667eea;
|
||||
border-color: #667eea;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
margin: 0 auto 30px;
|
||||
padding: 15px 25px;
|
||||
background: #2d2d2d;
|
||||
border: 2px solid #444;
|
||||
border-radius: 30px;
|
||||
color: #fff;
|
||||
font-size: 1.1em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.search-box:focus {
|
||||
outline: none;
|
||||
border-color: #667eea;
|
||||
}
|
||||
|
||||
.gallery {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.asset-card {
|
||||
background: #2d2d2d;
|
||||
border-radius: 15px;
|
||||
padding: 15px;
|
||||
border: 2px solid #444;
|
||||
transition: all 0.3s;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.asset-card:hover {
|
||||
transform: translateY(-5px);
|
||||
border-color: #667eea;
|
||||
box-shadow: 0 10px 30px rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.asset-card img {
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
object-fit: contain;
|
||||
background: #1a1a1a;
|
||||
border-radius: 10px;
|
||||
margin-bottom: 10px;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
.asset-name {
|
||||
font-size: 0.9em;
|
||||
text-align: center;
|
||||
word-break: break-word;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.asset-size {
|
||||
font-size: 0.75em;
|
||||
text-align: center;
|
||||
color: #666;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.category-section {
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.category-title {
|
||||
font-size: 2em;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 3px solid #667eea;
|
||||
}
|
||||
|
||||
.copy-badge {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
font-size: 0.8em;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.asset-card.copied .copy-badge {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>🎨 NovaFarma Asset Browser</h1>
|
||||
<p>Visual asset picker for Tiled - Click any asset to copy its path!</p>
|
||||
</div>
|
||||
|
||||
<input type="text" class="search-box" id="search"
|
||||
placeholder="🔍 Pretraži assete... (npr. 'tree', 'grass', 'tent')">
|
||||
|
||||
<div class="filters" id="filters">
|
||||
<button class="filter-btn active" onclick="filterCategory('all')">Vsi Asseti</button>
|
||||
<button class="filter-btn" onclick="filterCategory('teren')">🌍 Teren</button>
|
||||
<button class="filter-btn" onclick="filterCategory('narava')">🌿 Narava</button>
|
||||
<button class="filter-btn" onclick="filterCategory('zgradbe')">🏚️ Zgradbe</button>
|
||||
<button class="filter-btn" onclick="filterCategory('objekti')">📦 Objekti</button>
|
||||
<button class="filter-btn" onclick="filterCategory('crops')">🌾 Crops</button>
|
||||
<button class="filter-btn" onclick="filterCategory('biomi')">🗺️ Biomi</button>
|
||||
</div>
|
||||
|
||||
<div id="gallery-container"></div>
|
||||
|
||||
<script>
|
||||
// Asset categories and their file paths
|
||||
const assetPaths = {
|
||||
teren: 'assets/slike 🟢/teren',
|
||||
narava: 'assets/slike 🟢/narava',
|
||||
zgradbe: 'assets/slike 🟢/zgradbe',
|
||||
objekti: 'assets/slike 🟢/objekti',
|
||||
crops: 'assets/crops/faza1',
|
||||
biomi: 'assets/slike 🟢/biomi'
|
||||
};
|
||||
|
||||
let currentFilter = 'all';
|
||||
let allAssets = [];
|
||||
|
||||
// Load assets dynamically
|
||||
async function loadAssets() {
|
||||
const container = document.getElementById('gallery-container');
|
||||
|
||||
// For demo, manually list known assets
|
||||
const knownAssets = [
|
||||
// Teren
|
||||
{ path: 'assets/slike 🟢/teren/teren_dirt_path_style32.png', category: 'teren', name: 'Dirt Path' },
|
||||
{ path: 'assets/slike 🟢/teren/teren_corrupted_ground_style32.png', category: 'teren', name: 'Corrupted Ground' },
|
||||
{ path: 'assets/slike 🟢/teren/teren_lava_ground_style32.png', category: 'teren', name: 'Lava Ground' },
|
||||
{ path: 'assets/slike 🟢/teren/teren_roots_ground_style32.png', category: 'teren', name: 'Roots Ground' },
|
||||
|
||||
// Narava
|
||||
{ path: 'assets/slike 🟢/narava/rastline/narava_rastline_grass_tile.png', category: 'narava', name: 'Grass Tile' },
|
||||
{ path: 'assets/slike 🟢/narava/rastline/narava_rastline_grass_basic_style32.png', category: 'narava', name: 'Basic Grass' },
|
||||
{ path: 'assets/slike 🟢/narava/rastline/narava_rastline_grass_flowers_style32.png', category: 'narava', name: 'Grass with Flowers' },
|
||||
|
||||
// Crops (spritesheets)
|
||||
{ path: 'assets/maps 🟣/crop_spritesheets/carrots_spritesheet.png', category: 'crops', name: 'Carrots (All Seasons)' },
|
||||
{ path: 'assets/maps 🟣/crop_spritesheets/corn_spritesheet.png', category: 'crops', name: 'Corn (All Seasons)' },
|
||||
{ path: 'assets/maps 🟣/crop_spritesheets/lettuces_spritesheet.png', category: 'crops', name: 'Lettuce (All Seasons)' },
|
||||
{ path: 'assets/maps 🟣/crop_spritesheets/potatos_spritesheet.png', category: 'crops', name: 'Potatoes (All Seasons)' },
|
||||
{ path: 'assets/maps 🟣/crop_spritesheets/pumpkins_spritesheet.png', category: 'crops', name: 'Pumpkins (All Seasons)' },
|
||||
{ path: 'assets/maps 🟣/crop_spritesheets/tomatoes_spritesheet.png', category: 'crops', name: 'Tomatoes (All Seasons)' },
|
||||
];
|
||||
|
||||
allAssets = knownAssets;
|
||||
renderAssets(allAssets);
|
||||
}
|
||||
|
||||
function renderAssets(assets) {
|
||||
const container = document.getElementById('gallery-container');
|
||||
|
||||
// Group by category
|
||||
const grouped = {};
|
||||
assets.forEach(asset => {
|
||||
if (!grouped[asset.category]) grouped[asset.category] = [];
|
||||
grouped[asset.category].push(asset);
|
||||
});
|
||||
|
||||
container.innerHTML = '';
|
||||
|
||||
for (const [category, items] of Object.entries(grouped)) {
|
||||
const section = document.createElement('div');
|
||||
section.className = 'category-section';
|
||||
|
||||
const title = document.createElement('h2');
|
||||
title.className = 'category-title';
|
||||
title.textContent = getCategoryTitle(category);
|
||||
section.appendChild(title);
|
||||
|
||||
const gallery = document.createElement('div');
|
||||
gallery.className = 'gallery';
|
||||
|
||||
items.forEach(asset => {
|
||||
const card = createAssetCard(asset);
|
||||
gallery.appendChild(card);
|
||||
});
|
||||
|
||||
section.appendChild(gallery);
|
||||
container.appendChild(section);
|
||||
}
|
||||
}
|
||||
|
||||
function createAssetCard(asset) {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'asset-card';
|
||||
card.onclick = () => copyPath(asset.path, card);
|
||||
|
||||
const img = document.createElement('img');
|
||||
img.src = '../../' + asset.path;
|
||||
img.alt = asset.name;
|
||||
img.onerror = () => {
|
||||
img.src = 'data:image/svg+xml,' + encodeURIComponent(
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200"><rect fill="#333" width="200" height="200"/><text x="50%" y="50%" fill="#666" text-anchor="middle">No Preview</text></svg>'
|
||||
);
|
||||
};
|
||||
|
||||
const name = document.createElement('div');
|
||||
name.className = 'asset-name';
|
||||
name.textContent = asset.name;
|
||||
|
||||
const badge = document.createElement('div');
|
||||
badge.className = 'copy-badge';
|
||||
badge.textContent = '✓ Copied!';
|
||||
|
||||
card.appendChild(badge);
|
||||
card.appendChild(img);
|
||||
card.appendChild(name);
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
function getCategoryTitle(category) {
|
||||
const titles = {
|
||||
teren: '🌍 Teren (Ground Tiles)',
|
||||
narava: '🌿 Narava (Nature)',
|
||||
zgradbe: '🏚️ Zgradbe (Buildings)',
|
||||
objekti: '📦 Objekti (Objects)',
|
||||
crops: '🌾 Crops (All Seasons)',
|
||||
biomi: '🗺️ Biomi (Biomes)'
|
||||
};
|
||||
return titles[category] || category;
|
||||
}
|
||||
|
||||
function copyPath(path, card) {
|
||||
navigator.clipboard.writeText(path);
|
||||
card.classList.add('copied');
|
||||
setTimeout(() => card.classList.remove('copied'), 2000);
|
||||
console.log('Copied path:', path);
|
||||
}
|
||||
|
||||
function filterCategory(category) {
|
||||
currentFilter = category;
|
||||
|
||||
// Update button states
|
||||
document.querySelectorAll('.filter-btn').forEach(btn => btn.classList.remove('active'));
|
||||
event.target.classList.add('active');
|
||||
|
||||
if (category === 'all') {
|
||||
renderAssets(allAssets);
|
||||
} else {
|
||||
const filtered = allAssets.filter(a => a.category === category);
|
||||
renderAssets(filtered);
|
||||
}
|
||||
}
|
||||
|
||||
// Search functionality
|
||||
document.getElementById('search').addEventListener('input', (e) => {
|
||||
const query = e.target.value.toLowerCase();
|
||||
const filtered = allAssets.filter(a =>
|
||||
a.name.toLowerCase().includes(query) ||
|
||||
a.path.toLowerCase().includes(query)
|
||||
);
|
||||
renderAssets(filtered);
|
||||
});
|
||||
|
||||
// Load on start
|
||||
loadAssets();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user