8.8 KiB
8.8 KiB
铲除作物功能实现
功能概述
实现了玩家可以花费500金钱铲除地块上的作物,将地块变成空地的功能。这个功能完全基于服务器端处理,确保数据的一致性和安全性。
功能特点
- 费用固定:铲除任何作物都需要花费500金钱
- 服务器验证:所有验证和处理都在服务器端完成
- 状态重置:铲除后地块变成空地,可以重新种植
- 访客保护:访客模式下无法进行铲除操作
- 实时更新:操作完成后立即更新客户端显示
实现架构
1. 服务器端实现
消息路由
elif message_type == "remove_crop":
return self._handle_remove_crop(client_id, message)
主处理方法
def _handle_remove_crop(self, client_id, message):
"""处理铲除作物请求"""
# 检查用户是否已登录
logged_in, response = self._check_user_logged_in(client_id, "铲除作物", "remove_crop")
if not logged_in:
return self.send_data(client_id, response)
# 获取玩家数据
player_data, username, response = self._load_player_data_with_check(client_id, "remove_crop")
if not player_data:
return self.send_data(client_id, response)
lot_index = message.get("lot_index", -1)
# 验证地块索引
if lot_index < 0 or lot_index >= len(player_data.get("farm_lots", [])):
return self._send_action_error(client_id, "remove_crop", "无效的地块索引")
lot = player_data["farm_lots"][lot_index]
# 检查地块状态
if not lot.get("is_planted", False) or not lot.get("crop_type", ""):
return self._send_action_error(client_id, "remove_crop", "此地块没有种植作物")
# 处理铲除
return self._process_crop_removal(client_id, player_data, username, lot, lot_index)
铲除处理逻辑
def _process_crop_removal(self, client_id, player_data, username, lot, lot_index):
"""处理铲除作物逻辑"""
# 铲除费用
removal_cost = 500
# 检查玩家金钱是否足够
if player_data["money"] < removal_cost:
return self._send_action_error(client_id, "remove_crop", f"金钱不足,铲除作物需要 {removal_cost} 金钱")
# 获取作物名称用于日志
crop_type = lot.get("crop_type", "未知作物")
# 执行铲除操作
player_data["money"] -= removal_cost
lot["is_planted"] = False
lot["crop_type"] = ""
lot["grow_time"] = 0
lot["is_dead"] = False # 重置死亡状态
# 保存玩家数据
self.save_player_data(username, player_data)
# 发送作物更新
self._push_crop_update_to_player(username, player_data)
self.log('INFO', f"玩家 {username} 铲除了地块 {lot_index} 的作物 {crop_type},花费 {removal_cost} 金钱", 'SERVER')
return self.send_data(client_id, {
"type": "action_response",
"action_type": "remove_crop",
"success": True,
"message": f"成功铲除作物 {crop_type},花费 {removal_cost} 金钱",
"updated_data": {
"money": player_data["money"],
"farm_lots": player_data["farm_lots"]
}
})
2. 网络通信
客户端发送请求
#发送铲除作物信息
func sendRemoveCrop(lot_index):
if not client.is_client_connected():
return false
client.send_data({
"type": "remove_crop",
"lot_index": lot_index,
"timestamp": Time.get_unix_time_from_system()
})
return true
3. 客户端UI实现
按钮文本更新
# 更新按钮文本
func _update_button_texts():
dig_button.text = "开垦"+"\n花费:"+str(main_game.dig_money)
remove_button.text = "铲除"+"\n花费:500"
铲除操作处理
#铲除
func _on_remove_button_pressed():
# 检查是否处于访问模式
if main_game.is_visiting_mode:
Toast.show("访问模式下无法铲除作物", Color.ORANGE, 2.0, 1.0)
self.hide()
return
# 检查玩家金钱是否足够
var removal_cost = 500
if main_game.money < removal_cost:
Toast.show("金钱不足,铲除作物需要 " + str(removal_cost) + " 金钱", Color.RED, 2.0, 1.0)
self.hide()
return
# 检查地块是否有作物
var lot = main_game.farm_lots[selected_lot_index]
if not lot.get("is_planted", false) or lot.get("crop_type", "") == "":
Toast.show("此地块没有种植作物", Color.ORANGE, 2.0, 1.0)
self.hide()
return
# 发送铲除作物请求到服务器
if network_manager and network_manager.is_connected_to_server():
if network_manager.sendRemoveCrop(selected_lot_index):
Toast.show("正在铲除作物...", Color.YELLOW, 1.5, 1.0)
self.hide()
else:
Toast.show("发送铲除请求失败", Color.RED, 2.0, 1.0)
self.hide()
else:
Toast.show("网络未连接,无法铲除作物", Color.RED, 2.0, 1.0)
self.hide()
验证机制
服务器端验证
- 用户登录验证:确保用户已登录
- 地块索引验证:检查地块索引是否有效
- 地块状态验证:确保地块有作物可以铲除
- 金钱验证:检查玩家金钱是否足够支付铲除费用
客户端预验证
- 访问模式检查:访客模式下禁止操作
- 金钱预检查:提前检查金钱是否足够
- 地块状态预检查:确保地块有作物
- 网络连接检查:确保能够发送请求
操作流程
正常流程
- 玩家点击地块,显示操作面板
- 面板显示铲除按钮和费用信息
- 玩家点击铲除按钮
- 客户端进行预验证
- 发送铲除请求到服务器
- 服务器验证并处理请求
- 服务器返回操作结果
- 客户端更新UI显示
错误处理
- 金钱不足:显示错误提示,不发送请求
- 无作物:显示提示信息,不发送请求
- 访客模式:显示权限提示,不发送请求
- 网络错误:显示网络错误提示
- 服务器错误:显示服务器返回的错误信息
数据更新
地块状态重置
lot["is_planted"] = False # 取消种植状态
lot["crop_type"] = "" # 清空作物类型
lot["grow_time"] = 0 # 重置生长时间
lot["is_dead"] = False # 重置死亡状态
玩家数据更新
player_data["money"] -= removal_cost # 扣除金钱
实时同步
- 服务器保存玩家数据到文件
- 推送作物更新到客户端
- 客户端接收并更新UI显示
使用场景
- 清理死亡作物:当作物死亡时,玩家可以花费金钱清理
- 重新规划农场:玩家想要种植不同作物时
- 紧急处理:当玩家需要快速清理地块时
- 策略调整:根据市场需求调整种植策略
安全考虑
- 服务器权威:所有验证和处理都在服务器端
- 数据一致性:确保客户端和服务器数据同步
- 防作弊:客户端无法直接修改游戏数据
- 访问控制:访客模式下无法进行破坏性操作
扩展性
该功能设计具有良好的扩展性:
- 费用可配置:可以根据作物类型设置不同的铲除费用
- 条件扩展:可以添加更多的铲除条件(如等级要求)
- 奖励机制:可以在铲除时给予部分资源回收
- 工具系统:可以引入铲子等工具来影响铲除效果
测试用例
测试用例1:正常铲除
- 玩家有足够金钱(≥500)
- 地块有作物
- 点击铲除按钮
- 验证:金钱减少500,地块变成空地
测试用例2:金钱不足
- 玩家金钱不足(<500)
- 地块有作物
- 点击铲除按钮
- 验证:显示金钱不足提示,操作失败
测试用例3:无作物地块
- 玩家有足够金钱
- 地块为空地
- 点击铲除按钮
- 验证:显示无作物提示,操作失败
测试用例4:访客模式
- 玩家处于访客模式
- 点击铲除按钮
- 验证:显示权限提示,操作失败
测试用例5:网络断开
- 网络连接断开
- 点击铲除按钮
- 验证:显示网络错误提示,操作失败
总结
铲除作物功能的实现遵循了以下设计原则:
- ✅ 服务器权威:所有关键逻辑在服务器端处理
- ✅ 用户体验:提供清晰的费用信息和操作反馈
- ✅ 数据安全:多层验证确保数据完整性
- ✅ 错误处理:完善的错误提示和处理机制
- ✅ 代码复用:利用现有的验证和处理框架
- ✅ 可维护性:清晰的代码结构和文档
这个功能为玩家提供了更灵活的农场管理选项,同时保持了游戏的平衡性和数据安全性。