or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

actions.mdanimation.mdaudio.mdcameras.mddata-management.mdevents.mdgame-objects.mdindex.mdinput.mdloading.mdmath-geometry.mdphysics.mdrendering.mdscenes.mdtweens.mdutilities.md

rendering.mddocs/

0

# Rendering and Display Systems

1

2

Phaser's rendering system provides flexible WebGL and Canvas rendering with comprehensive texture management, visual effects, and display utilities. The system automatically chooses the best available renderer while providing fine-grained control over rendering operations.

3

4

## Renderer System

5

6

### Renderer Types and Configuration

7

Phaser supports multiple rendering backends:

8

9

```javascript { .api }

10

// Game configuration with renderer settings

11

const config = {

12

type: Phaser.AUTO, // Auto-detect best renderer

13

// type: Phaser.WEBGL, // Force WebGL

14

// type: Phaser.CANVAS, // Force Canvas

15

// type: Phaser.HEADLESS, // No rendering (testing)

16

17

width: 800,

18

height: 600,

19

20

render: {

21

antialias: true, // Enable anti-aliasing

22

pixelArt: false, // Optimize for pixel art

23

autoResize: true, // Auto-resize canvas

24

roundPixels: true, // Round pixel positions

25

transparent: false, // Transparent canvas background

26

clearBeforeRender: true, // Clear canvas each frame

27

preserveDrawingBuffer: false, // Keep drawing buffer (screenshots)

28

failIfMajorPerformanceCaveat: false, // Fail on poor performance

29

powerPreference: 'default', // 'high-performance' or 'low-power'

30

batchSize: 4096, // WebGL batch size

31

maxLights: 10, // Maximum point lights

32

maxTextures: -1, // Maximum texture units (-1 = auto)

33

mipmapFilter: 'LINEAR' // Mipmap filtering

34

},

35

36

backgroundColor: '#2c3e50', // Canvas background color

37

38

canvas: document.getElementById('game-canvas'), // Existing canvas

39

canvasStyle: 'width: 100%; height: 100%;', // Canvas CSS

40

41

scene: RenderingScene

42

};

43

44

class RenderingScene extends Phaser.Scene {

45

create() {

46

// Access renderer information

47

const renderer = this.renderer;

48

49

console.log('Renderer type:', renderer.type);

50

console.log('WebGL:', renderer.type === Phaser.WEBGL);

51

console.log('Canvas size:', renderer.width, renderer.height);

52

console.log('Max texture size:', renderer.maxTextureSize);

53

54

if (renderer.gl) {

55

console.log('WebGL context:', renderer.gl);

56

console.log('Extensions:', renderer.extensions);

57

console.log('Max textures:', renderer.maxTextures);

58

}

59

}

60

}

61

```

62

63

### WebGL Renderer Features

64

Advanced WebGL-specific rendering capabilities:

65

66

```javascript { .api }

67

class WebGLRenderingScene extends Phaser.Scene {

68

create() {

69

if (this.renderer.type === Phaser.WEBGL) {

70

const gl = this.renderer.gl;

71

const renderer = this.renderer;

72

73

// WebGL state management

74

renderer.setBlendMode(Phaser.BlendModes.ADD);

75

renderer.pushScissor(100, 100, 200, 150); // Clip region

76

renderer.popScissor(); // Restore previous clip

77

78

// Texture binding

79

renderer.setTexture2D(this.textures.get('myTexture'), 0);

80

renderer.resetTextures();

81

82

// Batch management

83

renderer.flush(); // Force render current batch

84

85

// Framebuffer operations

86

const framebuffer = renderer.createFramebuffer(256, 256, null, false);

87

renderer.setFramebuffer(framebuffer);

88

renderer.setFramebuffer(null); // Back to main framebuffer

89

90

// Custom WebGL operations

91

this.setupCustomWebGL();

92

}

93

}

94

95

setupCustomWebGL() {

96

const gl = this.renderer.gl;

97

98

// Create custom shader program

99

const vertexShaderSource = `

100

attribute vec2 a_position;

101

attribute vec2 a_texCoord;

102

uniform mat3 u_matrix;

103

varying vec2 v_texCoord;

104

105

