or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

camera-system.mdcore-graphics.mdgui-framework.mdindex.mdmath-utilities.mdphysics-engines.mdsound-system.mdspecialized-features.mdsprite-system.mdtexture-management.mdwindow-management.md

sprite-system.mddocs/

0

# Sprite System and Collision Detection

1

2

Complete sprite management system for game objects with support for animations, physics properties, collision detection, and efficient batch rendering through sprite lists.

3

4

## Capabilities

5

6

### Core Sprite Classes

7

8

Base sprite classes providing the foundation for all game objects in Arcade.

9

10

```python { .api }

11

class Sprite:

12

"""

13

Main sprite class for creating game objects with position, rotation, texture, and physics properties.

14

"""

15

def __init__(self, filename: str = None, scale: float = 1, image_x: float = 0, image_y: float = 0,

16

image_width: float = 0, image_height: float = 0, center_x: float = 0, center_y: float = 0,

17

repeat_count_x: int = 1, repeat_count_y: int = 1, flipped_horizontally: bool = False,

18

flipped_vertically: bool = False, flipped_diagonally: bool = False, hit_box_algorithm: str = "Simple",

19

hit_box_detail: float = 4.5, texture: arcade.Texture = None, angle: float = 0):

20

"""

21

Create a new sprite.

22

23

Args:

24

filename: Path to texture file or resource handle (e.g., ":resources:images/...")

25

scale: Scale factor for the sprite

26

image_x: X offset within source image

27

image_y: Y offset within source image

28

image_width: Width of region to use from source image

29

image_height: Height of region to use from source image

30

center_x: Initial X position

31

center_y: Initial Y position

32

repeat_count_x: Number of times to repeat texture horizontally

33

repeat_count_y: Number of times to repeat texture vertically

34

flipped_horizontally: Mirror sprite horizontally

35

flipped_vertically: Mirror sprite vertically

36

flipped_diagonally: Mirror sprite diagonally

37

hit_box_algorithm: Algorithm for hit box calculation ("Simple", "Detailed", or "None")

38

hit_box_detail: Detail level for "Detailed" hit box algorithm

39

texture: Texture object to use instead of loading from file

40

angle: Initial rotation angle in degrees

41

"""

42

43

# Position properties

44

center_x: float

45

center_y: float

46

left: float

47

right: float

48

top: float

49

bottom: float

50

51

# Movement properties

52

change_x: float

53

change_y: float

54

velocity: tuple[float, float]

55

56

# Rotation properties

57

angle: float

58

change_angle: float

59

radians: float

60

61

# Scale properties

62

scale: float

63

width: float

64

height: float

65

66

# Physics properties

67

physics_engines: list

68

69

# Texture properties

70

texture: arcade.Texture

71

textures: list[arcade.Texture]

72

cur_texture_index: int

73

74

# Hit box and collision

75

hit_box: list[tuple[float, float]]

76

77

# Identification

78

guid: str

79

80

def update(self) -> None:

81

"""Update sprite position based on velocity."""

82

83

def update_animation(self, delta_time: float = 1/60) -> None:

84

"""Update sprite animation."""

85

86

def on_update(self, delta_time: float = 1/60) -> None:

87

"""Override this method to add custom update logic."""

88

89

def draw(self, *, filter=None, pixelated=None, blend_function=None) -> None:

90

"""Draw the sprite."""

91

92

def draw_hit_box(self, color: arcade.types.Color = arcade.color.BLACK, line_thickness: float = 1) -> None:

93

"""Draw the sprite's hit box for debugging."""

94

95

def set_hit_box(self, points: list[tuple[float, float]]) -> None:

96

"""Manually set the hit box points."""

97

98

def get_adjusted_hit_box(self) -> list[tuple[float, float]]:

99

"""Get hit box adjusted for current position and rotation."""

100

101

class BasicSprite:

102

"""

103

Minimal sprite implementation with reduced memory footprint for simple use cases.

104

"""

105

def __init__(self, filename: str = None, scale: float = 1, center_x: float = 0, center_y: float = 0):

106

"""Create a basic sprite with minimal properties."""

107

108

center_x: float

109

center_y: float

110

angle: float

111

scale: float

112

texture: arcade.Texture

113

```

