Help with Buttons

Recommended Posts

5 hours ago, samme said:

That sounds like there's a problem with the state's create property.

I also looked at how my create was defined above, but I've called it the same thing everywhere I need to reference it, no typos or anything from what I can see, just really stumped as to what I've done wrong.

Share this post

Link to post
Share on other sites
18 minutes ago, samme said:

Can you post the whole script?

Absolutely. I'll warn you now though, its quite long and this is just the final state in my game to ask the user maths questions. Also the localstorage stuff is just there from when I was messing around earlier. I hope my comments makes sense too.

var Questions, Phaser, game, localStorage;
var gameOptions = {
    // maximum length of the sum
	maxSumLen: 5,
	// local storage name used to save high score
	localStorageName: "oneplustwo",
	// time allowed to answer a question, in milliseconds
	timeToAnswer: 4000,
	// score needed to increase difficulty
	nextLevel: 400

// "PlayGame" state
var Questions = {

	// when the state preloads...
    preload: function(){
        // making the game cover the biggest window area possible while showing all content
        game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
        // game.scale.pageAlignHorizontally = true;
        // game.scale.pageAlignVertically = true;
		// do not pause the game when it loses focus
		game.stage.disableVisibilityChange = true;
		// preloading images
		game.load.image("timebar", "./assets/images/timebar.png");
		// preloading a spritesheet where each sprite is 400x50 pixels
		game.load.spritesheet("buttons", "./assets/images/buttons.png", 400, 50);
    },	// when the state has been created...
    create : function() {
 		// create Questions state and start it
		game.state.add("Questions", Questions, true);
		// create a 500x500 pixels game using CANVAS rendering
		Questions = new Phaser.Game(500, 500, Phaser.AUTO);
		game.stage.backgroundColor = '#0D0D73';
		// it's not game over yet...
		this.isGameOver = false;
		// current score is set to zero
		this.score = 0;
		// we'll also keep track of correct answers
		this.correctAnswers = 0;
		// topScore gets the previously saved value in local storage if any, zero otherwise
		this.topScore = localStorage.getItem(gameOptions.localStorageName) == null ? 0 : localStorage.getItem(gameOptions.localStorageName);
		// sumsArray is the array with all possible questions
		this.sumsArray = [];
		// rather than tossing a random question each time, I found easier
		// to store all possible questions in an array then draw a random question
		// each time. I just need an algorithm to generate all possible questions.
		// let's start building all possible questions with this loop
		// ranging from 1 (only one operator, like 1+1) to maxSumLen
		// (in this case 5, like 1+1+1+1-1-1)
		for(var i = 1; i < gameOptions.maxSumLen; i++){
			// defining sumsArray[i] as an array of three empty arrays
			this.sumsArray[i]=[[], [], []];
			// looping from 1 to 3, which are the possible results of each sum
			for(var j = 1; j <= 3; j++){
				// buildTrees is the core of the script, see it explained
				// some lines below
				this.buildThrees(j, 1, i, j);
		// try this! You will see all possible combinations
		// questionText is the text object which will display the question
		this.questionText = game.add.text(250 , 160, "-", {
			font: "bold 72px Arial"
		// setting questionText registration point
		// scoreText will keep the current score
		this.scoreText = game.add.text(10, 10, "-", {
			font: "bold 24px Arial"
		// loop to create the three answer buttons
		for(i = 0;i < 3; i++){
			// creation of the answer button, set to frame "i"
			// Calls checkAnswer callback function once triggered
			game.add.button(50, 250 + i * 75, "buttons", this.checkAnswer).frame = i;
		// adding the time bar
		var numberTimer =  game.add.sprite(50, 250, "timebar");
		// creation of a graphic mask covering the three answer buttons
		this.buttonMask = game.add.graphics(50, 250);
		this.buttonMask.drawRect(0, 0, 400, 200);
		numberTimer.mask = this.buttonMask;
		// method to ask next question
	// buildThrees method, it will find all possible sums
	// arguments:
	// initialNumber: the first number. Each question always start with a positive number
	// currentIndex: it's the amount of operands already placed in the sum
	// limit: the max amount of operands allowed in the question
	// currentString: the string generated so far
	buildThrees: function(initialNummber, currentIndex, limit, currentString){
		// the possible operands, from -3 to 3, excluding the zero
		var numbersArray = [-3, -2, -1, 1, 2, 3];
		// looping from 0 to numbersArray's length
		for(var i = 0; i < numbersArray.length; i++){
			// "sum" is the sum between the first number and current numberArray item
			var sum = initialNummber + numbersArray[i];
			// output string is generated by the concatenation of current string with
			// current numbersArray item. I am adding a "+" if the item is greater than zero,
			// otherwise it already has its "-"
			var outputString = currentString + (numbersArray[i] < 0 ? "" : "+") + numbersArray[i];
			// if sum is between 1 and 3 and we reached the limit of operands we want...
			if(sum > 0 && sum < 4 && currentIndex == limit){
				// then push the output string into sumsArray[amount of operands][result]
				this.sumsArray[limit][sum - 1].push(outputString);
			// if the amount of operands is still below the amount we want...
			if(currentIndex < limit){
				// recursively calling buildThrees, passing as arguments:
				// the current sum
				// the new amount of operands
				// the amount of operands we want
				// the current output string
				this.buildThrees(sum, currentIndex + 1, limit, outputString);
	// this method asks next question
	nextNumber: function(){
		// updating score text
		this.scoreText.text = "Score: " + this.score.toString() + "\nBest Score: " + this.topScore.toString();
		// if we already answered more than one question...
		if(this.correctAnswers > 1){
			// stopping time tween
			// resetting mask horizontal position
			this.buttonMask.x = 50;
		// if we already answered at least one question...
		if(this.correctAnswers > 0){
			// tween to slide out the mask, unvealing what's behind it
			this.timeTween = game.add.tween(this.buttonMask).to({
				x: -350
			}, gameOptions.timeToAnswer, Phaser.Easing.Linear.None, true);
			// callback to be triggered when the tween ends
				// calling "gameOver" method. "?" is the string to display
			}, this);
		// drawing a random result between 0 and 2 (it will be from 1 to 3)
		this.randomSum = game.rnd.between(0, 2);
		// choosing question length according to current score
		var questionLength = Math.min(Math.floor(this.score / gameOptions.nextLevel) + 1, 4);
		// updating question text
		this.questionText.text = this.sumsArray[questionLength][this.randomSum][game.rnd.between(0, this.sumsArray[questionLength][this.randomSum].length - 1)];
	// method to check the answer, the argument is the button pressed
	checkAnswer: function(button){
		// we check the answer only if it's not game over yet
			// button frame is equal to randomSum means the answer is correct
			if(button.frame == this.randomSum){
				// score is increased according to the time spent to answer
     			this.score += Math.floor((this.buttonMask.x + 350) / 4);
				// one more correct answer
				// moving on to next question
			// wrong answer
				// if it's not the first question...
     			if(this.correctAnswers > 1) {
					// stop the tween
				// calling "gameOver" method. "button.frame + 1" is the string to display
     			this.gameOver(button.frame + 1);
	// method to end the game. The argument is the string to write
	gameOver: function(gameOverString){
		// displaying game over text
		this.questionText.text = this.questionText.text + " = " + gameOverString;
		// now it's game over
		this.isGameOver = true;
		// updating top score in local storage
		localStorage.setItem(gameOptions.localStorageName, Math.max(this.score, this.topScore));
		// restart the game after two seconds
		game.time.events.add(Phaser.Timer.SECOND * 20, function(){
		}, this);


Share this post

Link to post
Share on other sites
9 minutes ago, samme said:

When exactly do you get this error?

Ordinarily that would happen while a state is starting.

Yep happens as soon as the state loads. It also creates 2 smaller weird windows below the actual game, but I think that’s a separate issue

Share this post

Link to post
Share on other sites
8 hours ago, samme said:

Make sure you have only one new Phaser.Game(…).

See https://codepen.io/samme/pen/bLQeoV?editors=0010


You absolute genius, I knew it would be a simple error, I suppose that's what I get for using parts of other peoples code :lol:. I get a different error now relating to my game over state, but I'll try and solve that myself. Thank you so much samme!!

Share this post

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.