void main() {

106

vec3 position = u_matrix * vec3(a_position, 1.0);

107

gl_Position = vec4(position, 1.0);

108

v_texCoord = a_texCoord;

109

}

110

`;

111

112

const fragmentShaderSource = `

113

precision mediump float;

114

varying vec2 v_texCoord;

115

uniform sampler2D u_texture;

116

uniform float u_time;

117

118

void main() {

119

vec4 color = texture2D(u_texture, v_texCoord);

120

color.rgb *= 0.5 + 0.5 * sin(u_time);

121

gl_FragColor = color;

122

}

123

`;

124

125

// Compile shaders (simplified - use Phaser's shader system in practice)

126

this.customShader = this.createShaderProgram(vertexShaderSource, fragmentShaderSource);

127

}

128

}

129

```

130

131

## Texture Management

132

133

### Texture System

134

Comprehensive texture loading and management:

135

136

```javascript { .api }

137

class TextureManagementScene extends Phaser.Scene {

138

preload() {

139

// Load various texture types

140

this.load.image('logo', 'assets/logo.png');

141

this.load.atlas('sprites', 'assets/sprites.png', 'assets/sprites.json');

142

this.load.spritesheet('tiles', 'assets/tiles.png', {

143

frameWidth: 32,

144

frameHeight: 32

145

});

146

}

147

148

create() {

149

// Access texture manager

150

const textures = this.textures;

151

152

// Texture operations

153

console.log('Texture exists:', textures.exists('logo'));

154

console.log('All texture keys:', textures.getTextureKeys());

155

156

// Get texture and frame

157

const logoTexture = textures.get('logo');

158

const spriteFrame = textures.getFrame('sprites', 'character.png');

159

160

// Create runtime textures

161

this.createRuntimeTextures();

162

163

// Texture manipulation

164

this.manipulateTextures();

165

166

// Generate textures procedurally

167

this.generateTextures();

168

}

169

170

createRuntimeTextures() {

171

// Canvas texture

172

const canvas = document.createElement('canvas');

173

canvas.width = 128;

174

canvas.height = 128;

175

const ctx = canvas.getContext('2d');

176

177

// Draw on canvas

178

ctx.fillStyle = '#ff0000';

179

ctx.fillRect(0, 0, 64, 64);

180

ctx.fillStyle = '#00ff00';

181

ctx.fillRect(64, 0, 64, 64);

182

ctx.fillStyle = '#0000ff';

183

ctx.fillRect(0, 64, 64, 64);

184

ctx.fillStyle = '#ffff00';

185

ctx.fillRect(64, 64, 64, 64);

186

187

// Add to texture manager

188

this.textures.addCanvas('colorGrid', canvas);

189

190

// Base64 texture

191

this.textures.addBase64('base64Texture', 'data:image/png;base64,iVBORw0KGgoAAAANSUh...');

192

193

// Create from ImageData

194

const imageData = ctx.getImageData(0, 0, 128, 128);

195

this.textures.addImage('imageData', imageData);

196

197

// Use created textures

198

this.add.image(100, 100, 'colorGrid');

199

}

200

201

manipulateTextures() {

202

// Clone texture frame

203

const clonedFrame = this.textures.cloneFrame('logo', '__BASE');

204

205

// Get pixel color

206

const pixelColor = this.textures.getPixel(50, 50, 'logo');

207

console.log('Pixel color:', pixelColor);

208

209

// Get pixel alpha

210

const pixelAlpha = this.textures.getPixelAlpha(50, 50, 'logo');

211

console.log('Pixel alpha:', pixelAlpha);

212

213

// Texture as base64

214

const base64 = this.textures.getBase64('logo');

215

console.log('Texture as base64 length:', base64.length);

216

217

// Set texture filter

218

this.textures.setFilter('logo', 1); // 0 = nearest, 1 = linear

219

}

220

221

generateTextures() {

222

// Procedural noise texture

223

const noiseTexture = this.textures.createCanvas('noise', 256, 256);

224

const ctx = noiseTexture.getContext('2d');

225

const imageData = ctx.getImageData(0, 0, 256, 256);

226

const data = imageData.data;

227

228

for (let i = 0; i < data.length; i += 4) {

229

const noise = Math.random() * 255;

230

data[i] = noise; // Red

231

data[i + 1] = noise; // Green

232

data[i + 2] = noise; // Blue

233

data[i + 3] = 255; // Alpha

234

}

235

236

ctx.putImageData(imageData, 0, 0);

237

noiseTexture.refresh();

238

239

// Gradient texture

240

const gradientTexture = this.textures.createCanvas('gradient', 256, 64);

241

const gradCtx = gradientTexture.getContext('2d');

242

const gradient = gradCtx.createLinearGradient(0, 0, 256, 0);

243

gradient.addColorStop(0, '#ff0000');

244

gradient.addColorStop(0.5, '#00ff00');

245

gradient.addColorStop(1, '#0000ff');

246

247

gradCtx.fillStyle = gradient;

248

gradCtx.fillRect(0, 0, 256, 64);

249

gradientTexture.refresh();

250

251

// Use generated textures

252

this.add.image(300, 200, 'noise');

253

this.add.image(300, 300, 'gradient');

254

}

255

}

256

```