114

115

### Specialized Sprite Types

116

117

Pre-configured sprite classes for common game object patterns.

118

119

```python { .api }

120

class SpriteSolidColor(arcade.Sprite):

121

"""

122

Sprite with a solid color rectangle instead of a texture.

123

"""

124

def __init__(self, width: int, height: int, color: arcade.types.Color, center_x: float = 0, center_y: float = 0):

125

"""

126

Create a solid color sprite.

127

128

Args:

129

width: Width of the rectangle

130

height: Height of the rectangle

131

color: Color as RGB or RGBA tuple (0-255)

132

center_x: Initial X position

133

center_y: Initial Y position

134

"""

135

136

class SpriteCircle(arcade.Sprite):

137

"""

138

Sprite with a circular shape.

139

"""

140

def __init__(self, radius: int, color: arcade.types.Color, soft: bool = False, center_x: float = 0, center_y: float = 0):

141

"""

142

Create a circular sprite.

143

144

Args:

145

radius: Radius of the circle

146

color: Color as RGB or RGBA tuple (0-255)

147

soft: Whether to use soft edges

148

center_x: Initial X position

149

center_y: Initial Y position

150

"""

151

152

class TextureAnimationSprite(arcade.Sprite):

153

"""

154

Sprite with texture-based animation support.

155

"""

156

def __init__(self, filename: str = None, scale: float = 1):

157

"""Create an animated sprite."""

158

159

def update_animation(self, delta_time: float = 1/60) -> None:

160

"""Update animation based on elapsed time."""

161

162

class AnimatedWalkingSprite(arcade.Sprite):

163

"""

164

Sprite with directional walking animations.

165

"""

166

def __init__(self, scale: float = 1):

167

"""Create a walking animated sprite."""

168

169

# Texture lists for different directions

170

walk_up_textures: list[arcade.Texture]

171

walk_down_textures: list[arcade.Texture]

172

walk_left_textures: list[arcade.Texture]

173

walk_right_textures: list[arcade.Texture]

174

stand_up_textures: list[arcade.Texture]

175

stand_down_textures: list[arcade.Texture]

176

stand_left_textures: list[arcade.Texture]

177

stand_right_textures: list[arcade.Texture]

178

179

def update_animation(self, delta_time: float = 1/60) -> None:

180

"""Update walking animation based on movement direction."""

181

```

182

183

### Sprite Lists

184

185

Efficient containers for managing and rendering groups of sprites.

186

187

