This commit is contained in:
2026-01-21 02:25:15 +01:00
parent cf23eef790
commit 8c8d041097
29 changed files with 390 additions and 22 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 532 KiB

After

Width:  |  Height:  |  Size: 921 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 667 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 435 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 363 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

97
clean_backgrounds.py Normal file
View File

@@ -0,0 +1,97 @@
import os
from PIL import Image
def remove_background(image_path, color_to_remove=None, tolerance=30, mode="top_left"):
try:
img = Image.open(image_path).convert("RGBA")
datas = img.getdata()
# Determine background color to remove
bg_color = color_to_remove
if bg_color is None:
if mode == "top_left":
bg_color = datas[0][:3] # Pick top-left pixel
else:
bg_color = (0,0,0) # Default placeholder to avoid NoneType error in zip
newData = []
for item in datas:
# Check difference
pixel = item[:3]
# Simple Euclidean distance approximation or exact match
# Let's do a strict match for green if specified, or threshold for checkerboard
if mode == "green":
# Check for Green (0, 255, 0) logic
# Allow some tolerance for compression artifacts
if item[1] > 200 and item[0] < 100 and item[2] < 100:
newData.append((255, 255, 255, 0))
else:
newData.append(item)
elif mode == "checkerboard":
# Heuristic: if pixel is grey/white characteristic of checkerboard
# Checkerboard usually alternates white (255) and grey (204 or similar)
r, g, b = pixel
if (r > 200 and g > 200 and b > 200) or (150 < r < 210 and 150 < g < 210 and 150 < b < 210):
# Likely checkerboard, but dragging risk of deleting white parts of image.
# Using top-left reference is safer if image has borders.
diff = sum([abs(c1 - c2) for c1, c2 in zip(pixel, bg_color)])
if diff < tolerance:
newData.append((255, 255, 255, 0))
else:
newData.append(item)
else:
newData.append(item)
else:
newData.append(item)
img.putdata(newData)
img.save(image_path, "PNG")
print(f"cleaned: {image_path}")
except Exception as e:
print(f"Error cleaning {image_path}: {e}")
# Paths
ui_path = "/Users/davidkotnik/repos/novafarma/assets/slike/NOVE_SLIKE/UI"
char_path = "/Users/davidkotnik/repos/novafarma/assets/slike/characters"
ghost_path = "/Users/davidkotnik/repos/novafarma/assets/slike/NOVE_SLIKE/Characters/starsa/Ghost"
# 1. Clean UI (Checkerboard)
# Note: The checkerboard seems to be distinct. Let's try to target the grey/white pattern.
# Actually, since these were generated and saved with checkerboard 'baked in', it's tricky.
# I will aggressively target the specific checkerboard colors found in common generators.
# Or simpler: The user wants me to fix the scene. Cleaning assets is the permanent fix.
ui_files = [
"okvir_zarjavel.png",
"merilec_zdravja.png",
"amnezija_maska.png"
]
for f in ui_files:
full_path = os.path.join(ui_path, f)
if os.path.exists(full_path):
remove_background(full_path, mode="checkerboard", tolerance=50)
# 2. Clean Kai (Green Screen)
kai_path = os.path.join(char_path, "liki_kai_ref_kai.png")
if os.path.exists(kai_path):
remove_background(kai_path, mode="green")
# 3. Clean Ghosts (Cyan/Green Screen?)
# The user mentioned green key for everyone, so I'll apply green filter.
ghosts = [
"ghost_otac_cyan.png",
"MOJE_SLIKE_KONCNA_ostalo_parents_transparent_ghosts_clean.png"
]
for g in ghosts:
full_path = os.path.join(ghost_path, g)
if os.path.exists(full_path):
remove_background(full_path, mode="green")

60
finalize_ui.py Normal file
View File

