Using multiple layers from Tiled into Phaser game - javascript

I'm creating a game with the Phaser engine, and I'm currently using the application 'Tiled' to create a my own tilemap.
The actual problem seems to be with having multiple layers when creating this tilemap. I have 6 different layers:
"Background"
"WallBlocks"
"Grass"
"SpikeAnimation"
"DiamondAnimation"
"SlimeAnimation"
Here is my Game.js file
SleepSim.Game = function (game) {
this.map;
this.Background;
this.WallBlocks;
this.Grass;
this.SpikeAnimation;
this.DiamondAnimation;
this.SlimeAnimation;
}
SleepSim.Game.prototype = {
create: function () {
this.world.setBounds(0,0,5000,1000);
this.map = this.add.tilemap('gameWorld');
this.map.addTilesetImage('gameworld', 'tiles');
this.Background = this.map.createLayer('Background');
this.Background.resizeWorld();
this.WallBlocks = this.map.createLayer('WallBlocks');
this.Grass = this.map.createLayer('Grass');
this.SpikeAnimation = this.map.createLayer('SpikeAnimation');
this.DiamondAnimation = this.map.createLayer('DiamondAnimation');
this.SlimeAnimation = this.map.createLayer('SlimeAnimation');
},
update: function() {
if(this.input.keyboard.isDown(Phaser.Keyboard.DOWN)) {
this.camera.y += 10;
}
else if (this.input.keyboard.isDown(Phaser.Keyboard.UP)){
this.camera.y -= 10;
}
if (this.input.keyboard.isDown(Phaser.Keyboard.LEFT)){
this.camera.x -= 10;
}
else if (this.input.keyboard.isDown(Phaser.Keyboard.RIGHT)){
this.camera.x += 10;
}
}
}
I have the camera set this way at the moment to just fly through the map to make sure things can load.
Apologies if the formatting to this question is abit off, it's my first time posting! Any help would be super super appreciated.

I ran into a similar problem. You only need to create a variable for the first layer, the rest should not be variables.
this.map = this.add.tilemap('gameWorld');
this.map.addTilesetImage('gameworld', 'tiles');
this.Background = this.map.createLayer('Background');
this.Background.resizeWorld();
this.map.createLayer('WallBlocks');
this.map.createLayer('Grass');
this.map.createLayer('SpikeAnimation');
this.map.createLayer('DiamondAnimation');
this.map.createLayer('SlimeAnimation');

Related

Unable to get pixi js elements after init

I need help form this bit of code, been stuck for hours, cant seems to figure out. Any help will be much appreciated.
I have multiple sections that has pixi.js app. Initiated the functions as below.
var pixiFunctions = [
function(type) {
var pixi, sectionContainer, stage, texture, sprite, bars;
sectionContainer = $('section[data-media="established"]');
var established = {
init: function() {
pixi = new PIXI.Application({
width: getViewport().width,
height: getViewport().height,
transparent: true,
resolution: window.devicePixelRatio || 1,
antialias: true
});
sectionContainer.append(pixi.view);
stage = new PIXI.Container();
texture = new PIXI.Texture.from(loadedMedia[1].src);
texture.baseTexture.resource.autoplay = false;
texture.baseTexture.resource.source.loop = 'loop';
sprite = new PIXI.Sprite(texture);
texture.baseTexture.on('loaded', function() {
sprite.height = pixi.renderer.screen.height;
sprite.width = pixi.renderer.screen.width;
pixi.stage.addChild(sprite);
established.start();
});
},
start: function() {
pixi.render(stage);
requestAnimationFrame(established.start);
},
animateIn: function() {
console.log('animateIN');
**console.log(pixi)**
sectionContainer.addClass('active');
},
animateOut: function() {
console.log('animateOut');
sectionContainer.removeClass('active');
}
}
if (type === 'animateIn') established.animateIn();
if (type === 'animateOut') established.animateOut();
if (type === 'init') established.init();
}
]
I have a sets of functions like this for each ,
On DOM load, I am calling these functions in this manner,
for (var i = 0; i < pixiFunctions.length; i++) {
pixiFunctions[i]('init');
}
And here comes the issue, when I am scrolling, I have set up functions to fire up in this manner;
pixiFunctions[currentPosition]('animateIn');
[currentPosition] - refers to the count that increment as you scroll so that I can animate in sections.
Issue is whenever i call this function with a , the console logs as PIXI undefined. I have no clue how to sort it out. I needed this because I need to get a hold of pixi in order to animate the mask.
** pixiFunctionscurrentPosition;**
Thank you all.

Creating game like portable module