```python { .api }

188

class SpriteList:

189

"""

190

Container for managing groups of sprites with optimized batch rendering.

191

"""

192

def __init__(self, use_spatial_hash: bool = None, spatial_hash_cell_size: int = 128,

193

is_static: bool = False, atlas: arcade.TextureAtlasBase = None):

194

"""

195

Create a new sprite list.

196

197

Args:

198

use_spatial_hash: Enable spatial hashing for collision optimization

199

spatial_hash_cell_size: Size of spatial hash cells

200

is_static: Whether sprites in this list move (enables optimizations)

201

atlas: Custom texture atlas to use

202

"""

203

204

def append(self, sprite: arcade.Sprite) -> None:

205

"""Add a sprite to the list."""

206

207

def remove(self, sprite: arcade.Sprite) -> None:

208

"""Remove a sprite from the list."""

209

210

def insert(self, index: int, sprite: arcade.Sprite) -> None:

211

"""Insert a sprite at a specific index."""

212

213

def extend(self, sprites: list[arcade.Sprite]) -> None:

214

"""Add multiple sprites to the list."""

215

216

def clear(self) -> None:

217

"""Remove all sprites from the list."""

218

219

def update(self) -> None:

220

"""Update all sprites in the list."""

221

222

def update_animation(self, delta_time: float = 1/60) -> None:

223

"""Update animations for all sprites in the list."""

224

225

def on_update(self, delta_time: float = 1/60) -> None:

226

"""Override this method for custom update logic."""

227

228

def draw(self, *, filter=None, pixelated=None, blend_function=None) -> None:

229

"""Draw all sprites in the list using batch rendering."""

230

231

def draw_hit_boxes(self, color: arcade.types.Color = arcade.color.BLACK, line_thickness: float = 1) -> None:

232

"""Draw hit boxes for all sprites (debugging)."""

233

234

def move(self, change_x: float, change_y: float) -> None:

235

"""Move all sprites in the list by the specified offset."""

236

237

# List-like operations

238

def __len__(self) -> int:

239

"""Get the number of sprites in the list."""

240

241

def __getitem__(self, index: int) -> arcade.Sprite:

242

"""Get a sprite by index."""

243

244

def __iter__(self):

245

"""Iterate over sprites in the list."""

246

247

def __contains__(self, sprite: arcade.Sprite) -> bool:

248

"""Check if a sprite is in the list."""

249

250

class SpriteSequence:

251

"""

252

Sequence interface for sprite lists with additional functionality.

253

"""

254

def __init__(self):

255

"""Create a new sprite sequence."""

256

257

def pop(self, index: int = -1) -> arcade.Sprite:

258

"""Remove and return sprite at index."""

259

260

def reverse(self) -> None:

261

"""Reverse the order of sprites."""

262

263

def shuffle(self) -> None:

264

"""Randomly shuffle the sprites."""

265

```

266

267

### Spatial Indexing

268

269

Spatial data structures for optimizing collision detection and spatial queries.

270

271

```python { .api }

272

class SpatialHash:

273

"""

274

Spatial hash grid for efficient collision detection and spatial queries.

275

"""

276

def __init__(self, cell_size: int = 128):

277

"""

278

Create a spatial hash.

279

280

Args:

281

cell_size: Size of each hash cell in pixels

282

"""

283

284

def insert_object_for_box(self, new_object: arcade.Sprite) -> None:

285

"""Insert a sprite into the spatial hash."""

286

287

def remove_object(self, sprite_to_remove: arcade.Sprite) -> None:

288

"""Remove a sprite from the spatial hash."""

289

290

def get_objects_for_box(self, check_object: arcade.Sprite) -> list[arcade.Sprite]:

291

"""Get all objects that might collide with the given sprite."""

292

293

def reset(self) -> None:

294

"""Clear all objects from the spatial hash."""

295

```

296

297

### Animation System

298

299

Classes for managing texture-based sprite animations.

300

301

```python { .api }

302

class TextureAnimation:

303

"""

304

Container for managing a sequence of animation frames.

305

"""

306

def __init__(self, keyframes: list[arcade.TextureKeyframe] = None):

307

"""

308

Create a texture animation.

309

310

Args:

311

keyframes: List of animation keyframes

312

"""

313

314

keyframes: list[arcade.TextureKeyframe]

315

316

def add_keyframe(self, keyframe: arcade.TextureKeyframe) -> None:

317

"""Add a keyframe to the animation."""

318

319

class TextureKeyframe:

320

"""

321

Single frame in a texture animation with timing information.

322

"""

323

def __init__(self, texture: arcade.Texture, duration: float = 1.0):

324

"""

325

Create an animation keyframe.

326

327

Args:

328

texture: Texture to display during this frame

329

duration: Duration to display this frame (in seconds or frame counts)

330

"""

331

332

texture: arcade.Texture

333

duration: float

334

335

def load_animated_gif(filename: str, scale: float = 1) -> arcade.TextureAnimationSprite:

336

"""

337

Load an animated GIF file as an animated sprite.

338

339

Args:

340

filename: Path to GIF file

341

scale: Scale factor for the sprite

342

343

Returns:

344

TextureAnimationSprite with frames from the GIF

345

"""

346

```

347

348

### Physics Integration

349

350

Mixins and types for integrating sprites with physics engines.

351

352

