or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

audio.mdevents-input.mdfile-io.mdfonts-text.mdgraphics-rendering.mdimage-processing.mdindex.mdjoystick-input.mdsprites-animation.mdsystem-utils.mdtimer.mdwindow-display.md

sprites-animation.mddocs/

0

# Sprite and Animation System

1

2

High-level sprite management, animation, and rendering systems for 2D games and applications. The PySDL2 extension module provides object-oriented sprite classes and efficient batch rendering systems.

3

4

## Capabilities

5

6

### Sprite Classes

7

8

Core sprite classes for representing game objects and visual elements.

9

10

```python { .api }

11

class Sprite:

12

"""

13

Base sprite class for 2D game objects.

14

15

Attributes:

16

- x: horizontal position

17

- y: vertical position

18

- size: (width, height) tuple

19

"""

20

21

def __init__(self, x: int = 0, y: int = 0):

22

"""

23

Create sprite at position.

24

25

Parameters:

26

- x: initial X coordinate

27

- y: initial Y coordinate

28

"""

29

30

@property

31

def position(self) -> tuple[int, int]:

32

"""Get sprite position as (x, y) tuple."""

33

34

@position.setter

35

def position(self, value: tuple[int, int]) -> None:

36

"""Set sprite position from (x, y) tuple."""

37

38

@property

39

def size(self) -> tuple[int, int]:

40

"""Get sprite size as (width, height) tuple."""

41

42

class SoftwareSprite(Sprite):

43

"""

44

Software-rendered sprite using SDL surfaces.

45

46

Uses CPU-based blitting for rendering. Best for applications with

47

few sprites or when hardware acceleration is unavailable.

48

"""

49

50

def __init__(self, surface: SDL_Surface, free: bool = False, x: int = 0, y: int = 0):

51

"""

52

Create software sprite from surface.

53

54

Parameters:

55

- surface: SDL_Surface containing sprite image

56

- free: whether to free surface when sprite is destroyed

57

- x, y: initial position

58

"""

59

60

class TextureSprite(Sprite):

61

"""

62

Hardware-accelerated sprite using SDL textures.

63

64

Uses GPU-based rendering for better performance. Requires

65

hardware-accelerated renderer.

66

"""

67

68

def __init__(self, texture: SDL_Texture, x: int = 0, y: int = 0):

69

"""

70

Create texture sprite from texture.

71

72

Parameters:

73

- texture: SDL_Texture containing sprite image

74

- x, y: initial position

75

"""

76

```

77

78

### Sprite Factory

79

80

Factory class for creating sprites from various sources.

81

82

```python { .api }

83

class SpriteFactory:

84

"""Factory for creating sprites from images and other sources."""

85

86

def __init__(self, sprite_type: int = TEXTURE, renderer: Renderer = None,

87

fontmanager: FontManager = None):

88

"""

89

Create sprite factory.

90

91

Parameters:

92

- sprite_type: TEXTURE for TextureSprite, SOFTWARE for SoftwareSprite

93

- renderer: Renderer for texture sprites (required for TEXTURE type)

94

- fontmanager: FontManager for text sprites

95

"""

96

97

def from_image(self, fname: str) -> Sprite:

98

"""

99

Create sprite from image file.

100

101

Parameters:

102

- fname: path to image file

103

104

Returns:

105

Sprite object loaded from image

106

"""

107

108

def from_surface(self, surface: SDL_Surface, free: bool = False) -> Sprite:

109

"""

110

Create sprite from SDL surface.

111

112

Parameters:

113

- surface: SDL_Surface to create sprite from

114

- free: whether to free surface when sprite is destroyed

115

116

Returns:

117

Sprite object created from surface

118

"""

119

120

def from_color(self, color: tuple[int, int, int, int], size: tuple[int, int]) -> Sprite:

121

"""

122

Create solid color sprite.

123

124

Parameters:

125

- color: RGBA color tuple (0-255 each component)

126

- size: (width, height) sprite dimensions

127

128

Returns:

129

Sprite filled with solid color

130

"""

131

132

def from_text(self, text: str, font: FontTTF = None, size: int = 12,

133

color: tuple[int, int, int] = (255, 255, 255)) -> Sprite:

134

"""

135

Create text sprite.

136

137

Parameters:

138

- text: text string to render

139

- font: font to use (None for default)

140

- size: font size in points

141

- color: RGB text color

142

143

Returns:

144

Sprite containing rendered text

145

"""

146

147

def create_texture_sprite(self, renderer: Renderer, size: tuple[int, int]) -> TextureSprite:

148

"""

149

Create empty texture sprite for custom drawing.

150

151

Parameters:

152

- renderer: renderer to create texture for

153

- size: (width, height) texture dimensions

154

155

Returns:

156

Empty TextureSprite that can be drawn to

157

"""

158

```