257

258

### Render Textures

259

Dynamic textures for rendering operations:

260

261

```javascript { .api }

262

class RenderTextureScene extends Phaser.Scene {

263

create() {

264

// Create render texture

265

this.renderTexture = this.add.renderTexture(400, 300, 400, 300);

266

267

// Create objects to draw

268

const sprite = this.add.sprite(0, 0, 'player');

269

const graphics = this.add.graphics();

270

graphics.fillStyle(0xff0000);

271

graphics.fillCircle(50, 50, 30);

272

273

// Draw to render texture

274

this.renderTexture.draw(sprite, 100, 100);

275

this.renderTexture.draw(graphics, 200, 150);

276

277

// Draw texture frame

278

this.renderTexture.drawFrame('atlas', 'frame1', 50, 200);

279

280

// Batch drawing

281

const objects = [sprite, graphics];

282

objects.forEach((obj, index) => {

283

this.renderTexture.draw(obj, index * 100, 50);

284

});

285

286

// Render texture operations

287

this.renderTexture.clear(); // Clear contents

288

this.renderTexture.fill(0x00ff00); // Fill with color

289

this.renderTexture.stamp('logo', 10, 10); // Stamp texture

290

291

// Save render texture

292

this.renderTexture.snapshot((image) => {

293

console.log('Render texture saved as image');

294

// Could save to server or local storage

295

});

296

297

// Use render texture on other objects

298

const resultSprite = this.add.sprite(600, 400, this.renderTexture.texture);

299

300

// Dynamic painting system

301

this.setupDynamicPainting();

302

}

303

304

setupDynamicPainting() {

305

// Create painting canvas

306

this.paintTexture = this.add.renderTexture(100, 100, 300, 300);

307

this.paintTexture.fill(0xffffff); // White background

308

309

// Brush settings

310

this.brushSize = 5;

311

this.brushColor = 0x000000;

312

this.isDrawing = false;

313

314

// Mouse/touch painting

315

this.input.on('pointerdown', (pointer) => {

316

if (this.isPointerOverPaintArea(pointer)) {

317

this.isDrawing = true;

318

this.lastPaintPoint = { x: pointer.x - 100, y: pointer.y - 100 };

319

}

320

});

321

322

this.input.on('pointermove', (pointer) => {

323

if (this.isDrawing && this.isPointerOverPaintArea(pointer)) {

324

const currentPoint = { x: pointer.x - 100, y: pointer.y - 100 };

325

this.paintBrushStroke(this.lastPaintPoint, currentPoint);

326

this.lastPaintPoint = currentPoint;

327

}

328

});

329

330

this.input.on('pointerup', () => {

331

this.isDrawing = false;

332

});

333

334

// Brush size controls

335

this.input.keyboard.on('keydown-ONE', () => { this.brushSize = 2; });

336

this.input.keyboard.on('keydown-TWO', () => { this.brushSize = 5; });

337

this.input.keyboard.on('keydown-THREE', () => { this.brushSize = 10; });

338

339

// Color controls

340

this.input.keyboard.on('keydown-R', () => { this.brushColor = 0xff0000; });

341

this.input.keyboard.on('keydown-G', () => { this.brushColor = 0x00ff00; });

342

this.input.keyboard.on('keydown-B', () => { this.brushColor = 0x0000ff; });

343

}

344

345

paintBrushStroke(from, to) {

346

// Create brush graphics

347

const brush = this.add.graphics();

348

brush.fillStyle(this.brushColor);

349

350

// Draw line between points

351

const distance = Phaser.Math.Distance.Between(from.x, from.y, to.x, to.y);

352

const steps = Math.max(1, Math.floor(distance / (this.brushSize / 2)));

353

354

for (let i = 0; i <= steps; i++) {

355

const t = i / steps;

356

const x = Phaser.Math.Linear(from.x, to.x, t);

357

const y = Phaser.Math.Linear(from.y, to.y, t);

358

359

brush.fillCircle(x, y, this.brushSize);

360

}

361

362

// Draw to paint texture

363

this.paintTexture.draw(brush, 0, 0);

364

brush.destroy();

365

}

366

367

isPointerOverPaintArea(pointer) {

368

return pointer.x >= 100 && pointer.x <= 400 &&

369

pointer.y >= 100 && pointer.y <= 400;

370

}

371

}

372

```