```python { .api }

353

class PymunkMixin:

354

"""

355

Mixin class for adding Pymunk physics integration to sprites.

356

"""

357

pymunk_shape: object # pymunk.Shape

358

pymunk_body: object # pymunk.Body

359

360

def pymunk_moved(self, physics_engine: arcade.PymunkPhysicsEngine, dx: float, dy: float, d_angle: float) -> None:

361

"""Called when the physics engine moves the sprite."""

362

363

# Type alias for sprites with Pymunk physics

364

PyMunk = arcade.Sprite # Sprite with PymunkMixin

365

```

366

367

### Collision Detection

368

369

Comprehensive collision detection functions for sprite interactions.

370

371

```python { .api }

372

def check_for_collision(sprite1: arcade.Sprite, sprite2: arcade.Sprite) -> bool:

373

"""

374

Check if two sprites are colliding.

375

376

Args:

377

sprite1: First sprite

378

sprite2: Second sprite

379

380

Returns:

381

True if sprites are colliding, False otherwise

382

"""

383

384

def check_for_collision_with_list(sprite: arcade.Sprite, sprite_list: arcade.SpriteList) -> list[arcade.Sprite]:

385

"""

386

Check if a sprite collides with any sprites in a list.

387

388

Args:

389

sprite: Sprite to check

390

sprite_list: List of sprites to check against

391

392

Returns:

393

List of sprites that are colliding with the input sprite

394

"""

395

396

def check_for_collision_with_lists(sprite: arcade.Sprite, sprite_lists: list[arcade.SpriteList]) -> list[arcade.Sprite]:

397

"""

398

Check if a sprite collides with sprites in multiple lists.

399

400

Args:

401

sprite: Sprite to check

402

sprite_lists: List of sprite lists to check against

403

404

Returns:

405

List of sprites that are colliding with the input sprite

406

"""

407

408

def get_closest_sprite(sprite: arcade.Sprite, sprite_list: arcade.SpriteList) -> tuple[arcade.Sprite, float]:

409

"""

410

Find the closest sprite in a list to the given sprite.

411

412

Args:

413

sprite: Reference sprite

414

sprite_list: List of sprites to search

415

416

Returns:

417

Tuple of (closest_sprite, distance) or (None, None) if list is empty

418

"""

419

420

def get_distance_between_sprites(sprite1: arcade.Sprite, sprite2: arcade.Sprite) -> float:

421

"""

422

Calculate the distance between two sprites.

423

424

Args:

425

sprite1: First sprite

426

sprite2: Second sprite

427

428

Returns:

429

Distance between sprite centers in pixels

430

"""

431

432

def get_sprites_at_point(point: tuple[float, float], sprite_list: arcade.SpriteList) -> list[arcade.Sprite]:

433

"""

434

Get all sprites that contain a specific point.

435

436

Args:

437

point: (x, y) coordinate tuple

438

sprite_list: List of sprites to check

439

440

Returns:

441

List of sprites containing the point

442

"""

443

444

def get_sprites_at_exact_point(point: tuple[float, float], sprite_list: arcade.SpriteList) -> list[arcade.Sprite]:

445

"""

446

Get sprites at an exact point (no hit box checking).

447

448

Args:

449

point: (x, y) coordinate tuple

450

sprite_list: List of sprites to check

451

452

Returns:

453

List of sprites at the exact point

454

"""

455

456

def get_sprites_in_rect(rect: arcade.types.Rect, sprite_list: arcade.SpriteList) -> list[arcade.Sprite]:

457

"""

458

Get all sprites within a rectangular area.

459

460

Args:

461

rect: Rectangle to check (x, y, width, height)

462

sprite_list: List of sprites to check

463

464

Returns:

465

List of sprites within the rectangle

466

"""

467

```

468

469

### Sprite Constants and Types

470

471

Direction constants and type definitions for sprite system.

472

473

```python { .api }

474

# Direction constants for sprite facing

475

FACE_LEFT: str = "left"

476

FACE_RIGHT: str = "right"

477

FACE_UP: str = "up"

478

FACE_DOWN: str = "down"

479

480

# Type definitions

481

SpriteType = arcade.Sprite # Base sprite type

482

SpriteType_co = arcade.Sprite # Covariant sprite type (for type hints)

483

```

