Search code examples
javascripthtml5-canvasgame-development

2D HTML5 Canvas Game: Specific width/height restricts player movement (No collision implemented)


Q: Why is movement restricted in these directions depending on the canvas' width/height + player position, and how do I fix this?

As mentioned in the title I have been building a 2D canvas game (a top-down creature collector like Pokémon), and without implementing any collision there is a mysterious bug.

The bug is stopping my character from moving in two directions depending on character starting position and the canvas' width/height even though I am able to move to some tiles in these directions before being stopped:

  • Up / Right

or

  • Left / Down

This only happens when the canvas' width/height are set to specific values, and I'm able to still move as far as I want in the two directions not affected.

My desired width & height are 360x240 to display the map's 24x24 pixel tiles 15 across the width, and 10 across the height. When attempting to use 720x480 (2x the desired dimensions), and 300x200 the movement was not restricted.

Here is a link to the repo for the bug if you would like to test it out: https://github.com/LateSupper/CreatureCollectorBug

I've included two maps of varied sizes to test this issue with inside of the "engine.js" file. Just have to switch which one you'd like to test.

And here is an image of where the invisible diagonal barrier seems to be in the example I have in the repo: Invisible Barrier Visual (Player starts on the yellow square

Things I've tried include:

  • Console logging movement logic to see if it still fires (it does, but no movement)
  • Setting the canvas' width/height to various dimensions with differing results and mostly having 3:2 aspect ratio dimensions failing to allow movements in those directions
  • Created different maps which by my code's logic changes the starting position of the player, and changes which two directions are blocked
  • Googling. Of course I Googled the heck out of this today because why would this even happen? Oddest bug I've ever encountered with an HTML Canvas game.

edit: Per recommendation of adding code I think may be causing my troubles:

// "main.js" -> line 1
const game = new GameEngine(
  { width: 24 * 16, height: 24 * 10 }, // Dimensions
  24, // Tile Size
  18 // Camera Offset
)

In the above code when the width and/or height is multiplied by an odd number movement is restricted, but if both numbers are 24 * an even number it works perfectly fine.

Would this potentially be an issue of how I am drawing the background/player sprites onto the canvas?:

// "engine.js" -> GameEngine.determineSpriteProperties()
determineSpriteProperties = (image) => {
  const properties = {
    type: 0,
    position: { x: 0, y: 0 },
    image: image
  }
  if (image.currentSrc.indexOf("map_") > -1) {
    properties.position.x = ((this.canvas.width / 2) - (image.width / 2)) + (this.tileSize / 2),
    properties.position.y = ((this.canvas.height / 2) - (image.height / 2))
  } else {
    properties.type = 1
    properties.position.x = (this.canvas.width / 2 - (image.width / 3)) + ((image.width / 3) / 2)
    properties.position.y = this.canvas.height / 2 - (image.height / 4) + this.cameraOffset
  }
  return properties
}

Solution

  • The problem was in the condition to stop the movement...
    You had an if statement:

    this.mapSprite.position.x !== this.targetPosition.position && 
    this.mapSprite.position.y !== this.targetPosition.position
    

    ... but the targetPosition also has an axis property that you did not include in the that condition

    (targetPosition.axis == "x" && mapSprite.position.x !== targetPosition.position) ||
    (targetPosition.axis == "y" && mapSprite.position.y !== targetPosition.position)
    

    ( I removed some code to make this sample small )


    See my PR for details:
    https://github.com/LateSupper/CreatureCollectorBug/pull/1