You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Arcade库check_for_collision检测碰撞时触发ValueError问题求助

解决Arcade框架中贪吃蛇碰撞检测的ValueError问题

错误原因

你遇到的ValueError核心原因是:虽然Snake和Apple类都继承了arcade.Sprite,但你既没有给它们设置texture(Sprite默认通过纹理生成碰撞盒),也没有手动调用set_hit_box定义碰撞区域,而是自己实现了绘制方法。arcade.check_for_collision必须依赖Sprite的碰撞盒数据才能工作,因此触发报错。

解决方案

提供两种可行修复方式,推荐第二种,更贴合Arcade的Sprite设计逻辑:

方式1:手动设置碰撞盒

在Snake和Apple的初始化方法中,手动定义对应形状的碰撞区域:

修改Snake类的__init__:

class Snake(arcade.Sprite):
    def __init__(self):
        super().__init__()
        self.width = 16
        self.height = 16
        self.change_x = 0   
        self.change_y = 0
        self.center_x = WIDTH_SCREEN // 2
        self.center_y = HEIGHT_SCREEN //2
        self.color = arcade.color.RED
        self.score = 0
        self.speed = 1
        # 手动设置矩形碰撞盒的四个顶点
        self.set_hit_box([
            (-self.width//2, -self.height//2),
            (self.width//2, -self.height//2),
            (self.width//2, self.height//2),
            (-self.width//2, self.height//2)
        ])

修改Apple类的__init__:

class Apple(arcade.Sprite):
    def __init__(self):
        super().__init__()
        self.radius = 10
        self.center_x = random.randint(0, WIDTH_SCREEN)
        self.center_y = random.randint(0, HEIGHT_SCREEN)
        self.color = arcade.color.YELLOW
        # 用多边形近似生成圆形碰撞盒
        self.set_hit_box(arcade.create_hit_box_for_circle(self.radius))

方式2:使用Sprite内置纹理绘制(推荐)

直接利用Arcade的Texture.create_*方法生成对应形状的纹理,Sprite会自动匹配生成碰撞盒,同时可以去掉自定义的绘制方法:

修改后的完整代码:

import random, arcade
WIDTH_SCREEN = 500
HEIGHT_SCREEN = 500

class Game(arcade.Window):
    def __init__(self):
        super().__init__(width=WIDTH_SCREEN, height=HEIGHT_SCREEN, title='Snake')
        arcade.set_background_color(arcade.color.SAND)
        self.snake = Snake()
        self.apple = Apple()

    def on_draw(self):
        arcade.start_render()
        self.snake.draw()
        self.apple.draw()  # 改用Sprite默认绘制方法

    def on_update(self, delta_time: float):
        self.snake.move()
        if arcade.check_for_collision(self.snake, self.apple):
            self.snake.eat()
            self.apple = Apple()
            print(self.snake.score)

    def on_key_release(self, key: int, modifiers: int):
        if key == arcade.key.LEFT:
            self.snake.change_x = -1
            self.snake.change_y = 0
        elif key == arcade.key.RIGHT:
            self.snake.change_x = 1
            self.snake.change_y = 0
        elif key == arcade.key.UP:
            self.snake.change_x = 0
            self.snake.change_y = 1
        elif key == arcade.key.DOWN:
            self.snake.change_x = 0
            self.snake.change_y = -1         

class Snake(arcade.Sprite):
    def __init__(self):
        super().__init__()
        self.width = 16
        self.height = 16
        self.change_x = 0   
        self.change_y = 0
        self.center_x = WIDTH_SCREEN // 2
        self.center_y = HEIGHT_SCREEN //2
        self.color = arcade.color.RED
        self.score = 0
        self.speed = 1
        # 创建矩形纹理,自动生成匹配的碰撞盒
        self.texture = arcade.Texture.create_rectangle_texture(self.width, self.height, self.color)

    def move(self):
        if self.change_x > 0:
            self.center_x += self.speed
        elif self.change_x < 0:
            self.center_x -= self.speed
        elif self.change_y > 0:
            self.center_y += self.speed
        elif self.change_y < 0:
            self.center_y -= self.speed      

    def eat(self):
        self.score += 1

class Apple(arcade.Sprite):
    def __init__(self):
        super().__init__()
        self.radius = 10
        self.center_x = random.randint(0, WIDTH_SCREEN)
        self.center_y = random.randint(0, HEIGHT_SCREEN)
        self.color = arcade.color.YELLOW
        # 创建圆形纹理,自动生成匹配的碰撞盒
        self.texture = arcade.Texture.create_circle_texture(self.radius * 2, self.color)
        self.width = self.radius * 2
        self.height = self.radius * 2

game_board = Game()
arcade.run()

补充说明

  • 方式2中,create_rectangle_texture和create_circle_texture会自动为Sprite生成与形状匹配的碰撞盒,无需手动设置。
  • 去掉自定义绘制方法后,改用Sprite类默认的draw(),更符合Arcade框架的设计规范,后续扩展功能也更方便。

内容的提问来源于stack exchange,提问作者Ali Valizade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 21:57:10