Skip to content

Commit fb2ac96

Browse files
fix(gameobject): pass required props to TileSprite
1 parent 48a5052 commit fb2ac96

File tree

3 files changed

+106
-60
lines changed

3 files changed

+106
-60
lines changed

src/components/GameObjects.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,14 @@ export const TextStyle = GameObjects.TextStyle as unknown as FC<
743743
* An important note about Tile Sprites and NPOT textures: Internally, TileSprite textures use GL_REPEAT to provide seamless repeating of the textures. This, combined with the way in which the textures are handled in WebGL, means they need to be POT (power-of-two) sizes in order to wrap. If you provide a NPOT (non power-of-two) texture to a TileSprite it will generate a POT sized canvas and draw your texture to it, scaled up to the POT size. It's then scaled back down again during rendering to the original dimensions. While this works, in that it allows you to use any size texture for a Tile Sprite, it does mean that NPOT textures are going to appear anti-aliased when rendered, due to the interpolation that took place when it was resized into a POT texture. This is especially visible in pixel art graphics. If you notice it and it becomes an issue, the only way to avoid it is to ensure that you provide POT textures for Tile Sprites.
744744
*/
745745
export const TileSprite = GameObjects.TileSprite as unknown as FC<
746-
Props<GameObjects.TileSprite>
746+
Props<GameObjects.TileSprite> & {
747+
x: GameObjects.TileSprite['x'];
748+
y: GameObjects.TileSprite['y'];
749+
width: GameObjects.TileSprite['width'];
750+
height: GameObjects.TileSprite['height'];
751+
texture: string;
752+
frame?: string | number;
753+
}
747754
>;
748755

749756
/**

src/render/gameobject.test.tsx

Lines changed: 86 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,85 @@ describe('GameObject', () => {
246246
});
247247
});
248248

249+
describe.each(['Image', 'Sprite', 'NineSlice'] as const)('%s', (component) => {
250+
const Component = GameObjects[component];
251+
252+
it('adds game object', () => {
253+
const props = {
254+
x: 1,
255+
y: 2,
256+
};
257+
const texture = 'texture';
258+
const frame = 'frame';
259+
addGameObject(
260+
<Component {...props} texture={texture} frame={frame} />,
261+
scene,
262+
);
263+
expect(Phaser.GameObjects[component]).toHaveBeenCalledWith(
264+
scene,
265+
props.x,
266+
props.y,
267+
texture,
268+
frame,
269+
);
270+
expect(setProps).toHaveBeenCalledWith(expect.anything(), props, scene);
271+
});
272+
273+
it('does not pass certain props to setProps', () => {
274+
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
275+
const props = {
276+
children: [],
277+
key: null,
278+
ref: () => {},
279+
x: 1,
280+
y: 2,
281+
texture: 'texture',
282+
frame: 'frame',
283+
};
284+
addGameObject(<Component {...props} />, scene);
285+
expect(setProps).toHaveBeenCalledWith(
286+
expect.anything(),
287+
{
288+
x: props.x,
289+
y: props.y,
290+
},
291+
scene,
292+
);
293+
consoleErrorSpy.mockRestore();
294+
});
295+
});
296+
297+
describe('composite', () => {
298+
function Composite() {
299+
return (
300+
<Fragment>
301+
<GameObjects.Text
302+
text="text"
303+
style={{
304+
color: '#fff',
305+
font: '42px Arial',
306+
}}
307+
/>
308+
<GameObjects.Sprite texture="texture" frame="frame" />
309+
</Fragment>
310+
);
311+
}
312+
313+
it('renders composite component', () => {
314+
function MyComponent() {
315+
return (
316+
<Fragment>
317+
<Composite />
318+
<GameObjects.Text />
319+
</Fragment>
320+
);
321+
}
322+
addGameObject(<MyComponent />, scene);
323+
expect(Phaser.GameObjects.Text).toHaveBeenCalledTimes(2);
324+
expect(Phaser.GameObjects.Sprite).toHaveBeenCalledTimes(1);
325+
});
326+
});
327+
249328
describe('Light', () => {
250329
it('adds game object', () => {
251330
const props = {
@@ -446,81 +525,29 @@ describe('Text', () => {
446525
});
447526
});
448527

449-
describe.each(['Image', 'Sprite', 'NineSlice'] as const)('%s', (component) => {
450-
const Component = GameObjects[component];
451-
528+
describe('TileSprite', () => {
452529
it('adds game object', () => {
453530
const props = {
454531
x: 1,
455532
y: 2,
533+
width: 3,
534+
height: 4,
456535
};
457536
const texture = 'texture';
458537
const frame = 'frame';
459538
addGameObject(
460-
<Component {...props} texture={texture} frame={frame} />,
539+
<GameObjects.TileSprite {...props} texture={texture} frame={frame} />,
461540
scene,
462541
);
463-
expect(Phaser.GameObjects[component]).toHaveBeenCalledWith(
542+
expect(Phaser.GameObjects.TileSprite).toHaveBeenCalledWith(
464543
scene,
465544
props.x,
466545
props.y,
546+
props.width,
547+
props.height,
467548
texture,
468549
frame,
469550
);
470551
expect(setProps).toHaveBeenCalledWith(expect.anything(), props, scene);
471552
});
472-
473-
it('does not pass certain props to setProps', () => {
474-
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
475-
const props = {
476-
children: [],
477-
key: null,
478-
ref: () => {},
479-
x: 1,
480-
y: 2,
481-
texture: 'texture',
482-
frame: 'frame',
483-
};
484-
addGameObject(<Component {...props} />, scene);
485-
expect(setProps).toHaveBeenCalledWith(
486-
expect.anything(),
487-
{
488-
x: props.x,
489-
y: props.y,
490-
},
491-
scene,
492-
);
493-
consoleErrorSpy.mockRestore();
494-
});
495-
});
496-
497-
describe('composite', () => {
498-
function Composite() {
499-
return (
500-
<Fragment>
501-
<GameObjects.Text
502-
text="text"
503-
style={{
504-
color: '#fff',
505-
font: '42px Arial',
506-
}}
507-
/>
508-
<GameObjects.Sprite texture="texture" frame="frame" />
509-
</Fragment>
510-
);
511-
}
512-
513-
it('renders composite component', () => {
514-
function MyComponent() {
515-
return (
516-
<Fragment>
517-
<Composite />
518-
<GameObjects.Text />
519-
</Fragment>
520-
);
521-
}
522-
addGameObject(<MyComponent />, scene);
523-
expect(Phaser.GameObjects.Text).toHaveBeenCalledTimes(2);
524-
expect(Phaser.GameObjects.Sprite).toHaveBeenCalledTimes(1);
525-
});
526553
});

src/render/gameobject.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,18 @@ export function addGameObject(
157157
gameObject = new element.type(scene, props.x, props.y, props.text, style);
158158
break;
159159

160+
case element.type === Phaser.GameObjects.TileSprite:
161+
gameObject = new element.type(
162+
scene,
163+
props.x,
164+
props.y,
165+
props.width,
166+
props.height,
167+
texture,
168+
frame,
169+
);
170+
break;
171+
160172
// Phaser component
161173
case gameObjects.indexOf(element.type) !== -1:
162174
gameObject = new element.type(scene);

0 commit comments

Comments
 (0)