0
\$\begingroup\$

i'm making a snake game in javaScript from scratch. The problem is that the snake looks disjoint(see image). How can I connect the body(rectangles) of the snake?

here is the code of drawing snake:

    paintSnake(margin) {
    //draws the body of the snake
    this.snake.forEach((egg) => {
      //console.log(egg)
      const isSnakeHead = egg.cellX === this.headCellX && egg.cellY === this.headCellY
      if (!isSnakeHead) {
        this.ctx.fillStyle = "#9ef739"
        this.ctx.fillRect(egg.cellX * this.cellSize + margin,
          egg.cellY * this.cellSize + margin,
          this.cellSize - 2 * margin,
          this.cellSize - 2 * margin)
      }
    })
    //snake head
    // this.ctx.beginPath()
    // this.ctx.lineWidth = 4
    // this.ctx.strokeStyle = "red"
    // this.ctx.rect(this.headCellX * this.cellSize + margin, this.headCellY * this.cellSize + margin, this.cellSize - 2 * margin, this.cellSize - 2 * margin)
    // this.ctx.stroke()
    let head =
    {
      X: this.headCellX * this.cellSize + margin,
      Y: this.headCellY * this.cellSize + margin,
      width: this.cellSize,
      height: this.cellSize
    }

    const args = [head.X,
    head.Y,
    head.height,
    head.width]
    //draw the head of the snake
    if (this.direction === "up") {
      this.ctx.drawImage(
        snakeHeadUpImg,
        ...args)
    }
    else if (this.direction === "down") {
      this.ctx.drawImage(
        snakeHeadDownImg,
        ...args)
    }
    else if (this.direction === "right") {
      this.ctx.drawImage(
        snakeHeadRightImg,
        ...args)
    }
    else if (this.direction === "left") {
      this.ctx.drawImage(
        snakeHeadLeftImg,
        ...args)
    }
  }
}

to see the whole code go to: https://github.com/hackasaur/snake-game/blob/master/main.js

snake

i know that the rectangles(body parts) need to be extended in the direction of the next rectangle but how can i achieve this?

\$\endgroup\$
  • \$\begingroup\$ You need to draw new sprites, like the head is drawn. Then you need to include them in your game, and use them accordingly, e.g. left-right body, or up-down body. You will have to write the code to say when to use each piece. \$\endgroup\$ – Engineer May 5 at 13:53
  • \$\begingroup\$ @Engineer in the case of head I know which direction it is going by snake.direction but how to know which direction a body part is going as it may be going in a different direction than the head. \$\endgroup\$ – Manik May 5 at 16:03
  • \$\begingroup\$ It depends on how you store the snake's body data. Do you use a single 1D array, or a 2D grid to do that? \$\endgroup\$ – Engineer May 5 at 16:06
  • \$\begingroup\$ @Engineer snake's body is stored as an array of objects having cellX and cellY keys like this: [{…}, {…}, {…}] 0: {cellX: 3, cellY: 2} 1: {cellX: 2, cellY: 2} 2: {cellX: 1, cellY: 2} i think i can somehow know in which direction the next body part(rectangle) is and draw the rectangle \$\endgroup\$ – Manik May 5 at 16:16
0
\$\begingroup\$

Assuming that your snake's body is stored in ordered sequence from head to tail:

for (let p = 0; p < snake.length; p++)
{
    if (p == 0)
    {
        //use head sprite with your given direction
    }
    else // p > 0
    {
        //check last piece against next piece.
        let o = p - 1;
        let previous = snake[o];
        let current  = snake[p];

        //...these look like {cellX: 2, cellY: 5}

        if (current.cellX == previous.cellX) //they're on the same column
        {
            if (Math.abs(current.cellY - previous.cellY) == 1) //and adjacent rows
            {
                //use vertical body sprite
            }

        }
        else
        if (current.cellY == previous.cellY) //they're on the same row
        {
            if (Math.abs(current.cellX - previous.cellX) == 1) //and adjacent columns
            {
                //use horizontal body sprite
            }

        }
    }
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ i tried this, it works fine when the snake is going in a straight line but there is a problem when the snake turns, because i'm using the same vertical/horizontal body sprite so when the snake is joined at the turning point it is slightly extended. I think turning point needs separate logic for each possible turning directions. \$\endgroup\$ – Manik May 6 at 10:54
  • \$\begingroup\$ @Manik, for corners? Yes, you are correct - in that case you will need to check [p-1], [p], and [p+1] to see whether it is a straight or bent part. Can you see how that would be done? \$\endgroup\$ – Engineer May 6 at 11:00

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.