5
\$\begingroup\$

The Problem

I am having a problem in that I am finding it hard to understand how to update my current code so that it uses states. I am creating a game, the game has a menu, each page in the game will be a different state but I am unsure how to implement this in my current code.

enter image description here

Here is the menu I have created, below I have drawn what I am trying to explain.

enter image description here

The Question Would it be possible if somebody could, using my code below, help me understand how I can update it to include different states?

The Code

<div style id="canvas">
        <canvas id="myCanvas" style="border:5px solid #410b11" height="320" width="480">
            <p>Your browser does not support HTML5!</p>
        </canvas>
    </div>

        <script type="text/javascript">

            //Referencing the canvas
            var canvas = document.getElementById("myCanvas");
            var context = canvas.getContext("2d");
            var width = canvas.getAttribute('width');
            var height = canvas.getAttribute('height');

            //Finding the position of the mouse
            var mouseX;
            var mouseY;

            //Images
            var bgImage = new Image();
            var logoImage = new Image();
            var playImage = new Image();
            var instructImage = new Image();
            var settingsImage = new Image();
            var aboutImage = new Image();
            var peaceImage = new Image();

            var backgroundY = 0;
            var speed = 1;

            //Arrays below used for mouse over function
            var buttonX = [130,110,130,160];
            var buttonY = [100,140,180,220];
            var buttonWidth = [96,260,182,160];
            var buttonHeight = [40,40,40,40];

            var peaceX = [0,0];
            var peaceY = [0,0];
            var peaceWidth = 35;
            var peaceHeight = 35;

            var peaceVisible = false;
            var peaceSize = peaceWidth;
            var peaceRotate = 0;

            var frames = 30;
            var timerId = 0;
            var fadeId = 0;
            var time = 0.0;

            peaceImage.src = "Images/peace.png";
            bgImage.onload = function(){
                context.drawImage(bgImage, 0, backgroundY);
            };
            bgImage.src = "Images/background.png";
            logoImage.onload = function(){
                context.drawImage(logoImage, 50, -10);
            }
            logoImage.src = "Images/logo.png";
            playImage.onload = function(){
                context.drawImage(playImage, buttonX[0], buttonY[0]);
            }
            playImage.src = "Images/play.png";
            instructImage.onload = function(){
                context.drawImage(instructImage, buttonX[1], buttonY[1]);
            }
            instructImage.src = "Images/instructions.png";
            settingsImage.onload = function(){
                context.drawImage(settingsImage, buttonX[2], buttonY[2]);
            }
            settingsImage.src = "Images/settings.png";
            aboutImage.onload = function(){
                context.drawImage(aboutImage, buttonX[3], buttonY[3]);
            }
            aboutImage.src = "Images/about.png";

            timerId = setInterval("update()", 1000/frames);

            canvas.addEventListener("mousemove", checkPos);
            canvas.addEventListener("mouseup", checkClick);

            function update() {
                clear();
                move();
                draw();
            }
            function clear() {
                context.clearRect(0, 0, width, height);
            }
            function move(){
                backgroundY -= speed;
                if(backgroundY == -1 * height){
                    backgroundY = 0;
                }
                if(peaceSize == peaceWidth){
                    peaceRotate = -1;
                }
                if(peaceSize == 0){
                    peaceRotate = 1;
                }
                peaceSize += peaceRotate;
            }


            function draw(){

                context.drawImage(bgImage, 0, backgroundY);
                context.drawImage(logoImage, 50,-10);
                context.drawImage(playImage, buttonX[1], buttonY[0]);
                context.drawImage(instructImage, buttonX[2], buttonY[1]);
                context.drawImage(settingsImage, buttonX[2], buttonY[2]);
                context.drawImage(aboutImage, buttonX[3], buttonY[3]);
                    if(peaceVisible == true){
                    context.drawImage(peaceImage, peaceX[0] - (peaceSize/2), peaceY[0], peaceSize, peaceHeight);
                    context.drawImage(peaceImage, peaceX[2] - (peaceSize/2), peaceY[2], peaceSize, peaceHeight);
                }
            }

            function checkPos(mouseEvent){
                if(mouseEvent.pageX || mouseEvent.pageY == 0){
                    mouseX = mouseEvent.pageX - this.offsetLeft;
                    mouseY = mouseEvent.pageY - this.offsetTop;
                }else if(mouseEvent.offsetX || mouseEvent.offsetY == 0){
                    mouseX = mouseEvent.offsetX;
                    mouseY = mouseEvent.offsetY;
                }
                for(i = 0; i < buttonX.length; i++){
                    if(mouseX > buttonX[i] && mouseX < buttonX[i] + buttonWidth[i]){
                        if(mouseY > buttonY[i] && mouseY < buttonY[i] + buttonHeight[i]){
                            peaceVisible = true;
                            peaceX[0] = buttonX[i] - (peaceWidth/2) - 2;
                            peaceY[0] = buttonY[i] + 2;
                            peaceX[1] = buttonX[i] + buttonWidth[i] + (peaceWidth/2); 
                            peaceY[1] = buttonY[i] + 2;
                        }
                    }else{
                        peaceVisible = false;
                    }
                }
            }
            function checkClick(mouseEvent){
                for(i = 0; i < buttonX.length; i++){
                    if(mouseX > buttonX[i] && mouseX < buttonX[i] + buttonWidth[i]){
                        if(mouseY > buttonY[i] && mouseY < buttonY[i] + buttonHeight[i]){
                            fadeId = setInterval("fadeOut()", 1000/frames);
                            clearInterval(timerId);
                            canvas.removeEventListener("mousemove", checkPos);
                            canvas.removeEventListener("mouseup", checkClick);
                        }
                    }
                }
            }
            function fadeOut(){
                context.fillStyle = "rgba(0,0,0, 0.2)";
                context.fillRect (0, 0, width, height);
                time += 0.1;
                if(time >= 2){
                    clearInterval(fadeId);
                    time = 0;
                    timerId = setInterval("update()", 1000/frames);
                    canvas.addEventListener("mousemove", checkPos);
                    canvas.addEventListener("mouseup", checkClick);
                }
            }
