求助
我在网上学习用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)]
问题出在初始化Field类时,传入的COLUMNS和ROWS参数是浮点数,而不是整数。在代码中,COLUMNS和ROWS的值是通过屏幕宽度和高度除以CELL_SIZE得到的,而除法运算得到的结果是浮点数。而Field类的构造函数期望接收整数参数。
要解决这个问题,可以在初始化Field类时将COLUMNS和ROWS的值转换为整数。可以使用int()函数将浮点数转换为整数。修改代码如下:
self.field = Field(self.screen, int(COLUMNS), int(ROWS)) 根据错误信息分析,出错的原因是在创建Field类的实例时传入了错误的参数。具体来说,COLUMNS和ROWS变量的值被计算为浮点数,而Field类的构造函数期望接收整数值。
解决这个问题的方法是将COLUMNS和ROWS的计算结果转换为整数。可以使用int()函数将浮点数转换为整数。修改代码如下:
COLUMNS, ROWS = int(SCREEN_WIDTH / CELL_SIZE), int(SCREEN_HEIGHT / CELL_SIZE)
这样修改后,再次运行程序应该就不会出现这个错误了。希望能帮到你!如果还有其他问题,请随时提问。
如果问题已经解决,请设置最佳答案 我根据上面两位的建议,修改了代码,但还是有以下错误:
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' litengyue 发表于 2023-8-21 12:09
我根据上面两位的建议,修改了代码,但还是有以下错误:
Traceback (most recent call last):
你这代码问题多了去了,这是你写的还是抄的?都是简单问题。
self.key_test这个 key_test在哪?你代码中有写这样的属性或是方法???? 你是不是写漏了好多东西,抄错了把{:10_307:}
这种情况如果是你自己写的话实在找不到问题就从头开始吧,如果是抄的话下次注意点
如果你看完了小甲鱼的课程(至少看完一半,把练习做了),这些bug自己修应该没什么难度的{:10_257:} 课程我看完了,可练习做到一半没有了,说正在更新{:10_269:} litengyue 发表于 2023-8-23 16:02
课程我看完了,可练习做到一半没有了,说正在更新
你可以看老版的练习 向你推荐我的帖子
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]