litengyue 发表于 2023-8-21 12:03:40

求助

我在网上学习用Python制作贪吃蛇,中途不知道为什么出错了。
请各位大佬帮忙看一下。
代码:

import sys
import pygame

#COLORS
BLACK = 0, 0, 0
WHITE = 255, 255, 255
DARK_GREY = 33, 33, 33
BACKGROUND_COLOR = BLACK
GRID_COLOR = DARK_GREY

SNAKE_COLOR_SKIN = 33, 192, 33
SNAKE_COLOR_BODY = 255, 192, 33
SNAKE_COLOR_HEAD = 192, 192, 33

# KEY SETTINGS
KEY_EXIT = pygame.K_ESCAPE

KEY_UP = pygame.K_UP
KEY_DOWN = pygame.K_DOWN
KEY_LEFT = pygame.K_LEFT
KEY_RIGHT = pygame.K_RIGHT

GAME_NAME = "pysnake"
SCREEN_SIZE = SCREEN_WIDTH, SCREEN_HEIGHT = (640, 480)
CELL_SIZE = 20
COLUMNS, ROWS = SCREEN_WIDTH / CELL_SIZE, SCREEN_HEIGHT / CELL_SIZE
FPS = 60
UP, DOWN, LEFT, RIGHT = ((0, -CELL_SIZE), (0, CELL_SIZE),
                         (-CELL_SIZE, 0), (CELL_SIZE, 0))


class MyGame:
    "pygame模板类"
   
    def __init__(self, name="My Game", size=(640, 480), fps=60, icon=None):
      pygame.init()
      pygame.display.set_caption(name)
      
      self.screen_size = self.screen_width, self.screen_height = size
      self.screen = pygame.display.set_mode(self.screen_size)
      self.fps = fps
      pygame.display.set_icon(pygame.image.load(icon)) if icon else None
      
      self.clock = pygame.time.Clock()
      self.now = 0
      self.background = pygame.Surface(self.screen_size)
      
      self.key_event_binds = {}
      self.gamedata_update_actions = {}
      self.display_update_actions =

    def run(self):
      while True:
            self.now = pygame.time.get_ticks()
            self._process_events()
            self._update_gamedata()
            self._update_display()
      
            self.clock.tick(self.fps)

    def _process_events(self):
      for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.quit()
            elif event.type == pygame.KEYDOWN:
                action, kwargs = self.key_event_binds.get(event.key,
                                                      (None, None))
                action(**kwargs) if kwargs else action() if action else None

    def _update_gamedata(self):
      for name, action in self.gamedata_update_actions.items():
            if not action["next_time"]:
                action["run"]()
            elif self.now >= action["next_time"]:
                action["next_time"] += action["interval"]
                action["run"]()

    def _update_display(self):
      for action in self.display_update_actions:
            action()
      pygame.display.flip()

    def _draw_background(self):
      self.screen.blit(self.background, (0, 0))

    def key_bind(self, key, action, **kwargs):
      self.key_event_binds = action, kwargs

    def add_update_action(self, name, action, interval=0):
      next_time = self.now + interval if interval else None
      self.gamedata_update_actions = dict(run=action,
                                                interval=interval,
                                                next_time=next_time)
      
    def add_draw_action(self, action):
      self.display_update_actions.append(action)

    def quit(self):
      pygame.quit()
      sys.exit(0)
      

class Cell:
    """方块类"""

    def __init__(self, x, y, color1, color2):
      self.x, self.y = x, y
      self.color1, self.color2 = color1, color2

    def move(self, dx, dy):
      self.x += dx
      self.y += dy