159

160

### Sprite Factory Constants

161

162

```python { .api }

163

TEXTURE: int = 1 # Create TextureSprite objects

164

SOFTWARE: int = 2 # Create SoftwareSprite objects

165

```

166

167

### Sprite Rendering Systems

168

169

Efficient batch rendering systems for sprites.

170

171

```python { .api }

172

class SpriteRenderSystem:

173

"""Base class for sprite rendering systems."""

174

175

def render(self, sprites: list[Sprite]) -> None:

176

"""

177

Render list of sprites.

178

179

Parameters:

180

- sprites: list of Sprite objects to render

181

"""

182

183

class SoftwareSpriteRenderSystem(SpriteRenderSystem):

184

"""Software-based sprite rendering system using surface blitting."""

185

186

def __init__(self, window: Window):

187

"""

188

Create software sprite renderer.

189

190

Parameters:

191

- window: Window to render sprites to

192

"""

193

194

def render(self, sprites: list[Sprite]) -> None:

195

"""Render sprites using CPU blitting."""

196

197

class TextureSpriteRenderSystem(SpriteRenderSystem):

198

"""Hardware-accelerated sprite rendering system using textures."""

199

200

def __init__(self, renderer: Renderer):

201

"""

202

Create texture sprite renderer.

203

204

Parameters:

205

- renderer: Renderer to use for sprite rendering

206

"""

207

208

def render(self, sprites: list[Sprite]) -> None:

209

"""Render sprites using GPU acceleration."""

210

211

def render_sprite(self, sprite: TextureSprite, x: int = None, y: int = None,

212

area: SDL_Rect = None) -> None:

213

"""

214

Render single sprite.

215

216

Parameters:

217

- sprite: TextureSprite to render

218

- x, y: override position (None to use sprite position)

219

- area: source area to render (None for entire sprite)

220

"""

221

```

222

223

### Entity-Component System

224

225

Framework for managing game entities with component-based architecture.

226

227

```python { .api }

228

class Entity:

229

"""

230

Game entity in entity-component system.

231

232

Entities are containers for components that define behavior

233

and properties.

234

"""

235

236

def __init__(self, world: World = None, *args, **kwargs):

237

"""

238

Create entity.

239

240

Parameters:

241

- world: World to add entity to

242

- args, kwargs: additional arguments

243

"""

244

245

class World:

246

"""

247

Container for entities and systems.

248

249

Manages entity lifecycle and system processing.

250

"""

251

252

def __init__(self):

253

"""Create empty world."""

254

255

def add_system(self, system: System) -> None:

256

"""

257

Add system to world.

258

259

Parameters:

260

- system: System to add

261

"""

262

263

def remove_system(self, system: System) -> None:

264

"""

265

Remove system from world.

266

267

Parameters:

268

- system: System to remove

269

"""

270

271

def get_entities(self, component: type) -> list[Entity]:

272

"""

273

Get entities that have specific component.

274

275

Parameters:

276

- component: component type to search for

277

278

Returns:

279

List of entities with the component

280

"""

281

282

def process(self) -> None:

283

"""Process all systems in the world."""

284

285

class System:

286

"""

287

Base class for entity-component systems.

288

289

Systems process entities that have specific components.

290

"""

291

292

def __init__(self):

293

"""Create system."""

294

295

def process(self, world: World, components: dict) -> None:

296

"""

297

Process entities with required components.

298

299

Parameters:

300

- world: World containing entities

301

- components: dictionary of component types to process

302

"""

303

304

class Applicator:

305

"""

306

Utility for applying functions to entities with specific components.

307

308

Provides functional programming interface for entity processing.

309

"""

310

311

def __init__(self, world: World):

312

"""

313

Create applicator for world.

314

315

Parameters:

316

- world: World to operate on

317

"""

318

319

def apply(self, func: callable, *component_types) -> None:

320

"""

321

Apply function to entities with specified components.

322

323

Parameters:

324

- func: function to apply to matching entities

325

- component_types: component types entities must have

326

"""

327

```

