Skip to content

Commit

Permalink
Merge 0b14426 into 75b698c
Browse files Browse the repository at this point in the history
  • Loading branch information
eonarheim committed Jul 3, 2021
2 parents 75b698c + 0b14426 commit a2f5f54
Show file tree
Hide file tree
Showing 8 changed files with 236 additions and 101 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -47,6 +47,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Added

- Added `TileMap` arbitrary graphics support with `.addGraphic()` ([#1862](https://github.com/excaliburjs/Excalibur/issues/1862))
- Added `TileMap` row and column accessors `getRows()` and `getColumns()` ([#1859](https://github.com/excaliburjs/Excalibur/issues/1859))
- Added the ability to store arbitrary data in `TileMap` cells with `Cell.data.set('key', 'value')` and `Cell.data.get('key')` ([#1861](https://github.com/excaliburjs/Excalibur/issues/1861))
- Actions `moveTo()`, `moveBy()`, `easeTo()`, `scaleTo()`, and `scaleBy()` now have vector overloads
- `Animation.fromSpriteSheet` will now log a warning if an index into the `SpriteSheet` is invalid ([#1856](https://github.com/excaliburjs/Excalibur/issues/1856))
- `new ImageSource()` will now log a warning if an image type isn't fully supported. ([#1855](https://github.com/excaliburjs/Excalibur/issues/1855))
Expand Down
14 changes: 11 additions & 3 deletions sandbox/src/game.ts
Expand Up @@ -327,9 +327,17 @@ var tileBlockWidth = 64,
// var tileMap = new ex.TileMap(100, 300, tileBlockWidth, tileBlockHeight, 4, 500);
var tileMap = new ex.TileMap({ x: 100, y: 300, cellWidth: tileBlockWidth, cellHeight: tileBlockHeight, rows: 4, cols: 500 });
var blocks = ex.Graphics.Sprite.from(imageBlocks);
// var flipped = spriteTiles.sprites[0].clone();
// flipped.flipVertical = true;
// var blockAnim = new ex.Graphics.Animation({
// frames: [
// { graphic: spriteTiles.sprites[0], duration: 200 },
// { graphic: flipped, duration: 200 }
// ]
// })
tileMap.data.forEach(function(cell: ex.Cell) {
cell.solid = true;
cell.addSprite(spriteTiles.sprites[0]);
cell.addGraphic(spriteTiles.sprites[0]);
});
game.add(tileMap);

Expand Down Expand Up @@ -740,10 +748,10 @@ game.input.pointers.primary.on('down', (evt?: ex.Input.PointerEvent) => {
if (c) {
if (c.solid) {
c.solid = false;
c.sprites.pop();
c.clearGraphics();
} else {
c.solid = true;
c.addSprite(spriteTiles.sprites[0]);
c.addGraphic(spriteTiles.sprites[0]);
}
}
});
Expand Down
2 changes: 1 addition & 1 deletion sandbox/tests/tilemap/tilemap.ts
Expand Up @@ -31,7 +31,7 @@ var tm = new ex.TileMap({
var tilesprite = ss.sprites[0];

for (var i = 0; i < tm.rows * tm.cols; i++) {
tm.getCellByIndex(i).addSprite(tilesprite);
tm.getCellByIndex(i).addGraphic(tilesprite);
}

game.add(tm);
Expand Down
12 changes: 5 additions & 7 deletions src/engine/Graphics/GraphicsComponent.ts
@@ -1,12 +1,14 @@
import { Vector, vec } from '../Algebra';
import { Graphic } from './Graphic';
import { Animation } from './Animation';
import { GraphicsGroup } from './GraphicsGroup';
import { HasTick } from './Animation';
import { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext';
import { Logger } from '../Util/Log';
import { BoundingBox } from '../Collision/Index';
import { Component } from '../EntityComponentSystem/Component';

export function hasGraphicsTick(graphic: Graphic): graphic is Graphic & HasTick {
return !!(graphic as unknown as HasTick).tick;
}
export interface GraphicsShowOptions {
offset?: Vector;
anchor?: Vector;
Expand Down Expand Up @@ -355,10 +357,6 @@ export class GraphicsComponent extends Component<'ex.graphics'> {
this.layers.default.hide(nameOrGraphic);
}

private _isAnimationOrGroup(graphic: Graphic): graphic is Animation | GraphicsGroup {
return graphic instanceof Animation || graphic instanceof GraphicsGroup;
}

private _bounds: BoundingBox = null;
public set localBounds(bounds: BoundingBox) {
this._bounds = bounds;
Expand Down Expand Up @@ -391,7 +389,7 @@ export class GraphicsComponent extends Component<'ex.graphics'> {
public update(elapsed: number, idempotencyToken: number = 0) {
for (const layer of this.layers.get()) {
for (const { graphic } of layer.graphics) {
if (this._isAnimationOrGroup(graphic)) {
if (hasGraphicsTick(graphic)) {
graphic?.tick(elapsed, idempotencyToken);
}
}
Expand Down
137 changes: 91 additions & 46 deletions src/engine/TileMap.ts
Expand Up @@ -9,7 +9,7 @@ import * as Events from './Events';
import { Configurable } from './Configurable';
import { Entity } from './EntityComponentSystem/Entity';
import { TransformComponent } from './EntityComponentSystem/Components/TransformComponent';
import { ExcaliburGraphicsContext, GraphicsComponent } from './Graphics';
import { ExcaliburGraphicsContext, GraphicsComponent, hasGraphicsTick } from './Graphics';
import * as Graphics from './Graphics';
import { CanvasDrawComponent, Sprite } from './Drawing/Index';
import { Sprite as LegacySprite } from './Drawing/Index';
Expand All @@ -20,6 +20,7 @@ import { obsolete } from './Util/Decorators';
* @hidden
*/
export class TileMapImpl extends Entity {
private _token = 0;
private _collidingX: number = -1;
private _collidingY: number = -1;
private _onScreenXStart: number = 0;
Expand All @@ -30,13 +31,15 @@ export class TileMapImpl extends Entity {

private _legacySpriteMap = new Map<Graphics.Sprite, Sprite>();
public logger: Logger = Logger.getInstance();
public data: Cell[] = [];
public readonly data: Cell[] = [];
private _rows: Cell[][] = [];
private _cols: Cell[][] = [];
public visible = true;
public isOffscreen = false;
public cellWidth: number;
public cellHeight: number;
public rows: number;
public cols: number;
public readonly cellWidth: number;
public readonly cellHeight: number;
public readonly rows: number;
public readonly cols: number;

private _transform: TransformComponent;

Expand Down Expand Up @@ -139,13 +142,21 @@ export class TileMapImpl extends Entity {
this.rows = rows;
this.cols = cols;
this.data = new Array<Cell>(rows * cols);
this._rows = new Array(rows);
this._cols = new Array(cols);
let currentCol: Cell[] = [];
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
(() => {
const cd = new Cell(i * cellWidth + <number>xOrConfig, j * cellHeight + y, cellWidth, cellHeight, i + j * cols);
this.data[i + j * cols] = cd;
})();
const cd = new Cell(i * cellWidth + <number>xOrConfig, j * cellHeight + y, cellWidth, cellHeight, i + j * cols);
this.data[i + j * cols] = cd;
currentCol.push(cd);
if (!this._rows[j]) {
this._rows[j] = [];
}
this._rows[j].push(cd);
}
this._cols[i] = currentCol;
currentCol = [];
}
this._transform = this.get(TransformComponent);
this.get(GraphicsComponent).localBounds = new BoundingBox({
Expand Down Expand Up @@ -249,6 +260,14 @@ export class TileMapImpl extends Entity {
return null;
}

public getRows(): readonly Cell[][] {
return this._rows;
}

public getColumns(): readonly Cell[][] {
return this._cols;
}

public onPreUpdate(_engine: Engine, _delta: number) {
// Override me
}
Expand All @@ -260,7 +279,7 @@ export class TileMapImpl extends Entity {
public update(engine: Engine, delta: number) {
this.onPreUpdate(engine, delta);
this.emit('preupdate', new Events.PreUpdateEvent(engine, delta, this));

this._token++;
const worldBounds = engine.getWorldBounds();
const worldCoordsUpperLeft = vec(worldBounds.left, worldBounds.top);
const worldCoordsLowerRight = vec(worldBounds.right, worldBounds.bottom);
Expand Down Expand Up @@ -288,25 +307,28 @@ export class TileMapImpl extends Entity {
let y = this._onScreenYStart;
const yEnd = Math.min(this._onScreenYEnd, this.rows);

let sprites: Graphics.Sprite[], spriteIndex: number, cslen: number;
let graphics: Graphics.Graphic[], graphicsIndex: number, graphicsLen: number;

for (x; x < xEnd; x++) {
for (y; y < yEnd; y++) {
// get non-negative tile sprites
sprites = this.getCell(x, y).sprites;
graphics = this.getCell(x, y).graphics;

for (spriteIndex = 0, cslen = sprites.length; spriteIndex < cslen; spriteIndex++) {
for (graphicsIndex = 0, graphicsLen = graphics.length; graphicsIndex < graphicsLen; graphicsIndex++) {
// draw sprite, warning if sprite doesn't exist
const sprite = sprites[spriteIndex];
if (sprite) {
const graphic = graphics[graphicsIndex];
if (graphic) {
if (!(ctx instanceof CanvasRenderingContext2D)) {
sprite.draw(ctx, x * this.cellWidth, y * this.cellHeight);
} else {
if (hasGraphicsTick(graphic)) {
graphic?.tick(delta, this._token);
}
graphic.draw(ctx, x * this.cellWidth, y * this.cellHeight);
} else if (graphic instanceof Graphics.Sprite) {
// TODO legacy drawing mode
if (!this._legacySpriteMap.has(sprite)) {
this._legacySpriteMap.set(sprite, Graphics.Sprite.toLegacySprite(sprite));
if (!this._legacySpriteMap.has(graphic)) {
this._legacySpriteMap.set(graphic, Graphics.Sprite.toLegacySprite(graphic));
}
this._legacySpriteMap.get(sprite).draw(ctx, x * this.cellWidth, y * this.cellHeight);
this._legacySpriteMap.get(graphic).draw(ctx, x * this.cellWidth, y * this.cellHeight);
}
}
}
Expand Down Expand Up @@ -387,16 +409,38 @@ export class TileMap extends Configurable(TileMapImpl) {
*/
export class CellImpl extends Entity {
private _bounds: BoundingBox;
public x: number;
public y: number;
public width: number;
public height: number;
public index: number;
/**
* World space x coordinate of the left of the cell
*/
public readonly x: number;
/**
* World space y coordinate of the top of the cell
*/
public readonly y: number;
/**
* Width of the cell in pixels
*/
public readonly width: number;
/**
* Height of the cell in pixels
*/
public readonly height: number;
/**
* Current index in the tilemap
*/
public readonly index: number;
/**
* Current list of graphics for this cell
*/
public readonly graphics: Graphics.Graphic[] = [];
/**
* Wether this cell should be treated as solid by the tilemap
*/
public solid: boolean = false;
public sprites: Graphics.Sprite[] = [];

// public transform: TransformComponent;
// public graphics: GraphicsComponent;
/**
* Abitrary data storage per cell, useful for any game specific data
*/
public data = new Map<string, any>();

/**
* @param xOrConfig Gets or sets x coordinate of the cell in world coordinates or cell option bag
Expand All @@ -414,7 +458,7 @@ export class CellImpl extends Entity {
height: number,
index: number,
solid: boolean = false,
sprites: Graphics.Sprite[] = []
graphics: Graphics.Graphic[] = []
) {
super();
if (xOrConfig && typeof xOrConfig === 'object') {
Expand All @@ -425,15 +469,15 @@ export class CellImpl extends Entity {
height = config.height;
index = config.index;
solid = config.solid;
sprites = config.sprites;
graphics = config.sprites;
}
this.x = <number>xOrConfig;
this.y = y;
this.width = width;
this.height = height;
this.index = index;
this.solid = solid;
this.sprites = sprites;
this.graphics = graphics;
this._bounds = new BoundingBox(this.x, this.y, this.x + this.width, this.y + this.height);
}

Expand All @@ -451,32 +495,33 @@ export class CellImpl extends Entity {
*/
@obsolete({ message: 'Will be removed in v0.26.0', alternateMethod: 'addSprite' })
public pushSprite(sprite: Graphics.Sprite | LegacySprite) {
this.addSprite(sprite);
this.addGraphic(sprite);
}

/**
* Add another [[Sprite]] to this TileMap cell
* @param sprite
* Add another [[Graphic]] to this TileMap cell
* @param graphic
*/
public addSprite(sprite: Graphics.Sprite | LegacySprite) {
if (sprite instanceof LegacySprite) {
this.sprites.push(Graphics.Sprite.fromLegacySprite(sprite));
public addGraphic(graphic: Graphics.Graphic | LegacySprite) {
if (graphic instanceof LegacySprite) {
this.graphics.push(Graphics.Sprite.fromLegacySprite(graphic));
} else {
this.sprites.push(sprite);
this.graphics.push(graphic);
}
}

/**
* Remove an instance of [[Sprite]] from this cell
* Remove an instance of a [[Graphic]] from this cell
*/
public removeSprite(sprite: Graphics.Sprite | LegacySprite) {
removeItemFromArray(sprite, this.sprites);
public removeGraphic(graphic: Graphics.Graphic | LegacySprite) {
removeItemFromArray(graphic, this.graphics);
}

/**
* Clear all sprites from this cell
* Clear all graphis from this cell
*/
public clearSprites() {
this.sprites.length = 0;
public clearGraphics() {
this.graphics.length = 0;
}
}

Expand Down

0 comments on commit a2f5f54

Please sign in to comment.