6

Hello i'm fairly new to JavaScript and decided to learn more by following along the w3schools game tutorial.

I decided to make it a platform game, however I haven't been able to figure out how to add a viewport that follows the player outside the canvas.

Could anyone help me out? Thanks in advance.

Fiddle

//Background
var Background;

//Objects
var Player;
var Obstacle;

//Mobile buttons
var UpBtn;
var DownBtn;
var LeftBtn;
var RightBtn;
//End

function startGame() {
    Background = new component(656, 270, "gray", 0, 0);

    Player = new component(30, 30, "blue", 200, 75);

    Obstacle = new component(10,100, "red", 300, 170);

  //Mobile buttons
    UpBtn = new component(0, 0, "black", 50, 160);    
    DownBtn = new component(0, 0, "black", 50, 220);    
    LeftBtn = new component(30, 30, "black", 20, 200);    
    RightBtn = new component(30, 30, "black", 90, 200); 
    //End
    myGameArea.start();
}

var myGameArea = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 480;
        this.canvas.height = 270;
        this.context = this.canvas.getContext("2d");
        document.body.insertBefore(this.canvas, document.body.childNodes[0]);
        this.interval = setInterval(updateGameArea, 20);
        //Mobile buttons
        window.addEventListener('mousedown', function (e) {
            myGameArea.x = e.pageX;
            myGameArea.y = e.pageY;
        })
        window.addEventListener('mouseup', function (e) {
            myGameArea.x = false;
            myGameArea.y = false;
        })
        window.addEventListener('touchstart', function (e) {
            myGameArea.x = e.pageX;
            myGameArea.y = e.pageY;
        })
        window.addEventListener('touchend', function (e) {
            myGameArea.x = false;
            myGameArea.y = false;
        })
        //End


        //Keyboard
        window.addEventListener('keydown', function (e) {
          myGameArea.keys = (myGameArea.keys || []);
          myGameArea.keys[e.keyCode] = true;
        })
        window.addEventListener('keyup', function (e) {
          myGameArea.keys[e.keyCode] = false; 
        })
        //End

    },
    stop : function() {
        clearInterval(this.interval);
    },    
    clear : function() {
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
    },
    dead : function() {
      myGameArea.stop();
      startGame();
    }
}

function component(width, height, color, x, y, type) {
    this.type = type;
    if (type == "image") {
    this.image = new Image();
    this.image.src = color;
    }
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;
    speed = 4;
    this.speedX = 0;
    this.speedY = 0;    
    this.gravity = 0.175;
    this.gravitySpeed = 0;
    this.bounce = 1;
    this.update = function() {

        ctx = myGameArea.context;
        if (type == "image") {
            ctx.drawImage(this.image, 
                this.x, 
                this.y,
                this.width, this.height);
    } else {
        ctx.fillStyle = color;
        ctx.fillRect(this.x, this.y, this.width, this.height);
    }
}
    this.newPos = function() {
        this.gravitySpeed += this.gravity;
        this.x += this.speedX;
        this.y += this.speedY + this.gravitySpeed;
        this.hitBottom();
    }
    this.hitBottom = function() {
        var rockbottom = myGameArea.canvas.height - this.height;
        if (this.y > rockbottom) {
            this.y = rockbottom;
            this.gravitySpeed = -(this.gravitySpeed * this.bounce);
        }
    }
//Mobile buttons
    this.clicked = function() {
        var myleft = this.x;
        var myright = this.x + (this.width);
        var mytop = this.y;
        var mybottom = this.y + (this.height);
        var clicked = true;
        if ((mybottom < myGameArea.y) || (mytop > myGameArea.y) || (myright < myGameArea.x) || (myleft > myGameArea.x)) {
            clicked = false;
        }
        return clicked;
    }
    //End

      this.crashWith = function(otherobj) {
    var myleft = this.x;
    var myright = this.x + (this.width);
    var mytop = this.y;
    var mybottom = this.y + (this.height);
    var otherleft = otherobj.x;
    var otherright = otherobj.x + (otherobj.width);
    var othertop = otherobj.y;
    var otherbottom = otherobj.y + (otherobj.height);
    var crash = true;
    if ((mybottom < othertop) ||
    (mytop > otherbottom) ||
    (myright < otherleft) ||
    (myleft > otherright)) {
      crash = false;
    }
    return crash;
  }
}