class Field:
    """场地类"""

    def __init__(self, surface, columns, rows):
      self.surface = surface
      self.columns, self.rows = columns, rows
      self.cell_array = [ * self.columns for i in range(self.rows)]

    def put_cell(self, cell):
      if 0 <= cell.x < self.columns and 0 <= cell.y < self.rows:
            self.cell_array = cell

    def get_cell(self, x, y):
      return self.cell_array

    def pop_cell(self, cell):
      if 0 <= cell.x < self.columns and 0 <= cell.y < self.rows:
            cell = self.cell_array
            self.cell_array = None
            return cell

    def draw(self):
      for row in self.cell_array:
            for cell in row:
                if cell:
                  rect = pygame.Rect(cell.x * CELL_SIZE, cell.y * CELL_SIZE,
                                       CELL_SIZE, CELL_SIZE)
                  self.surface.fill(cell.color1, rect)
                  self.surface.fill(cell.color2, rect.inflate(-4, -4))


class Snake:
    """蛇的类"""

    def __init__(self, game, x, y, body_length, direction, speed, skin_color,
               body_color, head_color):
      self.game = game
      self.field = self.game.field
      self.skin_color = skin_color
      self.body_color = body_color
      self.head_color = head_color
      
      self.head = Cell(x, y, self.skin_color, self.head_color)
      self.field.put_cell(self.head)
      tmp_body_cell = Cell(-1, -1, self.skin_color, self.body_color)
      self.body = * body_length
      
      self.direction = direction
      self.new_direction = direction
      self.speed = speed
      interval = 1000 / self.speed
      
      self.game.add_update_action("snake.move", self.move, interval)
      self.alive = True
      self.live = 100

    def turn(self, **kwargs):
      if (self.direction in and
            args["direction"] in or
            self.direction in and
            args["direction"] in ):
            self.new_direction = args["direction"]

    def move(self):
      if self.alive:
            new_body_cell = Cell(self.head.x, self.head.y,
                                 self.skin_color, self.body_color)
            self.field.put_cell(new_body_cell)
            self.body, tail = + self.body[:-1], self.body[-1]
            self.field.pop_cell(tail)

            self.direction = self.new_direction
            self.head.move(self.direction)
            self.field.put_cell(self.head)
      
      
class PySnake(MyGame):
    """贪吃蛇游戏"""

    def __init__(self):
      super(PySnake, self).__init__(GAME_NAME, SCREEN_SIZE, FPS)
      self.background.fill(BACKGROUND_COLOR)
      for _ in range(CELL_SIZE, SCREEN_WIDTH, CELL_SIZE):
            pygame.draw.line(self.background, GRID_COLOR,
                           (_, 0), (_, SCREEN_HEIGHT))
      for _ in range(CELL_SIZE, SCREEN_HEIGHT, CELL_SIZE):
            pygame.draw.line(self.background, GRID_COLOR,
                           (0, _), (SCREEN_WIDTH, _))

      self.field = Field(self.screen, COLUMNS, ROWS)

      # 控制按键设定
      self.key_bind(KEY_EXIT, self.quit)

      self.key_bind(KEY_UP, self.key_test, text="上")
      self.key_bind(KEY_DOWN, self.key_test, text="下")
      self.key_bind(KEY_LEFT, self.key_test, text="左")
      self.key_bind(KEY_RIGHT, self.key_test, text="右")
      
      # 游戏数据更新设定
      self.add_update_action("timer", self.timer_test, 1000)
      
      # 画面更新设定
      self.add_draw_action(self.field.draw)

if __name__ == '__main__':
    PySnake().run()

错误信息:

Traceback (most recent call last):
File "C:/Users/Administrator/Desktop/pysnake/pysnake7.py", line 221, in <module>
    PySnake().run()
File "C:/Users/Administrator/Desktop/pysnake/pysnake7.py", line 204, in __init__
    self.field = Field(self.screen, COLUMNS, ROWS)
File "C:/Users/Administrator/Desktop/pysnake/pysnake7.py", line 121, in __init__
    self.cell_array = [ * self.columns for i in range(self.rows)]
TypeError: 'float' object cannot be interpreted as an integer

错误代码(一行代码对应一条错误信息):

PySnake().run()

self.field = Field(self.screen, COLUMNS, ROWS)

self.cell_array = [ * self.columns for i in range(self.rows)]

