Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

different pages in a canvas game

The Problem

I am creating a game using the HTML5 Canvas, the game has a main menu, the main menu has multiple buttons for you to choose. I am finding it difficult and confusing how I would, for example if the user presses the 'Play' button, to show the game. Here is an image of the main menu:

Main menu of game.

The Question

The question is how would I get from this page to another in my game?

enter image description here

I think you get the idea. I deliberately created the menu using the canvas, I know I could of made the menu using HTML for example but I cant as this is an example for students of what Canvas can do, whats good and bad etc.

The Code

<html>
<head>
    <title>Sean Coyne</title>
</head>
<body onload="start_game()">
<body>
    <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>

        <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>
    </body>
</html>
like image 283
RushFan2112 Avatar asked Mar 22 '16 13:03

RushFan2112


2 Answers

What I usually do is have a switch statement inside the draw loop, and a state variable which holds the current game state (menu, playing, etc...).

Then, based on the current game state you only draw the objects required for the current scene.

Something like this:

var STATES = { 
  Menu: 0,
  PauseMenu: 1,
  Playing: 2
};
var currentState = STATES.Menu;
...
function draw() {
  switch(currentState) {
    case STATES.Menu:
      // Draw buttons, etc..
    break;
    case STATES.Playing:
      // Draw the game screen, the player, etc...
    break;
  }
}

When the user presses the Play button the only thing you have to do is:

function onPlayButtonClick() {
   currentState = STATES.Playing;
   // Starting the next frame the new state will be "magically" drawn
}

If you don't like the switch statement, you can create a State class that has a draw method. Then you can simply create new states, each with it's own drawing method and in the main draw loop only call the draw method of the current state.

Same goes for the update function, each state has it's own update function (in the main menu you update buttons or animate things, while playing the game you update the game world and run your physics). So, based on the current state your update function is actually different. It's up to you how you structure your code and how you call different functions based on the current state.

like image 132
XCS Avatar answered Sep 21 '22 20:09

XCS


In each text option, you should create a smaller Canvas, only with the option text and add a 'click' event with the callbacks.

Tip: You don't need another page, just erase the main canvas and draw what you want.

like image 29
mariodiniz Avatar answered Sep 21 '22 20:09

mariodiniz