Jump to content

UI problem using Slick - help!


Nige
 Share

Recommended Posts

So I'm making a pokemon-ish RPG with an inventory screen and a battle screen using Flaxis' SlickUI plugin. I'm running into a strange error:

phaser.min.js:3 Uncaught TypeError: Cannot read property 'camera' of null
    at Roast.i.Component.FixedToCamera.postUpdate (phaser.min.js:3)

'Roast' is a collectible you can put in your inventory. When I use an item on the battle screen, I remove it from the inventory array. Then I rebuild the inventory without the used item - then the first item in the inventory (regardless of which item was used) throws the above error on the next frame.

You can see all my code on GitHub here: https://github.com/niall-slater/cup/tree/master/src, but my ui.js file, as well as my collectable.js, is below (apologies for length).

If you've got any idea what I'm doing wrong your advice would be much appreciated! Cheers.

//collectable.js

class Collectable extends Phaser.Sprite {
	
    constructor(game, x, y) {
        super(game, 0, 0);
		
		this.collected = false;
		//Treat this as an abstract class - do not create anything of class Collectable.
	}
	
	update() {
		
		if (playState.player.isNextTo(this) && !this.collected) {
			this.onCollect();
		}
	}
	
	onCollect() {
		this.collected = true;
		
		playState.world.currentChunk.groupItems.remove(this);
		playState.groupUI.add(this);
		
		playState.player.addToInventory(this);
		
		this.destroy();
	}
}
//ui.js

//UI values
let uiSize = {
	buttonWidth: 128,
	buttonHeight: 32,
	margin: 4,
	panelX: 4,
	panelY: 72,
	panelWidth: 480-8,
	panelHeight: 270-78
};

let style_default = { font: "24px VT323", fill: "#000", wordWrap: "true", wordWrapWidth: 330};
let style_small = { font: "19px VT323", fill: "#333", wordWrap: "true", wordWrapWidth: 330};


