Phaser 游戏对象 #
游戏对象概述 #
游戏对象(Game Objects)是 Phaser 游戏中所有可见元素的基础。Phaser 提供了多种类型的游戏对象,每种都有特定的用途。
text
┌─────────────────────────────────────────────────────────────┐
│ 游戏对象继承关系 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Phaser.GameObjects.GameObject │
│ ├── Phaser.GameObjects.Image │
│ ├── Phaser.GameObjects.Sprite │
│ ├── Phaser.GameObjects.Text │
│ ├── Phaser.GameObjects.Container │
│ ├── Phaser.GameObjects.Graphics │
│ ├── Phaser.GameObjects.Shape │
│ │ ├── Rectangle │
│ │ ├── Circle │
│ │ ├── Ellipse │
│ │ ├── Triangle │
│ │ ├── Line │
│ │ └── Polygon │
│ ├── Phaser.GameObjects.TileSprite │
│ ├── Phaser.GameObjects.BitmapText │
│ ├── Phaser.GameObjects.Rope │
│ └── Phaser.GameObjects.Particles.ParticleEmitter │
│ │
└─────────────────────────────────────────────────────────────┘
图像(Image) #
创建图像 #
javascript
const image = this.add.image(x, y, 'textureKey');
const image = this.add.image(400, 300, 'sky');
const image = this.add.image(400, 300, 'atlas', 'frameName');
图像属性 #
javascript
const image = this.add.image(400, 300, 'player');
image.x = 100;
image.y = 200;
image.setPosition(100, 200);
image.scaleX = 2;
image.scaleY = 2;
image.setScale(2, 2);
image.rotation = Math.PI / 4;
image.angle = 45;
image.alpha = 0.5;
image.visible = true;
image.setOrigin(0.5, 0.5);
image.depth = 10;
image.setFlipX(true);
image.setFlipY(true);
图像方法 #
javascript
const image = this.add.image(400, 300, 'player');
image.setTexture('newTexture');
image.setTexture('atlas', 'newFrame');
image.destroy();
const bounds = image.getBounds();
const center = image.getCenter();
const topLeft = image.getTopLeft();
精灵(Sprite) #
创建精灵 #
javascript
const sprite = this.add.sprite(x, y, 'textureKey');
const sprite = this.add.sprite(100, 100, 'player');
const sprite = this.physics.add.sprite(100, 100, 'player');
精灵与图像的区别 #
text
┌─────────────────────────────────────────────────────────────┐
│ Image vs Sprite │
├─────────────────────────────────────────────────────────────┤
│ │
│ Image: │
│ ├── 更轻量级 │
│ ├── 不支持动画 │
│ ├── 适合静态图像 │
│ └── 性能更好 │
│ │
│ Sprite: │
│ ├── 支持帧动画 │
│ ├── 可以播放动画 │
│ ├── 适合需要动画的游戏对象 │
│ └── 稍重于 Image │
│ │
└─────────────────────────────────────────────────────────────┘
精灵动画 #
javascript
preload() {
this.load.spritesheet('dude', 'assets/dude.png', {
frameWidth: 32,
frameHeight: 48
});
}
create() {
this.anims.create({
key: 'left',
frames: this.anims.generateFrameNumbers('dude', { start: 0, end: 3 }),
frameRate: 10,
repeat: -1
});
this.anims.create({
key: 'turn',
frames: [ { key: 'dude', frame: 4 } ],
frameRate: 20
});
this.anims.create({
key: 'right',
frames: this.anims.generateFrameNumbers('dude', { start: 5, end: 8 }),
frameRate: 10,
repeat: -1
});
const player = this.add.sprite(100, 100, 'dude');
player.anims.play('left');
player.anims.stop();
}
文本(Text) #
创建文本 #
javascript
const text = this.add.text(x, y, 'content', style);
const text = this.add.text(400, 300, 'Hello World', {
fontSize: '32px',
fill: '#ffffff'
});
const text = this.add.text(100, 100, 'Score: 0', {
fontFamily: 'Arial',
fontSize: '24px',
fontStyle: 'bold',
color: '#ffffff',
backgroundColor: '#000000',
padding: { x: 10, y: 5 }
});
文本样式 #
javascript
const style = {
fontFamily: 'Arial',
fontSize: '32px',
fontStyle: 'bold italic',
color: '#ffffff',
backgroundColor: '#000000',
stroke: '#ff0000',
strokeThickness: 2,
shadow: {
offsetX: 2,
offsetY: 2,
color: '#000000',
blur: 5,
fill: true
},
align: 'center',
padding: {
left: 10,
right: 10,
top: 5,
bottom: 5
},
lineSpacing: 10,
wordWrap: {
width: 300,
useAdvancedWrap: true
},
maxLines: 5,
fixedWidth: 200,
fixedHeight: 100
};
const text = this.add.text(400, 300, 'Hello', style);
文本方法 #
javascript
const text = this.add.text(400, 300, 'Score: 0', { fontSize: '32px' });
text.setText('Score: 100');
text.setStyle({ color: '#ff0000' });
text.setFontSize('48px');
text.setFontFamily('Georgia');
text.setColor('#00ff00');
text.setBackgroundColor('#333333');
text.setShadow(2, 2, '#000000', 5, true, true);
text.setAlign('center');
text.setPadding(10, 10, 10, 10);
text.setWordWrapWidth(300, true);
const width = text.width;
const height = text.height;
多行文本 #
javascript
const text = this.add.text(100, 100, 'Line 1\nLine 2\nLine 3', {
fontSize: '24px',
align: 'center',
lineSpacing: 10
});
const text = this.add.text(100, 100, '', {
fontSize: '24px',
wordWrap: { width: 200 }
});
text.setText('This is a very long text that will wrap automatically.');
图形(Graphics) #
创建图形 #
javascript
const graphics = this.add.graphics();
graphics.fillStyle(0xff0000, 1);
graphics.fillRect(100, 100, 200, 150);
graphics.lineStyle(2, 0x00ff00, 1);
graphics.strokeRect(100, 100, 200, 150);
graphics.fillStyle(0x0000ff, 0.5);
graphics.fillCircle(400, 300, 50);
graphics.lineStyle(3, 0xffff00, 1);
graphics.strokeCircle(400, 300, 50);
绘制方法 #
javascript
const graphics = this.add.graphics();
graphics.fillStyle(0xff0000, 1);
graphics.fillRect(x, y, width, height);
graphics.lineStyle(2, 0x00ff00, 1);
graphics.strokeRect(x, y, width, height);
graphics.fillStyle(0x0000ff, 1);
graphics.fillCircle(x, y, radius);
graphics.lineStyle(2, 0xffff00, 1);
graphics.strokeCircle(x, y, radius);
graphics.lineStyle(2, 0xff00ff, 1);
graphics.lineBetween(x1, y1, x2, y2);
graphics.beginPath();
graphics.moveTo(100, 100);
graphics.lineTo(200, 100);
graphics.lineTo(150, 50);
graphics.closePath();
graphics.strokePath();
graphics.fillStyle(0x00ffff, 1);
graphics.fillTriangle(x1, y1, x2, y2, x3, y3);
graphics.lineStyle(2, 0xff00ff, 1);
graphics.strokeTriangle(x1, y1, x2, y2, x3, y3);
graphics.fillStyle(0xffa500, 1);
graphics.fillRoundedRect(x, y, width, height, radius);
graphics.clear();
渐变填充 #
javascript
const graphics = this.add.graphics();
graphics.fillGradientStyle(0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 1);
graphics.fillRect(100, 100, 200, 150);
形状对象 #
矩形 #
javascript
const rect = this.add.rectangle(x, y, width, height, fillColor, fillAlpha);
const rect = this.add.rectangle(400, 300, 200, 100, 0xff0000);
rect.setStrokeStyle(2, 0x00ff00);
rect.setFillStyle(0x0000ff, 0.5);
圆形 #
javascript
const circle = this.add.circle(x, y, radius, fillColor, fillAlpha);
const circle = this.add.circle(400, 300, 50, 0x00ff00);
circle.setStrokeStyle(3, 0xff0000);
椭圆 #
javascript
const ellipse = this.add.ellipse(x, y, width, height, fillColor, fillAlpha);
const ellipse = this.add.ellipse(400, 300, 100, 50, 0x0000ff);
三角形 #
javascript
const triangle = this.add.triangle(x, y, x1, y1, x2, y2, x3, y3, fillColor, fillAlpha);
const triangle = this.add.triangle(400, 300, 0, 50, 50, -50, 100, 50, 0xffff00);
多边形 #
javascript
const polygon = this.add.polygon(x, y, points, fillColor, fillAlpha);
const polygon = this.add.polygon(400, 300, [0, 0, 50, 100, 100, 50, 50, -50], 0xff00ff);
线条 #
javascript
const line = this.add.line(x, y, x1, y1, x2, y2, strokeColor, strokeAlpha);
const line = this.add.line(400, 300, 0, 0, 100, 100, 0x00ffff);
容器(Container) #
创建容器 #
javascript
const container = this.add.container(x, y);
const container = this.add.container(400, 300);
const image = this.add.image(0, 0, 'player');
const text = this.add.text(0, 50, 'Player 1', { fontSize: '16px' });
container.add([image, text]);
container.add(image);
容器操作 #
javascript
const container = this.add.container(400, 300);
container.add(image);
container.addAt(text, 0);
container.remove(image);
container.removeAt(0);
container.removeAll();
container.moveUp(image);
container.moveDown(image);
container.moveTo(image, 2);
container.swap(image, text);
const first = container.first;
const last = container.last;
const count = container.length;
container.each((child) => {
child.alpha = 0.5;
});
container.iterate('sprite', (child) => {
child.setTint(0xff0000);
});
容器属性 #
javascript
const container = this.add.container(400, 300);
container.x = 100;
container.y = 200;
container.rotation = Math.PI / 4;
container.alpha = 0.8;
container.visible = true;
container.setScale(2, 2);
container.setSize(200, 150);
container.setAngle(45);
container.setDepth(10);
container.list.forEach(child => {
console.log(child);
});
容器嵌套 #
javascript
const outerContainer = this.add.container(400, 300);
const innerContainer = this.add.container(0, 0);
const image = this.add.image(0, 0, 'player');
innerContainer.add(image);
outerContainer.add(innerContainer);
平铺精灵(TileSprite) #
创建平铺精灵 #
javascript
const tileSprite = this.add.tileSprite(x, y, width, height, textureKey);
const tileSprite = this.add.tileSprite(400, 300, 800, 600, 'ground');
平铺精灵滚动 #
javascript
const background = this.add.tileSprite(400, 300, 800, 600, 'sky');
update() {
background.tilePositionX += 1;
background.tilePositionY += 0.5;
}
background.setTilePosition(100, 50);
background.setTileScale(2, 2);
background.tileScaleX = 2;
background.tileScaleY = 2;
位图文本(BitmapText) #
创建位图文本 #
javascript
preload() {
this.load.bitmapFont('font', 'assets/font.png', 'assets/font.xml');
}
create() {
const text = this.add.bitmapText(x, y, 'font', 'content', size);
const text = this.add.bitmapText(100, 100, 'font', 'Hello World', 32);
}
位图文本属性 #
javascript
const text = this.add.bitmapText(100, 100, 'font', 'Score: 0', 32);
text.setText('Score: 100');
text.setFontSize(48);
text.setLetterSpacing(2);
text.setAlign(1);
text.setTint(0xff0000);
text.setDropShadow(2, 2, 0x000000, 0.5);
渲染纹理(RenderTexture) #
创建渲染纹理 #
javascript
const rt = this.add.renderTexture(x, y, width, height);
const rt = this.add.renderTexture(0, 0, 800, 600);
渲染纹理操作 #
javascript
const rt = this.add.renderTexture(0, 0, 800, 600);
const image = this.add.image(0, 0, 'player').setVisible(false);
rt.draw(image, 100, 100);
rt.draw('player', 200, 200);
rt.clear();
rt.fill(0xff0000, 0.5);
rt.erase(image, 100, 100);
const texture = rt.saveTexture('savedTexture');
const snapshot = rt.snapshot();
游戏对象通用属性 #
变换属性 #
javascript
gameObject.x = 100;
gameObject.y = 200;
gameObject.setPosition(100, 200);
gameObject.scaleX = 2;
gameObject.scaleY = 2;
gameObject.setScale(2, 2);
gameObject.rotation = Math.PI / 4;
gameObject.angle = 45;
gameObject.setOrigin(0.5, 0.5);
显示属性 #
javascript
gameObject.alpha = 0.5;
gameObject.setAlpha(0.5);
gameObject.visible = true;
gameObject.setVisible(true);
gameObject.depth = 10;
gameObject.setDepth(10);
gameObject.setTint(0xff0000);
gameObject.setTint(0xff0000, 0x00ff00, 0x0000ff, 0xffff00);
gameObject.clearTint();
gameObject.setFlipX(true);
gameObject.setFlipY(true);
混合模式 #
javascript
gameObject.setBlendMode(Phaser.BlendModes.NORMAL);
gameObject.setBlendMode(Phaser.BlendModes.ADD);
gameObject.setBlendMode(Phaser.BlendModes.MULTIPLY);
gameObject.setBlendMode(Phaser.BlendModes.SCREEN);
游戏对象事件 #
交互事件 #
javascript
const sprite = this.add.sprite(400, 300, 'button').setInteractive();
sprite.on('pointerdown', (pointer) => {
console.log('Clicked at', pointer.x, pointer.y);
});
sprite.on('pointerup', (pointer) => {
console.log('Released');
});
sprite.on('pointerover', (pointer) => {
sprite.setTint(0xcccccc);
});
sprite.on('pointerout', (pointer) => {
sprite.clearTint();
});
sprite.on('pointermove', (pointer) => {
console.log('Moving over sprite');
});
拖拽事件 #
javascript
const sprite = this.add.sprite(400, 300, 'draggable')
.setInteractive({ draggable: true });
this.input.setDraggable(sprite);
this.input.on('drag', (pointer, gameObject, dragX, dragY) => {
gameObject.x = dragX;
gameObject.y = dragY;
});
this.input.on('dragstart', (pointer, gameObject) => {
gameObject.setTint(0xff0000);
});
this.input.on('dragend', (pointer, gameObject) => {
gameObject.clearTint();
});
下一步 #
现在你已经掌握了游戏对象,接下来学习 精灵系统,深入了解精灵的创建与管理!
最后更新:2026-03-29