373

374

## Blend Modes and Visual Effects

375

376

### Blend Modes

377

Control how objects are composited:

378

379

```javascript { .api }

380

class BlendModeScene extends Phaser.Scene {

381

create() {

382

// Create base objects

383

const background = this.add.rectangle(400, 300, 200, 200, 0x888888);

384

385

// Demonstrate different blend modes

386

const blendModes = [

387

{ mode: Phaser.BlendModes.NORMAL, name: 'Normal' },

388

{ mode: Phaser.BlendModes.ADD, name: 'Add' },

389

{ mode: Phaser.BlendModes.MULTIPLY, name: 'Multiply' },

390

{ mode: Phaser.BlendModes.SCREEN, name: 'Screen' },

391

{ mode: Phaser.BlendModes.OVERLAY, name: 'Overlay' },

392

{ mode: Phaser.BlendModes.DARKEN, name: 'Darken' },

393

{ mode: Phaser.BlendModes.LIGHTEN, name: 'Lighten' },

394

{ mode: Phaser.BlendModes.COLOR_DODGE, name: 'Color Dodge' },

395

{ mode: Phaser.BlendModes.COLOR_BURN, name: 'Color Burn' },

396

{ mode: Phaser.BlendModes.HARD_LIGHT, name: 'Hard Light' },

397

{ mode: Phaser.BlendModes.SOFT_LIGHT, name: 'Soft Light' },

398

{ mode: Phaser.BlendModes.DIFFERENCE, name: 'Difference' },

399

{ mode: Phaser.BlendModes.EXCLUSION, name: 'Exclusion' },

400

{ mode: Phaser.BlendModes.ERASE, name: 'Erase' }

401

];

402

403

blendModes.forEach((blend, index) => {

404

const x = 100 + (index % 4) * 150;

405

const y = 100 + Math.floor(index / 4) * 120;

406

407

// Background circle

408

this.add.circle(x, y, 40, 0xff0000, 0.8);

409

410

// Overlapping circle with blend mode

411

const blendedCircle = this.add.circle(x + 25, y + 25, 40, 0x0000ff, 0.8);

412

blendedCircle.setBlendMode(blend.mode);

413

414

// Label

415

this.add.text(x - 30, y + 60, blend.name, {

416

fontSize: '10px',

417

fill: '#ffffff'

418

});

419

});

420

421

// Interactive blend mode demo

422

this.setupInteractiveBlending();

423

}

424

425

setupInteractiveBlending() {

426

// Create interactive objects

427

this.baseLayer = this.add.circle(600, 300, 60, 0xff6600);

428

this.blendLayer = this.add.circle(650, 330, 60, 0x0066ff);

429

430

let currentBlendIndex = 0;

431

const blendModesList = Object.values(Phaser.BlendModes).filter(mode => typeof mode === 'number');

432

433

this.blendLayer.setBlendMode(blendModesList[currentBlendIndex]);

434

435

// Cycle through blend modes on click

436

this.blendLayer.setInteractive();

437

this.blendLayer.on('pointerdown', () => {

438

currentBlendIndex = (currentBlendIndex + 1) % blendModesList.length;

439

this.blendLayer.setBlendMode(blendModesList[currentBlendIndex]);

440

441

console.log('Blend mode:', Object.keys(Phaser.BlendModes)[currentBlendIndex]);

442

});

443

444

// Animate blend layer

445

this.tweens.add({

446

targets: this.blendLayer,

447

x: 550,

448

duration: 2000,

449

yoyo: true,

450

repeat: -1

451

});

452

}

453

}

454

```

