Files
UltraChat/jrpg/girl.py
2026-03-17 00:16:49 +05:00

390 lines
13 KiB
Python

import pygame
import math
import sys
pygame.init()
W, H = 600, 750
screen = pygame.display.set_mode((W, H))
pygame.display.set_caption("Anime Girl - Blue Pink Black")
# Color palette
BLACK = (5, 5, 15)
DARK = (10, 10, 30)
PINK = (255, 100, 180)
PINK2 = (255, 160, 210)
PINK3 = (200, 60, 130)
BLUE = (80, 180, 255)
BLUE2 = (40, 120, 220)
BLUE3 = (130, 210, 255)
CYAN = (0, 220, 255)
WHITE = (255, 255, 255)
SKIN = (255, 220, 210)
SKIN2 = (240, 195, 185)
PURPLE = (160, 80, 220)
GLITCH = (0, 255, 200)
clock = pygame.time.Clock()
t = 0
def draw_gradient_bg(surf):
for y in range(H):
ratio = y / H
r = int(5 + 15 * ratio)
g = int(5 + 10 * ratio)
b = int(15 + 40 * ratio)
pygame.draw.line(surf, (r, g, b), (0, y), (W, y))
def draw_glow(surf, color, pos, radius, alpha=80):
glow = pygame.Surface((radius*2, radius*2), pygame.SRCALPHA)
for i in range(radius, 0, -4):
a = int(alpha * (i / radius) ** 2)
r, g, b = color
pygame.draw.circle(glow, (r, g, b, a), (radius, radius), i)
surf.blit(glow, (pos[0]-radius, pos[1]-radius))
def draw_stars(surf, t):
import random
random.seed(42)
for i in range(60):
x = random.randint(0, W)
y = random.randint(0, H//2)
size = random.uniform(1, 2.5)
flicker = 0.5 + 0.5 * math.sin(t * 2 + i)
c = int(150 + 105 * flicker)
pygame.draw.circle(surf, (c, c, min(255, c+50)), (x, y), int(size))
def draw_scanlines(surf):
s = pygame.Surface((W, H), pygame.SRCALPHA)
for y in range(0, H, 4):
pygame.draw.line(s, (0, 0, 0, 30), (0, y), (W, y))
surf.blit(s, (0, 0))
def draw_girl(surf, t):
# floating bob
bob = math.sin(t * 1.5) * 5
cx = W // 2
base_y = 480 + bob
# --- HAIR BACK LAYER ---
# Long flowing hair behind body
hair_pts_back = [
(cx - 120, base_y - 320),
(cx - 160, base_y - 200),
(cx - 190, base_y - 50),
(cx - 170, base_y + 100),
(cx - 120, base_y + 200),
(cx - 60, base_y + 280),
(cx, base_y + 300),
(cx + 60, base_y + 280),
(cx + 120, base_y + 200),
(cx + 170, base_y + 100),
(cx + 190, base_y - 50),
(cx + 160, base_y - 200),
(cx + 120, base_y - 320),
]
pygame.draw.polygon(surf, BLUE2, hair_pts_back)
pygame.draw.polygon(surf, (20, 60, 120), hair_pts_back, 2)
# --- BODY / TORSO ---
# Dress / top
body_rect = pygame.Rect(cx - 70, base_y - 100, 140, 200)
pygame.draw.ellipse(surf, DARK, pygame.Rect(cx-65, base_y-95, 130, 180))
# Dress gradient effect - layered
for i, col in enumerate([(30, 10, 60), (50, 20, 90), (70, 30, 110)]):
pygame.draw.ellipse(surf, col,
pygame.Rect(cx-60+i*3, base_y-90+i*2, 120-i*6, 170-i*4))
# Collar / ribbon
ribbon_pts = [(cx-40, base_y-90), (cx, base_y-70), (cx+40, base_y-90),
(cx+20, base_y-60), (cx, base_y-50), (cx-20, base_y-60)]
pygame.draw.polygon(surf, PINK3, ribbon_pts)
# Bow on collar
bow_left = [(cx-35, base_y-78), (cx-8, base_y-65), (cx-8, base_y-75)]
bow_right = [(cx+35, base_y-78), (cx+8, base_y-65), (cx+8, base_y-75)]
pygame.draw.polygon(surf, PINK, bow_left)
pygame.draw.polygon(surf, PINK, bow_right)
pygame.draw.circle(surf, PINK2, (cx, base_y-72), 5)
# Glowing trim
pygame.draw.arc(surf, CYAN,
pygame.Rect(cx-62, base_y-92, 124, 40), 0, math.pi, 2)
# --- NECK ---
pygame.draw.rect(surf, SKIN, pygame.Rect(cx-18, base_y-140, 36, 55), border_radius=8)
# --- HEAD ---
head_cy = base_y - 200
# Face
pygame.draw.ellipse(surf, SKIN, pygame.Rect(cx-65, head_cy-75, 130, 155))
# Cheek blush
blush_alpha = pygame.Surface((60, 25), pygame.SRCALPHA)
pygame.draw.ellipse(blush_alpha, (255, 100, 130, 80), (0, 0, 60, 25))
surf.blit(blush_alpha, (cx-85, head_cy+10))
surf.blit(blush_alpha, (cx+25, head_cy+10))
# --- HAIR FRONT ---
# Top of head / bangs
hair_top = [
(cx-70, head_cy-70),
(cx-90, head_cy-100),
(cx-70, head_cy-130),
(cx-30, head_cy-155),
(cx, head_cy-165),
(cx+30, head_cy-155),
(cx+70, head_cy-130),
(cx+90, head_cy-100),
(cx+70, head_cy-70),
(cx+50, head_cy-40),
(cx, head_cy-30),
(cx-50, head_cy-40),
]
pygame.draw.polygon(surf, BLUE, hair_top)
# Bangs (front)
bang1 = [(cx-70, head_cy-70), (cx-95, head_cy-10), (cx-65, head_cy+20),
(cx-40, head_cy-10), (cx-50, head_cy-50)]
bang2 = [(cx-30, head_cy-75), (cx-45, head_cy-5), (cx-20, head_cy+10),
(cx+5, head_cy-10), (cx-5, head_cy-60)]
bang3 = [(cx+30, head_cy-75), (cx+10, head_cy-5), (cx+30, head_cy+15),
(cx+55, head_cy-5), (cx+45, head_cy-60)]
bang4 = [(cx+70, head_cy-70), (cx+50, head_cy-50), (cx+55, head_cy+20),
(cx+80, head_cy-10), (cx+95, head_cy-30)]
for bang in [bang1, bang2, bang3, bang4]:
pygame.draw.polygon(surf, BLUE, bang)
# Hair highlight
highlight_pts = [(cx-20, head_cy-155), (cx+20, head_cy-155),
(cx+10, head_cy-110), (cx-10, head_cy-110)]
pygame.draw.polygon(surf, BLUE3, highlight_pts)
# Hair shine line
pygame.draw.arc(surf, (200, 240, 255),
pygame.Rect(cx-30, head_cy-140, 60, 30), 0.2, math.pi-0.2, 2)
# --- EYES ---
eye_y = head_cy + 5
eye_offset = math.sin(t * 0.8) * 1 # subtle sway
for side in [-1, 1]:
ex = cx + side * 28
ey = eye_y
# Eye shadow
eye_sh = pygame.Surface((50, 30), pygame.SRCALPHA)
pygame.draw.ellipse(eye_sh, (80, 0, 60, 100), (0, 0, 50, 30))
surf.blit(eye_sh, (ex-25, ey-10))
# White of eye
pygame.draw.ellipse(surf, WHITE, pygame.Rect(ex-18, ey-12, 36, 28))
# Iris - blue gradient effect
pygame.draw.ellipse(surf, BLUE2, pygame.Rect(ex-13, ey-10, 26, 25))
pygame.draw.ellipse(surf, BLUE, pygame.Rect(ex-10, ey-7, 20, 19))
pygame.draw.ellipse(surf, CYAN, pygame.Rect(ex-6, ey-4, 12, 12))
# Pupil
pygame.draw.ellipse(surf, BLACK, pygame.Rect(ex-5, ey-3, 10, 11))
# Eye shine
pygame.draw.circle(surf, WHITE, (ex-4, ey-1), 3)
pygame.draw.circle(surf, WHITE, (ex+3, ey+3), 2)
# Eyelashes - upper lid
pygame.draw.arc(surf, BLACK,
pygame.Rect(ex-19, ey-14, 38, 22), 0.1, math.pi-0.1, 3)
# Lash lines
for lx_off, angle in [(-18, 2.4), (-10, 2.0), (-2, 1.7), (6, 1.5), (14, 1.8)]:
lx = ex + lx_off
pygame.draw.line(surf, BLACK,
(lx, ey - int(12 * math.sin(angle))),
(lx - side*2, ey - int(12 * math.sin(angle)) - 5), 2)
# Lower lash
pygame.draw.arc(surf, SKIN2,
pygame.Rect(ex-16, ey+2, 32, 14), math.pi+0.2, 2*math.pi-0.2, 1)
# --- NOSE (subtle) ---
pygame.draw.arc(surf, SKIN2,
pygame.Rect(cx-6, head_cy+28, 12, 8), math.pi+0.3, 2*math.pi-0.3, 1)
# --- MOUTH ---
mouth_y = head_cy + 50
# Smile
pygame.draw.arc(surf, PINK3,
pygame.Rect(cx-18, mouth_y, 36, 16), math.pi+0.3, 2*math.pi-0.3, 2)
# Lips
pygame.draw.ellipse(surf, PINK2, pygame.Rect(cx-14, mouth_y+1, 28, 9))
pygame.draw.arc(surf, PINK3,
pygame.Rect(cx-12, mouth_y, 24, 12), math.pi+0.4, 2*math.pi-0.4, 1)
# --- EARS ---
for side in [-1, 1]:
ex = cx + side * 63
pygame.draw.ellipse(surf, SKIN, pygame.Rect(ex - 10, head_cy - 5, 20, 28))
pygame.draw.ellipse(surf, SKIN2, pygame.Rect(ex - 6, head_cy, 12, 18))
# --- HAIRPIN / ACCESSORIES ---
# Star hairpin left
star_x, star_y = cx - 50, head_cy - 110
for i in range(5):
a1 = math.radians(i * 72 - 90)
a2 = math.radians(i * 72 + 36 - 90)
p1 = (star_x + 12 * math.cos(a1), star_y + 12 * math.sin(a1))
p2 = (star_x + 5 * math.cos(a2), star_y + 5 * math.sin(a2))
pygame.draw.line(surf, PINK, (int(p1[0]), int(p1[1])),
(int(p2[0]), int(p2[1])), 2)
pygame.draw.circle(surf, PINK, (star_x, star_y), 4)
# Glowing dot accessories in hair
for gx, gy, gc in [(cx+40, head_cy-130, CYAN),
(cx+70, head_cy-90, PINK),
(cx-60, head_cy-95, BLUE3)]:
draw_glow(surf, gc, (gx, gy), 15, 60)
pygame.draw.circle(surf, gc, (gx, gy), 4)
pygame.draw.circle(surf, WHITE, (gx, gy), 2)
# --- ARMS ---
# Left arm
arm_wave = math.sin(t * 1.2) * 8
arm_l_pts = [(cx-70, base_y-80), (cx-100, base_y-30+arm_wave),
(cx-115, base_y+60+arm_wave), (cx-95, base_y+65+arm_wave),
(cx-80, base_y-20+arm_wave), (cx-55, base_y-70)]
pygame.draw.polygon(surf, (40, 20, 80), arm_l_pts)
# Right arm
arm_r_pts = [(cx+70, base_y-80), (cx+100, base_y-30-arm_wave),
(cx+115, base_y+60-arm_wave), (cx+95, base_y+65-arm_wave),
(cx+80, base_y-20-arm_wave), (cx+55, base_y-70)]
pygame.draw.polygon(surf, (40, 20, 80), arm_r_pts)
# Hands
pygame.draw.circle(surf, SKIN, (cx-108, base_y+62+arm_wave), 14)
pygame.draw.circle(surf, SKIN, (cx+108, base_y+62-arm_wave), 14)
# Arm glow trim
pygame.draw.arc(surf, CYAN,
pygame.Rect(cx-118, base_y+46+arm_wave, 20, 20), 0, math.pi*2, 1)
pygame.draw.arc(surf, PINK,
pygame.Rect(cx+98, base_y+46-arm_wave, 20, 20), 0, math.pi*2, 1)
# --- SKIRT ---
skirt_top = base_y + 90
skirt_pts = [
(cx - 70, skirt_top),
(cx - 130, skirt_top + 100),
(cx - 110, skirt_top + 180),
(cx, skirt_top + 200),
(cx + 110, skirt_top + 180),
(cx + 130, skirt_top + 100),
(cx + 70, skirt_top),
]
pygame.draw.polygon(surf, (50, 20, 90), skirt_pts)
# Skirt details - ruffles
for i, col in enumerate([PURPLE, PINK3, PINK]):
offset = i * 15
s_pts = [
(cx - 70 - offset//2, skirt_top + offset*3),
(cx - 130 - offset, skirt_top + 100 + offset*2),
(cx + 130 + offset, skirt_top + 100 + offset*2),
(cx + 70 + offset//2, skirt_top + offset*3),
]
pygame.draw.lines(surf, col, False, s_pts, 2)
# Skirt sparkles
skirt_wave = math.sin(t * 2) * 3
for sx, sy in [(cx-80, skirt_top+40), (cx+60, skirt_top+60),
(cx-30, skirt_top+120), (cx+100, skirt_top+140)]:
pygame.draw.circle(surf, CYAN, (sx, sy+int(skirt_wave)), 2)
pygame.draw.circle(surf, PINK2, (sx+5, sy-5+int(skirt_wave)), 1)
# --- LEGS ---
leg_h = skirt_top + 180
pygame.draw.rect(surf, SKIN, pygame.Rect(cx-40, leg_h, 30, 80), border_radius=8)
pygame.draw.rect(surf, SKIN, pygame.Rect(cx+10, leg_h, 30, 80), border_radius=8)
# Stockings / boots
pygame.draw.rect(surf, (20, 20, 50), pygame.Rect(cx-42, leg_h+50, 34, 40), border_radius=5)
pygame.draw.rect(surf, (20, 20, 50), pygame.Rect(cx+8, leg_h+50, 34, 40), border_radius=5)
pygame.draw.line(surf, BLUE, (cx-42, leg_h+50), (cx-8, leg_h+50), 2)
pygame.draw.line(surf, BLUE, (cx+8, leg_h+50), (cx+42, leg_h+50), 2)
def draw_particles(surf, t):
for i in range(20):
px = int((W/2 + 220 * math.cos(t*0.3 + i * 0.9)) % W)
py = int((300 + 200 * math.sin(t*0.4 + i * 1.1) + i * 20) % H)
size = 1 + int(2 * abs(math.sin(t + i)))
colors = [PINK, CYAN, BLUE3, PINK2]
c = colors[i % len(colors)]
alpha_surf = pygame.Surface((size*4, size*4), pygame.SRCALPHA)
pygame.draw.circle(alpha_surf, (*c, 120), (size*2, size*2), size*2)
surf.blit(alpha_surf, (px-size*2, py-size*2))
pygame.draw.circle(surf, c, (px, py), size)
def draw_frame_decoration(surf, t):
# Corner decorations
corner_glow = abs(math.sin(t)) * 100 + 100
corners = [(20, 20), (W-20, 20), (20, H-20), (W-20, H-20)]
for cx, cy in corners:
pygame.draw.circle(surf, PINK, (cx, cy), 3)
draw_glow(surf, PINK, (cx, cy), 20, int(corner_glow*0.5))
# Animated border
border_col = (
int(60 + 40 * math.sin(t)),
int(20 + 20 * math.sin(t + 1)),
int(120 + 60 * math.sin(t + 2))
)
pygame.draw.rect(surf, border_col, (5, 5, W-10, H-10), 2, border_radius=8)
# Title text
try:
font = pygame.font.SysFont("Arial", 22, bold=True)
font_sm = pygame.font.SysFont("Arial", 13)
except:
font = pygame.font.Font(None, 28)
font_sm = pygame.font.Font(None, 18)
title = font.render("夢の少女", True, CYAN)
sub = font_sm.render("DREAM GIRL ✦ ANIME STYLE", True, PINK2)
# Glow effect for title
draw_glow(surf, CYAN, (W//2, H-38), 60, 40)
surf.blit(title, title.get_rect(center=(W//2, H-38)))
surf.blit(sub, sub.get_rect(center=(W//2, H-18)))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
running = False
t += 0.03
# Background
draw_gradient_bg(screen)
draw_stars(screen, t)
# Ambient glow behind character
draw_glow(screen, BLUE2, (W//2, 400), 200, 30)
draw_glow(screen, PINK3, (W//2, 300), 150, 20)
# Particles
draw_particles(screen, t)
# Character
draw_girl(screen, t)
# Post effects
draw_scanlines(screen)
draw_frame_decoration(screen, t)
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()