isdkz 发表于 2023-8-21 12:04:08

问题出在初始化Field类时,传入的COLUMNS和ROWS参数是浮点数,而不是整数。在代码中,COLUMNS和ROWS的值是通过屏幕宽度和高度除以CELL_SIZE得到的,而除法运算得到的结果是浮点数。而Field类的构造函数期望接收整数参数。

要解决这个问题,可以在初始化Field类时将COLUMNS和ROWS的值转换为整数。可以使用int()函数将浮点数转换为整数。修改代码如下:

self.field = Field(self.screen, int(COLUMNS), int(ROWS))

陶远航 发表于 2023-8-21 12:04:11

根据错误信息分析,出错的原因是在创建Field类的实例时传入了错误的参数。具体来说,COLUMNS和ROWS变量的值被计算为浮点数,而Field类的构造函数期望接收整数值。

解决这个问题的方法是将COLUMNS和ROWS的计算结果转换为整数。可以使用int()函数将浮点数转换为整数。修改代码如下:

COLUMNS, ROWS = int(SCREEN_WIDTH / CELL_SIZE), int(SCREEN_HEIGHT / CELL_SIZE)


这样修改后,再次运行程序应该就不会出现这个错误了。希望能帮到你!如果还有其他问题,请随时提问。
如果问题已经解决,请设置最佳答案

litengyue 发表于 2023-8-21 12:09:57

我根据上面两位的建议,修改了代码,但还是有以下错误:

Traceback (most recent call last):
File "C:/Users/Administrator/Desktop/pysnake/pysnake7.py", line 222, in <module>
    PySnake().run()
File "C:/Users/Administrator/Desktop/pysnake/pysnake7.py", line 210, in __init__
    self.key_bind(KEY_UP, self.key_test, text="上")
AttributeError: 'PySnake' object has no attribute 'key_test'

ba21 发表于 2023-8-21 14:32:34

litengyue 发表于 2023-8-21 12:09
我根据上面两位的建议,修改了代码,但还是有以下错误:

Traceback (most recent call last):


你这代码问题多了去了,这是你写的还是抄的?都是简单问题。

self.key_test这个 key_test在哪?你代码中有写这样的属性或是方法????

JasonChencCjj 发表于 2023-8-22 09:32:17

你是不是写漏了好多东西,抄错了把{:10_307:}

这种情况如果是你自己写的话实在找不到问题就从头开始吧,如果是抄的话下次注意点

如果你看完了小甲鱼的课程(至少看完一半,把练习做了),这些bug自己修应该没什么难度的{:10_257:}

litengyue 发表于 2023-8-23 16:02:21

课程我看完了,可练习做到一半没有了,说正在更新{:10_269:}

JasonChencCjj 发表于 2023-8-23 20:08:32

litengyue 发表于 2023-8-23 16:02
课程我看完了,可练习做到一半没有了,说正在更新

你可以看老版的练习

JasonChencCjj 发表于 2023-8-23 20:10:43

向你推荐我的帖子

pygameGUI 2.0 开发日志
https://fishc.com.cn/thread-232764-1-1.html
(出处: 鱼C论坛)

【pygameGUI 1.0】教程 —— 【已完结】 8/17
https://fishc.com.cn/thread-232461-1-1.html
(出处: 鱼C论坛)

【pygame】 教程:模拟车辆运动(持续更新)————7/31
https://fishc.com.cn/thread-231215-1-1.html
(出处: 鱼C论坛)

【pygame】框架有了这个可以节省几十行代码的时间!回帖奖励
https://fishc.com.cn/thread-230690-1-1.html
(出处: 鱼C论坛)

【pygame】 用粒子特效生成火焰 -- 7/25最新更新
https://fishc.com.cn/thread-230661-1-1.html
(出处: 鱼C论坛)


这些帖子对于一个喜欢pygame的开发者或许会有帮助,如果可以的话求个评分{:10_297:}

页: [1]
查看完整版本: 求助