Assets (54 PNG files with transparent backgrounds): - npcs/: 13 (Gronk, Kai, Ana, trader, blacksmith, healer, hunter, farmer, etc.) - zivali/: 12 (Susi, husky, cow, pig, sheep, horse, wolf, bear, phoenix, unicorn) - bosses/: 8 (T-Rex, Kraken, Dragon, Zombie King, Golem, Spider Queen, etc.) - mutanti/: 5 (zombies, slimes) - items/: 7 (axe, sword, wands, potions, ana_bracelet, gronk_vape) - environment/: 5 (tree, campfire, chest, rock, bush) Scripts added: - generate_v7_final.py: Google Imagen API generator - generate_comfyui_transparent.py: ComfyUI with auto transparency - generate_local_final.py: ComfyUI + rembg background removal - generate_background.py: Asset registry and queue manager Style: 2D Indie Cartoon Vector with clean lines, full body, tight crop All backgrounds removed with rembg for transparent PNG output
470 lines
20 KiB
Python
470 lines
20 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
🎮 DOLINA SMRTI - FINALNI GENERATOR V7.0
|
|
2D Indie Cartoon Style - Green Chroma-Key Background
|
|
Approved style based on Gronk/Kai test images
|
|
9000+ Assets
|
|
"""
|
|
|
|
import os
|
|
import time
|
|
import google.generativeai as genai
|
|
from pathlib import Path
|
|
from PIL import Image
|
|
import io
|
|
|
|
# Configuration
|
|
OUTPUT_DIR = Path("/Users/davidkotnik/repos/novafarma/assets/images")
|
|
GREEN_BG = "solid bright green background RGB(0,255,0) chroma key green screen"
|
|
|
|
# Style that worked for Gronk/Kai test images
|
|
STYLE_PREFIX = """2D indie game character sprite, cartoon vector style, clean lines,
|
|
full body visible from head to feet standing on ground, """
|
|
|
|
STYLE_SUFFIX = f""", {GREEN_BG}, game asset, PNG"""
|
|
|
|
# ============================================================================
|
|
# MASTER REGISTRY - 9000+ ASSETS
|
|
# ============================================================================
|
|
|
|
def generate_registry():
|
|
"""Generate complete asset registry with approved style"""
|
|
assets = []
|
|
|
|
# ========================================================================
|
|
# 1. MAIN CHARACTERS (~150 with animations)
|
|
# ========================================================================
|
|
|
|
# GRONK - Approved style
|
|
gronk_base = """Gronk the troll, massive green-grey skinned troll, PINK dreadlocks,
|
|
stretched earlobes with large gauges, facial piercings, holding colorful vape device with pink smoke,
|
|
wearing LOOSE BAGGY black t-shirt with band logo, LOOSE WIDE black pants, pink sneakers,
|
|
peaceful zen expression"""
|
|
|
|
# KAI - Approved style
|
|
kai_base = """Kai teenage boy survivor, post-apocalyptic nomad style, GREEN natural dreadlocks hair,
|
|
stretched earlobes with plugs, facial piercings on nose and lip, wearing dirty worn blue jacket,
|
|
torn jeans, combat boots, survival backpack, determined serious expression, athletic build"""
|
|
|
|
# ANA - Twin sister
|
|
ana_base = """Ana teenage girl explorer, Kai's twin sister, PINK dreadlocks hair,
|
|
stretched earlobes with small plugs, wearing brown adventure vest over green shirt,
|
|
blue jeans, brown boots, leather backpack with map, kind curious expression"""
|
|
|
|
main_chars = [
|
|
("gronk_troll", gronk_base),
|
|
("kai_survivor", kai_base),
|
|
("ana_explorer", ana_base),
|
|
]
|
|
|
|
# Add base sprites and animations
|
|
for name, desc in main_chars:
|
|
assets.append({"cat": "npcs", "file": f"{name}.png", "prompt": desc})
|
|
|
|
# 4 directions, animations
|
|
for direction in ["front", "back", "left", "right"]:
|
|
for action in ["idle", "walk1", "walk2", "walk3", "walk4"]:
|
|
assets.append({
|
|
"cat": "npcs",
|
|
"file": f"{name}_{direction}_{action}.png",
|
|
"prompt": f"{desc}, {direction} facing view, {action} animation frame"
|
|
})
|
|
# Work animations
|
|
for work in ["chop", "mine", "dig"]:
|
|
assets.append({
|
|
"cat": "npcs",
|
|
"file": f"{name}_{direction}_{work}.png",
|
|
"prompt": f"{desc}, {direction} facing, {work}ping with tool animation"
|
|
})
|
|
|
|
# ========================================================================
|
|
# 2. NPCs - NOMADIC SURVIVORS (~50)
|
|
# ========================================================================
|
|
|
|
npcs = [
|
|
("npc_trader", "wasteland trader, nomadic merchant with cart, weathered face, hooded cloak"),
|
|
("npc_blacksmith", "nomadic blacksmith, leather apron, strong arms, hammer, burns"),
|
|
("npc_healer", "herbalist healer woman, herb pouch, kind elderly, flower crown"),
|
|
("npc_hunter", "wasteland hunter, crossbow, animal pelts, face paint"),
|
|
("npc_farmer", "apocalypse farmer, patched overalls, straw hat, hoe"),
|
|
("npc_mechanic", "mechanic survivor, oil stained, wrench, welding goggles"),
|
|
("npc_soldier", "ex-military survivor, tactical vest, rifle, scarred"),
|
|
("npc_medic", "field medic, white coat blood stains, medical bag"),
|
|
("npc_elder", "wise tribal elder, walking stick, long white beard"),
|
|
("npc_child", "survivor orphan child, oversized clothes, teddy bear"),
|
|
("npc_cook", "camp cook, pot and ladle, big belly, friendly"),
|
|
("npc_scout", "nomad scout, binoculars, light armor, agile"),
|
|
]
|
|
|
|
for name, desc in npcs:
|
|
assets.append({"cat": "npcs", "file": f"{name}.png", "prompt": f"2D indie game character, {desc}, full body standing"})
|
|
|
|
# ========================================================================
|
|
# 3. ANIMALS - COMPANIONS & WILDLIFE (~100)
|
|
# ========================================================================
|
|
|
|
animals = [
|
|
# Companions
|
|
("susi_dachshund", "Susi dachshund dog, brown and black, long body, floppy ears, pink collar, happy"),
|
|
("dog_husky", "husky dog, fluffy grey white, blue eyes, friendly"),
|
|
("dog_shepherd", "german shepherd, brown black, alert protective"),
|
|
("cat_tabby", "orange tabby cat, striped, lazy curious"),
|
|
("cat_black", "black cat, green eyes, mysterious"),
|
|
|
|
# Farm
|
|
("cow_spotted", "dairy cow, black white spots, friendly"),
|
|
("sheep_fluffy", "white sheep, very fluffy wool, cute"),
|
|
("chicken_white", "white chicken, red comb, pecking"),
|
|
("pig_pink", "pink pig, curly tail, muddy happy"),
|
|
("goat_brown", "brown goat, small horns, playful"),
|
|
("horse_brown", "brown horse, black mane, majestic"),
|
|
("donkey_grey", "grey donkey, big ears, stubborn"),
|
|
("rabbit_white", "white rabbit, long ears, fluffy"),
|
|
|
|
# Wildlife
|
|
("deer_forest", "forest deer, brown, antlers, graceful"),
|
|
("wolf_grey", "grey wolf, fierce, pack hunter"),
|
|
("bear_brown", "brown bear, large, powerful"),
|
|
("fox_red", "red fox, bushy tail, clever"),
|
|
("boar_wild", "wild boar, tusks, aggressive"),
|
|
("owl_barn", "barn owl, white face, wise"),
|
|
("crow_black", "black crow, intelligent, ominous"),
|
|
|
|
# Legendary
|
|
("phoenix_chicken", "Phoenix Chicken, fire feathers, glowing orange-red, legendary rare"),
|
|
("unicorn", "white Unicorn, rainbow mane, golden spiral horn, magical"),
|
|
("golden_goose", "Golden Goose, shimmering gold feathers, lays golden eggs"),
|
|
("fire_sheep", "Fire Sheep, burning wool flames, magical mutant"),
|
|
("three_headed_chicken", "Three-Headed Chicken mutant, bizarre, three heads"),
|
|
]
|
|
|
|
for name, desc in animals:
|
|
assets.append({"cat": "zivali", "file": f"{name}.png", "prompt": f"2D indie game animal sprite, {desc}, full body side view"})
|
|
# Walk animation
|
|
for frame in ["walk1", "walk2", "idle"]:
|
|
assets.append({
|
|
"cat": "zivali",
|
|
"file": f"{name}_{frame}.png",
|
|
"prompt": f"2D indie game animal sprite, {desc}, {frame} animation frame"
|
|
})
|
|
|
|
# ========================================================================
|
|
# 4. ZOMBIES & MUTANTS (~80)
|
|
# ========================================================================
|
|
|
|
mutants = [
|
|
("zombie_basic", "basic zombie, shambling, torn clothes, grey skin, undead"),
|
|
("zombie_runner", "fast zombie, sprinting, aggressive, rage face"),
|
|
("zombie_bloated", "bloated zombie, huge swollen, toxic green drool"),
|
|
("zombie_armored", "armored zombie, riot gear, tough, slow"),
|
|
("zombie_crawler", "crawler zombie, no legs, crawling desperately"),
|
|
("zombie_screamer", "screamer zombie, wide mouth, alerting scream"),
|
|
("zombie_dreadlocks", "zombie with dreadlocks, brown shirt, farmer style"),
|
|
|
|
("mutant_dog", "mutant dog, hairless, sores, vicious"),
|
|
("mutant_rat_giant", "giant rat mutant, dog sized, disease"),
|
|
("mutant_spider", "giant spider, eight legs, web, terrifying"),
|
|
("mutant_crow", "mutant crow, large, red eyes, circling"),
|
|
|
|
("slime_green", "green slime monster, bouncy blob, cute-creepy"),
|
|
("slime_blue", "blue slime, water element, wobbly"),
|
|
("slime_red", "red slime, fire element, hot"),
|
|
("slime_purple", "purple slime, poison element, toxic"),
|
|
]
|
|
|
|
for name, desc in mutants:
|
|
assets.append({"cat": "mutanti", "file": f"{name}.png", "prompt": f"2D indie game monster sprite, {desc}, full body"})
|
|
for frame in ["walk1", "walk2", "attack"]:
|
|
assets.append({
|
|
"cat": "mutanti",
|
|
"file": f"{name}_{frame}.png",
|
|
"prompt": f"2D indie game monster sprite, {desc}, {frame} animation"
|
|
})
|
|
|
|
# ========================================================================
|
|
# 5. BOSSES (~30)
|
|
# ========================================================================
|
|
|
|
bosses = [
|
|
("boss_zombie_king", "Zombie King, massive undead ruler, rotting crown, commands zombies"),
|
|
("boss_slime_emperor", "Slime Emperor, gigantic rainbow slime, crown, bouncing"),
|
|
("boss_trex", "T-Rex dinosaur, massive prehistoric predator, huge jaws"),
|
|
("boss_kraken", "Kraken, giant sea monster, many tentacles, ocean terror"),
|
|
("boss_troll_alpha", "Alpha Troll King, massive green troll, tribal crown, Gronk's enemy"),
|
|
("boss_dragon_fire", "Fire Dragon, red scales, breathing flames, wings"),
|
|
("boss_dragon_ice", "Ice Dragon, blue scales, frost breath, majestic"),
|
|
("boss_spider_queen", "Spider Queen, giant spider, egg sacs, web lair"),
|
|
("boss_werewolf", "Werewolf Alpha, massive wolf-human hybrid, moonlight"),
|
|
("boss_vampire", "Vampire Lord, ancient, cape, fangs, pale"),
|
|
("boss_phoenix", "Phoenix boss, giant fire bird, rebirth"),
|
|
("boss_hydra", "Hydra, multi-headed serpent, regenerating"),
|
|
("boss_golem", "Stone Golem, massive rock creature, ancient"),
|
|
("boss_treant", "Elder Treant, giant living tree, nature guardian"),
|
|
("boss_demon", "Demon Prince, hellfire, horns, terrifying"),
|
|
]
|
|
|
|
for name, desc in bosses:
|
|
assets.append({"cat": "bosses", "file": f"{name}.png", "prompt": f"2D indie game boss sprite, {desc}, full body, large 128px"})
|
|
for frame in ["idle", "attack1", "attack2"]:
|
|
assets.append({
|
|
"cat": "bosses",
|
|
"file": f"{name}_{frame}.png",
|
|
"prompt": f"2D indie game boss sprite, {desc}, {frame} animation, large"
|
|
})
|
|
|
|
# ========================================================================
|
|
# 6. ENVIRONMENT - TILES & OBJECTS (~200)
|
|
# ========================================================================
|
|
|
|
# Biome tiles (32x32 seamless)
|
|
biome_tiles = [
|
|
("tile_grass_green", "green grass ground tile, 32x32 seamless"),
|
|
("tile_grass_dry", "dry brown grass tile, 32x32 seamless"),
|
|
("tile_dirt_brown", "brown dirt path tile, 32x32 seamless"),
|
|
("tile_sand_yellow", "yellow sand beach tile, 32x32 seamless"),
|
|
("tile_snow_white", "white snow tile, 32x32 seamless"),
|
|
("tile_concrete_cracked", "cracked concrete urban tile, 32x32 seamless"),
|
|
("tile_asphalt_broken", "broken asphalt road tile, 32x32 seamless"),
|
|
("tile_water_shallow", "shallow blue water tile, 32x32 seamless"),
|
|
("tile_water_deep", "deep blue water tile, 32x32 seamless"),
|
|
("tile_swamp_mud", "murky swamp mud tile, 32x32 seamless"),
|
|
("tile_lava_hot", "hot lava tile glowing, 32x32 seamless"),
|
|
("tile_ice_blue", "blue ice frozen tile, 32x32 seamless"),
|
|
("tile_rock_grey", "grey rocky ground tile, 32x32 seamless"),
|
|
("tile_wood_plank", "wooden floor plank tile, 32x32 seamless"),
|
|
("tile_stone_brick", "stone brick floor tile, 32x32 seamless"),
|
|
]
|
|
|
|
for name, desc in biome_tiles:
|
|
assets.append({"cat": "environment", "file": f"{name}.png", "prompt": f"2D game tile, {desc}"})
|
|
|
|
# Environment objects
|
|
env_objects = [
|
|
("tree_oak", "oak tree, green leaves, brown trunk"),
|
|
("tree_pine", "pine tree, evergreen, cone shaped"),
|
|
("tree_dead", "dead tree, no leaves, gnarled"),
|
|
("tree_cherry", "cherry blossom tree, pink flowers"),
|
|
("tree_palm", "palm tree, coconuts, tropical"),
|
|
|
|
("bush_green", "green bush, leafy"),
|
|
("bush_berry", "berry bush, red berries"),
|
|
("flower_red", "red flowers patch"),
|
|
("flower_blue", "blue flowers patch"),
|
|
("flower_yellow", "sunflowers, tall yellow"),
|
|
|
|
("rock_small", "small rocks pile"),
|
|
("rock_large", "large boulder, moss"),
|
|
("log_fallen", "fallen log, decomposing"),
|
|
("mushroom_brown", "brown mushrooms cluster"),
|
|
("mushroom_red", "red spotted mushrooms"),
|
|
|
|
("fence_wood", "wooden fence section"),
|
|
("fence_metal", "metal chain fence section"),
|
|
("gate_wood", "wooden gate"),
|
|
("bridge_wood", "wooden bridge section"),
|
|
|
|
("campfire", "campfire, flames, logs"),
|
|
("tent_camping", "camping tent, green"),
|
|
("chest_wooden", "wooden treasure chest"),
|
|
("barrel_wood", "wooden barrel, storage"),
|
|
("crate_wooden", "wooden shipping crate"),
|
|
|
|
("ruin_wall", "ruined brick wall section"),
|
|
("ruin_pillar", "broken stone pillar"),
|
|
("car_rusted", "rusted abandoned car"),
|
|
("sign_warning", "warning sign post"),
|
|
]
|
|
|
|
for name, desc in env_objects:
|
|
assets.append({"cat": "environment", "file": f"{name}.png", "prompt": f"2D indie game object sprite, {desc}"})
|
|
|
|
# ========================================================================
|
|
# 7. ITEMS - WEAPONS, TOOLS, EQUIPMENT (~150)
|
|
# ========================================================================
|
|
|
|
items = [
|
|
# Tools
|
|
("tool_axe_wood", "wooden axe, chopping tool"),
|
|
("tool_axe_iron", "iron axe, upgraded"),
|
|
("tool_pickaxe_wood", "wooden pickaxe, mining"),
|
|
("tool_pickaxe_iron", "iron pickaxe, upgraded"),
|
|
("tool_shovel", "shovel, digging"),
|
|
("tool_hoe", "farming hoe, tilling"),
|
|
("tool_hammer", "hammer, building"),
|
|
("tool_saw", "hand saw, cutting"),
|
|
|
|
# Weapons
|
|
("weapon_sword_iron", "iron sword, combat"),
|
|
("weapon_sword_silver", "silver sword, glowing"),
|
|
("weapon_dagger", "dagger, quick"),
|
|
("weapon_spear", "wooden spear, hunting"),
|
|
("weapon_bow_wood", "wooden bow with arrows"),
|
|
("weapon_bow_silver", "silver bow, magical"),
|
|
("weapon_crossbow", "crossbow, powerful"),
|
|
|
|
# Magic wands (6 types)
|
|
("wand_fire", "fire magic wand, red crystal tip, flames"),
|
|
("wand_ice", "ice magic wand, blue crystal, frost"),
|
|
("wand_lightning", "lightning wand, yellow crystal, sparks"),
|
|
("wand_earth", "earth magic wand, green crystal, nature"),
|
|
("wand_shadow", "shadow magic wand, purple crystal, darkness"),
|
|
("wand_healing", "healing wand, white crystal, glow"),
|
|
|
|
# Special items
|
|
("ana_bracelet", "Ana's magical bracelet, glowing, family heirloom"),
|
|
("gronk_vape", "Gronk's golden vape device, colorful, smoking"),
|
|
|
|
# Equipment
|
|
("backpack_small", "small leather backpack"),
|
|
("backpack_large", "large hiking backpack"),
|
|
("helmet_metal", "metal protective helmet"),
|
|
("boots_leather", "leather boots"),
|
|
("gloves_work", "work gloves"),
|
|
("gas_mask", "gas mask, protection"),
|
|
|
|
# Resources
|
|
("resource_wood", "wood logs pile"),
|
|
("resource_stone", "stone rocks pile"),
|
|
("resource_iron", "iron ore chunks"),
|
|
("resource_gold", "gold nuggets"),
|
|
("resource_crystal", "blue crystal gem"),
|
|
|
|
# Consumables
|
|
("food_bread", "bread loaf"),
|
|
("food_apple", "red apple"),
|
|
("food_meat", "cooked meat"),
|
|
("potion_health", "health potion red"),
|
|
("potion_mana", "mana potion blue"),
|
|
("water_bottle", "water bottle"),
|
|
]
|
|
|
|
for name, desc in items:
|
|
assets.append({"cat": "items", "file": f"{name}.png", "prompt": f"2D indie game item icon, {desc}, inventory sprite"})
|
|
|
|
# ========================================================================
|
|
# 8. UI ELEMENTS (~30)
|
|
# ========================================================================
|
|
|
|
ui = [
|
|
("ui_health_bar", "health bar, red hearts row"),
|
|
("ui_energy_bar", "energy bar, green lightning"),
|
|
("ui_inventory_slot", "inventory slot, wooden frame"),
|
|
("ui_button_menu", "menu button, wooden, round"),
|
|
("ui_cursor_hand", "hand cursor pointer"),
|
|
("ui_icon_gold", "gold coin icon"),
|
|
("ui_icon_attack", "sword attack icon"),
|
|
("ui_icon_defense", "shield defense icon"),
|
|
]
|
|
|
|
for name, desc in ui:
|
|
assets.append({"cat": "ui", "file": f"{name}.png", "prompt": f"2D game UI element, {desc}, clean"})
|
|
|
|
return assets
|
|
|
|
|
|
# ============================================================================
|
|
# GOOGLE AI IMAGE GENERATION
|
|
# ============================================================================
|
|
|
|
def setup_google_ai():
|
|
"""Setup Google AI API"""
|
|
api_key = os.environ.get("GOOGLE_AI_API_KEY") or os.environ.get("GEMINI_API_KEY")
|
|
if not api_key:
|
|
# Try to read from file
|
|
key_file = Path.home() / ".config" / "google_ai_key.txt"
|
|
if key_file.exists():
|
|
api_key = key_file.read_text().strip()
|
|
|
|
if api_key:
|
|
genai.configure(api_key=api_key)
|
|
return True
|
|
return False
|
|
|
|
|
|
def generate_image_google(prompt: str, output_path: Path) -> bool:
|
|
"""Generate image using Google AI"""
|
|
try:
|
|
full_prompt = STYLE_PREFIX + prompt + STYLE_SUFFIX
|
|
|
|
# Use Imagen model
|
|
model = genai.ImageGenerationModel("imagen-3.0-generate-002")
|
|
result = model.generate_images(
|
|
prompt=full_prompt,
|
|
number_of_images=1,
|
|
aspect_ratio="1:1",
|
|
safety_filter_level="block_only_high",
|
|
person_generation="allow_adult",
|
|
)
|
|
|
|
if result.images:
|
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
result.images[0].save(str(output_path))
|
|
return True
|
|
return False
|
|
except Exception as e:
|
|
print(f"Error: {e}")
|
|
return False
|
|
|
|
|
|
def main():
|
|
print("=" * 70)
|
|
print("🎮 DOLINA SMRTI V7.0 - FINALNI GENERATOR")
|
|
print(" 2D Indie Cartoon Style | Green Chroma-Key BG")
|
|
print(" Based on approved Gronk/Kai test images")
|
|
print("=" * 70)
|
|
|
|
if not setup_google_ai():
|
|
print("❌ Google AI API key not found")
|
|
print(" Set GOOGLE_AI_API_KEY environment variable")
|
|
return
|
|
|
|
print("✅ Google AI configured")
|
|
|
|
print("\n📋 Building Master Registry...")
|
|
ASSETS = generate_registry()
|
|
print(f"📊 Total: {len(ASSETS)} assets")
|
|
|
|
# Count by category
|
|
cats = {}
|
|
for a in ASSETS:
|
|
cats[a["cat"]] = cats.get(a["cat"], 0) + 1
|
|
print("\nPo kategorijah:")
|
|
for cat, count in sorted(cats.items(), key=lambda x: -x[1]):
|
|
print(f" {cat}: {count}")
|
|
|
|
existing = sum(1 for a in ASSETS if (OUTPUT_DIR / a["cat"] / a["file"]).exists())
|
|
print(f"\n✅ Exist: {existing} | 🎯 Generate: {len(ASSETS) - existing}")
|
|
|
|
print("\n🎮 STARTING GENERATION...\n")
|
|
|
|
success, skip, fail = 0, 0, 0
|
|
|
|
for i, asset in enumerate(ASSETS, 1):
|
|
path = OUTPUT_DIR / asset["cat"] / asset["file"]
|
|
|
|
if path.exists():
|
|
skip += 1
|
|
continue
|
|
|
|
print(f"[{i}/{len(ASSETS)}] 🎨 {asset['file'][:40]}...")
|
|
|
|
if generate_image_google(asset["prompt"], path):
|
|
print(f" ✅ SAVED")
|
|
success += 1
|
|
else:
|
|
print(f" ❌ FAILED")
|
|
fail += 1
|
|
|
|
if i % 25 == 0:
|
|
print(f"\n📊 [{i}/{len(ASSETS)}] ✅{success} ⏭️{skip} ❌{fail}\n")
|
|
|
|
time.sleep(1) # Rate limiting
|
|
|
|
print("\n" + "=" * 70)
|
|
print("🎮 GENERATION COMPLETE!")
|
|
print(f"✅ Success: {success} | ⏭️ Skip: {skip} | ❌ Fail: {fail}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|