Загрузка данных
import pgzrun
import random
import pygame
from pgzhelper import load_sound, play_music, audio_status
WIDTH = 450
HEIGHT = 800
TITLE = "Мой огород"
music_started = False
# Каждый эффект — отдельная переменная.
# Пути строит pgzhelper относительно СВОЕГО файла, который лежит в папке проекта.
plant_sound = load_sound("plant.wav", 1.0)
water_sound = load_sound("water.wav", 1.0)
harvest_sound = load_sound("harvest.wav", 1.0)
def start_music():
# OGG надёжнее MP3 для pygame/pygame-zero.
play_music("background.ogg", volume=1.0, loops=-1)
# ---------------------------------------------------------
# ОСНОВНЫЕ ПАНЕЛИ
# ---------------------------------------------------------
background = Actor("background")
background.topleft = (0, 0)
top_panel = Actor("top_panel")
top_panel.center = (218, 40)
settings_button = Actor("settings_new")
settings_button.center = (426, 37)
bottom_panel = Actor("bottom_panel")
bottom_panel.center = (225, 743)
# ---------------------------------------------------------
# РЕСУРСЫ
# ---------------------------------------------------------
resource_x = [72, 225, 378]
resource_panels = []
for x in resource_x:
panel = Actor("resource_panel_new")
panel.center = (x, 96)
resource_panels.append(panel)
coin_icon = Actor("coin_new")
coin_icon.center = (resource_x[0] - 49, 96)
water_icon = Actor("water_new")
water_icon.center = (resource_x[1] - 49, 96)
sun_icon = Actor("sun_new")
sun_icon.center = (resource_x[2] - 49, 96)
level_panel = Actor("level_panel_new")
level_panel.center = (225, 132)
# ---------------------------------------------------------
# ЗАДАНИЯ
# ---------------------------------------------------------
tasks_title = Actor("tasks_title_new")
tasks_title.center = (82, 157)
tasks_panel = Actor("tasks_panel_new")
tasks_panel.center = (82, 248)
task_plant_icon = Actor("task_plant")
task_plant_icon.center = (48, 201)
task_harvest_icon = Actor("task_basket")
task_harvest_icon.center = (48, 276)
plant_progress_bg = Actor("progress_bg_new")
plant_progress_bg.center = (82, 228)
harvest_progress_bg = Actor("progress_bg_new")
harvest_progress_bg.center = (82, 303)
plant_progress_fill = Actor("progress_fill_25")
harvest_progress_fill = Actor("progress_fill_25")
progress_width = {
25: 27,
50: 54,
75: 81,
100: 108
}
# ---------------------------------------------------------
# ШЕСТЬ ГРЯДОК
# ---------------------------------------------------------
bed_positions = [
(82, 392),
(225, 392),
(368, 392),
(82, 512),
(225, 512),
(368, 512)
]
beds = []
plants = []
ready_effects = []
empty_marks = []
for position in bed_positions:
bed = Actor("bed_empty")
bed.center = position
beds.append(bed)
plants.append(None)
effect = Actor("ready_effect_new")
effect.center = (position[0] + 38, position[1] - 42)
ready_effects.append(effect)
mark = Actor("plus_bed_new")
mark.center = (position[0], position[1] - 5)
empty_marks.append(mark)
plant_name = ["", "", "", "", "", ""]
plant_stage = [0, 0, 0, 0, 0, 0]
plant_time = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
plant_watered = [False, False, False, False, False, False]
plant_ready = [False, False, False, False, False, False]
# ---------------------------------------------------------
# СООБЩЕНИЕ И БОЛЬШАЯ КНОПКА СБОРА
# ---------------------------------------------------------
message_panel = Actor("message_panel_new")
message_panel.center = (145, 660)
harvest_big = Actor("harvest_big_new")
harvest_big.center = (365, 660)
message_line1 = ""
message_line2 = ""
message_time = 0.0
# ---------------------------------------------------------
# НИЖНЕЕ МЕНЮ
# ---------------------------------------------------------
button_x = [45, 135, 225, 315, 405]
button_y = 758
button_water = Actor("button_water")
button_water.center = (button_x[0], button_y)
button_seeds = Actor("button_seeds")
button_seeds.center = (button_x[1], button_y)
button_shovel = Actor("button_shovel")
button_shovel.center = (button_x[2], button_y)
button_harvest = Actor("button_harvest")
button_harvest.center = (button_x[3], button_y)
button_shop = Actor("button_shop")
button_shop.center = (button_x[4], button_y)
menu_buttons = [
button_water,
button_seeds,
button_shovel,
button_harvest,
button_shop
]
selected_marker = Actor("selected_new")
selected_check = Actor("check_new")
selected_check.center = (0, 0)
# ---------------------------------------------------------
# МАГАЗИН И ОКНА
# ---------------------------------------------------------
overlay_panel = Actor("overlay_panel")
overlay_panel.center = (225, 400)
close_button = Actor("check_new")
close_button.center = (385, 154)
shop_y = [220, 292, 364, 436, 508, 580]
shop_rows = []
for y in shop_y:
row = Actor("shop_item")
row.center = (225, y)
shop_rows.append(row)
shop_icons = [
Actor("shop_carrot"),
Actor("shop_potato"),
Actor("shop_tomato"),
Actor("shop_cucumber"),
Actor("shop_water_icon"),
Actor("shop_sun_icon")
]
for icon, y in zip(shop_icons, shop_y):
icon.center = (105, y)
pause_continue = Actor("shop_item")
pause_continue.center = (225, 360)
pause_restart = Actor("shop_item")
pause_restart.center = (225, 450)
win_restart = Actor("shop_item")
win_restart.center = (225, 500)
# ---------------------------------------------------------
# ИГРОВЫЕ ДАННЫЕ
# ---------------------------------------------------------
mode = "game"
tool = "seeds"
coins = 250
water = 25
sun = 12
level = 1
plant_progress = 0
harvest_progress = 0
level_plant_goal = [3, 4, 5, 6, 8]
level_harvest_goal = [3, 4, 5, 6, 8]
crop_order = ["carrot", "potato", "tomato", "cucumber"]
selected_crop = "carrot"
unlocked_crops = ["carrot"]
seed_count = {
"carrot": 8,
"potato": 0,
"tomato": 0,
"cucumber": 0
}
crop_title = {
"carrot": "МОРКОВЬ",
"potato": "КАРТОФЕЛЬ",
"tomato": "ПОМИДОР",
"cucumber": "ОГУРЕЦ"
}
crop_reward = {
"carrot": 10,
"potato": 15,
"tomato": 20,
"cucumber": 25
}
shop_price = {
"carrot": 15,
"potato": 25,
"tomato": 35,
"cucumber": 45,
"water": 20,
"sun": 25
}
shop_names = [
"Семена моркови +5",
"Семена картофеля +5",
"Семена помидоров +5",
"Семена огурцов +5",
"Вода +10",
"Солнце +5"
]
shop_items = ["carrot", "potato", "tomato", "cucumber", "water", "sun"]
pressed_button = ""
pressed_time = 0.0
coin_effects = []
# ---------------------------------------------------------
# СООБЩЕНИЯ
# ---------------------------------------------------------
def split_message(text):
words = str(text).split()
line1 = ""
line2 = ""
for word in words:
test = word if line1 == "" else line1 + " " + word
if len(test) <= 28 or line1 == "":
line1 = test
else:
line2 = word if line2 == "" else line2 + " " + word
return line1, line2
def set_message(line1, line2=""):
global message_line1
global message_line2
global message_time
if line2 == "":
message_line1, message_line2 = split_message(line1)
else:
message_line1 = str(line1)
message_line2 = str(line2)
message_time = 3.5
def press_button(name):
global pressed_button
global pressed_time
pressed_button = name
pressed_time = 0.15
def add_coin_effect(index, amount):
x = bed_positions[index][0] + random.randint(-8, 8)
y = bed_positions[index][1] - 45
coin_effects.append([x, y, "+" + str(amount), 1.2])
# ---------------------------------------------------------
# РАСТЕНИЯ
# ---------------------------------------------------------
def create_plant(index):
image_name = plant_name[index] + "_" + str(plant_stage[index])
if plants[index] is None:
plants[index] = Actor(image_name)
else:
plants[index].image = image_name
plants[index].center = (
bed_positions[index][0],
bed_positions[index][1] - 14
)
def reset_bed(index):
plant_name[index] = ""
plant_stage[index] = 0
plant_time[index] = 0.0
plant_watered[index] = False
plant_ready[index] = False
plants[index] = None
beds[index].image = "bed_empty"
def plant_seed(index):
global sun
global plant_progress
if index < 0 or index >= len(beds):
return False
if plant_stage[index] != 0:
set_message("Эта грядка уже занята")
return False
if selected_crop not in unlocked_crops:
set_message("Эта культура ещё закрыта")
return False
if seed_count[selected_crop] <= 0:
set_message("Семена закончились", "Откройте магазин")
return False
if sun <= 0:
set_message("Недостаточно солнца")
return False
seed_count[selected_crop] -= 1
sun -= 1
plant_name[index] = selected_crop
plant_stage[index] = 1
plant_time[index] = 0.0
plant_watered[index] = False
plant_ready[index] = False
beds[index].image = "bed_empty"
create_plant(index)
plant_progress += 1
set_message("Посажено: " + crop_title[selected_crop])
check_level()
return True
def water_bed(index):
global water
if index < 0 or index >= len(beds):
return False
if plant_stage[index] == 0:
set_message("Сначала посадите растение")
return False
if plant_ready[index]:
set_message("Урожай уже созрел")
return False
if plant_watered[index]:
set_message("Эта грядка уже полита")
return False
if water <= 0:
set_message("Вода закончилась")
return False
water -= 1
plant_watered[index] = True
beds[index].image = "bed_watered"
set_message("Грядка полита", "Рост ускорен")
return True
def clear_bed(index):
if index < 0 or index >= len(beds):
return False
if plant_stage[index] == 0:
set_message("Грядка уже пустая")
return False
reset_bed(index)
set_message("Грядка очищена")
return True
def harvest_bed(index):
global coins
global harvest_progress
if index < 0 or index >= len(beds):
return False
if not plant_ready[index]:
set_message("Урожай ещё не созрел")
return False
crop = plant_name[index]
reward = crop_reward[crop]
coins += reward
harvest_progress += 1
add_coin_effect(index, reward)
reset_bed(index)
set_message("Урожай собран", "+" + str(reward) + " монет")
check_level()
return True
def harvest_all():
count = 0
for index in range(len(beds)):
if plant_ready[index]:
if harvest_bed(index):
count += 1
if count == 0:
set_message("Готового урожая пока нет")
else:
set_message("Собрано грядок: " + str(count))
return count
# ---------------------------------------------------------
# УРОВНИ И КУЛЬТУРЫ
# ---------------------------------------------------------
def current_plant_goal():
return level_plant_goal[level - 1]
def current_harvest_goal():
return level_harvest_goal[level - 1]
def unlock_crop(name):
global selected_crop
if name not in unlocked_crops:
unlocked_crops.append(name)
seed_count[name] += 4
selected_crop = name
def check_level():
global level
global plant_progress
global harvest_progress
global water
global sun
global mode
if plant_progress < current_plant_goal():
return False
if harvest_progress < current_harvest_goal():
return False
if level == 5:
mode = "win"
set_message("Все уровни пройдены!")
return True
level += 1
plant_progress = 0
harvest_progress = 0
water += 5
sun += 3
if level == 2:
unlock_crop("potato")
elif level == 3:
unlock_crop("tomato")
elif level == 4:
unlock_crop("cucumber")
set_message("Открыт уровень " + str(level), "Новая культура доступна")
return True
def cycle_crop():
global selected_crop
available = []
for name in crop_order:
if name in unlocked_crops:
available.append(name)
if selected_crop not in available:
selected_crop = available[0]
else:
index = available.index(selected_crop)
index = (index + 1) % len(available)
selected_crop = available[index]
set_message("Выбрано: " + crop_title[selected_crop],
"Семян: " + str(seed_count[selected_crop]))
# ---------------------------------------------------------
# МАГАЗИН
# ---------------------------------------------------------
def buy_item(item):
global coins
global water
global sun
if item not in shop_price:
return False
if item in crop_order and item not in unlocked_crops:
set_message("Культура откроется позже")
return False
price = shop_price[item]
if coins < price:
set_message("Недостаточно монет")
return False
coins -= price
if item == "water":
water += 10
set_message("Куплено воды: +10")
elif item == "sun":
sun += 5
set_message("Куплено солнца: +5")
else:
seed_count[item] += 5
set_message("Куплено 5 семян", crop_title[item])
return True
# ---------------------------------------------------------
# НОВАЯ ИГРА
# ---------------------------------------------------------
def new_game():
global mode
global tool
global coins
global water
global sun
global level
global plant_progress
global harvest_progress
global selected_crop
global unlocked_crops
global message_line1
global message_line2
global message_time
global coin_effects
mode = "game"
tool = "seeds"
coins = 250
water = 25
sun = 12
level = 1
plant_progress = 0
harvest_progress = 0
selected_crop = "carrot"
unlocked_crops = ["carrot"]
seed_count["carrot"] = 8
seed_count["potato"] = 0
seed_count["tomato"] = 0
seed_count["cucumber"] = 0
for index in range(len(beds)):
reset_bed(index)
coin_effects = []
message_line1 = "Выберите СЕМЕНА"
message_line2 = "и нажмите на грядку"
message_time = 5.0
# ---------------------------------------------------------
# ОТРИСОВКА ПРОГРЕССА
# ---------------------------------------------------------
def progress_percent(value, goal):
if goal <= 0 or value <= 0:
return 0
percent = value * 100 / goal
if percent <= 25:
return 25
if percent <= 50:
return 50
if percent <= 75:
return 75
return 100
def draw_progress(fill_actor, center_x, center_y, value, goal):
percent = progress_percent(value, goal)
if percent == 0:
return
fill_actor.image = "progress_fill_" + str(percent)
width = progress_width[percent]
left = center_x - 54
fill_actor.center = (left + width / 2, center_y)
fill_actor.draw()
# ---------------------------------------------------------
# ОТРИСОВКА ЭКРАНА ИГРЫ
# ---------------------------------------------------------
def draw_resources():
for panel in resource_panels:
panel.draw()
coin_icon.draw()
water_icon.draw()
sun_icon.draw()
screen.draw.text(str(coins), center=(resource_x[0] + 8, 96),
fontsize=19, color="#6b3b14", shadow=(1, 1),
scolor="#fff4ce")
screen.draw.text(str(water), center=(resource_x[1] + 8, 96),
fontsize=19, color="#16548d", shadow=(1, 1),
scolor="#ffffff")
screen.draw.text(str(sun), center=(resource_x[2] + 8, 96),
fontsize=19, color="#9a5a00", shadow=(1, 1),
scolor="#fff9c2")
def draw_tasks():
tasks_panel.draw()
tasks_title.draw()
task_plant_icon.draw()
task_harvest_icon.draw()
screen.draw.text("Посадить", center=(100, 196), fontsize=14,
color="#5b3518")
screen.draw.text("Собрать", center=(100, 271), fontsize=14,
color="#5b3518")
plant_progress_bg.draw()
harvest_progress_bg.draw()
draw_progress(plant_progress_fill, 82, 228,
plant_progress, current_plant_goal())
draw_progress(harvest_progress_fill, 82, 303,
harvest_progress, current_harvest_goal())
screen.draw.text(str(plant_progress) + "/" + str(current_plant_goal()),
center=(82, 228), fontsize=12, color="white",
shadow=(1, 1), scolor="#356020")
screen.draw.text(str(harvest_progress) + "/" + str(current_harvest_goal()),
center=(82, 303), fontsize=12, color="white",
shadow=(1, 1), scolor="#356020")
def draw_beds():
for index in range(len(beds)):
beds[index].draw()
if plants[index] is not None:
plants[index].draw()
else:
empty_marks[index].draw()
if plant_ready[index]:
ready_effects[index].draw()
def draw_message():
message_panel.draw()
screen.draw.text(message_line1, center=(145, 653), fontsize=15,
color="#5b3518")
if message_line2 != "":
screen.draw.text(message_line2, center=(145, 672), fontsize=14,
color="#5b3518")
def selected_button_index():
if tool == "water":
return 0
if tool == "seeds":
return 1
if tool == "shovel":
return 2
if tool == "harvest":
return 3
return -1
def draw_bottom_menu():
bottom_panel.draw()
index = selected_button_index()
if index >= 0:
selected_marker.center = (button_x[index], button_y + 2)
selected_marker.draw()
for button in menu_buttons:
button.draw()
if index >= 0:
selected_check.center = (button_x[index] + 27, button_y - 23)
selected_check.draw()
def draw_coin_effects():
for effect in coin_effects:
screen.draw.text(effect[2], center=(effect[0], effect[1]),
fontsize=20, color="#ffe34f", shadow=(1, 1),
scolor="#8a4b00")
def draw_game():
background.draw()
top_panel.draw()
settings_button.draw()
draw_resources()
level_panel.draw()
screen.draw.text("УРОВЕНЬ " + str(level), center=(225, 132),
fontsize=16, color="white", shadow=(1, 1),
scolor="#6b3512")
draw_tasks()
draw_beds()
draw_message()
harvest_big.draw()
draw_bottom_menu()
draw_coin_effects()
# ---------------------------------------------------------
# МАГАЗИН, ПАУЗА, ПОБЕДА
# ---------------------------------------------------------
def draw_shop():
draw_game()
overlay_panel.draw()
close_button.draw()
screen.draw.text("МАГАЗИН", center=(225, 164), fontsize=30,
color="#6b3512")
for index in range(len(shop_rows)):
shop_rows[index].draw()
shop_icons[index].draw()
item = shop_items[index]
locked = item in crop_order and item not in unlocked_crops
title = shop_names[index]
if locked:
title = "ЗАКРЫТО ДО УРОВНЯ " + str(crop_order.index(item) + 1)
screen.draw.text(title, midleft=(138, shop_y[index] - 10),
fontsize=15, color="#5b3518")
if not locked:
screen.draw.text(str(shop_price[item]) + " монет",
midleft=(138, shop_y[index] + 13),
fontsize=14, color="#a05a00")
def draw_pause():
draw_game()
overlay_panel.draw()
close_button.draw()
screen.draw.text("ПАУЗА", center=(225, 225), fontsize=42,
color="#6b3512")
pause_continue.draw()
pause_restart.draw()
screen.draw.text("ПРОДОЛЖИТЬ", center=pause_continue.center,
fontsize=24, color="#5b3518")
screen.draw.text("НОВАЯ ИГРА", center=pause_restart.center,
fontsize=24, color="#5b3518")
def draw_win():
background.draw()
overlay_panel.draw()
screen.draw.text("ПОБЕДА!", center=(225, 250), fontsize=48,
color="#4f9b22", shadow=(2, 2), scolor="#ffffff")
screen.draw.text("Все 5 уровней пройдены", center=(225, 320),
fontsize=22, color="#5b3518")
screen.draw.text("Монеты: " + str(coins), center=(225, 360),
fontsize=22, color="#9a5a00")
win_restart.draw()
screen.draw.text("ИГРАТЬ СНОВА", center=win_restart.center,
fontsize=23, color="#5b3518")
def draw():
if mode == "game":
draw_game()
elif mode == "shop":
draw_shop()
elif mode == "pause":
draw_pause()
elif mode == "win":
draw_win()
# ---------------------------------------------------------
# ОБНОВЛЕНИЕ
# ---------------------------------------------------------
def update(dt):
global message_time
global pressed_time
global music_started
# update() вызывается уже после запуска pgzrun.go(),
# поэтому здесь аудиосистема Pygame Zero уже готова.
if not music_started:
start_music()
music_started = True
if mode == "game":
for index in range(len(beds)):
if plant_stage[index] > 0 and not plant_ready[index]:
speed = 2.0 if plant_watered[index] else 1.0
plant_time[index] += dt * speed
if plant_time[index] >= 8.0:
plant_stage[index] = 3
plant_ready[index] = True
beds[index].image = "bed_ready"
create_plant(index)
elif plant_time[index] >= 4.0 and plant_stage[index] == 1:
plant_stage[index] = 2
create_plant(index)
if message_time > 0:
message_time -= dt
if pressed_time > 0:
pressed_time -= dt
for effect in coin_effects[:]:
effect[1] -= 22 * dt
effect[3] -= dt
if effect[3] <= 0:
coin_effects.remove(effect)
# ---------------------------------------------------------
# МЫШЬ
# ---------------------------------------------------------
def choose_tool(name):
global tool
tool = name
press_button(name)
if name == "water":
set_message("Выбрана лейка", "Нажмите на растение")
elif name == "seeds":
set_message("Выбрано: " + crop_title[selected_crop],
"Семян: " + str(seed_count[selected_crop]))
elif name == "shovel":
set_message("Выбрана лопата", "Нажмите на грядку")
elif name == "harvest":
set_message("Выбран урожай", "Нажмите на готовую грядку")
def on_mouse_down(pos):
global mode
if mode == "game":
if settings_button.collidepoint(pos):
mode = "pause"
return
if button_water.collidepoint(pos):
choose_tool("water")
return
if button_seeds.collidepoint(pos):
if tool == "seeds":
cycle_crop()
else:
choose_tool("seeds")
return
if button_shovel.collidepoint(pos):
choose_tool("shovel")
return
if button_harvest.collidepoint(pos):
choose_tool("harvest")
harvest_sound.play()
return
if button_shop.collidepoint(pos):
mode = "shop"
return
if harvest_big.collidepoint(pos):
count = harvest_all()
if count > 0:
harvest_sound.play()
press_button("harvest_all")
return
for panel in resource_panels:
if panel.collidepoint(pos):
mode = "shop"
return
for index in range(len(beds)):
if beds[index].collidepoint(pos):
if tool == "seeds":
if plant_seed(index):
plant_sound.play()
elif tool == "water":
if water_bed(index):
sounds.water.play()
elif tool == "shovel":
clear_bed(index)
elif tool == "harvest":
if harvest_bed(index):
harvest_sound.play()
return
elif mode == "shop":
if close_button.collidepoint(pos):
mode = "game"
return
for index in range(len(shop_rows)):
if shop_rows[index].collidepoint(pos):
buy_item(shop_items[index])
return
elif mode == "pause":
if close_button.collidepoint(pos) or pause_continue.collidepoint(pos):
mode = "game"
return
if pause_restart.collidepoint(pos):
new_game()
return
elif mode == "win":
if win_restart.collidepoint(pos):
new_game()
new_game()
pgzrun.go()