455

456

### Visual Effects and Filters

457

Apply visual effects to game objects:

458

459

```javascript { .api }

460

class VisualEffectsScene extends Phaser.Scene {

461

create() {

462

// Tint effects

463

const redTintedSprite = this.add.sprite(100, 100, 'logo');

464

redTintedSprite.setTint(0xff0000);

465

466

// Multiple tints (corners)

467

const multiTintSprite = this.add.sprite(200, 100, 'logo');

468

multiTintSprite.setTint(0xff0000, 0x00ff00, 0x0000ff, 0xffff00);

469

470

// Alpha effects

471

const alphaSprite = this.add.sprite(300, 100, 'logo');

472

alphaSprite.setAlpha(0.5);

473

474

// Scale effects

475

const scaledSprite = this.add.sprite(400, 100, 'logo');

476

scaledSprite.setScale(2, 0.5);

477

478

// Rotation effects

479

const rotatedSprite = this.add.sprite(500, 100, 'logo');

480

rotatedSprite.setRotation(Math.PI / 4);

481

482

// Flip effects

483

const flippedSprite = this.add.sprite(600, 100, 'logo');

484

flippedSprite.setFlipX(true);

485

flippedSprite.setFlipY(true);

486

487

// Origin effects

488

const originSprite = this.add.sprite(700, 100, 'logo');

489

originSprite.setOrigin(0, 0); // Top-left corner

490

491

// Mask effects

492

this.setupMaskEffects();

493

494

// Shader effects (WebGL only)

495

if (this.renderer.type === Phaser.WEBGL) {

496

this.setupShaderEffects();

497

}

498

499

// Animation effects

500

this.setupAnimationEffects();

501

}

502

503

setupMaskEffects() {

504

// Geometry mask

505

const maskShape = this.add.graphics();

506

maskShape.fillStyle(0xffffff);

507

maskShape.fillCircle(200, 300, 80);

508

509

const geometryMask = maskShape.createGeometryMask();

510

511

const maskedImage = this.add.image(200, 300, 'logo');

512

maskedImage.setMask(geometryMask);

513

514

// Bitmap mask

515

const maskTexture = this.add.image(400, 300, 'maskTexture');

516

const bitmapMask = maskTexture.createBitmapMask();

517

518

const bitmapMaskedImage = this.add.image(400, 300, 'logo');

519

bitmapMaskedImage.setMask(bitmapMask);

520

521

// Animated mask

522

this.tweens.add({

523

targets: maskShape,

524

scaleX: 1.5,

525

scaleY: 1.5,

526

duration: 2000,

527

yoyo: true,

528

repeat: -1

529

});

530

}

531

532

setupShaderEffects() {

533

// Load and create shader

534

this.load.glsl('waveShader', 'assets/shaders/wave.frag');

535

536

this.load.once('complete', () => {

537

const shader = this.add.shader('waveShader', 600, 300, 200, 200);

538

539

// Animate shader uniforms

540

shader.setUniform('time.value', 0);

541

542

this.tweens.add({

543

targets: shader,

544

'uniforms.time.value': 10,

545

duration: 5000,

546

repeat: -1

547

});

548

});

549

550

this.load.start();

551

}

552

553

setupAnimationEffects() {

554

// Pulsing effect

555

const pulsingSprite = this.add.sprite(100, 400, 'logo');

556

this.tweens.add({

557

targets: pulsingSprite,

558

scaleX: 1.2,

559

scaleY: 1.2,

560

duration: 1000,

561

yoyo: true,

562

repeat: -1,

563

ease: 'Sine.easeInOut'

564

});

565

566

// Glowing effect

567

const glowSprite = this.add.sprite(300, 400, 'logo');

568

this.tweens.add({

569

targets: glowSprite,

570

alpha: 0.3,

571

duration: 800,

572

yoyo: true,

573

repeat: -1

574

});

575

576

// Color cycling effect

577

const colorSprite = this.add.sprite(500, 400, 'logo');

578

let hue = 0;

579

580

this.time.addEvent({

581

delay: 50,

582

repeat: -1,

583

callback: () => {

584

hue = (hue + 5) % 360;

585

const color = Phaser.Display.Color.HSVToRGB(hue / 360, 1, 1);

586

colorSprite.setTint(color.color);

587

}

588

});

589

590

// Particle trail effect

591

this.setupParticleTrail();

592

}

593

594

setupParticleTrail() {

595

const trailSprite = this.add.sprite(700, 400, 'logo');

596

597

// Create particle emitter for trail

598

const particles = this.add.particles(0, 0, 'particle', {

599

follow: trailSprite,

600

quantity: 2,

601

scale: { start: 0.3, end: 0 },

602

alpha: { start: 0.8, end: 0 },

603

lifespan: 500,

604

tint: 0x00ff88

605

});

606

607

// Move sprite in circle

608

this.tweens.add({

609

targets: trailSprite,

610

x: 700 + Math.cos(0) * 100,

611

y: 400 + Math.sin(0) * 100,

612

duration: 0

613

});

614

615

let angle = 0;

616

this.time.addEvent({

617

delay: 16,

618

repeat: -1,

619

callback: () => {

620

angle += 0.05;

621

trailSprite.x = 700 + Math.cos(angle) * 100;

622

trailSprite.y = 400 + Math.sin(angle) * 50;

623

}

624

});

625

}

626

}

627

```

