Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- # 海岛求生终极版(完整功能优化版)
- import tkinter as tk
- from tkinter import ttk, messagebox, filedialog
- import random
- from datetime import datetime, timedelta
- import os
- import json # 新增导入
- try:
- import pygame
- pygame.mixer.init()
- SOUND_ENABLED = True
- except (ImportError, ModuleNotFoundError):
- SOUND_ENABLED = False
- class IslandSurvivalGame:
- def __init__(self, root):
- self.root = root
- self.root.title("海岛求生-终极版")
- self.root.geometry("1100x800")
- self.root.configure(bg='#1a1a1a')
- self.init_styles()
- self.init_game_data()
- self.create_widgets()
- self.update_display()
- self.check_status()
- self.show_logs()
- # region 初始化部分
- def init_styles(self):
- self.style = ttk.Style()
- self.style.theme_use('clam')
- self.color = {
- 'bg': '#1a1a1a', 'fg': '#e0e0e0', 'secondary': '#2c3e50',
- 'progress': '#2ecc71', 'danger': '#e74c3c', 'warning': '#f39c12',
- 'log_bg': '#2c3e50', 'log_fg': '#bdc3c7'
- }
- self.style.configure('.', background=self.color['bg'], foreground=self.color['fg'], font=('微软雅黑', 10))
- self.style.configure("TProgressbar", thickness=20, troughcolor='#34495e', background=self.color['progress'])
- self.style.configure('Dark.TFrame', background=self.color['secondary'])
- self.style.configure('Dark.TLabel', background=self.color['secondary'], foreground='white')
- self.style.configure('Action.TButton', font=('微软雅黑', 11, 'bold'), padding=10, background='#34495e', foreground='white')
- self.style.configure('Dark.Treeview', background='#2c3e50', foreground='#bdc3c7', fieldbackground='#2c3e50')
- self.style.map('Dark.Treeview', background=[('selected', '#3498db')])
- def init_game_data(self):
- self.resources = {'木材':5, '淡水':3, '食物':2, '石头':0, '种子':0, '鱼':0}
- self.base_levels = {'住所':1, '工具':1, '防御':1, '农田':0}
- self.areas = ["沙滩", "棕榈树林", "岩石海岸", "淡水溪流", "山洞", "丛林深处", "废弃营地"]
- self.current_area_idx = 0
- self.farm = {'planted':False, 'growth_stage':0.0, 'crop_type':None}
- self.health = 100.0
- self.stamina = 80.0
- self.game_start_time = datetime(2023, 1, 1, 6, 0)
- self.current_time = self.game_start_time
- self.seasons = {
- 1:"❄️冬季",2:"❄️冬季",3:"🌸春季",4:"🌸春季",5:"🌸春季",
- 6:"☀️夏季",7:"☀️夏季",8:"☀️夏季",9:"🍂秋季",10:"🍂秋季",11:"🍂秋季",12:"❄️冬季"
- }
- self.log_types = ['全部', '收集', '建造', '种植', '危险', '系统']
- self.current_filter = '全部'
- self.log_buffer = []
- self.max_log_lines = 100
- @property
- def current_area(self):
- return self.areas[self.current_area_idx]
- # endregion
- # region 界面创建
- def create_widgets(self):
- # 时间面板
- time_frame = ttk.Frame(self.root, style='Dark.TFrame')
- time_frame.pack(fill=tk.X, pady=(0, 10))
- self.time_label = ttk.Label(time_frame, font=('微软雅黑', 10, 'bold'), style='Dark.TLabel')
- self.time_label.pack(side=tk.LEFT, padx=15)
- self.season_label = ttk.Label(time_frame, font=('微软雅黑', 10, 'bold'), style='Dark.TLabel')
- self.season_label.pack(side=tk.RIGHT, padx=15)
- # 主界面
- main_frame = ttk.Frame(self.root)
- main_frame.pack(pady=10, fill=tk.BOTH, expand=True)
- # 场景区域
- scene_frame = ttk.LabelFrame(main_frame, text="当前区域", style='Dark.TLabelframe')
- scene_frame.pack(side=tk.LEFT, padx=15, fill=tk.BOTH, expand=True)
- self.area_name_label = ttk.Label(scene_frame, font=('微软雅黑', 12, 'bold'),
- style='Dark.TLabel', foreground='#e67e22')
- self.area_name_label.pack(pady=5)
- scene_control = ttk.Frame(scene_frame)
- scene_control.pack(fill=tk.BOTH, expand=True)
- self.btn_prev = ttk.Button(scene_control, text="《", command=self.prev_area, style='Action.TButton', width=3)
- self.btn_prev.pack(side=tk.LEFT, fill=tk.Y)
- self.scene_ascii = ttk.Label(scene_control, font=('Courier New', 14, 'bold'), foreground='#7f8c8d', anchor=tk.CENTER)
- self.scene_ascii.pack(side=tk.LEFT, expand=True, fill=tk.BOTH)
- self.btn_next = ttk.Button(scene_control, text="》", command=self.next_area, style='Action.TButton', width=3)
- self.btn_next.pack(side=tk.RIGHT, fill=tk.Y)
- self.resource_info_label = ttk.Label(scene_frame, font=('微软雅黑', 10),
- style='Dark.TLabel', foreground='#2ecc71')
- self.resource_info_label.pack(pady=5)
- status_frame = ttk.LabelFrame(main_frame, text="生存状态", style='Dark.TLabelframe')
- status_frame.pack(side=tk.RIGHT, padx=15, fill=tk.Y)
- ttk.Label(status_frame, text="健康值:").grid(row=0, column=0, sticky=tk.W)
- self.health_bar = ttk.Progressbar(status_frame, length=200)
- self.health_bar.grid(row=0, column=1, pady=5)
- ttk.Label(status_frame, text="体力值:").grid(row=1, column=0, sticky=tk.W)
- self.stamina_bar = ttk.Progressbar(status_frame, length=200)
- self.stamina_bar.grid(row=1, column=1, pady=5)
- self.resource_labels = {}
- for idx, (text, key) in enumerate([('🪵 木材','木材'),('💧 淡水','淡水'),('🍎 食物','食物'),
- ('🐟 鱼','鱼'),('🪨 石头','石头'),('🌾 种子','种子')]):
- ttk.Label(status_frame, text=text).grid(row=idx+2, column=0, sticky=tk.W)
- self.resource_labels[key] = ttk.Label(status_frame)
- self.resource_labels[key].grid(row=idx+2, column=1, sticky=tk.E)
- action_frame = ttk.Frame(self.root)
- action_frame.pack(pady=15, fill=tk.X)
- button_config = [
- ("🪓 收集", self.gather_resources), ("🏗️ 建造", self.show_build),
- ("🌱 种植", self.show_farm), ("💤 休息", self.rest),
- ("📜 日志", self.show_logs), ("📦 库存", self.show_inventory)
- ]
- for text, cmd in button_config:
- ttk.Button(action_frame, text=text, command=cmd, style='Action.TButton').pack(side=tk.LEFT, padx=8)
- self.info_frame = ttk.LabelFrame(self.root, style='Dark.TLabelframe')
- self.info_frame.pack(pady=10, fill=tk.BOTH, expand=True)
- self.create_log_panel()
- self.create_inventory_panel()
- self.create_build_panel()
- self.create_farm_panel()
- def create_log_panel(self):
- self.log_panel = ttk.Frame(self.info_frame)
- log_control = ttk.Frame(self.log_panel)
- log_control.pack(fill=tk.X)
- ttk.Label(log_control, text="日志类型:").pack(side=tk.LEFT)
- self.filter_combo = ttk.Combobox(log_control, values=self.log_types, state='readonly')
- self.filter_combo.current(0)
- self.filter_combo.pack(side=tk.LEFT, padx=5)
- self.filter_combo.bind('<<ComboboxSelected>>', self.apply_log_filter)
- ttk.Button(log_control, text="保存存档", command=self.save_game).pack(side=tk.RIGHT)
- ttk.Button(log_control, text="加载存档", command=self.load_game).pack(side=tk.RIGHT, padx=5)
- self.log_text = tk.Text(self.log_panel, wrap=tk.WORD, state='disabled', bg=self.color['log_bg'],
- fg=self.color['log_fg'], font=('Consolas', 9))
- scrollbar = ttk.Scrollbar(self.log_panel, command=self.log_text.yview)
- self.log_text.configure(yscrollcommand=scrollbar.set)
- scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
- self.log_text.pack(fill=tk.BOTH, expand=True)
- def create_inventory_panel(self):
- self.inventory_panel = ttk.Frame(self.info_frame)
- columns = ('资源', '数量')
- self.inventory_tree = ttk.Treeview(
- self.inventory_panel,
- columns=columns,
- show='headings',
- selectmode='none',
- style='Dark.Treeview'
- )
- for col in columns:
- self.inventory_tree.heading(col, text=col, anchor=tk.CENTER)
- self.inventory_tree.column(col, width=120, anchor=tk.CENTER)
- scrollbar = ttk.Scrollbar(self.inventory_panel, command=self.inventory_tree.yview)
- self.inventory_tree.configure(yscrollcommand=scrollbar.set)
- scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
- self.inventory_tree.pack(fill=tk.BOTH, expand=True)
- def create_build_panel(self):
- self.build_panel = ttk.Frame(self.info_frame)
- status_frame = ttk.Frame(self.build_panel)
- status_frame.pack(fill=tk.X, pady=5)
- self.build_status_labels = {}
- buildings = [
- ("住所", "提高休息恢复效率", "每级增加10%体力恢复"),
- ("工具", "提升收集效率", "每级增加20%收集量"),
- ("防御", "减少遭遇危险概率", "每级减少15%危险几率"),
- ("农田", "解锁种植功能", "1级解锁基础种植")
- ]
- for idx, (name, effect, detail) in enumerate(buildings):
- frame = ttk.Frame(status_frame)
- frame.grid(row=0, column=idx, padx=10)
- ttk.Label(frame, text=f"🏗️ {name}", font=("微软雅黑", 10, "bold")).pack()
- self.build_status_labels[name] = ttk.Label(frame, text="等级 0")
- self.build_status_labels[name].pack()
- ttk.Label(frame, text=detail, foreground="#888").pack()
- self.build_tree_frame = ttk.Frame(self.build_panel)
- self.build_tree_frame.pack(fill=tk.BOTH, expand=True, pady=10)
- def create_farm_panel(self):
- self.farm_panel = ttk.Frame(self.info_frame)
- self.farm_status_frame = ttk.Frame(self.farm_panel)
- self.farm_status_frame.pack(fill=tk.X, pady=5)
- self.farm_status_labels = {
- 'crop': ttk.Label(self.farm_status_frame, text="当前作物:无", font=("微软雅黑", 10)),
- 'growth': ttk.Label(self.farm_status_frame, text="生长阶段:0/3", font=("微软雅黑", 10)),
- 'effect': ttk.Label(self.farm_status_frame, text="农田等级:0", font=("微软雅黑", 10))
- }
- for label in self.farm_status_labels.values():
- label.pack(side=tk.LEFT, padx=15)
- self.farm_action_frame = ttk.Frame(self.farm_panel)
- self.farm_action_frame.pack(fill=tk.BOTH, expand=True)
- # endregion
- # region 核心游戏逻辑
- def prev_area(self):
- self.current_area_idx = (self.current_area_idx - 1) % len(self.areas)
- self.add_time(0.5)
- self.update_display()
- def next_area(self):
- self.current_area_idx = (self.current_area_idx + 1) % len(self.areas)
- self.add_time(0.5)
- self.update_display()
- def generate_scene_art(self):
- scenes = {
- "沙滩": "╔══════════════════╗\n║ ________║\n║ (🌴 🏖️ 🐚) ║\n║  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄║\n╚══════════════════╝",
- "棕榈树林": "╔══════════════════╗\n║ \\ | / ║\n║ '-.O.-' ║\n║ / | \\ ║\n╚══════════════════╝",
- "岩石海岸": "╔══════════════════╗\n║ ░░░░░▄▄▄▄▄▄▄▄▄ ║\n║ ░░▄███████████▄ ║\n╚══════════════════╝",
- "淡水溪流": "╔══════════════════╗\n║ ~ ~ ~ ~ ~ ~ ║\n║~ ~ ~ ~ ║\n╚══════════════════╝",
- "山洞": "╔══════════════════╗\n║ /\\ ║\n║ / \\ 🕳️ ║\n║ /____\\_________ ║\n╚══════════════════╝",
- "丛林深处": "╔══════════════════╗\n║ ▒▒▒▒▒▒▒▒▒▒▒▒ ║\n║ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ║\n╚══════════════════╝",
- "废弃营地": "╔══════════════════╗\n║ ░░▄▀▄▀▀▀▀▄▀▄░░ ║\n║ ░█░░░░░░░░▀▄░ ║\n╚══════════════════╝"
- }
- return scenes.get(self.current_area, "未知区域")
- def get_area_resources_info(self):
- resource_map = {
- "沙滩": {'木材': (1,3), '鱼': (1,2)},
- "棕榈树林": {'木材': (2,4), '食物': (1,2)},
- "岩石海岸": {'食物': (1,2), '石头': (1,3)},
- "淡水溪流": {'淡水': (2,5)},
- "山洞": {'石头': (3,5)},
- "丛林深处": {'木材': (3,5), '食物': (1,3), '种子': (1,2)},
- "废弃营地": {'木材': (1,4), '淡水': (1,3), '食物': (1,3),
- '石头': (1,2), '种子': (1,3)}
- }
- current_res = resource_map.get(self.current_area, {})
- return " | ".join([f"{k}({v[0]}-{v[1]})" for k,v in current_res.items()]) if current_res else "该区域没有可收集资源"
- def add_time(self, hours):
- original_date = self.current_time.date()
- self.current_time += timedelta(hours=hours)
- # 实时状态消耗
- self.health = max(0, self.health - 0.2 * hours)
- self.stamina = max(0, self.stamina - 0.5 * hours)
- # 实时作物生长
- if self.farm['planted'] and self.base_levels['农田'] > 0:
- season_factor = 1.5 if self.seasons[self.current_time.month] == "🌸春季" else 1.0
- growth = hours * 0.125 * season_factor
- prev_stage = int(self.farm['growth_stage'])
- self.farm['growth_stage'] = min(3, self.farm['growth_stage'] + growth)
- if int(self.farm['growth_stage']) > prev_stage:
- self.add_log(f"作物进入第{int(self.farm['growth_stage'])}阶段", "#2ecc71", '种植')
- if self.current_time.date() != original_date:
- self.daily_update()
- # 新增状态刷新
- self.refresh_farm_panel()
- self.update_display()
- def daily_update(self):
- if random.random() <0.3 and self.resources['食物']>0:
- lost = random.randint(1,2)
- self.resources['食物'] = max(0, self.resources['食物'] - lost)
- self.add_log(f"食物腐败损失{lost}单位", "#e67e22", '系统')
- self.refresh_inventory()
- def gather_resources(self):
- if self.stamina < 20:
- self.add_log("体力不足!需要至少20体力才能收集", "#e74c3c", '危险')
- return
- self.add_time(2)
- self.stamina = max(0, self.stamina - 20)
- resource_map = {
- "沙滩": {'木材':(1,3), '鱼':(1,2)},
- "棕榈树林": {'木材':(2,4), '食物':(1,2)},
- "岩石海岸": {'食物':(1,2), '石头':(1,3)},
- "淡水溪流": {'淡水':(2,5)},
- "山洞": {'石头':(3,5)},
- "丛林深处": {'木材':(3,5), '食物':(1,3), '种子':(1,2)},
- "废弃营地": {'木材':(1,4), '淡水':(1,3), '食物':(1,3), '石头':(1,2), '种子':(1,3)}
- }
- season_bonus = 1.15 if self.seasons[self.current_time.month] == "🍂秋季" else 1.0
- gains = {}
- for res, rng in resource_map.get(self.current_area, {}).items():
- base_gain = random.randint(rng[0], rng[1])
- gain = int(round(base_gain * season_bonus * self.base_levels['工具']))
- gains[res] = gains.get(res, 0) + gain
- self.resources[res] = max(0, self.resources[res] + gain)
- self.add_log("收集获得:" + " ".join([f"{k}×{v}" for k,v in gains.items()]), "#2ecc71", '收集')
- self.refresh_inventory()
- if random.random() < 0.35:
- self.handle_danger()
- def handle_danger(self):
- dangers = [
- ("🐍 毒蛇袭击!", "需要消耗1食物治疗", '食物', 1),
- ("🌧️ 暴雨来袭!", "需要消耗2木材生火", '木材', 2),
- ("🌴 树木倒塌!", "需要消耗1石头制作工具", '石头', 1)
- ]
- danger = random.choice(dangers)
- res_type = danger[2]
- res_cost = danger[3]
- if self.resources[res_type] >= res_cost:
- self.resources[res_type] = max(0, self.resources[res_type] - res_cost)
- health_loss = random.randint(5, 15)
- self.health = max(0, self.health - health_loss)
- self.add_log(f"{danger[0]} {danger[1]},处理成功!(健康-{health_loss})", "#2ecc71", '危险')
- else:
- health_loss = random.randint(25, 35)
- self.health = max(0, self.health - health_loss)
- self.add_log(f"{danger[0]} 资源不足{danger[1]},处理失败!(健康-{health_loss})", "#e74c3c", '危险')
- self.refresh_inventory()
- self.update_display()
- def check_status(self):
- if self.health <= 0:
- messagebox.showinfo("游戏结束", "你的健康状况恶化,没能生存下去...")
- self.root.destroy()
- elif all(v >=50 for v in self.resources.values()) and self.base_levels['住所'] >=3:
- messagebox.showinfo("胜利", "你成功建造了坚固的避难所,生存希望大增!")
- self.root.destroy()
- def rest(self):
- if self.resources['鱼'] <= 0 and self.resources['食物'] <= 0:
- messagebox.showwarning("无法休息", "需要至少1单位鱼或食物才能休息!")
- return
- self.add_time(8)
- self.stamina = min(100, self.stamina + 30 + self.base_levels['住所']*10)
- if self.resources['鱼'] > 0:
- self.resources['鱼'] = max(0, self.resources['鱼'] - 1)
- health_gain = 15
- else:
- self.resources['食物'] = max(0, self.resources['食物'] - 1)
- health_gain = 10
- self.health = min(100, self.health + health_gain)
- self.add_log(f"休息恢复体力", "#3498db", '系统')
- self.refresh_inventory()
- self.update_display()
- def build_project(self, cost, name):
- level_map = {"升级住所":"住所", "制作工具":"工具", "建造防御":"防御", "开辟农田":"农田"}
- key = level_map[name]
- if all(self.resources[k] >= v for k,v in cost.items()):
- self.add_time(4)
- for k,v in cost.items():
- self.resources[k] = max(0, self.resources[k] - v)
- self.base_levels[key] += 1
- self.add_log(f"{name}建造完成!", "#9b59b6", '建造')
- self.refresh_inventory()
- self.refresh_build_panel()
- if key == "农田":
- self.refresh_farm_panel()
- self.update_display()
- else:
- messagebox.showerror("资源不足", "缺少必要资源!")
- def plant_crop(self, crop_type, seeds_needed):
- if self.resources['种子'] < seeds_needed:
- messagebox.showwarning("种子不足", f"需要{seeds_needed}个种子!")
- return
- self.add_time(1)
- self.resources['种子'] = max(0, self.resources['种子'] - seeds_needed)
- self.farm.update(planted=True, growth_stage=0.0, crop_type=crop_type)
- self.add_log(f"种植{crop_type}成功", "#2ecc71", '种植')
- self.refresh_inventory()
- self.refresh_farm_panel() # 立即刷新农田状态
- def harvest_crop(self):
- base_yield = 5 if self.farm['crop_type'] == "普通作物" else 15
- total = base_yield + self.base_levels['工具']*2 + self.base_levels['农田']*3
- self.resources['食物'] = max(0, self.resources['食物'] + total)
- self.farm['planted'] = False
- self.add_log(f"收获{total}单位食物", "#f1c40f", '种植')
- self.refresh_inventory()
- self.refresh_farm_panel()
- # endregion
- # region 界面更新方法
- def refresh_inventory(self):
- self.inventory_tree.delete(*self.inventory_tree.get_children())
- for item, qty in self.resources.items():
- self.inventory_tree.insert('', 'end', values=(item, qty))
- def refresh_build_panel(self):
- level_map = {
- "住所": self.base_levels['住所'],
- "工具": self.base_levels['工具'],
- "防御": self.base_levels['防御'],
- "农田": self.base_levels['农田']
- }
- for name, label in self.build_status_labels.items():
- current_level = level_map.get(name, 0)
- label.config(text=f"等级 {current_level}")
- for widget in self.build_tree_frame.winfo_children():
- widget.destroy()
- projects = [
- ("升级住所", {"木材":15, "石头":10}, "提高休息恢复效率", self.base_levels['住所'] < 5),
- ("制作工具", {"木材":8, "石头":5}, "提升收集效率", self.base_levels['工具'] < 3),
- ("建造防御", {"木材":20, "石头":15}, "减少遭遇危险概率", self.base_levels['防御'] < 3),
- ("开辟农田", {"木材":25, "石头":10}, "解锁种植功能", self.base_levels['农田'] == 0)
- ]
- for name, cost, desc, condition in projects:
- if not condition: continue
- frame = ttk.Frame(self.build_tree_frame)
- frame.pack(pady=5, fill=tk.X, padx=10)
- ttk.Label(frame, text=name, width=15, anchor=tk.W).pack(side=tk.LEFT)
- ttk.Label(frame, text=desc, width=25, foreground="#888").pack(side=tk.LEFT)
- ttk.Label(frame, text=" ".join([f"{k}×{v}" for k,v in cost.items()]),
- width=15, foreground="#e67e22").pack(side=tk.LEFT)
- ttk.Button(frame, text="建造", width=8,
- command=lambda c=cost.copy(),n=name: self.build_project(c,n)).pack(side=tk.RIGHT)
- def refresh_farm_panel(self):
- self.farm_status_labels['crop'].config(
- text=f"当前作物:{self.farm['crop_type'] or '无'}")
- self.farm_status_labels['growth'].config(
- text=f"生长阶段:{self.farm['growth_stage']:.1f}/3")
- self.farm_status_labels['effect'].config(
- text=f"农田等级:{self.base_levels['农田']}(每级+20%产量)")
- for widget in self.farm_action_frame.winfo_children():
- widget.destroy()
- if self.base_levels['农田'] == 0:
- ttk.Label(self.farm_action_frame,
- text="需要先建造农田才能种植!",
- foreground="#e74c3c").pack(pady=20)
- return
- if self.farm['planted']:
- if self.farm['growth_stage'] >= 3:
- ttk.Button(self.farm_action_frame, text="🪴 收获作物",
- command=self.harvest_crop,
- style='Action.TButton').pack(pady=15)
- else:
- ttk.Label(self.farm_action_frame,
- text="作物生长中,请耐心等待...",
- foreground="#2ecc71").pack(pady=15)
- else:
- ttk.Label(self.farm_action_frame,
- text="选择要种植的作物:",
- font=("微软雅黑", 11)).pack(pady=10)
- crop_frame = ttk.Frame(self.farm_action_frame)
- crop_frame.pack()
- if self.resources['种子'] >=1:
- ttk.Button(crop_frame, text="🌾 普通作物\n(需要1种子)",
- command=lambda: self.plant_crop("普通作物",1),
- width=15,
- style='Action.TButton').pack(side=tk.LEFT, padx=10)
- if self.resources['种子'] >=3:
- ttk.Button(crop_frame, text="🎃 高产作物\n(需要3种子)",
- command=lambda: self.plant_crop("高产作物",3),
- width=15,
- style='Action.TButton').pack(side=tk.LEFT, padx=10)
- def update_display(self):
- self.area_name_label.config(text=f"🏝️ {self.current_area}")
- self.resource_info_label.config(text=self.get_area_resources_info())
- self.scene_ascii.config(text=self.generate_scene_art())
- self.time_label.config(text=f"🕒 {self.current_time.strftime('%Y年%m月%d日 %H:%M')}")
- self.season_label.config(text=f"🌡️ {self.seasons[self.current_time.month]}")
- self.health_bar['value'] = self.health
- self.stamina_bar['value'] = self.stamina
- for key, label in self.resource_labels.items():
- label.config(text=str(self.resources[key]))
- self.check_status()
- def show_logs(self):
- self.hide_all_panels()
- self.log_panel.pack(fill=tk.BOTH, expand=True)
- self.info_frame.configure(text="生存日志")
- def show_inventory(self):
- self.hide_all_panels()
- self.inventory_panel.pack(fill=tk.BOTH, expand=True)
- self.info_frame.configure(text="库存信息")
- self.refresh_inventory()
- def show_build(self):
- self.hide_all_panels()
- self.build_panel.pack(fill=tk.BOTH, expand=True)
- self.info_frame.configure(text="基地建设")
- self.refresh_build_panel()
- def show_farm(self):
- self.hide_all_panels()
- self.farm_panel.pack(fill=tk.BOTH, expand=True)
- self.info_frame.configure(text="农田管理")
- self.refresh_farm_panel()
- def hide_all_panels(self):
- for panel in [self.log_panel, self.inventory_panel, self.build_panel, self.farm_panel]:
- panel.pack_forget()
- # endregion
- # region 存档系统
- def save_game(self):
- filepath = filedialog.asksaveasfilename(
- defaultextension=".sav",
- filetypes=[("存档文件", "*.sav")]
- )
- if filepath:
- try:
- # 获取当前日志内容
- self.log_text.configure(state='normal')
- logs = self.log_text.get(1.0, "end-1c")
- self.log_text.configure(state='disabled')
- save_data = {
- 'resources': self.resources,
- 'base_levels': self.base_levels,
- 'current_area_idx': self.current_area_idx,
- 'farm': self.farm,
- 'health': self.health,
- 'stamina': self.stamina,
- 'current_time': self.current_time.isoformat(),
- 'log_buffer': self.log_buffer,
- 'logs': logs
- }
- with open(filepath, 'w', encoding='utf-8') as f:
- json.dump(save_data, f, ensure_ascii=False, indent=2)
- self.add_log("游戏存档保存成功", "#27ae60", '系统')
- except Exception as e:
- messagebox.showerror("保存失败", f"无法保存存档: {str(e)}")
- def load_game(self):
- filepath = filedialog.askopenfilename(
- filetypes=[("存档文件", "*.sav")]
- )
- if filepath:
- try:
- with open(filepath, 'r', encoding='utf-8') as f:
- save_data = json.load(f)
- # 恢复游戏状态
- self.resources = save_data['resources']
- self.base_levels = save_data['base_levels']
- self.current_area_idx = save_data['current_area_idx']
- self.farm = save_data['farm']
- self.health = save_data['health']
- self.stamina = save_data['stamina']
- self.current_time = datetime.fromisoformat(save_data['current_time'])
- self.log_buffer = save_data['log_buffer']
- # 恢复日志显示
- self.log_text.configure(state='normal')
- self.log_text.delete(1.0, 'end')
- self.log_text.insert('end', save_data['logs'])
- self.log_text.configure(state='disabled')
- # 刷新所有界面
- self.update_display()
- self.refresh_inventory()
- self.refresh_build_panel()
- self.refresh_farm_panel()
- self.apply_log_filter()
- self.add_log(f"成功加载存档:{os.path.basename(filepath)}", "#2980b9", '系统')
- except Exception as e:
- messagebox.showerror("加载失败", f"无效的存档文件: {str(e)}")
- # endregion
- # region 日志系统
- def add_log(self, message, color="#bdc3c7", log_type='系统'):
- timestamp = self.current_time.strftime("[%m-%d %H:%M]")
- self.log_text.configure(state='normal')
- self.log_text.insert('end', f"{timestamp} {message}\n")
- line_num = int(self.log_text.index('end-1c').split('.')[0])
- self.log_buffer.append({'start':f"{line_num}.0", 'end':f"{line_num+1}.0", 'type':log_type})
- self.log_text.tag_add(log_type, "end-2l linestart", "end-1l lineend")
- self.log_text.tag_config(log_type, foreground=color)
- if line_num > self.max_log_lines: self.log_text.delete(1.0, "2.0")
- self.apply_log_filter()
- self.log_text.see('end')
- self.log_text.configure(state='disabled')
- if SOUND_ENABLED: self.play_sound(log_type)
- def apply_log_filter(self, event=None):
- filter_type = self.filter_combo.get()
- self.log_text.configure(state='normal')
- self.log_text.tag_remove('hidden', 1.0, 'end')
- if filter_type != '全部':
- for log in self.log_buffer:
- if log['type'] != filter_type:
- self.log_text.tag_add('hidden', log['start'], log['end'])
- self.log_text.tag_configure('hidden', elide=True)
- self.log_text.configure(state='disabled')
- def play_sound(self, log_type):
- sound_map = {'危险':'alert', '收集':'collect', '建造':'build', '系统':'system', '种植':'plant'}
- try:
- sound = pygame.mixer.Sound(f"sounds/{sound_map.get(log_type, 'default')}.wav")
- sound.set_volume(0.3)
- sound.play()
- except: pass
- # endregion
- if __name__ == "__main__":
- root = tk.Tk()
- game = IslandSurvivalGame(root)
- root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement