Cannot rotate car and tilemap is not fully visible - javascript

I am trying to port the following Phaser2 example (https://phaser.io/examples/v2/tilemaps/fill-tiles) into Phaser3. I am experiencing two issues:
I cannot rotate the vehicle as the left/right keys will not work.
I cannot get the tilemap to display correctly, it seems cut off.
import Phaser from "phaser";
const config = {
type: Phaser.AUTO,
parent: "phaser-example",
width: 800,
height: 600,
physics: {
default: 'arcade'
},
scene: {
preload: preload,
create: create,
update: update,
render: render
}
};
const game = new Phaser.Game(config);
let cursors;
let player;
let map;
let speed = 0;
function preload() {
this.load.tilemapTiledJSON('desert', 'desert.json');
this.load.image('tiles', 'https://examples.phaser.io/assets/tilemaps/tiles/tmw_desert_spacing.png')
this.load.image('car', 'http://labs.phaser.io/assets/sprites/car90.png')
}
function create() {
map = this.make.tilemap({ key: 'desert' });
const tiles = map.addTilesetImage('Desert', 'tiles');
const layer = map.createDynamicLayer('Ground', tiles, 0, 0);
cursors = this.input.keyboard.createCursorKeys();
player = this.physics.add.sprite(450, 80, 'car');
this.cameras.main.startFollow(player, true, 0.05, 0.05);
}
function update() {
// Drive forward if cursor up key is pressed down
if (cursors.up.isDown && speed <= 400) {
speed += 10;
} else {
if (speed >= 10) {
speed -= 10
}
}
// Drive backwards if cursor down key is pressed down
if (cursors.down.isDown && speed >= -200) {
speed -= 5;
} else {
if (speed <= -5) {
speed += 5
}
}
// Steer the car
if (cursors.left.isDown) {
player.body.angularVelocity = -5 * (speed / 1000);
} else if (cursors.right.isDown) {
player.body.angularVelocity = 5 * (speed / 1000);
} else {
player.body.angularVelocity = 0;
}
player.body.velocity.x = speed * Math.cos((player.body.angle - 360) * 0.01745);
player.body.velocity.y = speed * Math.sin((player.body.angle - 360) * 0.01745);
}
function render() {
}
How can I fix this?

I loaded the code in a blank project without assets, and was able to see the image missing object rotate. However, it looks like the dependency of speed in angular rotation is too low. If you reduce the decrease in scaling of speed used for calculating angular velocity, you can get the car to turn more quickly.
Proof -> https://stackblitz.com/edit/phaser-2-example-so

Related

trying to make a drawn line move like a laser in javascript

I made this red line in JavaScript that goes to closest target (balloon 1 to 3) to the player but I need to make it so that it moves like a laser starting from player position into the target position. I thought about multiple ways of implementing this with no luck.
function Tick() {
// Erase the sprite from its current location.
eraseSprite();
for (var i = 0; i < lasers.length; i++) {
lasers[i].x += lasers[i].direction.x * laserSpeed;
lasers[i].y += lasers[i].direction.y * laserSpeed;
//Hit detection here
}
function detectCharClosest() {
var ballon1char = {
x: balloon1X,
y: balloon1Y
};
var ballon2char = {
x: balloon2X,
y: balloon2Y
};
var ballon3char = {
x: balloon3X,
y: balloon3Y,
};
ballon1char.distanceFromPlayer = Math.sqrt((CharX - balloon1X) ** 2 + (CharY - balloon1Y) ** 2);
ballon2char.distanceFromPlayer = Math.sqrt((CharX - balloon2X) ** 2 + (CharY - balloon2Y) ** 2);
ballon3char.distanceFromPlayer = Math.sqrt((CharX - balloon3X) ** 2 + (CharY - balloon3Y) ** 2);
var minDistance = Math.min(
ballon1char.distanceFromPlayer,
ballon2char.distanceFromPlayer,
ballon3char.distanceFromPlayer);
console.log(ballon1char);
console.log(ballon2char);
console.log(ballon3char);
for (let i = 0; i < 3; i++) {
if (minDistance == ballon1char.distanceFromPlayer)
return ballon1char
if (minDistance == ballon2char.distanceFromPlayer)
return ballon2char
if (minDistance == ballon3char.distanceFromPlayer)
return ballon3char
}
}
function loadComplete() {
console.log("Load is complete.");
canvas = document.getElementById("theCanvas");
ctx = canvas.getContext("2d");
myInterval = self.setInterval(function () { Tick() }, INTERVAL);
myInterval = self.setInterval(function () { laserTicker(detectCharClosest()) }, 2000);
function laserTicker(balloon) {
//gets the closest ballon to go to
laserDo(balloon);
}
function laserDo(balloon) {
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = "#F44336"; // "red";
ctx.moveTo(CharX + 16, CharY + 16);
ctx.lineTo(balloon.x, balloon.y);
// lasers.push({x: })
ctx.stroke();
}
I didn't put all of my code here so If something doesn't make sense please tell me. I'm still new to JavaScript and learning it. One way I thought I could make this work was by taking the distance between the player and the target and dividing it by the speed on the x and y axis then changing having it start from the player position and keeps on adding up on both axis until it reaches the target. That didn't work out though. If you have any suggestions then please tell me.
Thanks

Tiled map overlap detection not working properly

I am building a tower defence game and I am facing an issue in Phaser with tiled maps.
You see different layers in tiled always have coordinates from (0,0) to (600,600) -> or whatever your tiled width and height is. I have a backgroundLayer and a path. The creeps properly collide with the path.
Now I am trying to change the cursor to a building sprite (for UI when I click on some button and select a tower I want it to turn red when it is on the road or above another tower/creep) and I am using an overlap function for path and buildings.
This overlap function in Phaser checks the rectangle of building sprite and path, but path rectangle is the whole map. The collision works but I only need an overlap. Any ideas how to achieve this? Here is my code.
var RedPlanetGame = RedPlanetGame || {};
var pressed = {
is: false
};
var buildingOverlaps = {
is: false
};
//title screen
RedPlanetGame.Game = function () {
};
RedPlanetGame.Game.prototype = {
create: function create() {
//A door for multyplayer
this.players = [];
this.player = new Player(1, 'Daniel', 300);
this.players.push(this.player);
this.playerInfo = {};
//Tile map
this.map = this.game.add.tilemap('sample2');
this.map.addTilesetImage('32x32_map_tile v3.1 [MARGINLESS]', 'gameTiles');
//background and layers
this.backgroundlayer = this.map.createLayer('backgroundLayer');
this.path = this.map.createLayer('path');
this.map.setCollisionBetween(1, 2000, true, 'backgroundLayer');
this.map.setCollisionBetween(1, 2000, true, 'path');
//objects from tile map
this.spawnCreepsAt = this.map.objects['objectsLayer'][0];
this.destinationForCreeps = this.map.objects['objectsLayer'][1];
//resize world
this.backgroundlayer.resizeWorld();
//this.game.world.setBounds(0, 0, 100, 100);
//groups
this.game.enemies = new UnitsPoolFactory(this.game);
this.game.buildings = this.game.add.group();//TODO: make buildings for each player
this.game.bullets = new BulletsPoolFactory(this.game);
//creep spawning
var _this = this;
const creepYOffset = 15;
setInterval(function () {
_this.game.enemies.factory(_this.spawnCreepsAt.x, _this.spawnCreepsAt.y + creepYOffset, UNIT_TYPES.CREEP1);
}, 1000);
//text and player info
var textX = 150;
var textY = 0;
this.playerInfo.gold = this.game.add.text(textX, textY, 'Player gold: ' + this.player.gold,
{font: "24px Arial", fill: '#FFD700'}
);
//Here is test straight forward code for building towers
this.game.build = this.game.add.group();
this.buildingSprite = this.game.add.sprite(0, 0, 'tower1-1');
this.game.physics.enable(this.buildingSprite, Phaser.Physics.ARCADE);
this.buildingSprite.anchor.setTo(0.5);
this.buildingSprite.scale.setTo(0.5);
this.game.build.add(this.buildingSprite);
console.log(this.path.getBounds());
console.log(this.backgroundlayer.getBounds());
},
update: function update() {
var _this = this;
//Camera follow cursor
if (this.game.input.mousePointer.x > gameHeight - gameHeight / 10) {
this.game.camera.x += 10;
} else if (this.game.input.mousePointer.x <= 100) {
this.game.camera.x -= 10;
}
if (this.game.input.mousePointer.y > gameWidth - gameWidth / 10) {
this.game.camera.y += 10;
} else if (this.game.input.mousePointer.y <= 100) {
this.game.camera.y -= 10;
}
//check for collision between enemy and non-path layer
this.game.physics.arcade.collide(this.game.enemies, this.backgroundlayer);
//checks for collision between bullets and enemies
this.game.physics.arcade.overlap(this.game.bullets, this.game.enemies, function (bullet, enemy) {
enemy.takeHit(bullet, _this.player);
bullet.kill();
}, null, this);
//updates enemies
this.game.enemies.forEach(function (enemy) {
enemy.onUpdate(_this.destinationForCreeps);
});
//updates buildings
this.game.buildings.forEach(function (building) {
building.onUpdate(_this.game.bullets);
});
//on mouse down event
if (this.game.input.activePointer.leftButton.isDown && !pressed.is) {//yo Yoda
//builds new building of type TOWER1
buffer(pressed, 1000);
if (Building.prototype.canBuild(this.player.gold, Tower1.prototype.moneyCost)) {
var poss = this.game.input.mousePointer;
BuildingsFactory(this.game, poss.x, poss.y, this.player, BUILDING_TYPES.TOWER1);
this.player.gold -= Tower1.prototype.moneyCost
} else {
alert('Not enought gold');
}
}
//Here is test straight forward code for building towers
if (Phaser.Rectangle.contains(this.buildingSprite.body, this.game.input.x, this.game.input.y)) {
this.buildingSprite.body.velocity.setTo(0, 0);
}
else {
this.game.physics.arcade.moveToPointer(this.buildingSprite, 700);
}
this.game.physics.arcade.collideGroupVsTilemapLayer(this.game.build, this.path, function (sprite) {
if (!buildingOverlaps.is) {
buffer(buildingOverlaps, 500);
console.log('overlap')
}
}, null, this, true);
},
render: function render() {
this.playerInfo.gold.text = 'Player gold: ' + this.player.gold;
}
};

Set the maximum and current speed of a car in Phaser

I am making a top-down racing game using the Phaser framework which uses JS. I am having some trouble getting the car to slow down, at the moment it just stops when no button is pressed. I want it to slow down to stopped. Here is my code so far:
create: function () {
//run in canvas mode
this.game.renderer.clearBeforeRender - false;
this.game.renderer.roundPixels = true;
//Add arcade physics
this.game.physics.startSystem(Phaser.Physics.ARCADE);
//Add background sprites
this.game.add.sprite(0, 0, 'background');
this.game.add.sprite(0, 0, 'track');
//Add car sprite
car = this.game.add.sprite(800, 135, 'car-concept');
//Car physics settings
this.game.physics.enable(car, Phaser.Physics.ARCADE);
car.body.drag.set(100);
car.body.maxVelocity.set(200);
car.body.maxAngular = 500;
car.body.angularDrag = 500;
car.body.collideWorldBounds = true;
//Game input
cursors = this.game.input.keyboard.createCursorKeys();
this.game.input.keyboard.addKeyCapture([ Phaser.Keyboard.SPACEBAR]);
//pivot point
car.pivot.x = car.width * .3;
car.pivot.y = car.height * .5;
car.anchor.setTo(0.3, 0.5);
//scale the car
car.scale.setTo(0.3, 0.3);
},
update: function () {
car.body.velocity.x = 0;
car.body.velocity.y = 0;
car.body.angularVelocity = 0;
if(cursors.left.isDown)
{
car.body.angularVelocity = -200;
}
else if(cursors.right.isDown)
{
car.body.angularVelocity = 200;
}
if(cursors.up.isDown)
{
this.game.physics.arcade.velocityFromAngle(car.angle, -200, car.body.velocity)
if(this.currentSpeed < this.maxSpeed)
{
this.currentSpeed += 10;
}
}
else
{
if(this.currentSpeed > 0)
{
this.currentSpeed -= 10;
}
}
if(cursors.down.isDown)
{
this.game.physics.arcade.velocityFromAngle(car.angle, 200, car.body.velocity)
if(this.currentSpeed > 0)
{
this.currentSpeed -= 30;
}
}
},
speed: function()
{
this.maxSpeed = 100;
this.currentSpeed = 0;
},
I have looked a few questions on here about the same problem and this is how I got to the point where I am now. I have set the maxSpeed and currentSpeed but for some reason it won't allow me to actually use it. The console in the browser does not give me any errors, so if anyone can guide me on this, that would be great!
Thanks.
The reason it stops dead is because you're moving it with velocity, not acceleration - and are setting velocity to zero in your update loop (this effectively says "stop, now!").
Remove those lines and in your call to velocityFromAngle you should feed that into body.acceleration instead of body.velocity.
Here is an update loop you can use, although you'll need to mix in your currentSpeed settings and such like:
function update() {
if (cursors.up.isDown)
{
game.physics.arcade.accelerationFromRotation(sprite.rotation, 200, sprite.body.acceleration);
}
else
{
sprite.body.acceleration.set(0);
}
if (cursors.left.isDown)
{
sprite.body.angularVelocity = -300;
}
else if (cursors.right.isDown)
{
sprite.body.angularVelocity = 300;
}
else
{
sprite.body.angularVelocity = 0;
}
}
you never used currentSpeed. You set your speed to -200 and 200 in velocityFromAngle.

Placing platforms randomly in world with Phaser

I'm making a vertical scrolling platform game using Phaser, but I can't figure out how to create randomly placed platforms to jump on. This is the code I have so far (removed unneccesary stuff):
Platformer.Game = function (game) {
this._platforms = null;
this._platform = null;
this._numberOfPlatforms = 15;
this._x = this.x;
this._y = this.y;
};
Platformer.Game.prototype = {
create: function (){
this.physics.startSystem(Phaser.Physics.ARCADE);
this.physics.arcade.gravity.y = 200;
this._platforms = this.add.group();
Platformer.platform.createPlatform(this);
Platformer.platform.createPlatform(this);
Platformer.platform.createPlatform(this);
Platformer.platform.createPlatform(this);
Platformer.platform.createPlatform(this);
Platformer.platform.createPlatform(this);
game.camera.follow(this._player);
},
managePause: function () {
this.game.paused = true;
var pausedText = this.add.text(100, 250, "Game paused. Click anywhere to continue.", this._fontStyle);
this.input.onDown.add(function(){
pausedText.destroy();
this.game.paused = false;
}, this);
},
update: function () {
}
};
Platformer.platform = {
createPlatform: function (game) {
var posX = Math.floor(Math.random() * Platformer.GAME_WIDTH * this._numberOfPlatforms * 70);
var posY = Math.floor(Math.random() * Platformer.GAME_HEIGHT * this._numberOfPlatforms * 50);
var platform = game.add.sprite(posX, posY, 'platform');
game._platforms.add(platform);
platform.events.onOutOfBounds.add(this.removePlatform, this);
},
removePlatform: function (game) {
this._platform.kill();
}
}
I can get it to work to place them randomly, but the idea of a platformer should be you could actually jump on it. With enough distance but not too much, so I guess not entirely random.
Hope you have some ideas!
Here's a simple approach, just a start really.
The idea is to build up some basic rules basing the position of each platform on the one that came before. For example, if the last one was on the left, put the next one somewhere to the right.
Min/max ranges are also good in these situations: In this example the next platform is always at least 200px higher up than the last and no more than 300px higher.
There's a playable example here on codepen
platforms = game.add.group();
platforms.enableBody = true;
platforms.physicsBodyType = Phaser.Physics.ARCADE;
// start off on the left 220px above the ground
var x = 0, y = height - 220;
// keep adding platforms until close to the top
while(y > 200) {
var platform = platforms.create(x, y, 'platform');
platform.body.immovable = true;
platform.body.allowGravity = false;
// find center of game canvas
var center = width / 2;
if(x > center) {
// if the last platform was to the right of the
// center, put the next one on the left
x = Math.random() * center;
}
else {
// if it was on the left, put the next one on the right
x = center + Math.random() * (center - platformWidth);
}
// place the next platform at least 200px higher and at most 300px higher
y = y - 200 - 100 * Math.random();
}

How to move two layers independently from each other in OpenLayers?

Is it possible to create two layers (with one being translucent) in OpenLayers and move them independently? If so, how?
I want to let the user choose which layer to move or if that's not possible, move one layer via my own JavaScript code while the other is controlled by the user.
Both will be prerendered pixmap layers, if that is important.
This is the solution I came up with. It isn't pretty but it works for my purposes.
Better alternatives are very welcome ...
/**
* #requires OpenLayers/Layer/TMS.js
*/
MyLayer = OpenLayers.Class(OpenLayers.Layer.TMS, {
latShift: 0.0,
latShiftPx: 0,
setMap: function(map) {
OpenLayers.Layer.TMS.prototype.setMap.apply(this, arguments);
map.events.register("moveend", this, this.mapMoveEvent)
},
// This is the function you will want to modify for your needs
mapMoveEvent: function(event) {
var resolution = this.map.getResolution();
var center = this.map.getCenter();
// This is some calculation I use, replace it whatever you like:
var h = center.clone().transform(projmerc, proj4326);
var elliptical = EllipticalMercator.fromLonLat(h.lon, h.lat);
var myCenter = new OpenLayers.LonLat(elliptical.x, elliptical.y);
this.latShift = myCenter.lat - center.lat;
this.latShiftPx = Math.round(this.latShift/resolution);
this.div.style.top = this.latShiftPx + "px";
},
moveTo: function(bounds, zoomChanged, dragging) {
bounds = bounds.add(0, this.latShift);
OpenLayers.Layer.TMS.prototype.moveTo.apply(this, [bounds, zoomChanged, dragging]);
},
// mostly copied and pasted from Grid.js ...
moveGriddedTiles: function() {
var buffer = this.buffer + 1;
while(true) {
var tlTile = this.grid[0][0];
var tlViewPort = {
x: tlTile.position.x +
this.map.layerContainerOriginPx.x,
y: tlTile.position.y +
this.map.layerContainerOriginPx.y + this.latShiftPx // ... except this line
};
var ratio = this.getServerResolution() / this.map.getResolution();
var tileSize = {
w: Math.round(this.tileSize.w * ratio),
h: Math.round(this.tileSize.h * ratio)
};
if (tlViewPort.x > -tileSize.w * (buffer - 1)) {
this.shiftColumn(true, tileSize);
} else if (tlViewPort.x < -tileSize.w * buffer) {
this.shiftColumn(false, tileSize);
} else if (tlViewPort.y > -tileSize.h * (buffer - 1)) {
this.shiftRow(true, tileSize);
} else if (tlViewPort.y < -tileSize.h * buffer) {
this.shiftRow(false, tileSize);
} else {
break;
}
}
},
CLASS_NAME: "MyLayer"
});
Note that this only works with OpenLayers 2.13 or newer

Categories

Resources