628

629

## Display Utilities

630

631

### Alignment and Layout

632

Position and align objects systematically:

633

634

```javascript { .api }

635

class DisplayUtilitiesScene extends Phaser.Scene {

636

create() {

637

// Create container for alignment demo

638

const container = this.add.rectangle(400, 300, 300, 200, 0x333333, 0.5);

639

640

// Create objects to align

641

const objects = [];

642

for (let i = 0; i < 9; i++) {

643

const obj = this.add.circle(0, 0, 15, Phaser.Display.Color.HSVToRGB(i / 9, 1, 1).color);

644

objects.push(obj);

645

}

646

647

// Alignment using Display.Align

648

const alignPositions = [

649

Phaser.Display.Align.TOP_LEFT,

650

Phaser.Display.Align.TOP_CENTER,

651

Phaser.Display.Align.TOP_RIGHT,

652

Phaser.Display.Align.LEFT_CENTER,

653

Phaser.Display.Align.CENTER,

654

Phaser.Display.Align.RIGHT_CENTER,

655

Phaser.Display.Align.BOTTOM_LEFT,

656

Phaser.Display.Align.BOTTOM_CENTER,

657

Phaser.Display.Align.BOTTOM_RIGHT

658

];

659

660

objects.forEach((obj, index) => {

661

Phaser.Display.Align.In.QuickSet(obj, container, alignPositions[index]);

662

});

663

664

// Grid layout

665

this.createGridLayout();

666

667

// Bounds utilities

668

this.demonstrateBounds();

669

670

// Color utilities

671

this.demonstrateColors();

672

}

673

674

createGridLayout() {

675

// Create grid of objects

676

const gridObjects = [];

677

for (let i = 0; i < 20; i++) {

678

const obj = this.add.rectangle(0, 0, 30, 30, 0xff6600);

679

gridObjects.push(obj);

680

}

681

682

// Arrange in grid

683

Phaser.Actions.GridAlign(gridObjects, {

684

width: 5,

685

height: 4,

686

cellWidth: 40,

687

cellHeight: 40,

688

x: 50,

689

y: 50

690

});

691

692

// Circular arrangement

693

const circleObjects = [];

694

for (let i = 0; i < 12; i++) {

695

const obj = this.add.circle(0, 0, 8, 0x00ff88);

696

circleObjects.push(obj);

697

}

698

699

const circle = new Phaser.Geom.Circle(600, 200, 80);

700

Phaser.Actions.PlaceOnCircle(circleObjects, circle);

701

702

// Line arrangement

703

const lineObjects = [];

704

for (let i = 0; i < 10; i++) {

705

const obj = this.add.triangle(0, 0, 0, 10, 10, 10, 5, 0, 0x8800ff);

706

lineObjects.push(obj);

707

}

708

709

const line = new Phaser.Geom.Line(100, 500, 300, 450);

710

Phaser.Actions.PlaceOnLine(lineObjects, line);

711

}

712

713

demonstrateBounds() {

714

const sprite = this.add.sprite(500, 500, 'logo');

715

sprite.setScale(0.5);

716

717

// Get bounds information

718

const bounds = sprite.getBounds();

719

console.log('Sprite bounds:', bounds);

720

721

// Bounds utilities

722

const left = Phaser.Display.Bounds.GetLeft(sprite);

723

const right = Phaser.Display.Bounds.GetRight(sprite);

724

const top = Phaser.Display.Bounds.GetTop(sprite);

725

const bottom = Phaser.Display.Bounds.GetBottom(sprite);

726

const centerX = Phaser.Display.Bounds.GetCenterX(sprite);

727

const centerY = Phaser.Display.Bounds.GetCenterY(sprite);

728

729

console.log('Bounds - Left:', left, 'Right:', right, 'Top:', top, 'Bottom:', bottom);

730

console.log('Center:', centerX, centerY);

731

732

// Set bounds positions

733

const boundSprite = this.add.sprite(0, 0, 'logo');

734

Phaser.Display.Bounds.SetLeft(boundSprite, 100);

735

Phaser.Display.Bounds.SetTop(boundSprite, 100);

736

737

// Center object

738

Phaser.Display.Bounds.CenterOn(boundSprite, 400, 100);

739

740

// Visualize bounds

741

const graphics = this.add.graphics();

742

graphics.lineStyle(2, 0xff0000);

743

graphics.strokeRectShape(bounds);

744

}

745

746

demonstrateColors() {

747

// Color class usage

748

const color1 = new Phaser.Display.Color(255, 128, 64);

749

const color2 = new Phaser.Display.Color();

750

751

// Color operations

752

color2.setFromRGB({ r: 128, g: 255, b: 192 });

753

754

console.log('Color 1 hex:', color1.color32);

755

console.log('Color 2 HSV:', color2.h, color2.s, color2.v);

756

757

// Color manipulation

758

color1.brighten(20);

759

color1.saturate(10);

760

color2.desaturate(15);

761

762

// Color interpolation

763

const interpolated = Phaser.Display.Color.Interpolate.ColorWithColor(

764

color1, color2, 10, 5

765

);

766

767

// Random colors

768

const randomColor = Phaser.Display.Color.RandomRGB();

769

770

// HSV color wheel

771

const colorWheel = Phaser.Display.Color.HSVColorWheel(1, 1);

772

773

// Display color examples

774

colorWheel.forEach((color, index) => {

775

const x = 50 + (index % 16) * 25;

776

const y = 550 + Math.floor(index / 16) * 25;

777

this.add.circle(x, y, 10, color.color);

778

});

779

}

780

}

781

```