function updateGameArea() {

    if (Player.crashWith(Obstacle)) {
    myGameArea.dead();
  } else {
    myGameArea.clear();
    Obstacle.update();
  }
    //Mobile buttons
        if (myGameArea.x && myGameArea.y) {
        /*if (myUpBtn.clicked()) {
            Player.y -= this.speed;
        }
        if (myDownBtn.clicked()) {
            Player.y += this.speed;
        }*/
        if (LeftBtn.clicked()) {
            Player.x += -this.speed;
        }
        if (RightBtn.clicked()) {
            Player.x += this.speed;
        }
    }
    UpBtn.update();        
    DownBtn.update();        
    LeftBtn.update();     
    RightBtn.update();                                
    Player.update();

    //End

    //Keyboard
  Player.speedX = 0;
  Player.speedY = 0; 

  if (myGameArea.keys && myGameArea.keys[37]) {Player.speedX = -this.speed; }
  if (myGameArea.keys && myGameArea.keys[39]) {Player.speedX = this.speed; }
  //if (myGameArea.keys && myGameArea.keys[38]) {Player.speedY = -this.speed; }
  //if (myGameArea.keys && myGameArea.keys[40]) {Player.speedY = this.speed; }
  //End
    Background.newPos(); 
    Background.update();
    Player.newPos();
    Player.update();

    Obstacle.update();

    //UpBtn.update();        
    //DownBtn.update();        
    LeftBtn.update();     
    RightBtn.update();
}
3
  • Do you want the blue player to not exceed the boundaries? Commented Sep 2, 2019 at 21:43
  • 1
    Yeah, also with the answer below my mobile controls (buttons) stop working. :/ tried to fix that but cant figure it out. Commented Sep 3, 2019 at 7:52
  • 1
    Sorry, I didn't noted that black square were buttons. I updated the answer with the fix. I created an attribute (isFixed) to handle this. Commented Sep 3, 2019 at 13:54

1 Answer 1

4
+150

You can create a variable to store the offsetX in canvas:

var offsetX = 0;

And then, in method updateGameArea(), update this offsetX to center at player x coordinate:

offsetX = Player.x - myGameArea.canvas.width/2;

Also, subtract the offsetX when drawing the components:

ctx.fillRect(
    this.x - (this.isFixed ? 0 : offsetX), // <--- here
    this.y, 
    this.width, 
    this.height);

I also create a new attribute to tell if the component is fixed on the screen or not:

this.isFixed = false;

And set isFixed = true to the control buttons and the background:

Background.isFixed=true;
LeftBtn.isFixed=true;
RightBtn.isFixed=true;

Here is the updated code (Fiddle):

https://jsfiddle.net/xkbvphjz/13/

Full code:

//Background
var Background;

//Objects
var Player;
var Obstacle;

//Mobile buttons
var UpBtn;
var DownBtn;
var LeftBtn;
var RightBtn;
//End

var offsetX = 0;

function startGame() {
    Background = new component(656, 270, "gray", 0, 0);
        Background.isFixed=true;

    Player = new component(30, 30, "blue", 200, 75);

    Obstacle = new component(10,100, "red", 300, 170);

  //Mobile buttons
    UpBtn = new component(0, 0, "black", 50, 160);    
    DownBtn = new component(0, 0, "black", 50, 220);    
    LeftBtn = new component(30, 30, "black", 20, 200);
    LeftBtn.isFixed=true;
    RightBtn = new component(30, 30, "black", 90, 200); 
    RightBtn.isFixed=true;
    //End
    myGameArea.start();
}

var myGameArea = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 480;
        this.canvas.height = 270;
        this.context = this.canvas.getContext("2d");
        document.body.insertBefore(this.canvas, document.body.childNodes[0]);
        this.interval = setInterval(updateGameArea, 20);
        //Mobile buttons
        window.addEventListener('mousedown', function (e) {
            myGameArea.x = e.pageX;
            myGameArea.y = e.pageY;
        })
        window.addEventListener('mouseup', function (e) {
            myGameArea.x = false;
            myGameArea.y = false;
        })
        window.addEventListener('touchstart', function (e) {
            myGameArea.x = e.pageX;
            myGameArea.y = e.pageY;
        })
        window.addEventListener('touchend', function (e) {
            myGameArea.x = false;
            myGameArea.y = false;
        })
        //End


        //Keyboard
        window.addEventListener('keydown', function (e) {
          myGameArea.keys = (myGameArea.keys || []);
          myGameArea.keys[e.keyCode] = true;
        })
        window.addEventListener('keyup', function (e) {
          myGameArea.keys[e.keyCode] = false; 
        })
        //End

    },
    stop : function() {
        clearInterval(this.interval);
    },    
    clear : function() {
        this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
    },
    dead : function() {
      myGameArea.stop();
      startGame();
    }
}