I want to create some game. Is it good, that my view on this game has to be like view on the module? It means, anywhere on the other website I want to run my game, I'll just put my module to it.
So, if we imagine "my view" like class, will it look some like this?
class Mario {
// Whole game module
class Game {
// Game properties
class Player {
}
class Card {
}
}
class Init {
// This take care about gui etc.
class Gui {
show_cards() {
}
}
}
start() {
var init = new Init();
something to init Gui and run method show_cards();
}
}
var mario = new Mario();
mario.start();
Am I right?
But is this syntax right in JavaScript and is this even possible?
Thanks for help!
If you want the extra awesomesauce of an HTML element you can drop into your page to hold your game code, you could make a custom element, but I bet you could get by just fine with a module.
As far as your code structure, this should help you out. It's a Game class template that utilizes separate Player and Resource classes -- and I stuck in a GameHandler class at the top for you (which would be like your Mario class.)
Happy coding!
class GameHandler {
constructor(){
this.handlerSetup();
const gameResources = [ // Array of resource objects for setResources method
{
type: "card",
number: 1,
},
{
type: "card",
number: 2,
options: { category: "A", description:"special" }
}
];
this.game = new Game(4, gameResources); // This can go in a loop to allow sequential games
}
handlerSetup(){ /* Do setup tasks here */ }
}
class Game {
constructor(playerCount, resourcesArray){
this.players = this.setPlayers(playerCount);
this.resources = this.setResources(resourcesArray);
this.winnerIfAny = null;
this.turnNumber = 0;
this.output("Ready to play");
// Main loop
while(this.winnerIfAny === null){
this.winnerIfAny = this.nextTurn(++this.turnNumber);
}
this.output(`Game over -- Player number ${this.winnerIfAny.number} wins`);
}
setPlayers(count){
let i = 0, players = [];
while(i < count){
players.push(new Player(i++));
}
this.output(`${count} players added`)
return players;
}
setResources(resourcesProvided){
let resources = [];
for(let resource of resourcesProvided){
resources.push(new Resource(resource));
}
this.output(`${resources.length} resources added`)
return resources;
}
nextTurn(turnNumber){
this.output("Taking turn...");
let winnerFound = null;
// Turn loop code goes here
// (eg switch to next player, take turn, check for winner
// This demo game is not very interesting -- it randomly assigns a winner
let rand = (Math.floor(Math.random() * (11 - turnNumber * 2)));
if (turnNumber > 1 && rand < 4) { winnerFound = this.players[rand]; }
if(winnerFound){ return winnerFound; }
return null;
}
output(text){ document.querySelector("#outputDiv").innerHTML += `${text}<br/>`; }
}
class Player {
constructor(number){
this.number = number;
//etc...
}
}
class Resource {
constructor(type, number, options){
this.number = number;
//etc...
}
}
new GameHandler();
<div id="outputDiv"></div>

Javascript class variable undefined error [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
So i'm trying to make a "game" with javascipt witc has rectangles that go arround the canvas and they have timers. When rectangles timer goes above certain limit rectangle gets a new direction.
I'm trying to make the rectangles with class so i can have multiple of them running at same time. But the problem is that i cant get the functions inside of the class pass data to eachother (i think that's the problem...).
On the draw function this.cubeLocX is not defined and this.ctx.fillStyle="#2a2b2d"; gets error Cannot set property 'fillStyle' of undefined
class cubeV3 {
constructor(canvas) {
//var canvas = document.getElementById('canvas');
this.canvas = canvas;
this.cubeLocX = 100;
this.cubeLocY = 0;
this.speed = getRandomNumber();
this.dir = 0;
this.turnTimer = 0;
this.turnTimerMax = getRandomNumberV2(30,100);
this.ctx = this.canvas.getContext("2d");
}
testClass() {
alert('This is CubeV3 classes testfunction reporting in!');
/*you have put the call to the private method inside the constructor of the javascript class. in that point the functions are not yet initialized
but if you initialize the object like so:
var test = new MyObject();
and then do this:
test.myMethod();
it will work.*/
}
update() {
this.turnTimer ++;
if (this.turnTimer > this.turnTimerMax) {
this.dir = this.turnTimerMax = getRandomNumberV2(1,4);
this.turnTimer = 0;
this.turnTimerMax = getRandomNumberV2(30,100);
}
if (this.dir == 1) {this.cubeLocY -=this.speed;}//UP
if (this.dir == 2) {this.cubeLocY +=this.speed;}//DOWN
if (this.dir == 3) {this.cubeLocX -=this.speed;}//LEFT
if (this.dir == 4) {this.cubeLocX +=this.speed;}//RIGHT
}
draw(self,) {
//this.cubeLocX = 555;
resetCanvas();
console.log(this.cubeLocX);
alert(this.cubeLocX);
this.ctx.fillStyle="#2a2b2d";
this.ctx.fillRect(this.cube_loc_x,this.cube_loc_y,25,25);
}
}
So how can i make my class work?
EDIT calling the class
This is placed after the draw for calling and updating the class
//setInterval(resetCanvas,10)
var testCube = new cubeV3(canvas);
setInterval(cube, 10);
//setInterval(testCube, 10);
setInterval(testCube.update, 10);
setInterval(testCube.draw, 10);
Advice 1: "this" can be tricky in js, avoid it if it is possible.
Advice 2: maybe it is not the best Oop design to define the draw function in the rectangle class. It should be better to define a standalone draw function which has a shape argument:
function draw(shape){
shape.ctx.fillStyle = ...
...
}
This way you can avoid some headache in the future also.

three.js textureloader multiple images