782

783

## Performance Optimization

784

785

### Rendering Optimization

786

Techniques for optimal rendering performance:

787

788

```javascript { .api }

789

class RenderingOptimizationScene extends Phaser.Scene {

790

create() {

791

// Object pooling for frequently created/destroyed objects

792

this.bulletPool = this.add.group({

793

classType: Phaser.GameObjects.Image,

794

key: 'bullet',

795

frame: 0,

796

active: false,

797

visible: false,

798

maxSize: 100

799

});

800

801

// Texture atlasing to reduce draw calls

802

this.createAtlasedSprites();

803

804

// Culling optimization

805

this.setupCulling();

806

807

// Batch rendering

808

this.setupBatchRendering();

809

810

// Level-of-detail (LOD) system

811

this.setupLOD();

812

}

813

814

createAtlasedSprites() {

815

// Use texture atlas instead of individual images

816

const atlasSprites = [];

817

const frames = ['sprite1', 'sprite2', 'sprite3', 'sprite4'];

818

819

for (let i = 0; i < 100; i++) {

820

const frame = Phaser.Utils.Array.GetRandom(frames);

821

const sprite = this.add.sprite(

822

Phaser.Math.Between(0, 800),

823

Phaser.Math.Between(0, 600),

824

'gameAtlas',

825

frame

826

);

827

atlasSprites.push(sprite);

828

}

829

}

830

831

setupCulling() {

832

// Manual culling for large number of objects

833

this.objects = [];

834

835

for (let i = 0; i < 500; i++) {

836

const obj = this.add.rectangle(

837

Phaser.Math.Between(0, 2000),

838

Phaser.Math.Between(0, 2000),

839

20, 20,

840

Phaser.Math.Between(0x000000, 0xffffff)

841

);

842

this.objects.push(obj);

843

}

844

845

// Culling update

846

this.cullObjects();

847

}

848

849

cullObjects() {

850

const camera = this.cameras.main;

851

const worldView = camera.worldView;

852

853

this.objects.forEach(obj => {

854

// Check if object is within camera bounds

855

const inView = Phaser.Geom.Rectangle.Overlaps(worldView, obj.getBounds());

856

obj.setVisible(inView);

857

858

// Disable expensive operations for off-screen objects

859

if (!inView && obj.body) {

860

obj.body.enable = false;

861

} else if (inView && obj.body) {

862

obj.body.enable = true;

863

}

864

});

865

}

866

867

setupBatchRendering() {

868

// Use Graphics object for batched drawing

869

this.batchGraphics = this.add.graphics();

870

871

// Draw many shapes in single batch

872

this.batchGraphics.fillStyle(0xff0000);

873

for (let i = 0; i < 100; i++) {

874

this.batchGraphics.fillCircle(

875

Phaser.Math.Between(0, 800),

876

Phaser.Math.Between(0, 600),

877

Phaser.Math.Between(5, 15)

878

);

879

}

880

881

// Use Blitter for many similar sprites

882

this.blitter = this.add.blitter(0, 0, 'particle');

883

884

for (let i = 0; i < 200; i++) {

885

this.blitter.create(

886

Phaser.Math.Between(0, 800),

887

Phaser.Math.Between(0, 600)

888

);

889

}

890

}

891

892

setupLOD() {

893

// Level-of-detail based on distance from camera

894

this.lodObjects = [];

895

896

for (let i = 0; i < 50; i++) {

897

const obj = {

898

x: Phaser.Math.Between(0, 2000),

899

y: Phaser.Math.Between(0, 2000),

900

highDetail: this.add.sprite(0, 0, 'highDetailSprite'),

901

mediumDetail: this.add.sprite(0, 0, 'mediumDetailSprite'),

902

lowDetail: this.add.sprite(0, 0, 'lowDetailSprite')

903

};

904

905

obj.highDetail.setPosition(obj.x, obj.y);

906

obj.mediumDetail.setPosition(obj.x, obj.y);

907

obj.lowDetail.setPosition(obj.x, obj.y);

908

909

this.lodObjects.push(obj);

910

}

911

912

this.updateLOD();

913

}

914

915

updateLOD() {

916

const camera = this.cameras.main;

917

const cameraCenter = new Phaser.Math.Vector2(

918

camera.scrollX + camera.width / 2,

919

camera.scrollY + camera.height / 2

920

);

921

922

this.lodObjects.forEach(obj => {

923

const distance = Phaser.Math.Distance.Between(

924

cameraCenter.x, cameraCenter.y, obj.x, obj.y

925

);

926

927

// Show different detail levels based on distance

928

obj.highDetail.setVisible(distance < 200);

929

obj.mediumDetail.setVisible(distance >= 200 && distance < 500);

930

obj.lowDetail.setVisible(distance >= 500);

931

});

932

}

933

934

update() {

935

// Update optimization systems

936

this.cullObjects();

937

this.updateLOD();

938

939

// Performance monitoring

940

if (this.time.now % 1000 < 16) { // Once per second

941

console.log('FPS:', this.game.loop.actualFps);

942

console.log('Visible objects:', this.children.list.filter(child => child.visible).length);

943

}

944

}

945

}

946

```

947

948

This comprehensive rendering system provides all the tools needed to create visually stunning games with optimal performance across different devices and rendering contexts.