var ui = {
	
	inventory: {
		
		items: [],
		displaying: false,
		
		margin: 12,
		padding: 12,
		listStartY: 0,
		entryHeight: 18,
		
		init: function() {
		
			//Create inventory panel
			slickUI.add(ui.inventory.panel = new SlickUI.Element.Panel(this.margin, this.margin, gameWidth - this.margin*2, gameHeight - this.margin*2));

			//Title
			ui.inventory.panel.add(ui.inventory.panel.title = new SlickUI.Element.Text(0, 0, 'INVENTORY', null, style_default)).centerHorizontally();
			
			ui.inventory.panel.alpha = .95;
			ui.inventory.panel.x = this.margin + 256;
			
			for (let i = 0; i < this.items.length; i++) {
				this.addEntryToList(this.items[i]);
			}
		},
		
		//Toggle inventory display
		toggle: function() {
			if (this.displaying) {
				this.hideInventory();
				this.displaying = false;
				
			} else {
				this.showInventory();
				this.displaying = true;
			}
		},
		
		showInventory: function() {
            game.add.tween(ui.inventory.panel).to( {x: ui.inventory.margin}, 500, Phaser.Easing.Exponential.Out, true);

			//Bring UI to top
			game.world.bringToTop(playState.groupUI);
		},
		
		hideInventory: function() {
			
            game.add.tween(ui.inventory.panel).to( {x: 256 + ui.inventory.margin}, 500, Phaser.Easing.Exponential.Out, true);
			
		},
		
		addItem: function(item) {
			
			//itemSprite is the object from the game world, which is a sub-subtype of Phaser.Sprite
			//store the itemSprite in an item object, which will have item.sprite, item.label
			
			this.items.push(item);
			
			this.addEntryToList(item);
			
		},
		
		addEntryToList: function(item) {
			let numItems = this.items.length;
			
			ui.inventory.panel.add(item.icon = new SlickUI.Element.DisplayObject(this.padding, Math.floor(this.listStartY + this.padding * 2 + (numItems * this.entryHeight - 2)), item));
			
			ui.inventory.panel.add(item.label = new SlickUI.Element.Text(Math.floor(this.padding * 2), Math.floor(this.listStartY + numItems * this.entryHeight + this.padding), item.name, null, style_small));
		},
		
		removeItem: function(item) {
			
			let index = this.items.indexOf(item);
			
			ui.inventory.panel.destroy();
			
			this.items.splice(index, 1);
			
			ui.inventory.init();
			
		}
	},
	
	encounter: {
		
		margin: 4,
		padding: 2,
		
		menuHeight: 64,
		buttonWidth: 76,
		
		position_monster: {x: 144, y: 64},
		
		delay: 600,
		tweenDistance: 128,
		
		sprite_background: null,
		
		sprite_monster: null,
		
		cursor: null,
		
		init: function() {
			
			game.camera.x = 0;
			game.camera.y = 0;
			game.camera.unfollow();
			
			let numSprites = 5;
			let legsSelection, bodySelection, headSelection;
			legsSelection = Math.floor(Math.random() * numSprites);
			bodySelection = Math.floor(Math.random() * numSprites);
			headSelection = Math.floor(Math.random() * numSprites);
			
			//Create sprites
			this.sprite_background = game.add.sprite(0, 0, 'enc_background');
			this.sprite_player = game.add.sprite(16, gameHeight - 116, 'enc_player');
			this.sprite_monster = [];
			this.sprite_monster.push(game.add.sprite(this.position_monster.x + this.tweenDistance, this.position_monster.y, 'enc_monster_bodies', bodySelection));
			this.sprite_monster.push(game.add.sprite(this.position_monster.x + this.tweenDistance, this.position_monster.y, 'enc_monster_heads', headSelection));

			/* CREATE MENU */
			//base panel
			slickUI.add(this.menu = new SlickUI.Element.Panel(
				this.margin, gameHeight - this.menuHeight - this.margin,
				gameWidth - this.margin*2, this.menuHeight));
			this.menu.add(this.menu.title = new SlickUI.Element.Text(this.padding, 0, 'BATTLE', 14, style_small));
			
			//Give button
			this.menu.add(this.menu.buttonGive = new SlickUI.Element.Button(this.padding, this.padding + 20, this.buttonWidth, this.menuHeight/2));
			this.menu.buttonGive.add(this.menu.buttonGive.label = new SlickUI.Element.Text(this.padding, 0, 'FOOD', 10, style_small)).centerHorizontally();
			this.menu.buttonGive.events.onInputUp.add(this.openFood);
			
			/*
			//Eat button
			this.menu.add(this.menu.buttonEat = new SlickUI.Element.Button(this.padding * 2 + this.buttonWidth, this.padding + 20, this.buttonWidth, this.menuHeight/2));
			this.menu.buttonEat.add(this.menu.buttonEat.label = new SlickUI.Element.Text(this.padding, 0, 'EAT', 10, style_small)).centerHorizontally();
			this.menu.buttonRun.events.onInputUp.add(this.openGive);
			*/
			
			//Run button
			this.menu.add(this.menu.buttonRun = new SlickUI.Element.Button(this.padding * 3 + this.buttonWidth * 2, this.padding + 20, this.buttonWidth, this.menuHeight/2));
			this.menu.buttonRun.add(this.menu.buttonRun.label = new SlickUI.Element.Text(this.padding, 0, 'RUN', 10, style_small)).centerHorizontally();
			this.menu.buttonRun.events.onInputUp.add(this.endEncounter);
			
			//Put menu out of view so it can slide in
			this.menu.y += this.tweenDistance;
			game.camera.flash(0xffffff, this.delay/2, false);
			game.time.events.add(this.delay, this.tweenInUI, this);
			
			/* CREATE FOOD MENU */
			
			slickUI.add(this.menuFood = new SlickUI.Element.Panel(
				this.margin, this.margin,
				gameWidth*.75, gameHeight - this.margin*2));
			this.menuFood.add(this.menuFood.title = new SlickUI.Element.Text(this.margin, 0, 'FOOD', 14, style_small));
			this.menuFood.x = -gameWidth*.75;
			
			this.menuFood.add(this.menuFood.buttonClose = new SlickUI.Element.Button(this.menuFood.width - this.margin - 24, this.margin, 24, 24));
			this.menuFood.buttonClose.add(this.menuFood.buttonClose.label = new SlickUI.Element.Text(0, -4, 'x', 8, style_small)).centerHorizontally();
			this.menuFood.buttonClose.events.onInputUp.add(this.closeFood);
			
			this.menuFood.entries = [];
			for (let i = 0; i < ui.inventory.items.length; i++) {
				let itemButton;
				let itemHeight = 32;
				let itemWidth = 124;
				let itemsStartY = 16;
				let item = ui.inventory.items[i];
				this.menuFood.add(itemButton = new SlickUI.Element.Button(this.margin, itemsStartY + this.margin + (i * itemHeight), itemWidth, itemHeight));
				itemButton.add(new SlickUI.Element.Text(0, 0, item.name, 8, style_small));
				itemButton.events.onInputUp.add(()=>{ui.encounter.useFood(item)});
				this.menuFood.entries.push(itemButton);
			}
            
		},
		
		refreshFoodList: function() {
			
			for (let i = 0; i < this.menuFood.entries.length; i++) {
				this.menuFood.remove(this.menuFood.entries[i]);
			}
			
			this.menuFood.entries = [];
			
			for (let i = 0; i < ui.inventory.items.length; i++) {
				let itemButton;
				let itemHeight = 32;
				let itemWidth = 124;
				let itemsStartY = 16;
				let item = ui.inventory.items[i];
				this.menuFood.add(itemButton = new SlickUI.Element.Button(this.margin, itemsStartY + this.margin + (i * itemHeight), itemWidth, itemHeight));
				itemButton.add(new SlickUI.Element.Text(0, 0, item.name, 8, style_small));
				itemButton.events.onInputUp.add(()=>{ui.encounter.useFood(item)});
				this.menuFood.entries.push(itemButton);
			}
			
		},
		
		tweenInUI: function() {
			//Tween in the monster
			this.sprite_monster.forEach((element)=>{
				game.add.tween(element).to( {x: this.position_monster.x}, 500, Phaser.Easing.Cubic.Out, true);
			});
			
			//Tween in the menu after a delay
			game.time.events.add(this.delay, () => {
				game.add.tween(this.menu).to( {y: gameHeight - this.menuHeight - this.margin}, 500, Phaser.Easing.Cubic.Out, true)
			}, this);
			
		},
		
		//MENU OPTIONS
		
		openFood: function() {
			game.add.tween(ui.encounter.menu).to( {y: ui.encounter.menu.y + ui.encounter.tweenDistance}, 500, Phaser.Easing.Cubic.Out, true);
			
			game.add.tween(ui.encounter.menuFood).to( {x: ui.encounter.margin}, 500, Phaser.Easing.Cubic.Out, true);
		},
		
		closeFood: function() {
			game.add.tween(ui.encounter.menu).to( {y: ui.encounter.menu.y - ui.encounter.tweenDistance}, 500, Phaser.Easing.Cubic.Out, true);
			
			game.add.tween(ui.encounter.menuFood).to( {x: 0 - gameWidth*.75}, 500, Phaser.Easing.Cubic.Out, true);
		},
		
		useFood: function(item) {
			console.log('Chose ' + item.name);
			ui.inventory.removeItem(item);
			this.refreshFoodList();
//			ui.encounter.closeFood();
		},
		
		endEncounter: function() {
			playState.endEncounter();
		}
		
	}
};

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...