2024-12-30 14:36:23 +08:00

561 lines
21 KiB
Python

import pygame
import math
from constants import *
def draw_sunflower(surface, x, y, size):
# Get animation offset based on time
time = pygame.time.get_ticks()
sway = math.sin(time * 0.003) * 3
petal_spin = time * 0.002
# Draw stem with swaying animation
stem_points = [
(x + size//2 + sway, y + size*3//4),
(x + size//2, y + size*7//8),
(x + size//2, y + size)
]
pygame.draw.lines(surface, GREEN, False, stem_points, 3)
# Draw leaves
leaf_color = (34, 139, 34) # Forest green
leaf_points = [
(x + size//2, y + size*3//4),
(x + size//3, y + size*7//8),
(x + size//2, y + size*13//16)
]
pygame.draw.polygon(surface, leaf_color, leaf_points)
leaf_points = [
(x + size//2, y + size*3//4),
(x + size*2//3, y + size*7//8),
(x + size//2, y + size*13//16)
]
pygame.draw.polygon(surface, leaf_color, leaf_points)
# Draw center with gradient
center_x, center_y = x + size//2 + sway, y + size//2
pygame.draw.circle(surface, (160, 82, 45), (center_x, center_y), size//4) # Dark brown
pygame.draw.circle(surface, (139, 69, 19), (center_x, center_y), size//5) # Medium brown
pygame.draw.circle(surface, (101, 67, 33), (center_x, center_y), size//6) # Light brown
# Draw petals with rotation animation
petal_colors = [(255, 218, 0), (255, 200, 0), (255, 182, 0)] # Different yellow shades
for i, angle in enumerate(range(0, 360, 45)):
rad = math.radians(angle + petal_spin)
petal_x = center_x + math.cos(rad) * size//3
petal_y = center_y + math.sin(rad) * size//3
# Draw each petal with multiple layers for depth
pygame.draw.circle(surface, petal_colors[i % 3], (int(petal_x), int(petal_y)), size//6)
pygame.draw.circle(surface, petal_colors[(i + 1) % 3], (int(petal_x), int(petal_y)), size//8)
def draw_peashooter(surface, x, y, size):
# Get animation offset
time = pygame.time.get_ticks()
sway = math.sin(time * 0.003) * 3
# Draw stem with swaying animation
stem_points = [
(x + size//2 + sway, y + size*2//3),
(x + size//2, y + size*7//8),
(x + size//2, y + size)
]
pygame.draw.lines(surface, GREEN, False, stem_points, 3)
# Draw leaves
leaf_color = (34, 139, 34)
leaf_points = [
(x + size//2, y + size*3//4),
(x + size//3, y + size*7//8),
(x + size//2, y + size*13//16)
]
pygame.draw.polygon(surface, leaf_color, leaf_points)
# Draw head with gradient
head_x = x + size//2 + sway
head_color = (0, 200, 0)
pygame.draw.ellipse(surface, head_color, (head_x - size//4, y + size//4, size//2, size//2))
pygame.draw.ellipse(surface, (0, 180, 0), (head_x - size//5, y + size//3, size//2.5, size//2.5))
# Draw shooter with highlight
shooter_x = head_x + size//4
shooter_color = (0, 100, 0)
pygame.draw.circle(surface, shooter_color, (int(shooter_x), y + size//2), size//7)
pygame.draw.circle(surface, (0, 150, 0), (int(shooter_x), y + size//2), size//10)
# Draw eyes
eye_color = (0, 0, 0)
eye_x = head_x - size//8
pygame.draw.ellipse(surface, eye_color, (eye_x, y + size//3, size//10, size//8))
pygame.draw.ellipse(surface, eye_color, (eye_x + size//6, y + size//3, size//10, size//8))
def draw_wallnut(surface, x, y, size):
# Get animation offset
time = pygame.time.get_ticks()
wobble = math.sin(time * 0.004) * 2
# Draw main body with gradient and texture
nut_colors = [(139, 69, 19), (160, 82, 45), (205, 133, 63)]
for i, color in enumerate(nut_colors):
offset = i * 4
pygame.draw.ellipse(surface, color,
(x + size//6 + offset + wobble,
y + size//6 + offset,
size*2//3 - offset*2,
size*2//3 - offset*2))
# Draw crack details
crack_color = (101, 67, 33)
crack_points = [
(x + size//2, y + size//4),
(x + size*2//3, y + size//3),
(x + size//2, y + size//2)
]
pygame.draw.lines(surface, crack_color, False, crack_points, 2)
# Draw face with expression
eye_color = BLACK
blink = (time % 3000) < 200 # Blink every 3 seconds
if not blink:
# Draw eyes
pygame.draw.ellipse(surface, eye_color, (x + size//3, y + size//3, size//6, size//6))
pygame.draw.ellipse(surface, eye_color, (x + size//2, y + size//3, size//6, size//6))
# Draw white highlights in eyes
pygame.draw.circle(surface, WHITE, (x + size//3 + size//12, y + size//3 + size//12), size//20)
pygame.draw.circle(surface, WHITE, (x + size//2 + size//12, y + size//3 + size//12), size//20)
else:
# Draw closed eyes
pygame.draw.line(surface, eye_color, (x + size//3, y + size//3), (x + size//3 + size//6, y + size//3), 2)
pygame.draw.line(surface, eye_color, (x + size//2, y + size//3), (x + size//2 + size//6, y + size//3), 2)
# Draw smile that changes with wobble
smile_rect = pygame.Rect(x + size//3 + wobble, y + size//2, size//3, size//6)
pygame.draw.arc(surface, eye_color, smile_rect, 0, math.pi, 2)
def draw_chomper(surface, x, y, size):
# Get animation offset
time = pygame.time.get_ticks()
chomp = abs(math.sin(time * 0.004)) * size//4
sway = math.sin(time * 0.003) * 3
# Draw stem with swaying animation
stem_points = [
(x + size//2 + sway, y + size*2//3),
(x + size//2, y + size*7//8),
(x + size//2, y + size)
]
pygame.draw.lines(surface, GREEN, False, stem_points, 4)
# Draw head
head_color = (148, 0, 211) # Purple
head_x = x + size//2 + sway
# Draw back of mouth
pygame.draw.ellipse(surface, (101, 0, 148),
(head_x - size//3, y + size//4, size*2//3, size//2))
# Draw tongue
tongue_color = (255, 105, 180)
tongue_points = [
(head_x, y + size//2),
(head_x - size//4, y + size//2 + size//4),
(head_x + size//4, y + size//2 + size//4)
]
pygame.draw.polygon(surface, tongue_color, tongue_points)
# Draw mouth (upper and lower jaw)
jaw_points_upper = [
(head_x - size//3, y + size//3),
(head_x + size//3, y + size//3),
(head_x + size//2, y + size//2),
(head_x - size//2, y + size//2)
]
jaw_points_lower = [
(head_x - size//3, y + size//2 + chomp),
(head_x + size//3, y + size//2 + chomp),
(head_x + size//2, y + size*2//3 + chomp),
(head_x - size//2, y + size*2//3 + chomp)
]
pygame.draw.polygon(surface, head_color, jaw_points_upper)
pygame.draw.polygon(surface, head_color, jaw_points_lower)
# Draw teeth
teeth_color = WHITE
tooth_width = size//8
for tooth_x in range(int(head_x - size//3), int(head_x + size//3), tooth_width):
# Upper teeth
pygame.draw.polygon(surface, teeth_color, [
(tooth_x, y + size//2),
(tooth_x + tooth_width//2, y + size//2 - size//8),
(tooth_x + tooth_width, y + size//2)
])
# Lower teeth
pygame.draw.polygon(surface, teeth_color, [
(tooth_x, y + size//2 + chomp),
(tooth_x + tooth_width//2, y + size//2 + size//8 + chomp),
(tooth_x + tooth_width, y + size//2 + chomp)
])
def draw_snow_pea(surface, x, y, size):
# Get animation offset
time = pygame.time.get_ticks()
sway = math.sin(time * 0.003) * 3
ice_spin = time * 0.003
# Draw stem with swaying animation
stem_points = [
(x + size//2 + sway, y + size*2//3),
(x + size//2, y + size*7//8),
(x + size//2, y + size)
]
pygame.draw.lines(surface, GREEN, False, stem_points, 3)
# Draw leaves with frost effect
leaf_color = (150, 200, 150)
leaf_points = [
(x + size//2, y + size*3//4),
(x + size//3, y + size*7//8),
(x + size//2, y + size*13//16)
]
pygame.draw.polygon(surface, leaf_color, leaf_points)
# Draw head with ice effect
head_x = x + size//2 + sway
head_colors = [(0, 191, 255), (135, 206, 235), (176, 224, 230)]
for i, color in enumerate(head_colors):
offset = i * 3
pygame.draw.ellipse(surface, color,
(head_x - size//4 + offset,
y + size//4 + offset,
size//2 - offset*2,
size//2 - offset*2))
# Draw ice crystals with rotation
crystal_color = (200, 232, 255)
for i in range(4):
angle = ice_spin + i * (math.pi/2)
crystal_x = head_x + math.cos(angle) * size//3
crystal_y = y + size//2 + math.sin(angle) * size//3
crystal_points = [
(crystal_x, crystal_y - size//8),
(crystal_x + size//8, crystal_y),
(crystal_x, crystal_y + size//8),
(crystal_x - size//8, crystal_y)
]
pygame.draw.polygon(surface, crystal_color, crystal_points)
# Draw frost particles
for i in range(3):
particle_x = head_x + math.cos(time * 0.001 + i * 2) * size//4
particle_y = y + size//2 + math.sin(time * 0.001 + i * 2) * size//4
pygame.draw.circle(surface, (255, 255, 255, 128),
(int(particle_x), int(particle_y)), size//16)
def draw_normal_zombie(surface, x, y, size):
# Get animation offset
time = pygame.time.get_ticks()
wobble = math.sin(time * 0.004) * 3
# Draw shadow
shadow_surface = pygame.Surface((size*2//3, size//4), pygame.SRCALPHA)
pygame.draw.ellipse(shadow_surface, (0, 0, 0, 64), (0, 0, size*2//3, size//4))
surface.blit(shadow_surface, (x + size//6, y + size - size//8))
# Draw legs with walking animation
leg_color = (100, 100, 100)
leg_offset = abs(math.sin(time * 0.004)) * 5
pygame.draw.line(surface, leg_color,
(x + size//2, y + size*2//3),
(x + size//3, y + size - leg_offset), 4)
pygame.draw.line(surface, leg_color,
(x + size//2, y + size*2//3),
(x + size*2//3, y + size - leg_offset), 4)
# Draw tattered clothes
clothes_color = (50, 50, 50)
clothes_points = [
(x + size//3, y + size//2),
(x + size*2//3, y + size//2),
(x + size*2//3, y + size*3//4),
(x + size//3, y + size*3//4)
]
pygame.draw.polygon(surface, clothes_color, clothes_points)
# Draw arms with swaying animation
arm_color = (100, 100, 100)
arm_sway = math.sin(time * 0.004) * 10
pygame.draw.line(surface, arm_color,
(x + size//2, y + size//2),
(x + size//4 + arm_sway, y + size*2//3), 4)
pygame.draw.line(surface, arm_color,
(x + size//2, y + size//2),
(x + size*3//4 + arm_sway, y + size*2//3), 4)
# Draw body with details
body_color = (169, 169, 169)
pygame.draw.ellipse(surface, body_color,
(x + size//3 + wobble, y + size//3, size//3, size//2))
# Draw head with details
head_color = (169, 169, 169)
pygame.draw.circle(surface, head_color,
(int(x + size//2 + wobble), int(y + size//3)), size//4)
# Draw facial features
eye_color = (255, 0, 0) # Red eyes
pygame.draw.circle(surface, eye_color,
(int(x + size//2 - size//8 + wobble), int(y + size//3)), size//12)
pygame.draw.circle(surface, eye_color,
(int(x + size//2 + size//8 + wobble), int(y + size//3)), size//12)
# Draw mouth
mouth_color = (100, 0, 0)
mouth_points = [
(x + size//2 - size//6 + wobble, y + size//3 + size//6),
(x + size//2 + size//6 + wobble, y + size//3 + size//6),
(x + size//2 + wobble, y + size//3 + size//4)
]
pygame.draw.polygon(surface, mouth_color, mouth_points)
def draw_cone_zombie(surface, x, y, size):
# Draw base zombie
draw_normal_zombie(surface, x, y, size)
# Get animation offset
time = pygame.time.get_ticks()
wobble = math.sin(time * 0.004) * 3
# Draw cone with details and shading
cone_colors = [(139, 69, 19), (160, 82, 45), (205, 133, 63)] # Different shades of brown
for i, color in enumerate(cone_colors):
offset = i * 2
points = [
(x + size//2 + wobble, y - size//6 + offset),
(x + size//3 + offset, y + size//3),
(x + size*2//3 - offset, y + size//3)
]
pygame.draw.polygon(surface, color, points)
# Draw cone damage (dents and scratches)
scratch_color = (101, 67, 33)
scratch_points = [
(x + size//2 - size//8 + wobble, y + size//6),
(x + size//2 + size//8 + wobble, y + size//4)
]
pygame.draw.lines(surface, scratch_color, False, scratch_points, 2)
def draw_bucket_zombie(surface, x, y, size):
# Draw base zombie
draw_normal_zombie(surface, x, y, size)
# Get animation offset
time = pygame.time.get_ticks()
wobble = math.sin(time * 0.004) * 3
# Draw bucket with metallic effect
bucket_colors = [(192, 192, 192), (169, 169, 169), (128, 128, 128)]
for i, color in enumerate(bucket_colors):
offset = i * 2
pygame.draw.rect(surface, color,
(x + size//4 + offset + wobble,
y - size//6 + offset,
size//2 - offset*2,
size//3))
# Draw bucket rim
rim_color = (211, 211, 211)
pygame.draw.rect(surface, rim_color,
(x + size//4 - 2 + wobble, y - size//6, size//2 + 4, 4))
# Draw bucket highlights
highlight_color = (255, 255, 255)
pygame.draw.line(surface, highlight_color,
(x + size//3 + wobble, y),
(x + size*2//3 + wobble, y), 2)
# Draw dents and damage
dent_color = (128, 128, 128)
pygame.draw.arc(surface, dent_color,
(x + size//3 + wobble, y, size//4, size//6),
0, math.pi, 2)
def draw_newspaper_zombie(surface, x, y, size):
# Draw base zombie
draw_normal_zombie(surface, x, y, size)
# Get animation offset
time = pygame.time.get_ticks()
wobble = math.sin(time * 0.004) * 3
paper_shake = math.sin(time * 0.008) * 2
# Draw newspaper with animated shaking
paper_color = (255, 255, 255)
pygame.draw.rect(surface, paper_color,
(x + size//6 + paper_shake,
y + size//3,
size//2,
size//2))
# Draw newspaper content (headlines and text)
text_color = (0, 0, 0)
for i in range(4):
y_pos = y + size//3 + i*size//8
pygame.draw.line(surface, text_color,
(x + size//5 + paper_shake, y_pos),
(x + size*2//3 + paper_shake, y_pos), 1)
# Draw newspaper damage
if time % 2000 < 1000: # Animate paper damage
tear_points = [
(x + size//3 + paper_shake, y + size//3),
(x + size//2 + paper_shake, y + size//2),
(x + size//3 + paper_shake, y + size*2//3)
]
pygame.draw.lines(surface, (200, 200, 200), False, tear_points, 2)
def draw_dancing_zombie(surface, x, y, size):
# Get animation offset
time = pygame.time.get_ticks()
dance_move = math.sin(time * 0.006) * 10
spin = math.sin(time * 0.003) * 0.3
# Draw shadow
shadow_surface = pygame.Surface((size*2//3, size//4), pygame.SRCALPHA)
pygame.draw.ellipse(shadow_surface, (0, 0, 0, 64), (0, 0, size*2//3, size//4))
surface.blit(shadow_surface, (x + size//6, y + size - size//8))
# Draw legs in dancing pose
leg_color = (100, 100, 100)
pygame.draw.line(surface, leg_color,
(x + size//2, y + size//2),
(x + size//4 + dance_move, y + size), 4)
pygame.draw.line(surface, leg_color,
(x + size//2, y + size//2),
(x + size*3//4 - dance_move, y + size), 4)
# Draw disco outfit
outfit_color = (148, 0, 211) # Purple
outfit_points = [
(x + size//3 + dance_move/2, y + size//3),
(x + size*2//3 + dance_move/2, y + size//3),
(x + size*2//3 - dance_move/2, y + size*3//4),
(x + size//3 - dance_move/2, y + size*3//4)
]
pygame.draw.polygon(surface, outfit_color, outfit_points)
# Draw arms in dancing pose
arm_color = (100, 100, 100)
pygame.draw.line(surface, arm_color,
(x + size//2, y + size//2),
(x + size//4 - dance_move, y + size//3), 4)
pygame.draw.line(surface, arm_color,
(x + size//2, y + size//2),
(x + size*3//4 + dance_move, y + size//3), 4)
# Draw body with disco moves
body_color = (169, 169, 169)
body_rect = pygame.Rect(x + size//3 + dance_move/2, y + size//4,
size//3, size//2)
rotated_surface = pygame.Surface((size, size), pygame.SRCALPHA)
pygame.draw.ellipse(rotated_surface, body_color, body_rect)
# Draw head with cool hair
head_color = (169, 169, 169)
pygame.draw.circle(rotated_surface, head_color,
(int(x + size//2 + dance_move/2), int(y + size//3)),
size//4)
# Draw spiky hair with animation
hair_color = (0, 0, 0)
for i in range(6):
angle = i * math.pi/3 + spin
hair_x = x + size//2 + math.cos(angle) * size//3 + dance_move/2
hair_y = y + size//3 + math.sin(angle) * size//4
pygame.draw.line(surface, hair_color,
(x + size//2 + dance_move/2, y + size//3),
(hair_x, hair_y), 3)
# Draw sunglasses
glasses_color = (0, 0, 0)
pygame.draw.rect(surface, glasses_color,
(x + size//3 + dance_move/2, y + size//4,
size//3, size//8))
# Draw disco ball effect
for i in range(8):
angle = i * math.pi/4 + time * 0.01
sparkle_x = x + size//2 + math.cos(angle) * size//2
sparkle_y = y + size//3 + math.sin(angle) * size//2
pygame.draw.circle(surface, (255, 255, 255),
(int(sparkle_x), int(sparkle_y)), 2)
def draw_rose_shooter(surface, x, y, size):
# Get animation offset
time = pygame.time.get_ticks()
sway = math.sin(time * 0.003) * 3
petal_spin = time * 0.002
# Draw stem with swaying animation
stem_points = [
(x + size//2 + sway, y + size*2//3),
(x + size//2, y + size*7//8),
(x + size//2, y + size)
]
pygame.draw.lines(surface, GREEN, False, stem_points, 3)
# Draw leaves
leaf_color = (34, 139, 34) # Forest green
leaf_points = [
(x + size//2, y + size*3//4),
(x + size//3, y + size*7//8),
(x + size//2, y + size*13//16)
]
pygame.draw.polygon(surface, leaf_color, leaf_points)
# Draw thorns
thorn_color = (139, 69, 19) # Brown
thorn_points = [
[(x + size//2 - 5, y + size*3//4), (x + size//2 - 10, y + size*3//4 - 5), (x + size//2 - 5, y + size*3//4 - 5)],
[(x + size//2 + 5, y + size*3//4), (x + size//2 + 10, y + size*3//4 - 5), (x + size//2 + 5, y + size*3//4 - 5)]
]
for points in thorn_points:
pygame.draw.polygon(surface, thorn_color, points)
# Draw rose head with gradient
head_x = x + size//2 + sway
head_y = y + size//2
rose_colors = [(255, 192, 203), (255, 182, 193), (255, 105, 180)] # Pink gradients
# Draw petals in layers
for i, color in enumerate(rose_colors):
offset = i * 3
for angle in range(0, 360, 45):
rad = math.radians(angle + petal_spin)
petal_x = head_x + math.cos(rad) * (size//4 - offset)
petal_y = head_y + math.sin(rad) * (size//4 - offset)
pygame.draw.circle(surface, color, (int(petal_x), int(petal_y)), size//6 - offset)
# Draw center
pygame.draw.circle(surface, (139, 0, 0), (int(head_x), int(head_y)), size//8) # Dark red center
# Draw shooter with highlight
shooter_x = head_x + size//4
shooter_color = (255, 20, 147) # Deep pink
pygame.draw.circle(surface, shooter_color, (int(shooter_x), head_y), size//7)
pygame.draw.circle(surface, (255, 105, 180), (int(shooter_x), head_y), size//10) # Highlight
# Dictionary mapping plant types to their drawing functions
PLANT_DRAWINGS = {
PlantType.SUNFLOWER: draw_sunflower,
PlantType.PEASHOOTER: draw_peashooter,
PlantType.ROSE_SHOOTER: draw_rose_shooter,
PlantType.CHOMPER: draw_chomper,
PlantType.SNOW_PEA: draw_snow_pea
}
# Dictionary mapping zombie types to their drawing functions
ZOMBIE_DRAWINGS = {
ZombieType.NORMAL: draw_normal_zombie,
ZombieType.CONE: draw_cone_zombie,
ZombieType.BUCKET: draw_bucket_zombie,
ZombieType.NEWSPAPER: draw_newspaper_zombie,
ZombieType.DANCING: draw_dancing_zombie
}