function component(width, height, color, x, y, type, isFixed) {
    this.type = type;
    if (type == "image") {
    this.image = new Image();
    this.image.src = color;
    }
    this.width = width;
    this.height = height;
    this.x = x;
    this.y = y;
    speed = 4;
    this.speedX = 0;
    this.speedY = 0;    
    this.gravity = 0.175;
    this.gravitySpeed = 0;
    this.bounce = 1;
    this.isFixed = false;
    this.update = function() {

        ctx = myGameArea.context;
        if (type == "image") {
            ctx.drawImage(this.image, 
                this.x - (this.isFixed ? 0 : offsetX), 
                this.y,
                this.width, this.height);
    } else {
        ctx.fillStyle = color;
        ctx.fillRect(
            this.x - (this.isFixed ? 0 : offsetX),
            this.y, 
          this.width, 
          this.height);
    }
}
    this.newPos = function() {
            if (!this.isFixed) {
          this.gravitySpeed += this.gravity;
          this.x += this.speedX;
          this.y += this.speedY + this.gravitySpeed;
          this.hitBottom();
          //offsetX += this.speedX;
        }
    }
    this.hitBottom = function() {
        var rockbottom = myGameArea.canvas.height - this.height;
        if (this.y > rockbottom) {
            this.y = rockbottom;
            this.gravitySpeed = -(this.gravitySpeed * this.bounce);
        }
    }
//Mobile buttons
    this.clicked = function() {
        var myleft = this.x;
        var myright = this.x + (this.width);
        var mytop = this.y;
        var mybottom = this.y + (this.height);
        var clicked = true;
        if ((mybottom < myGameArea.y) || (mytop > myGameArea.y) || (myright < myGameArea.x) || (myleft > myGameArea.x)) {
            clicked = false;
        }
        return clicked;
    }
    //End

      this.crashWith = function(otherobj) {
    var myleft = this.x;
    var myright = this.x + (this.width);
    var mytop = this.y;
    var mybottom = this.y + (this.height);
    var otherleft = otherobj.x;
    var otherright = otherobj.x + (otherobj.width);
    var othertop = otherobj.y;
    var otherbottom = otherobj.y + (otherobj.height);
    var crash = true;
    if ((mybottom < othertop) ||
    (mytop > otherbottom) ||
    (myright < otherleft) ||
    (myleft > otherright)) {
      crash = false;
    }
    return crash;
  }
}

function updateGameArea() {

    if (Player.crashWith(Obstacle)) {
    myGameArea.dead();
  } else {
    myGameArea.clear();
    Obstacle.update();
  }
    //Mobile buttons
        if (myGameArea.x && myGameArea.y) {
        /*if (myUpBtn.clicked()) {
            Player.y -= this.speed;
        }
        if (myDownBtn.clicked()) {
            Player.y += this.speed;
        }*/
        if (LeftBtn.clicked()) {
            Player.x += -this.speed;
        }
        if (RightBtn.clicked()) {
            Player.x += this.speed;
        }
    }
    UpBtn.update();        
    DownBtn.update();        
    LeftBtn.update();     
    RightBtn.update();                                
    Player.update();

    offsetX = Player.x - myGameArea.canvas.width/2;

    //End

    //Keyboard
  Player.speedX = 0;
  Player.speedY = 0; 

  if (myGameArea.keys && myGameArea.keys[37]) {Player.speedX = -this.speed; }
  if (myGameArea.keys && myGameArea.keys[39]) {Player.speedX = this.speed; }
  //if (myGameArea.keys && myGameArea.keys[38]) {Player.speedY = -this.speed; }
  //if (myGameArea.keys && myGameArea.keys[40]) {Player.speedY = this.speed; }
  //End
    Background.newPos(); 
    Background.update();
    Player.newPos();
    Player.update();

    Obstacle.update();

    //UpBtn.update();        
    //DownBtn.update();        
    LeftBtn.update();     
    RightBtn.update();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.