检测到Replit DB循环引用

2024-10-04 09:30:55 发布

您现在位置:Python中文网/ 问答频道 /正文

最近,我正在使用repl.it的数据库系统编程一个Python MMORPG。然而,我遇到了一个我不知道如何修复的错误。我试图在数据库中创建一个键,列出某个区域内的所有人形机器人,以便不同的屏幕可以看到相同的人形机器人。但无论我做什么,它都会出错并给出相同的错误:ValueError: Circular reference detected。(我的代码只能在on replit下运行,因为它使用replit的数据库系统。)

错误消息:

Traceback (most recent call last):
  File "main.py", line 156, in <module>
    db["humanoids_in_"+background[1]] = humanoids
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/replit/database/database.py", line 491, in __setitem__
    self.set(key, value)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/replit/database/database.py", line 500, in set
    self.set_raw(key, _dumps(value))
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/replit/database/database.py", line 56, in dumps
    return json.dumps(val, separators=(",", ":"), cls=DBJSONEncoder)
  File "/usr/lib/python3.8/json/__init__.py", line 234, in dumps
    return cls(
  File "/usr/lib/python3.8/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.8/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
ValueError: Circular reference detected

主文件代码:

import pygame
from pygame.locals import *
from replit import db
from config import *
import replit

# STATS FORMAT: 0: Password, 1: Level, 2: Abilities
# IF: you can't see the full screen THEN: put your zoom to 80/70%
# IF: the program is loading infinitely THEN: reload
# IF: click is not being detected THEN: try a lighter click (usually works) or harder click (or just try again until it works)

screen = pygame.display.set_mode((700, 800))
pygame.display.set_caption("Alterpolis")
clock = pygame.time.Clock()

pygame.init()

Player = Humanoid(20, ["Punch", "Rock Throw"], (325, 375))
humanoids.append(Player)

# Bandit = Humanoid(15, ["Punch", "Rock Throw"], ai=True) MAKE BANDIT BODY PARTS

#enemies = [Bandit]

replit.clear()

while True:
  clock.tick(1000)
  screen.fill(BLACK)
  for event in pygame.event.get():
    if event.type == QUIT:
      quit()
    if event.type == MOUSEBUTTONDOWN:
      mousepos = event.pos
      if stage == "main_menu":
        if touching(mousepos[0], mousepos[1], 225, 400, 180, 120) == True:
          stage = "account"
          box_selected = "login_button"
      if stage == "account":
        if touching(mousepos[0], mousepos[1], 650, 350, 20, 20) == True:
          if "username" not in selected:
            selected = "username_typing_box"
          else:
            seleted = ""
        if touching(mousepos[0], mousepos[1], 650, 385, 20, 20) == True:
          if selected != "password_typing_box":
            selected = "password_typing_box"
          else:
            selected = ""
        if touching(mousepos[0], mousepos[1], 210, 425, 100, 150) == True:
          # Login button 
          box_selected = "login_button"
        if touching(mousepos[0], mousepos[1], 20, 425, 100, 150) == True:
          # Create account button 
          box_selected = "create_account_button"
        if touching(mousepos[0], mousepos[1], 20, 550, 200, 200) == True:
          # submit button 
          if box_selected == "login_button":
            try:
              if typing_password in db["UserStats="+typing_username]:
                print("Successfully signed in!")
                user_stats = db["UserStats="+typing_username]
                Player.stats = user_stats
                stage = "actual_game"
                selected = ""
            except:
              print("Incorrect password/username.")
          if box_selected == "create_account_button":
            try:
              if db["UserStats="+typing_username]:
                print("Username already used.")
            except:
              db["UserStats="+typing_username] = [typing_password, 1, []]
              user_stats = db["UserStats="+typing_username]
              Player.stats = user_stats
              print("Account created successfully!")
              stage = "actual_game"
              selected = ""
    if event.type == KEYDOWN:
      if selected == "username_typing_box":
        if event.key == K_LSHIFT or event.key == K_RSHIFT:
          event.key = 1
        char = chr(event.key)
        if event.key == K_BACKSPACE:
          typing_username = typing_username.rstrip(typing_username[-1])
        else:
          typing_username = typing_username + char
      if selected == "password_typing_box":
        char = chr(event.key)
        if event.key == K_BACKSPACE:
          typing_password = typing_password.rstrip(typing_password[-1])
          typing_password_shown = typing_password_shown.rstrip(typing_password_shown[-1])
        else:
          typing_password = typing_password + char
          typing_password_shown = typing_password_shown + "*"
      if stage == "actual_game":
        if event.key == K_UP:
          Player.up = True
        if event.key == K_DOWN:
          Player.down = True
        if event.key == K_LEFT:
          Player.left = True
        if event.key == K_RIGHT:
          Player.right = True
        try:
          Player.process(chr(event.key))
        except:
          pass
    if event.type == KEYUP:
      if stage == "actual_game":
        if event.key == K_UP:
          Player.up = False
        if event.key == K_DOWN:
          Player.down = False
        if event.key == K_LEFT:
          Player.left = False
        if event.key == K_RIGHT:
          Player.right = False
  if stage == "main_menu":
    screen.blit(title_screen, (0,0))
    screen.blit(play_button, (225, 400))
  elif stage == "account":
    screen.blit(title_screen, (0,0))
    show_text("Username: "+typing_username, 20, 350, WHITE, 20, screen)
    show_text("Password: "+typing_password_shown, 20, 380, WHITE, 20, screen)
    # Username Interaction Button
    screen.blit(white_box, (650, 355))
    # Password Interaction Button
    screen.blit(white_box, (650, 385))
    if box_selected == "login_button":
      screen.blit(login_box_selected, (210, 425))
    else:
      screen.blit(login_box_unselected, (210, 425))
    if box_selected == "create_account_button":
      screen.blit(create_account_box_selected, (20, 425))
    else:
      screen.blit(create_account_box_unselected, (20, 425))
    screen.blit(submit_button, (20, 550))
  elif stage == "actual_game":
    Player.name = typing_username
    Player.tick(screen)
    screen.blit(background[0], (0,0))
    screen.blit(player_char, (Player.headpos))
    show_text(background[1], 10, 10, BLACK, 25, screen)
    for i in humanoids:
      show_text(i.name, i.headpos[0] - (len(i.name) * 3.5), i.headpos[1] - 25, BLACK, 25, screen)
      show_text("Level: "+str(i.stats[1]), i.headpos[0] - (len("Level: "+str(i.stats[1])) * 3.5), i.headpos[1] - 50, BLACK, 25, screen)
      show_text(str(i.health) + "/" + str(i.maxhealth), i.headpos[0] - (len(str(i.health) + "/" + str(i.maxhealth)) * 3.5), i.headpos[1] - 75, GREEN, 25, screen)
    v = 0
    for i in humanoids:
      if i.name == typing_username:
        humanoids[v] = Player
      v = v + 1
    db["humanoids_in_"+background[1]] = humanoids
  for i in humanoids:
    if i.ticks > 0:
      i.ticks = i.ticks - 1
      if i.ticktype == "PUNCH":
        screen.blit(impact_circle, i.tickpos)
      i.canmove = False
    else:
      i.canmove = True
  pygame.display.update()

配置文件代码:

import pygame
from pygame.event import *
from pygame.locals import *
import random
ticks = 0
ticktype = 'NONE'

RED = (255,0,0)
GREEN = (0,255,0)
BLUE = (0,0,255)
WHITE = (255,255,255)
BLACK = (0,0,0)
PURPLE = (102, 0, 204)
BROWN = (139,69,19)
COLORS = [RED, GREEN, BLUE, PURPLE, BROWN]
GOLD = (255,215,0)
pygame.init()

humanoids = []

screen = pygame.display.set_mode((1,1))

stage = "main_menu"

play_button = pygame.image.load("assets/play_button.png")
play_button = pygame.transform.scale(play_button, (180, 120)).convert()

title_screen = pygame.image.load("assets/title_screen.png").convert()

account_screen = pygame.image.load("assets/account_screen.png").convert()

white_box = pygame.image.load("assets/white_box.png").convert()

login_box_selected = pygame.image.load("assets/login-account-selected.png").convert()

login_box_unselected = pygame.image.load("assets/login-account-unselected.png").convert()

create_account_box_selected = pygame.image.load("assets/create-account-selected.png").convert()

create_account_box_unselected = pygame.image.load("assets/create-account-unselected.png").convert()

impact_circle = pygame.transform.scale(pygame.image.load("assets/impact_circle.png"), (60, 60))

submit_button = pygame.image.load("assets/submit-button.png").convert()

error_notification = pygame.image.load("assets/error.png").convert()

ai_unselected = pygame.image.load("assets/ai-unselected.png").convert()

ai_selected = pygame.image.load("assets/ai-selected.png").convert()

player_unselected = pygame.image.load("assets/player-unselected.png").convert()

player_selected = pygame.image.load("assets/player-selected.png").convert()

battle_arena = pygame.image.load("assets/battle-arena.png").convert()

player_char = pygame.image.load("assets/characters/main_char.png")

test_place = pygame.image.load("assets/locations/test_place.png")

events = {"Punch":impact_circle}

typing_username = ""
typing_password = ""
typing_password_shown = ""
selected = ""
box_selected = ""
user_stats = []
attacks_database = {"Punch" : 2, "Rock Throw" : 4, "Pheonix Strike" : 100000000000000000}

background = [test_place, "Test Place"]

class Humanoid():
  def __init__(self, maxhealth, moves, headpos, ai = False, health=1, speed = 0.4, name = "none"):
    self.maxhealth = maxhealth
    self.headpos = headpos
    self.up = False
    self.down = False
    self.right = False
    self.left = False
    self.speed = speed
    self.name = name
    self.stats = []
    self.ticks = 0
    self.ticktype = "NONE"
    self.tickpos = (0,0)
    self.canmove = True
    if health == 1:
      self.health = maxhealth
    else:
      self.health = health
    self.moves = moves
    self.ai = ai
  def tick(self, window):
    if self.health <= 0:
      self.delete()
    if self.canmove == True:
      if self.up == True:
        self.headpos = (self.headpos[0], self.headpos[1] - self.speed)
      elif self.down == True:
        self.headpos = (self.headpos[0], self.headpos[1] + self.speed)
      if self.left == True:
        self.headpos = (self.headpos[0] - self.speed, self.headpos[1])
      elif self.right == True:
        self.headpos = (self.headpos[0] + self.speed, self.headpos[1])
    if self.ai == True:
      self.move = random.choice(moves)
      # execute the move in target direction if target in range. if not in range then move towards target.
    show_text(self.name, self.headpos[0] - (len(self.name) / 2), self.headpos[1] + 20, BLACK, 25, window)
  def process(self, key):
    key = key.lower()
    if key == "q":
      screen.blit(trigger_server_event(self.moves[0]), self.headpos)
      self.ticktype = "PUNCH"
      self.ticks = 175
      self.tickpos = (self.headpos[0] - 17, self.headpos[1] - 17)

enemies = []

#touching - checks for touch

def touching(obj1x,obj1y,obj2x,obj2y,obj2length, obj2width):
    if obj1x in range(obj2x, obj2x + obj2length - 1) and obj1y in range(obj2y, obj2y + obj2length - 1):
        return True
    else:
        return False
    if obj1x in range(obj2x, obj2x + obj2width - 1) and obj1y in range(obj2y, obj2y + obj2width + 1):
        return True
    else:
        return False

#show_text - displays pygame text
def show_text(msg, x, y, color, size, screen):
        fontobj= pygame.font.SysFont("freesans", size)
        msgobj = fontobj.render(msg,False,color)
        screen.blit(msgobj,(x, y))

def trigger_server_event(event):
  return events[event]

Tags: keyinselfboxeventtruetypingif
1条回答
网友
1楼 · 发布于 2024-10-04 09:30:55

Replit DB doc

async set(key, value)

    Set a key in the database to the result of JSON encoding value.

    Parameters

            key (str) – The key to set

            value (Any) – The value to set it to. Must be JSON-serializable.

    Return type

    None

这里,您的播放器是一个python对象,它不是json序列化的。多亏了这个答案:https://stackoverflow.com/a/10252138/16668765,这应该行得通

db["humanoids_in_"+background[1]] = [vars(x) for x in humanoids]

相关问题 更多 >