@@ -0,0 +1,60 @@
import os
from PIL import Image
# Source map from BRAIN (using the best versions available)
source_map = {
"okvir_zarjavel.png": "/Users/davidkotnik/.gemini/antigravity/brain/998d0b10-1733-4e5b-85ed-249b986ba9b3/okvir_zarjavel_v3_1768956071037.png",
"srce_postapo.png": "/Users/davidkotnik/.gemini/antigravity/brain/998d0b10-1733-4e5b-85ed-249b986ba9b3/srce_postapo_1768956084773.png",
"merilec_zdravja.png": "/Users/davidkotnik/.gemini/antigravity/brain/998d0b10-1733-4e5b-85ed-249b986ba9b3/merilec_zdravja_v2_1768954479566.png",
"gumb_start.png": "/Users/davidkotnik/.gemini/antigravity/brain/998d0b10-1733-4e5b-85ed-249b986ba9b3/gumb_recikliran_v2_1768954494464.png",
"amnezija_maska.png": "/Users/davidkotnik/.gemini/antigravity/brain/998d0b10-1733-4e5b-85ed-249b986ba9b3/amnezija_maska_v2_1768954510228.png"
}
# Source map fallback (if v3 doesn't exist, use v2)
source_map_fallback = {
"okvir_zarjavel.png": "/Users/davidkotnik/.gemini/antigravity/brain/998d0b10-1733-4e5b-85ed-249b986ba9b3/okvir_zarjavel_v2_1768954465913.png",
}
# Updated target dimensions from User Request
dimensions = {
"okvir_zarjavel.png": (800, 250),
"srce_postapo.png": (128, 128),
"merilec_zdravja.png": (192, 100),
"gumb_start.png": (300, 100),
"amnezija_maska.png": (1920, 1080)
}
output_dir = "/Users/davidkotnik/repos/novafarma/assets/slike/NOVE_SLIKE/UI/UI/"
os.makedirs(output_dir, exist_ok=True)
for filename, source_path in source_map.items():
if not os.path.exists(source_path):
if filename in source_map_fallback and os.path.exists(source_map_fallback[filename]):
print(f"Fallback: using v2 for {filename}")
source_path = source_map_fallback[filename]
else:
print(f"Source missing for {filename}: {source_path}")
continue
try:
with Image.open(source_path) as img:
img = img.convert("RGBA")
target_size = dimensions[filename]
resized_img = img.resize(target_size, Image.Resampling.LANCZOS)
dest_path = os.path.join(output_dir, filename)
resized_img.save(dest_path, "PNG")
print(f"Processed: {filename} -> {target_size}")
except Exception as e:
print(f"Error processing {filename}: {e}")
# Remove old/garbage files if they define conflicts or are broken
files_to_remove = ["gumb_recikliran.png", "srce_health.png"] # Renamed/Replaced
for f in files_to_remove:
path = os.path.join(output_dir, f)
if os.path.exists(path):
os.remove(path)
print(f"Removed old file: {f}")

45
finalize_v4_assets.py Normal file
View File

@@ -0,0 +1,45 @@
import os
from PIL import Image
def process_and_save(source_path, dest_path, target_size):
try:
img = Image.open(source_path).convert("RGBA")
datas = img.getdata()
newData = []
# Tolerance for black background removal
threshold = 15
for item in datas:
# Check if pixel is black (allowing for slight compression noise)
if item[0] < threshold and item[1] < threshold and item[2] < threshold:
newData.append((0, 0, 0, 0)) # Transparent
else:
newData.append(item)
img.putdata(newData)
# Resize using Lanczos for quality
img = img.resize(target_size, Image.Resampling.LANCZOS)
# Save to final destination
img.save(dest_path, "PNG")
print(f"✅ Success: {dest_path}")
except Exception as e:
print(f"❌ Error: {e}")
# Source files (New V4 generations with black bg from Brain)
frame_source = "/Users/davidkotnik/.gemini/antigravity/brain/998d0b10-1733-4e5b-85ed-249b986ba9b3/okvir_zarjavel_v4_1768958404477.png"
gauge_source = "/Users/davidkotnik/.gemini/antigravity/brain/998d0b10-1733-4e5b-85ed-249b986ba9b3/merilec_zdravja_v4_1768958417465.png"
# Destination directory
dest_dir = "/Users/davidkotnik/repos/novafarma/assets/slike/NOVE_SLIKE/UI"
# Execution
# 1. Rusty Frame (800x250)
process_and_save(frame_source, os.path.join(dest_dir, "okvir_zarjavel.png"), (800, 250))
# 2. Health Gauge (150x150) - Resizing to match scene usage
process_and_save(gauge_source, os.path.join(dest_dir, "merilec_zdravja.png"), (150, 150))

41
fix_ui_images.py Normal file
View File

