import os import xml.etree.ElementTree as ET from PIL import Image import numpy as np def generate_nature_animation(): base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) out_dir = os.path.join(base_dir, 'assets', 'maps', 'tilesets') # 1. GRASS grass_src = os.path.join(base_dir, 'assets', 'grounds', 'grass.png') # 2. WATER water_src = os.path.join(base_dir, 'assets', 'grounds', 'water.png') # 3. CANNABIS # Try finding loop to locate specific file import glob cannabis_matches = glob.glob(os.path.join(base_dir, '**', '*cannabis*stage4*.png'), recursive=True) cannabis_src = None if cannabis_matches: cannabis_src = cannabis_matches[0] # Pick first valid else: # Fallback cannabis_src = os.path.join(base_dir, 'assets', 'intro_assets', 'cannabis_stage4.png') # If exists? targets = [] if os.path.exists(grass_src): targets.append(('Grass_Animated', grass_src)) if os.path.exists(water_src): targets.append(('Water_Animated', water_src)) if cannabis_src and os.path.exists(cannabis_src): targets.append(('Cannabis_Animated', cannabis_src)) else: print("⚠️ Could not find Cannabis Stage 4 image.") if not os.path.exists(out_dir): os.makedirs(out_dir) # Function to create wind sway (Skew) - FOR GRASS ONLY def create_sway_frame(image, factor=0.0): """Subtle skew transform for grass wind effect.""" width, height = image.size return image.transform((width, height), Image.AFFINE, (1, factor, 0, 0, 1, 0), resample=Image.BILINEAR) # Function to create water glimmer (Subtle brightness/color shift) def create_water_glimmer_frame(image, brightness_factor=1.0): """ Creates a subtle glimmer effect for water. brightness_factor: 1.0 = normal, 1.05 = slightly brighter (glimmer peak) """ from PIL import ImageEnhance # Brightness shift for shimmer enhancer = ImageEnhance.Brightness(image) return enhancer.enhance(brightness_factor) for name, src in targets: print(f"Processing {name} from {src}...") img = Image.open(src).convert('RGBA') width, height = img.size # Different animation based on type if 'Grass' in name or 'Cannabis' in name: # GRASS: Wind sway (gentle skew) print(f" → Grass/Plant: Using wind sway animation") f1 = img f2 = create_sway_frame(img, -0.08) # Gentle right sway f3 = img f4 = create_sway_frame(img, 0.08) # Gentle left sway elif 'Water' in name: # WATER: Glimmer effect (brightness shift, NO movement) print(f" → Water: Using glimmer animation (no skew)") f1 = img f2 = create_water_glimmer_frame(img, 1.03) # Subtle brighten f3 = img f4 = create_water_glimmer_frame(img, 0.97) # Subtle darken else: # Fallback f1 = f2 = f3 = f4 = img frames = [f1, f2, f3, f4] # Combine total_height = height * 4 combined = Image.new('RGBA', (width, total_height)) for i, f in enumerate(frames): combined.paste(f, (0, i * height)) out_img_path = os.path.join(out_dir, f"{name}.png") combined.save(out_img_path) print(f"Saved PNG: {out_img_path}") # Generate TSX tile_w, tile_h = 32, 32 # Assuming standard tiles # If image is larger (like Cannabis sprite), we treat it as big tiles? # Tiled animations work on per-tile basis. # If Cannabis is 64x128, it's composed of 8 tiles (2x4). # We need to animate EACH tile. cols = width // tile_w rows = height // tile_h total_tiles_per_frame = cols * rows total_tiles_all = total_tiles_per_frame * 4 root = ET.Element("tileset") root.set("version", "1.10") root.set("tiledversion", "1.11.0") root.set("name", name) root.set("tilewidth", str(tile_w)) root.set("tileheight", str(tile_h)) root.set("tilecount", str(total_tiles_all)) root.set("columns", str(cols)) image_node = ET.SubElement(root, "image") image_node.set("source", f"{name}.png") image_node.set("width", str(width)) image_node.set("height", str(total_height)) # Anim definitions for i in range(total_tiles_per_frame): tile_node = ET.SubElement(root, "tile") tile_node.set("id", str(i)) anim_node = ET.SubElement(tile_node, "animation") for k in range(4): frame_node = ET.SubElement(anim_node, "frame") frame_node.set("tileid", str(i + k * total_tiles_per_frame)) frame_node.set("duration", "200") # Slower wind tree = ET.ElementTree(root) ET.indent(tree, space=" ", level=0) out_tsx_path = os.path.join(out_dir, f"{name}.tsx") tree.write(out_tsx_path, encoding='UTF-8', xml_declaration=True) print(f"Saved TSX: {out_tsx_path}") if __name__ == "__main__": generate_nature_animation()