So I have a website that does a few things in webgl w/ three.js, and I noticed that loadTexture is going away soon, and that I should probably switch to using textureloaders. Basically, i'd like to preload all my textures before any code executes at the start of my code. I was thinking about doing something like below, which will allow me to load any number of images, and assign them to a texture object that can be called when needed.
var loadedtex = {}
var to_load = ['images/a.png','images/b.png','images/c.png']
var texture_loader = new THREE.TextureLoader();
for(var i=0;i<to_load.length;i++){
texture_loader.load(to_load[i],function(tex){
loadedtex[to_load[i]] = tex
})
}
I'm probably missing something obvious, but I can't quite get it to work correctly. When I use the code above, loadedtex will fill up loadedtex['images/c.png'] every time, instead of properly looping and remember which "i" value it should be using.
Proper result should be something like:
loadedtex['images/a.png'] = Three.Texture{}...
loadedtex['images/b.png'] = Three.Texture{}...
loadedtex['images/c.png'] = Three.Texture{}...
but what i really get is:
loadedtex['images/c.png'] = Three.Texture{}
I know its because the "i" variable will always be max value by the time anything loads, but i'm not sure how to accomplish what i want.
Thanks.
---edit---
This is what I ended up with. Seems to work well. Thanks for the advice.
var loadedtex = {}
var textureloaded = 0
var to_load = ['images/a.png','images/b.png','images/c.png']
var texture_loader = new THREE.TextureLoader();
load_textures = function(){
if (textureloaded == to_load.length){return}
var texture = to_load[textureloaded]
texture_loader.load(texture,function(tex){
loadedtex[texture] = tex
textureloaded += 1
load_textures()
})
}
load_textures()
If you're using ES6:
let assets = [
{ name:'img1', url:'img/img1.png' },
{ name:'img2', url:'img/img2.png' },
{ name:'img3', url:'img/img3.png' },
];
this.textures = {};
for ( let img of assets ) {
this.loader.load(img.url, ( texture ) => {
this.textures[img.name] = texture;
assets.splice( assets.indexOf(img), 1);
if ( !assets.length ) {
this.init()
}
console.log('[TextureLoader] Loaded %o', img.name);
});
}
Try to make a closure function for it like,
for(var i=0;i<to_load.length;i++){
(function(tl){
texture_loader.load(tl,function(tex){
loadedtex[tl] = tex
})
})(to_load[i]);
}

EaselJS: BitmapSequence issue in a OOP-like class

I have been playing a bit with gskinner.com's EaselJS library (http://easeljs.com/, http://easeljs.com/examples/game/game.html), which makes dealing with HTML5's canvas a lot easier.
So I'm trying to remake something like Space Invaders in the canvas. So far it's not much, just the payer moving left to right. See the progress here: http://jansensan.net/experiments/easeljs-space-invader/
For the invaders, I needed an animation, so I followed a tutorial on how to do so: http://www.youtube.com/watch?v=HaJ615V6qLk
Now that is all good and dandy, however I follow gskinner.com's way of creating "classes": http://easeljs.com/examples/game/Ship.js I'm not certain if I can call that a class, but it is used as such.
So below is the class that I wrote for the Invader, however it seems like the BitmapSequence does not seem to be added to EaselJS's stage. Anyone can guide me through this? Thanks!
// REFERENCES
/*
http://easeljs.com/examples/game/Ship.js
*/
// CLASS
(function(window)
{
function Invader()
{
this.initialize();
}
var p = Invader.prototype = new Container();
// CONSTANTS
// VARS
p.image;
p.bitmapSequence;
// CONSTRUCTOR
p.Container_initialize = p.initialize; //unique to avoid overiding base class
p.initialize = function()
{
this.Container_initialize();
this.image = new Image();
this.image.onload = p.imageLoadHandler;
this.image.onerror = p.imageErrorHandler;
this.image.src = "assets/images/invader-spritesheet.png";
}
p.imageLoadHandler = function()
{
var frameData = {
anim:[0, 1, "anim"]
}
var spriteSheet = new SpriteSheet(p.image, 22, 16, frameData);
p.bitmapSequence = new BitmapSequence(spriteSheet);
p.bitmapSequence.regX = p.bitmapSequence.spriteSheet.frameWidth * 0.5;
p.bitmapSequence.regY = p.bitmapSequence.spriteSheet.frameHeight * 0.5;
p.bitmapSequence.gotoAndStop("anim");
p.addChild(p.bitmapSequence);
}
p.imageErrorHandler = function()
{
console.log("Error: the url assets/images/invader-spritesheet.png could not be loaded.");
}
window.Invader = Invader;
}(window));
Does you p.image/this.Container_initalize actually exist at that point? As you switch between using this. and p. between your init and other functions, while they might seem to be the same practice has often taught me its not the case. Try changing your init function to this:
p.initialize = function()
{
p.Container_initialize();
p.image = new Image();
p.image.onload = p.imageLoadHandler;
p.image.onerror = p.imageErrorHandler;
p.image.src = "assets/images/invader-spritesheet.png";
}

Categories