鱼C论坛

 找回密码
 立即注册
查看: 1022|回复: 8

求助

[复制链接]
发表于 2023-8-21 12:03:40 | 显示全部楼层 |阅读模式
50鱼币
我在网上学习用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 = [self._draw_background]

    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[key] = action, kwargs

    def add_update_action(self, name, action, interval=0):
        next_time = self.now + interval if interval else None
        self.gamedata_update_actions[name] = 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 = [[None] * 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.y][cell.x] = cell

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

    def pop_cell(self, cell):
        if 0 <= cell.x < self.columns and 0 <= cell.y < self.rows:
            cell = self.cell_array[cell.y][cell.x]
            self.cell_array[cell.y][cell.x] = 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 = [tmp_body_cell] * 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 [LEFT, RIGHT] and
            args["direction"] in [UP, DOWN] or
            self.direction in [UP, DOWN] and
            args["direction"] in [LEFT, RIGHT]):
            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 = [new_body_cell] + 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 = [[None] * 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 = [[None] * self.columns for i in range(self.rows)]

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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)

这样修改后,再次运行程序应该就不会出现这个错误了。希望能帮到你!如果还有其他问题,请随时提问。
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 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'
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-21 14:32:34 | 显示全部楼层
litengyue 发表于 2023-8-21 12:09
我根据上面两位的建议,修改了代码,但还是有以下错误:

Traceback (most recent call last):

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

self.key_test  这个 key_test在哪?你代码中有写这样的属性或是方法????
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-22 09:32:17 | 显示全部楼层
你是不是写漏了好多东西,抄错了把

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

如果你看完了小甲鱼的课程(至少看完一半,把练习做了),这些bug自己修应该没什么难度的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-8-23 16:02:21 | 显示全部楼层
课程我看完了,可练习做到一半没有了,说正在更新
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-8-23 20:08:32 | 显示全部楼层
litengyue 发表于 2023-8-23 16:02
课程我看完了,可练习做到一半没有了,说正在更新

你可以看老版的练习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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的开发者或许会有帮助,如果可以的话求个评分

评分

参与人数 1荣誉 +2 鱼币 +2 收起 理由
额外减小 + 2 + 2

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-23 12:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表