Ice Movement
Press the arrow keys to move. This is an example of how to implement ice movement with GridEngine. Move on the ice to see the effect.
Code
📖 How to execute examples locally
js
const game = new Phaser.Game(config(preload, create, update));
let slidingDirection = 'none';
function preload() {
this.load.image("tiles", "../../assets/tf_winter_terrain.png");
this.load.tilemapTiledJSON("ice-movement-map", "../../assets/ice-movement.json");
this.load.spritesheet("player", "../../assets/characters.png", {
frameWidth: 52,
frameHeight: 72,
});
}
function create() {
const tilemap = createTilemap.call(this);
const playerSprite = createPlayerSprite.call(this);
setupCamera.call(this, playerSprite);
const gridEngineConfig = {
characters: [
{
id: "player",
sprite: playerSprite,
walkingAnimationMapping: 6,
startPosition: { x: 5, y: 5 },
},
],
};
this.gridEngine.create(tilemap, gridEngineConfig);
this.gridEngine
.positionChangeStarted()
.subscribe(({ charId, exitTile, enterTile }) => {
if (isIceTile(enterTile.x, enterTile.y)) {
startSliding(
this.gridEngine,
playerSprite,
getDirection(enterTile, exitTile),
);
} else {
stopSliding(this.gridEngine, playerSprite);
}
});
this.gridEngine
.movementStopped()
.subscribe(({ charId, direction }) => {
stopSliding(this.gridEngine, playerSprite);
});
}
function update() {
if (slidingDirection !== 'none') {
this.gridEngine.move("player", slidingDirection);
return;
}
const cursors = this.input.keyboard.createCursorKeys();
if (cursors.left.isDown) {
this.gridEngine.move("player", "left");
} else if (cursors.right.isDown) {
this.gridEngine.move("player", "right");
} else if (cursors.up.isDown) {
this.gridEngine.move("player", "up");
} else if (cursors.down.isDown) {
this.gridEngine.move("player", "down");
}
}
function startSliding(gridEngine, playerSprite, direction) {
gridEngine.setWalkingAnimationMapping('player', undefined);
slidingDirection = direction;
playerSprite.anims.play('spin', true);
}
function stopSliding(gridEngine, playerSprite) {
gridEngine.setWalkingAnimationMapping('player', 6);
playerSprite.anims.stop();
slidingDirection = 'none';
}
function isIceTile(x, y) {
return x >= 4 && x <= 7 && y >= 6 && y <= 11;
}
function getDirection(fromPos, toPos) {
if (fromPos.x < toPos.x) {
return 'left';
} else if (fromPos.x > toPos.x) {
return 'right';
} else if (fromPos.y < toPos.y) {
return 'up';
} else if (fromPos.y > toPos.y) {
return 'down';
}
return 'none';
}
function setupCamera(playerSprite) {
this.cameras.main.startFollow(playerSprite, true);
this.cameras.main.setFollowOffset(-playerSprite.width, -playerSprite.height);
}
function createPlayerSprite() {
const playerSprite = this.add.sprite(0, 0, "player");
playerSprite.scale = 1.5;
this.anims.create({
key: 'spin',
frames:
this.anims.generateFrameNumbers("player", {
frames:
[91, 79, 55, 67],
}),
frameRate: 7,
repeat: -1,
yoyo: false,
});
return playerSprite;
}
function createTilemap() {
const tilemap = this.make.tilemap({ key: "ice-movement-map" });
tilemap.addTilesetImage("tf-winter-terrain", "tiles");
for (let i = 0; i < tilemap.layers.length; i++) {
const layer = tilemap.createLayer(i, "tf-winter-terrain", 0, 0);
layer.scale = 3;
}
return tilemap;
}
html
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="../styles.css" />
<script src="../../js/phaser-3.80.1.min.js"></script>
<script src="../../js/grid-engine-2.44.3.min.js"></script>
<script src="../../js/examplePhaserConfig.js"></script>
<script src="code.js"></script>
</head>
<body></body>
</html>
js
function config(preload, create, update) {
return {
title: "GridEngineExample",
render: {
antialias: false,
},
type: Phaser.AUTO,
plugins: {
scene: [
{
key: "gridEngine",
plugin: GridEngine,
mapping: "gridEngine",
},
],
},
scale: {
width: 700,
height: 528,
},
scene: {
preload: preload,
create: create,
update: update,
},
parent: "game",
backgroundColor: "#48C4F8",
input: {
mouse: {
preventDefaultWheel: false
},
touch: {
capture: false
}
}
};
}
css
body {
margin: 0;
padding: 0;
background: #1e1e20;
font-family: Inter,-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
color: #cacaca;
}
.settings {
margin-top: 20px;
display: flex;
flex-direction: column;
/* border: 1px solid white; */
background: #282828;
margin-bottom: 20px;
width: 640px;
padding: 0 30px;
}
label {
font-weight: bold;
margin-top: 30px;
margin-bottom: 10px;
}
select {
width: 100px;
}
input {
width: 100px;
}
button {
width: 120px;
margin-top: 30px;
margin-bottom: 20px;
}
.wait-timeout-group {
display: flex;
align-items: center;
justify-content: flex-start;
}
.wait-timeout-group input {
width: auto;
margin-right: 10px;
}
.wait-timeout-group label {
margin:0;
}
#json-config {
margin-bottom: 10px;
}
#json-config pre {
font-family: "Consolas", monospace;
}
.disabled {
display: none;
}