@@ -0,0 +1,41 @@
import os
from PIL import Image
# Source map (using the v2 originals found in temp)
source_map = {
"okvir_zarjavel.png": "/Users/davidkotnik/.gemini/antigravity/brain/998d0b10-1733-4e5b-85ed-249b986ba9b3/okvir_zarjavel_v2_1768954465913.png",
"merilec_zdravja.png": "/Users/davidkotnik/.gemini/antigravity/brain/998d0b10-1733-4e5b-85ed-249b986ba9b3/merilec_zdravja_v2_1768954479566.png",
"gumb_recikliran.png": "/Users/davidkotnik/.gemini/antigravity/brain/998d0b10-1733-4e5b-85ed-249b986ba9b3/gumb_recikliran_v2_1768954494464.png",
"amnezija_maska.png": "/Users/davidkotnik/.gemini/antigravity/brain/998d0b10-1733-4e5b-85ed-249b986ba9b3/amnezija_maska_v2_1768954510228.png"
}
# Target dimensions
dimensions = {
"okvir_zarjavel.png": (800, 250),
"merilec_zdravja.png": (256, 256),
"gumb_recikliran.png": (300, 100),
"amnezija_maska.png": (1920, 1080)
}
output_dir = "/Users/davidkotnik/repos/novafarma/assets/slike/NOVE_SLIKE/UI/UI/"
for filename, source_path in source_map.items():
if os.path.exists(source_path):
try:
with Image.open(source_path) as img:
# Ensure it's RGBA
img = img.convert("RGBA")
# Resize
target_size = dimensions[filename]
resized_img = img.resize(target_size, Image.Resampling.LANCZOS)
# Save as proper PNG
dest_path = os.path.join(output_dir, filename)
resized_img.save(dest_path, "PNG")
print(f"Fixed and saved: {dest_path}")
except Exception as e:
print(f"Error processing {filename}: {e}")
else:
print(f"Source not found for {filename}: {source_path}")

81
remove_checkerboard.py Normal file
View File