328

329

### Particle System

330

331

Basic particle system for visual effects.

332

333

```python { .api }

334

class ParticleEngine:

335

"""

336

Basic particle system for effects.

337

338

Note: This is from the particles module which may have encoding issues.

339

Check source if this doesn't work as expected.

340

"""

341

342

def __init__(self):

343

"""Create particle engine."""

344

345

def process(self, world: World, componentsets: dict) -> None:

346

"""Process particle components."""

347

```

348

349

## Usage Examples

350

351

### Basic Sprite Creation and Rendering

352

353

```python

354

import sdl2.ext

355

356

# Initialize SDL2 extensions

357

sdl2.ext.init()

358

359

# Create window and renderer

360

window = sdl2.ext.Window("Sprite Example", size=(800, 600))

361

window.show()

362

renderer = sdl2.ext.Renderer(window)

363

364

# Create sprite factory for texture sprites

365

factory = sdl2.ext.SpriteFactory(sdl2.ext.TEXTURE, renderer=renderer)

366

367

# Create sprite from image file

368

player_sprite = factory.from_image("player.png")

369

player_sprite.position = (100, 100)

370

371

# Create colored sprite

372

enemy_sprite = factory.from_color((255, 0, 0, 255), (32, 32)) # Red 32x32 square

373

enemy_sprite.position = (200, 150)

374

375

# Create rendering system

376

render_system = sdl2.ext.TextureSpriteRenderSystem(renderer)

377

378

# Main game loop

379

running = True

380

while running:

381

# Handle events

382

events = sdl2.ext.get_events()

383

for event in events:

384

if event.type == sdl2.SDL_QUIT:

385

running = False

386

elif event.type == sdl2.SDL_KEYDOWN:

387

# Move player sprite with arrow keys

388

if event.key.keysym.sym == sdl2.SDLK_LEFT:

389

player_sprite.x -= 5

390

elif event.key.keysym.sym == sdl2.SDLK_RIGHT:

391

player_sprite.x += 5

392

elif event.key.keysym.sym == sdl2.SDLK_UP:

393

player_sprite.y -= 5

394

elif event.key.keysym.sym == sdl2.SDLK_DOWN:

395

player_sprite.y += 5

396

397

# Clear screen

398

renderer.clear((0, 50, 100))

399

400

# Render sprites

401

render_system.render([player_sprite, enemy_sprite])

402

403

# Present frame

404

renderer.present()

405

406

sdl2.ext.quit()

407

```

408

409

### Software Sprite Rendering

410

411

```python

412

import sdl2.ext

413

414

# Initialize with software rendering

415

sdl2.ext.init()

416

window = sdl2.ext.Window("Software Sprites", size=(640, 480))

417

window.show()

418

419

# Create software sprite factory

420

factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE)

421

422

# Create sprites from images

423

sprites = []

424

for i in range(5):

425

sprite = factory.from_image(f"sprite_{i}.bmp")

426

sprite.position = (i * 100, 100)

427

sprites.append(sprite)

428

429

# Create software rendering system

430

render_system = sdl2.ext.SoftwareSpriteRenderSystem(window)

431

432

# Main loop

433

running = True

434

while running:

435

events = sdl2.ext.get_events()

436

for event in events:

437

if event.type == sdl2.SDL_QUIT:

438

running = False

439

440

# Move sprites

441

for sprite in sprites:

442

sprite.y = 100 + 50 * math.sin((sprite.x + frame_count) * 0.05)

443

444

# Render all sprites

445

render_system.render(sprites)

446

447

frame_count += 1

448

449

sdl2.ext.quit()

450

```

451

452

### Entity-Component System Example

453

454

