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\$
4
  • \$\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, 2020 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, 2020 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, 2020 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, 2020 at 16:16

1 Answer 1

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
            }

        }
    }
}
\$\endgroup\$
2
  • \$\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, 2020 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, 2020 at 11:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .