Files
novafarma/scripts/generate_v7_final.py
David Kotnik 7a3782d83e 🎨 Add 54 PNG assets with transparent backgrounds + generation scripts
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
2025-12-29 00:49:23 +01:00

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()