484

485

## Usage Examples

486

487

### Basic Sprite Creation and Management

488

489

```python

490

import arcade

491

492

class GameView(arcade.View):

493

def __init__(self):

494

super().__init__()

495

496

# Create sprite lists

497

self.player_list = arcade.SpriteList()

498

self.enemy_list = arcade.SpriteList()

499

self.coin_list = arcade.SpriteList()

500

501

def setup(self):

502

# Create player sprite

503

self.player = arcade.Sprite(":resources:images/space_shooter/meteorGrey_med1.png", 0.5)

504

self.player.center_x = 400

505

self.player.center_y = 300

506

self.player_list.append(self.player)

507

508

# Create enemy sprites

509

for i in range(5):

510

enemy = arcade.Sprite(":resources:images/space_shooter/meteorGrey_med2.png", 0.3)

511

enemy.center_x = 100 + i * 150

512

enemy.center_y = 500

513

enemy.change_y = -2

514

self.enemy_list.append(enemy)

515

516

# Create collectible coins

517

for i in range(10):

518

coin = arcade.SpriteCircle(15, arcade.color.YELLOW)

519

coin.center_x = 50 + i * 70

520

coin.center_y = 100

521

self.coin_list.append(coin)

522

523

def on_update(self, delta_time):

524

# Update all sprites

525

self.player_list.update()

526

self.enemy_list.update()

527

528

# Check collisions

529

hit_list = arcade.check_for_collision_with_list(self.player, self.coin_list)

530

for coin in hit_list:

531

coin.remove_from_sprite_lists()

532

533

# Check enemy collisions

534

if arcade.check_for_collision_with_list(self.player, self.enemy_list):

535

print("Player hit by enemy!")

536

537

def on_draw(self):

538

self.clear()

539

self.player_list.draw()

540

self.enemy_list.draw()

541

self.coin_list.draw()

542

```

543

544

### Animated Sprite Example

545

546

```python

547

import arcade

548

549

class AnimatedPlayer(arcade.AnimatedWalkingSprite):

550

def __init__(self):

551

super().__init__(scale=0.5)

552

553

# Load walking animations

554

self.walk_right_textures = []

555

for i in range(8):

556

texture = arcade.load_texture(f":resources:images/animated_characters/female_person/femalePerson_walk{i}.png")

557

self.walk_right_textures.append(texture)

558

559

# Mirror for left walking

560

self.walk_left_textures = []

561

for texture in self.walk_right_textures:

562

self.walk_left_textures.append(texture.texture.flip_horizontally())

563

564

# Set initial texture

565

self.texture = self.walk_right_textures[0]

566

567

def update_animation(self, delta_time: float = 1/60):

568

# Update animation based on movement

569

if self.change_x > 0:

570

self.texture = self.walk_right_textures[int(self.cur_texture_index)]

571

elif self.change_x < 0:

572

self.texture = self.walk_left_textures[int(self.cur_texture_index)]

573

574

# Advance animation frame

575

if abs(self.change_x) > 0:

576

self.cur_texture_index += 0.1

577

if self.cur_texture_index >= len(self.walk_right_textures):

578

self.cur_texture_index = 0

579

580

class GameView(arcade.View):

581

def setup(self):

582

self.player_list = arcade.SpriteList()

583

self.player = AnimatedPlayer()

584

self.player.center_x = 400

585

self.player.center_y = 300

586

self.player_list.append(self.player)

587

588

def on_update(self, delta_time):

589

self.player_list.update()

590

self.player_list.update_animation(delta_time)

591

592

def on_key_press(self, key, modifiers):

593

if key == arcade.key.LEFT:

594

self.player.change_x = -5

595

elif key == arcade.key.RIGHT:

596

self.player.change_x = 5

597

598

def on_key_release(self, key, modifiers):

599

if key in (arcade.key.LEFT, arcade.key.RIGHT):

600

self.player.change_x = 0

601

```