2

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
}
3
  • To get a good answer here it would help if you paste the exact code here that is giving you problems, instead of a link to the whole project. One of the problems in your code seems to be a complicated list of nested if statements in the movement controller. This becomes a bit spaghetti code and is often the cause of unexpected results. Once you find out where exactly your bug is you can focus your question a bit better. Commented Nov 17, 2023 at 12:09
  • @Kokodoko OK I added some code I think may be the culprit(s). Commented Nov 17, 2023 at 16:01
  • 1
    I sent you a PR on github: github.com/LateSupper/CreatureCollectorBug/pull/1/files Commented Nov 17, 2023 at 17:27

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

7 Comments

I appreciate the help and the PR! Do you have any advice as to how I could refactor the code and make it less of a mess?
@Undwell recommendation for future questions... you need to reduce the code in your sample code, on this problem for example the sprites was not an issue just a distraction from what really is the problem, read this: stackoverflow.com/help/minimal-reproducible-example even in the process of reducing the code we often find the problem
Great advice. I'll take that into consideration for future questions.
@Undwell for making it less of a mess ?!? maybe adopt a true game engine: github.com/collections/javascript-game-engines
there are advantages and disadvantages, it is 100% up to you... look at what games are built with each and see if you find something like yours
|

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.