@@ -0,0 +1,81 @@
import os
from PIL import Image, ImageDraw
def process_image(file_path, mode="flood_corners"):
try:
img = Image.open(file_path).convert("RGBA")
width, height = img.size
pixels = img.load()
# Define checkerboard colors to target
# Typically White and Gray.
# We'll treat anything very light/grey as background if it's connected to start point.
# Gray is often (204, 204, 204) or (192, 192, 192)
def is_checkerboard(p):
r, g, b, a = p
# Check for white-ish
if r > 240 and g > 240 and b > 240: return True
# Check for neutral grey-ish
if abs(r - g) < 10 and abs(r - b) < 10 and 150 < r < 230: return True
return False
# Flood fill algorithm
visited = set()
queue = []
if mode == "flood_corners":
# Start from all 4 corners
starts = [(0, 0), (width-1, 0), (0, height-1), (width-1, height-1)]
for s in starts:
if is_checkerboard(pixels[s]):
queue.append(s)
visited.add(s)
elif mode == "flood_center":
# For the mask, we want to clear the center
center = (width // 2, height // 2)
if is_checkerboard(pixels[center]):
queue.append(center)
visited.add(center)
# Processing queue
while queue:
x, y = queue.pop(0)
pixels[x, y] = (0, 0, 0, 0) # Make transparent
# Check neighbors
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
nx, ny = x + dx, y + dy
if 0 <= nx < width and 0 <= ny < height:
if (nx, ny) not in visited:
if is_checkerboard(pixels[nx, ny]):
visited.add((nx, ny))
queue.append((nx, ny))
img.save(file_path)
print(f"Processed: {file_path}")
except Exception as e:
print(f"Error processing {file_path}: {e}")
# Paths
ui_dir = "/Users/davidkotnik/repos/novafarma/assets/slike/NOVE_SLIKE/UI"
# 1. Solid Objects (Frame, Meter, Button) - Flood from corners
solid_objects = [
"okvir_zarjavel.png",
"merilec_zdravja.png",
"gumb_start.png"
]
for f in solid_objects:
path = os.path.join(ui_dir, f)
if os.path.exists(path):
process_image(path, mode="flood_corners")
# 2. Mask (Vignette) - Flood from center (remove the middle checkerboard)
mask_path = os.path.join(ui_dir, "amnezija_maska.png")
if os.path.exists(mask_path):
process_image(mask_path, mode="flood_center")

View File

@@ -4,36 +4,80 @@ export default class GrassScene extends Phaser.Scene {
} }
preload() { preload() {
console.log("🌱 Loading Clean Assets..."); console.log("👻 Loading Haunted Memory Assets...");
// 1. TERRAIN (From new 'assets/slike/environment' folder) // 1. TERRAIN & CHARACTER
this.load.image('ground', 'assets/slike/environment/plot_watered.png'); this.load.image('grass', 'assets/slike/environment/grass_tile.png');
this.load.image('kai', 'assets/slike/characters/liki_kai_ref_kai.png');
// 2. UI (From new 'assets/slike/ui' folder) // 2. GHOSTS (Memory of Parents)
this.load.image('buy_btn', 'assets/slike/ui/shop_11_buy_button.png'); // Path corrected after rename (Ghost: -> Ghost)
this.load.image('ghost_father', 'assets/slike/NOVE_SLIKE/Characters/starsa/Ghost/ghost_otac_cyan.png');
this.load.image('ghost_parents', 'assets/slike/NOVE_SLIKE/Characters/starsa/Ghost/MOJE_SLIKE_KONCNA_ostalo_parents_transparent_ghosts_clean.png');
// 3. UI ELEMENTS (Rusty Industrial Style)
this.load.image('frame_rusty', 'assets/slike/NOVE_SLIKE/UI/okvir_zarjavel.png');
this.load.image('health_gauge', 'assets/slike/NOVE_SLIKE/UI/merilec_zdravja.png');
this.load.image('amnesia_mask', 'assets/slike/NOVE_SLIKE/UI/amnezija_maska.png');
} }
create() { create() {
console.log("✅ Scene Created. Placing Clean Assets..."); console.log("💀 Reconstructing Memory...");
const { width, height } = this.cameras.main; const { width, height } = this.cameras.main;
const centerX = width / 2;
const centerY = height / 2;
// A. BACKGROUND (Tiled Ground) // --- LAYER 0: BACKGROUND ---
// Using tileSprite to repeat the texture across the screen // Trava (Depth: 0)
this.add.tileSprite(0, 0, width, height, 'ground') const bg = this.add.tileSprite(0, 0, width, height, 'grass').setOrigin(0, 0);
.setOrigin(0, 0) bg.setTint(0x888888);
.setTileScale(4); // Scale up for retro look bg.setDepth(0);
// B. UI ELEMENT (Corner Test) // --- LAYER 10: CHARACTERS ---
// Placing button in top-left corner // Father Ghost (Left) - Depth: 10
const btn = this.add.image(100, 100, 'buy_btn'); const father = this.add.image(centerX - 300, centerY, 'ghost_father');
btn.setScale(2); // Make check visible father.setAlpha(0.4);
father.setScale(0.8);
father.setDepth(10);
// C. LABEL // Parents Ghost (Right) - Depth: 10
this.add.text(width / 2, height - 50, 'SOURCE: assets/slike/ (NEW)', { const parents = this.add.image(centerX + 300, centerY, 'ghost_parents');
fontFamily: 'monospace', parents.setAlpha(0.4);
fontSize: '24px', parents.setScale(0.8);
color: '#ffffff', parents.setDepth(10);
backgroundColor: '#000000'
}).setOrigin(0.5); // Kai (Center) - Depth: 10
const kai = this.add.image(centerX, centerY, 'kai');
kai.setScale(0.8);
kai.setDepth(10);
// --- LAYER 100: UI & EFFECTS ---
// 1. Amnesia Mask (Full Screen Overlay) - Depth: 100
const mask = this.add.image(centerX, centerY, 'amnesia_mask');
mask.setDisplaySize(width, height); // Stretch to cover FULL screen
mask.setAlpha(0.9);
mask.setDepth(100);
// 2. Health Gauge (Top Left, Small) - Depth: 100
const gauge = this.add.image(90, 90, 'health_gauge');
gauge.setDisplaySize(150, 150); // Resize to 150x150 as requested
gauge.setDepth(100);
// 3. Rusty Frame (Bottom Center) - Depth: 100
const frameY = height - 100;
const frame = this.add.image(centerX, frameY, 'frame_rusty');
frame.setDepth(100);
// 4. Dialog Text (Centered on Frame) - Depth: 101 (On top of frame)
this.add.text(centerX, frameY, "Kai... se naju spomniš?", {
fontFamily: 'Courier New, monospace',
fontSize: '28px',
color: '#e0e0e0',
fontStyle: 'bold',
stroke: '#000000',
strokeThickness: 5,
shadow: { offsetX: 2, offsetY: 2, color: '#000', blur: 4, fill: true }
}).setOrigin(0.5).setDepth(101);
} }
} }