Исправления:
1. Игровой процесс + сохраняетсяв базу данных + после успешного прохождения уровня всплывает окно победы, после нажатия на кнопку "следующий уровень" появляется обратный отсчёт и начинается следующий уровень, карта обновляется.
This commit is contained in:
parent
5d34162267
commit
57f7c09541
6 changed files with 2762 additions and 54 deletions
Binary file not shown.
|
|
@ -323,5 +323,19 @@ def update_question(question_id, text, helpful_info):
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
session.rollback()
|
session.rollback()
|
||||||
return False, f"Ошибка при обновлении: {e}"
|
return False, f"Ошибка при обновлении: {e}"
|
||||||
|
finally:
|
||||||
|
session.close()
|
||||||
|
|
||||||
|
def update_user_level(user_id, new_level):
|
||||||
|
"""Обновляет уровень пользователя в базе данных."""
|
||||||
|
session = get_session()
|
||||||
|
try:
|
||||||
|
user = session.query(Users).filter_by(user_id=user_id).first()
|
||||||
|
if user and user.level < new_level:
|
||||||
|
user.level = new_level
|
||||||
|
session.commit()
|
||||||
|
except Exception as e:
|
||||||
|
session.rollback()
|
||||||
|
logging.error(f"Ошибка при обновлении уровня пользователя: {e}")
|
||||||
finally:
|
finally:
|
||||||
session.close()
|
session.close()
|
||||||
|
|
@ -1,31 +1,44 @@
|
||||||
import logging
|
import logging
|
||||||
from sqlalchemy import func
|
|
||||||
from database.db_events import get_user_progress
|
from database.db_events import get_user_progress
|
||||||
from database.db_session import get_session
|
from database.db_session import get_session
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
|
||||||
from database.models import GameSession
|
from database.models import GameSession
|
||||||
|
|
||||||
|
|
||||||
def save_game_session(user_id, level, score, steps, duration=0, health=100, hunger=0, sleepiness=0):
|
def save_game_session(user_id, level, score, duration, steps, health, hunger, sleepiness):
|
||||||
"""Сохранение игрового прогресса."""
|
"""Сохранение игрового прогресса с обновлением существующей записи."""
|
||||||
session = get_session()
|
session = get_session() # Получаем сессию для работы с базой данных
|
||||||
try:
|
try:
|
||||||
session.add(GameSession(
|
# Проверяем, существует ли уже запись для данного пользователя и уровня
|
||||||
user_id=user_id,
|
existing_session = session.query(GameSession).filter_by(user_id=user_id, level=level).first()
|
||||||
level=level,
|
if existing_session:
|
||||||
score=score,
|
logging.info(f"Обновление прогресса для user_id={user_id}, level={level}.")
|
||||||
steps=steps,
|
existing_session.score = score
|
||||||
duration=duration,
|
existing_session.duration = duration
|
||||||
health=health,
|
existing_session.steps = steps
|
||||||
hunger=hunger,
|
existing_session.health = health
|
||||||
sleepiness=sleepiness
|
existing_session.hunger = hunger
|
||||||
))
|
existing_session.sleepiness = sleepiness
|
||||||
session.commit()
|
else:
|
||||||
logging.info(f"Сессия сохранена: user_id={user_id}, level={level}, score={score}")
|
# Если записи нет, создаем новую
|
||||||
|
new_session = GameSession(
|
||||||
|
user_id=user_id,
|
||||||
|
level=level,
|
||||||
|
score=score,
|
||||||
|
duration=duration,
|
||||||
|
steps=steps,
|
||||||
|
health=health,
|
||||||
|
hunger=hunger,
|
||||||
|
sleepiness=sleepiness
|
||||||
|
)
|
||||||
|
session.add(new_session) # Добавляем в сессию
|
||||||
|
session.commit() # Сохраняем изменения в базе данных
|
||||||
|
logging.info(f"Прогресс успешно сохранён: user_id={user_id}, level={level}, score={score}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
session.rollback()
|
session.rollback() # Откатываем изменения в случае ошибки
|
||||||
logging.error(f"Ошибка при сохранении игровой сессии: {e}")
|
logging.error(f"Ошибка при сохранении прогресса: {e}")
|
||||||
raise
|
finally:
|
||||||
|
session.close() # Закрываем сессию
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def print_user_progress(user_id):
|
def print_user_progress(user_id):
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ class GameSession(Base):
|
||||||
level = Column(Integer, nullable=False)
|
level = Column(Integer, nullable=False)
|
||||||
score = Column(Integer, default=0)
|
score = Column(Integer, default=0)
|
||||||
duration = Column(Integer) # Время игры в секундах
|
duration = Column(Integer) # Время игры в секундах
|
||||||
|
steps = Column(Integer, default=0) # Количество шагов
|
||||||
start_time = Column(DateTime, default=func.now())
|
start_time = Column(DateTime, default=func.now())
|
||||||
end_time = Column(DateTime, nullable=True)
|
end_time = Column(DateTime, nullable=True)
|
||||||
health = Column(Integer, default=100) # Здоровье
|
health = Column(Integer, default=100) # Здоровье
|
||||||
|
|
|
||||||
2641
logs/logfile.log
2641
logs/logfile.log
File diff suppressed because it is too large
Load diff
|
|
@ -4,7 +4,7 @@ from tkinter import messagebox
|
||||||
from PIL import Image, ImageTk
|
from PIL import Image, ImageTk
|
||||||
import random
|
import random
|
||||||
import logging
|
import logging
|
||||||
from database.db_events import get_user_by_id, get_user_progress, save_progress
|
from database.db_events import get_user_by_id, get_user_progress, save_progress, update_user_level
|
||||||
from database.info.GameSessions_table import save_game_session
|
from database.info.GameSessions_table import save_game_session
|
||||||
from src.user_functions.game_logs import setup_logging
|
from src.user_functions.game_logs import setup_logging
|
||||||
from config import DOG_CHARACTERS, DONE, BONE, BACKGROUND_GAME
|
from config import DOG_CHARACTERS, DONE, BONE, BACKGROUND_GAME
|
||||||
|
|
@ -150,6 +150,7 @@ class GameUI:
|
||||||
level_frame = tk.Frame(self.root, bg="#E5E5E5")
|
level_frame = tk.Frame(self.root, bg="#E5E5E5")
|
||||||
level_frame.place(relx=0.5, rely=0.5, anchor=tk.CENTER)
|
level_frame.place(relx=0.5, rely=0.5, anchor=tk.CENTER)
|
||||||
|
|
||||||
|
# Получаем обновлённый прогресс пользователя
|
||||||
progress = get_user_progress(self.user_id)
|
progress = get_user_progress(self.user_id)
|
||||||
completed_levels = {session.level for session in progress if session.score > 0}
|
completed_levels = {session.level for session in progress if session.score > 0}
|
||||||
self.max_unlocked_level = max(completed_levels) if completed_levels else 1
|
self.max_unlocked_level = max(completed_levels) if completed_levels else 1
|
||||||
|
|
@ -183,14 +184,18 @@ class GameUI:
|
||||||
def handle_level_selection(self, level):
|
def handle_level_selection(self, level):
|
||||||
"""Обработка выбора уровня."""
|
"""Обработка выбора уровня."""
|
||||||
if level in self.completed_levels:
|
if level in self.completed_levels:
|
||||||
|
# Если уровень завершён, предложить пройти заново
|
||||||
if messagebox.askyesno("Повторить уровень", f"Вы уже прошли уровень {level}. Хотите пройти его заново?"):
|
if messagebox.askyesno("Повторить уровень", f"Вы уже прошли уровень {level}. Хотите пройти его заново?"):
|
||||||
self.current_level = level
|
self.current_level = level
|
||||||
self.total_bones = 0
|
self.total_bones = 0 # Сбрасываем косточки
|
||||||
self.steps_taken = 0
|
self.steps_taken = 0 # Сбрасываем количество шагов
|
||||||
self.start_game()
|
self.dog_position = [1, 1] # Сбрасываем позицию собаки
|
||||||
|
self.bones_positions = self.generate_bones() # Генерация новых косточек
|
||||||
|
self.start_game() # Запуск уровня заново
|
||||||
elif level <= self.max_unlocked_level:
|
elif level <= self.max_unlocked_level:
|
||||||
|
# Запуск уровня, если он доступен
|
||||||
self.current_level = level
|
self.current_level = level
|
||||||
self.countdown()
|
self.countdown() # Обратный отсчёт перед началом уровня
|
||||||
else:
|
else:
|
||||||
messagebox.showinfo("Недоступно", "Пройдите предыдущие уровни, чтобы разблокировать этот.")
|
messagebox.showinfo("Недоступно", "Пройдите предыдущие уровни, чтобы разблокировать этот.")
|
||||||
|
|
||||||
|
|
@ -276,18 +281,28 @@ class GameUI:
|
||||||
self.bones_positions.remove(bone)
|
self.bones_positions.remove(bone)
|
||||||
self.total_bones += 1
|
self.total_bones += 1
|
||||||
|
|
||||||
# Сохранение прогресса
|
# Сохраняем прогресс
|
||||||
save_progress(self.user_id, self.current_level, self.total_bones, self.steps_taken, 100, 0, 0)
|
save_game_session(
|
||||||
|
user_id=self.user_id,
|
||||||
|
level=self.current_level,
|
||||||
|
score=self.total_bones,
|
||||||
|
duration=self.steps_taken, # Количество шагов как продолжительность
|
||||||
|
steps=self.steps_taken, # Сохраняем количество шагов
|
||||||
|
health=100,
|
||||||
|
hunger=0,
|
||||||
|
sleepiness=0
|
||||||
|
)
|
||||||
|
|
||||||
self.bones_label.config(text=f"{self.total_bones}")
|
self.bones_label.config(text=f"{self.total_bones}")
|
||||||
|
|
||||||
# Условие для победы
|
# Проверка на завершение уровня
|
||||||
target_bones = 10 * (2 ** (self.current_level - 1)) # Модифицируем целевое количество косточек
|
target_bones = 10 * (2 ** (self.current_level - 1))
|
||||||
if self.total_bones >= target_bones and not self.is_victory_screen_open:
|
if self.total_bones >= target_bones and not self.is_victory_screen_open:
|
||||||
self.show_victory_screen() # Показываем экран победы
|
self.show_victory_screen()
|
||||||
|
|
||||||
|
# Генерация дополнительных косточек, если нужно
|
||||||
if self.steps_taken % 10 == 0 and len(self.bones_positions) < self.max_bones_per_level:
|
if self.steps_taken % 10 == 0 and len(self.bones_positions) < self.max_bones_per_level:
|
||||||
self.bones_positions.extend(self.generate_bones()) # Генерация новых косточек, если нужно
|
self.bones_positions.extend(self.generate_bones())
|
||||||
|
|
||||||
def move_up(self, event):
|
def move_up(self, event):
|
||||||
"""Движение вверх."""
|
"""Движение вверх."""
|
||||||
|
|
@ -422,12 +437,37 @@ class GameUI:
|
||||||
self.is_victory_screen_open = True
|
self.is_victory_screen_open = True
|
||||||
self.is_game_active = False
|
self.is_game_active = False
|
||||||
|
|
||||||
|
# Сохраняем прогресс текущего уровня
|
||||||
|
save_game_session(
|
||||||
|
user_id=self.user_id,
|
||||||
|
level=self.current_level,
|
||||||
|
score=self.total_bones,
|
||||||
|
duration=self.steps_taken,
|
||||||
|
steps=self.steps_taken,
|
||||||
|
health=100,
|
||||||
|
hunger=0,
|
||||||
|
sleepiness=0
|
||||||
|
)
|
||||||
|
|
||||||
|
# Обновляем данные о разблокированном уровне
|
||||||
|
next_level = self.current_level + 1
|
||||||
|
update_user_level(self.user_id, next_level)
|
||||||
|
self.max_unlocked_level = max(self.max_unlocked_level, next_level)
|
||||||
|
|
||||||
|
# Открываем окно победы
|
||||||
victory_window = tk.Toplevel(self.root)
|
victory_window = tk.Toplevel(self.root)
|
||||||
victory_window.title("Ура, победа!")
|
victory_window.title("Уровень завершён!")
|
||||||
victory_window.geometry("800x600")
|
victory_window.geometry("800x600")
|
||||||
victory_window.configure(bg="#E5E5E5")
|
victory_window.configure(bg="#E5E5E5")
|
||||||
victory_window.grab_set()
|
victory_window.grab_set()
|
||||||
|
|
||||||
|
tk.Label(
|
||||||
|
victory_window,
|
||||||
|
text=f"Поздравляем! Уровень {self.current_level} завершён!",
|
||||||
|
font=("Comic Sans MS", 24),
|
||||||
|
bg="#E5E5E5"
|
||||||
|
).pack(pady=20)
|
||||||
|
|
||||||
# Изображение собаки
|
# Изображение собаки
|
||||||
dog_image = Image.open(DOG_CHARACTERS[self.selected_dog]["image"]).resize((200, 200), Image.Resampling.LANCZOS)
|
dog_image = Image.open(DOG_CHARACTERS[self.selected_dog]["image"]).resize((200, 200), Image.Resampling.LANCZOS)
|
||||||
dog_photo = ImageTk.PhotoImage(dog_image)
|
dog_photo = ImageTk.PhotoImage(dog_image)
|
||||||
|
|
@ -464,7 +504,7 @@ class GameUI:
|
||||||
bg="#4CAF50",
|
bg="#4CAF50",
|
||||||
command=lambda: [victory_window.destroy(), self.start_next_level()]
|
command=lambda: [victory_window.destroy(), self.start_next_level()]
|
||||||
)
|
)
|
||||||
next_level_button.place(relx=0.5, rely=0.65, anchor=tk.CENTER)
|
next_level_button.place(relx=0.5, rely=0.7, anchor=tk.CENTER)
|
||||||
|
|
||||||
# Кнопка выхода в главное меню
|
# Кнопка выхода в главное меню
|
||||||
exit_button = tk.Button(
|
exit_button = tk.Button(
|
||||||
|
|
@ -492,28 +532,27 @@ class GameUI:
|
||||||
self.show_main_menu() # Переходим в главное меню
|
self.show_main_menu() # Переходим в главное меню
|
||||||
|
|
||||||
def start_next_level(self):
|
def start_next_level(self):
|
||||||
"""Переход на следующий уровень."""
|
"""Запуск следующего уровня."""
|
||||||
try:
|
self.current_level += 1 # Переход на следующий уровень
|
||||||
# Сохранение текущего прогресса
|
self.total_bones = 0 # Сброс собранных косточек
|
||||||
self.save_progress()
|
self.steps_taken = 0 # Сброс количества шагов
|
||||||
|
self.dog_position = [1, 1] # Возвращаем собаку в начальную позицию
|
||||||
|
self.bones_positions = [] # Очищаем косточки
|
||||||
|
self.is_victory_screen_open = False # Закрываем экран победы, если он был открыт
|
||||||
|
|
||||||
# Переход на следующий уровень
|
# Сохраняем новый прогресс в базу данных
|
||||||
self.current_level += 1
|
save_game_session(
|
||||||
self.max_unlocked_level = max(self.max_unlocked_level, self.current_level)
|
user_id=self.user_id,
|
||||||
|
level=self.current_level,
|
||||||
# Сброс состояния игры: собака возвращается в начальную позицию
|
score=0,
|
||||||
self.total_bones = 0
|
duration=0,
|
||||||
self.steps_taken = 0
|
steps=0,
|
||||||
self.dog_position = [1, 1] # Начальная позиция собаки
|
health=100,
|
||||||
self.bones_positions = [] # Очищаем текущие косточки
|
hunger=0,
|
||||||
|
sleepiness=0
|
||||||
# Генерация новых косточек с увеличением их количества по геометрической прогрессии
|
)
|
||||||
self.bones_positions = self.generate_bones()
|
logging.info(f"Запуск уровня {self.current_level}.")
|
||||||
|
self.countdown() # Запускаем обратный отсчёт перед началом уровня
|
||||||
# Начинаем новый уровень с обратным отсчётом
|
|
||||||
self.countdown() # Запуск обратного отсчёта
|
|
||||||
except Exception as e:
|
|
||||||
logging.error(f"Ошибка при переходе на следующий уровень: {e}")
|
|
||||||
|
|
||||||
def save_progress(self):
|
def save_progress(self):
|
||||||
"""Сохранение игрового процесса в таблицу GameSessions."""
|
"""Сохранение игрового процесса в таблицу GameSessions."""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue