如何根据胜负平设置Discord Embed消息的颜色?
Discord.py 石头剪刀布命令的Embed颜色设置错误修复
我在开发Discord机器人的石头剪刀布命令,需求是:
- 失败时Embed颜色设为红色
- 胜利时设为绿色
- 平局时设为灰色
但目前代码无法正确设置结果Embed的颜色,附上我的实现代码:
@bot.command() async def rps(ctx): options = ["rock", "paper", "scissors", "r", "p", "s"] ask_rps_em = discord.Embed(title="Rock, Paper or Scissors?", color=discord.Color.blue()) await ctx.send(embed=ask_rps_em) def check(m): return m.author == ctx.author and m.channel == ctx.channel and m.content.lower() in options try: choice = (await bot.wait_for('message', check=check, timeout=30.0)).content except asyncio.TimeoutError: await ctx.send("You didn't answer in time. Please try again.") if choice.lower() not in options: await ctx.send("Invalid choice. Please choose rock, paper, or scissors.") return bot_choice = random.choice(options) result = None if choice.lower() == "rock": if bot_choice == "rock": result = "It's a tie!" color = "cyan" elif bot_choice == "paper": result = "You lose! Paper beats rock." color = "red" elif bot_choice == "scissors": result = "You win! Rock beats scissors." color = "green" elif choice.lower() == "paper": if bot_choice == "rock": result = "You win! Paper beats rock." color = "green" elif bot_choice == "paper": result = "It's a tie!" color = "cyan" elif bot_choice == "scissors": result = "You lose! Scissors beats paper." color = "red" elif choice.lower() == "scissors": if bot_choice == "rock": result = "You lose! Rock beats scissors." color = "red" elif bot_choice == "paper": result = "You win! Scissors beats paper." color = "green" elif bot_choice == "scissors": result = "It's a tie!" color = "cyan" result_em = discord.Embed(title=f"You chose {choice.lower()}. I chose {bot_choice}. {result}", color=discord.Color.{color}()) # should it be like that or what? await ctx.send(embed=result_em)
注:我需要将平局时的颜色改为灰色,且正确设置结果Embed的颜色。
问题分析与修复步骤
- 颜色调用语法错误:Python不支持
discord.Color.{color}()这种字符串拼接式的方法调用,需直接使用discord.Color提供的颜色属性。 - 选项显示不友好:当前代码允许选择缩写(r/p/s),但结果直接显示缩写会影响体验,需映射成全名。
- 平局颜色未达标:原代码使用cyan,需替换为灰色系的
discord.Color.grey()或discord.Color.dark_grey()。 - 冗余逻辑简化:原胜负判断代码重复度高,可合并为更简洁的条件判断。
修改后的完整代码
import discord import asyncio import random from discord.ext import commands @bot.command() async def rps(ctx): # 建立缩写与全名的映射关系 option_map = { "r": "rock", "p": "paper", "s": "scissors", "rock": "rock", "paper": "paper", "scissors": "scissors" } valid_options = list(option_map.keys()) # 发送选择提示 ask_embed = discord.Embed(title="Rock, Paper or Scissors?", color=discord.Color.blue()) await ctx.send(embed=ask_embed) # 消息检查器 def check_message(m): return m.author == ctx.author and m.channel == ctx.channel and m.content.lower() in valid_options try: user_input = (await bot.wait_for('message', check=check_message, timeout=30.0)).content.lower() except asyncio.TimeoutError: await ctx.send("You didn't answer in time. Please try again.") return # 超时后终止流程 # 转换为全名 user_choice = option_map[user_input] bot_input = random.choice(valid_options) bot_choice = option_map[bot_input] # 初始化结果与颜色 result_text = "" embed_color = discord.Color.grey() # 默认平局颜色 # 判断胜负 if user_choice == bot_choice: result_text = "It's a tie!" elif (user_choice == "rock" and bot_choice == "scissors") or \ (user_choice == "paper" and bot_choice == "rock") or \ (user_choice == "scissors" and bot_choice == "paper"): result_text = f"You win! {user_choice.capitalize()} beats {bot_choice}." embed_color = discord.Color.green() else: result_text = f"You lose! {bot_choice.capitalize()} beats {user_choice}." embed_color = discord.Color.red() # 发送结果Embed result_embed = discord.Embed( title=f"You chose {user_choice}. I chose {bot_choice}. {result_text}", color=embed_color ) await ctx.send(embed=result_embed)
关键修改说明
- 选项映射:通过
option_map统一处理缩写与全名的转换,确保结果显示清晰。 - 颜色赋值:直接调用
discord.Color的内置颜色方法(green()/red()/grey()),避免语法错误。 - 逻辑简化:用组合条件判断胜负,减少冗余代码,提升可读性。
- 流程优化:超时后添加
return,避免后续代码无意义执行。
内容的提问来源于stack exchange,提问作者user19932233
相关产品推荐
相关产品推荐