```python

455

import sdl2.ext

456

457

# Define components

458

class Position:

459

def __init__(self, x=0, y=0):

460

self.x = x

461

self.y = y

462

463

class Velocity:

464

def __init__(self, vx=0, vy=0):

465

self.vx = vx

466

self.vy = vy

467

468

class Renderable:

469

def __init__(self, sprite):

470

self.sprite = sprite

471

472

# Define movement system

473

class MovementSystem(sdl2.ext.System):

474

def __init__(self):

475

super().__init__()

476

self.componenttypes = (Position, Velocity)

477

478

def process(self, world, componentsets):

479

for entity in componentsets:

480

position = entity[Position]

481

velocity = entity[Velocity]

482

483

position.x += velocity.vx

484

position.y += velocity.vy

485

486

# Wrap around screen edges

487

if position.x < 0:

488

position.x = 800

489

elif position.x > 800:

490

position.x = 0

491

492

# Initialize SDL2

493

sdl2.ext.init()

494

window = sdl2.ext.Window("ECS Example", size=(800, 600))

495

window.show()

496

renderer = sdl2.ext.Renderer(window)

497

498

# Create world and systems

499

world = sdl2.ext.World()

500

movement_system = MovementSystem()

501

render_system = sdl2.ext.TextureSpriteRenderSystem(renderer)

502

503

world.add_system(movement_system)

504

505

# Create sprite factory

506

factory = sdl2.ext.SpriteFactory(sdl2.ext.TEXTURE, renderer=renderer)

507

508

# Create entities

509

for i in range(10):

510

entity = sdl2.ext.Entity(world)

511

512

# Add components

513

entity.components[Position] = Position(i * 80, 200)

514

entity.components[Velocity] = Velocity(random.randint(-3, 3), random.randint(-2, 2))

515

516

sprite = factory.from_color((255, 255, 0, 255), (16, 16))

517

entity.components[Renderable] = Renderable(sprite)

518

519

# Main loop

520

running = True

521

while running:

522

events = sdl2.ext.get_events()

523

for event in events:

524

if event.type == sdl2.SDL_QUIT:

525

running = False

526

527

# Process systems

528

world.process()

529

530

# Render

531

renderer.clear((0, 0, 0))

532

533

# Get all entities with Position and Renderable components

534

renderable_entities = world.get_entities((Position, Renderable))

535

sprites_to_render = []

536

537

for entity in renderable_entities:

538

position = entity.components[Position]

539

renderable = entity.components[Renderable]

540

541

renderable.sprite.position = (position.x, position.y)

542

sprites_to_render.append(renderable.sprite)

543

544

render_system.render(sprites_to_render)

545

renderer.present()

546

547

sdl2.ext.quit()

548

```

549

550

### Sprite Animation Example

551

552

```python

553

import sdl2.ext

554

import time

555

556

# Initialize SDL2

557

sdl2.ext.init()

558

window = sdl2.ext.Window("Sprite Animation", size=(800, 600))

559

window.show()

560

renderer = sdl2.ext.Renderer(window)

561

562

# Create sprite factory

563

factory = sdl2.ext.SpriteFactory(sdl2.ext.TEXTURE, renderer=renderer)

564

565

# Load animation frames

566

animation_frames = []

567

for i in range(8): # Assuming 8 frame animation

568

frame = factory.from_image(f"animation_frame_{i}.png")

569

animation_frames.append(frame)

570

571

# Animation variables

572

current_frame = 0

573

frame_duration = 0.1 # 100ms per frame

574

last_frame_time = time.time()

575

576

# Create rendering system

577

render_system = sdl2.ext.TextureSpriteRenderSystem(renderer)

578

579

# Main loop

580

running = True

581

while running:

582

current_time = time.time()

583

584

events = sdl2.ext.get_events()

585

for event in events:

586

if event.type == sdl2.SDL_QUIT:

587

running = False

588

589

# Update animation

590

if current_time - last_frame_time >= frame_duration:

591

current_frame = (current_frame + 1) % len(animation_frames)

592

last_frame_time = current_time

593

594

# Position current frame

595

current_sprite = animation_frames[current_frame]

596

current_sprite.position = (350, 250)

597

598

# Render

599

renderer.clear((0, 0, 0))

600

render_system.render([current_sprite])

601

renderer.present()

602

603

sdl2.ext.quit()

604

```