</script>
\$\endgroup\$
1
\$\begingroup\$

A state is intended to help your program determine what situation it has found itself in. To implement a simple state machine, all you really need is a simple variable. For example var state = 1;. What I'd suggest you do is update the draw() function to include a switch-case statement. This function should be responsible for everything that has to do with screen output - no other function should do any drawing to the canvas. The idea is that you set everything up via variables (including state machines) before this function is called. Then you call it, and the frame is done. This function will first clear your canvas and then completely redraw the UI based on what state it's in. So for example:

var state = 1;
function DrawUI(){
    context.clearRect(0, 0, canvas.width, canvas.height); //Clear canvas
    switch(state){
        case 1:
            //draw main menu
            break;
        case 2:
            //draw play menu
            break;
        case 3:
            //draw settings menu
            break;
        default:
            alert("Unknown state: "+state);
            break;
    }
}

function ClickedOnPlayButton(){
    state = 2;
    DrawUI();
}

function ClickedOnSettingsButton(){
    state = 3;
    DrawUI();
}
\$\endgroup\$
  • \$\begingroup\$ How would this be applied to the current situation of the OP? \$\endgroup\$ – Vaillancourt Mar 22 '16 at 18:55
  • \$\begingroup\$ Your Update() function calls Clear(), Move() and Draw(). My recommendation is that you first do Move() and everything else that needs to happen for the "game" part of your game to work. Once all of that is done, you clear the canvas and draw it based on what the variables are saying. My DrawUI() function is a combination of your Clear() and Draw() wherein it first clears the canvas and then draws it. The state variable can then be used to determine which menu the player has open, and based on this information, you draw the correct menu. \$\endgroup\$ – Liam Lime Mar 22 '16 at 19:04
  • \$\begingroup\$ You should update your answer. The idea is to fix the user's problem. You can start by giving guidelines on how state machines work, but ultimately, you have to help the user. \$\endgroup\$ – Vaillancourt Mar 22 '16 at 19:06
  • \$\begingroup\$ I understand why i would do that @LiamLime but how would I implement it into my code correctly, would you be able to expand slightly? Thanks for indepth answer, I want to put a thumbs up but i cant haha! \$\endgroup\$ – RushFan2112 Mar 22 '16 at 19:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.