Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

for loop - Beyond JavaScript Snake Game - help needed with different berry codes for game

Help needed. I have programmed almost a year and more then half of the time i have done in C# (programs), for school project i am doing HTML, CSS & JavaScript (mainly) Snake game. Where i need to add different objects to eat to get different values. I have transparent pictures for these berries (raspberry, blackberry, gooseberry that i need to add in game instead of colored tiles (is it possible?). Main game itself is fully ready and working when eating Food i get +1 for snake (that value i can change how i wish). Now i need to add new berries (raspberry, blackberry, gooseberry). When eating RASPBERRY it should make my snake smaller by 5 units or up to the head (ex: if snake is only 3 grids long and i eat raspberry then i cannot go to -2 but instead going to 1 aka the head of snake. But when snake is 20 grids long and You eat raspberry you lose 5 grids and then your snake will be 15 grids long. With berry random re-spawn delay 20 seconds after eating). Blackberry and gooseberry both of them are for speed. Normal snake speed is 2 moves per second. Eating blackberry will increase speed to 5 moves per second that last for 30 second and re-spawn of blackberry is 1 minute. Eating gooseberry will decrease speed 4x (snake speed should be 0,5 moves per second) and last 1,5 minute, re-spawn of gooseberry 3 minutes. Also for the code there must be spawn location so that it won't spawn on snake or any of the food/berries (in below code there is function so that food won't spawn on top of snake).

As i have already learned programming almost a year, i know that there is for/while loop needed for berry actions, but i am not so good programmer (jet) to write it my own. I have looked for that info whole day but cannot find solution for the for loop.

Is there any nice person who could help me with this for loop request? I am using type=modul for JavaScript. Also every element have it's own JS file (game.js, input.js (arrowkeys), grid.js, snake.js, food.js as well as future codes raspberry.js, blackberry.js, gooseberry.js). Also each berry would need it's own JS file. My food.js code for the game.

food.js

import { onSnake, expandSnake } from './snake.js'
import { randomGridPosition } from './grid.js'

let food = getRandomFoodPosition() //food location, must be grid numbers, and in CSS always starts from 1, not 0! Use { x: umber, y: number } if you want specific location food to come
const EXPANSION_RATE = 1 //how much snake grows after eating food

export function update() 
{  //checking if snake is over the food
  if (onSnake(food)) 
  {
    expandSnake(EXPANSION_RATE)
    food = getRandomFoodPosition() //this is new food spawn with random location, but not on top of snake
  }
}

export function draw(gameBoard) 
{ //draw(gameBoard) means it will draw food on gameboard
  const foodElement = document.createElement('div')
  foodElement.style.gridRowStart = food.y //vertical location
  foodElement.style.gridColumnStart = food.x //horizontal location
  foodElement.classList.add('food')
  gameBoard.appendChild(foodElement)
}

//randomizing food location and not on top of snake
function getRandomFoodPosition()
{
  let newFoodPosition
  while (newFoodPosition == null || onSnake(newFoodPosition)) 
  {
    newFoodPosition = randomGridPosition()
  }
  return newFoodPosition
}

EDIT: i added raspberry.js and also snake.js below

raspberry.js

import { onSnake, decreaseSnake } from './snake.js'
import { randomGridPosition } from './grid.js'

let raspberry = getRandomRaspberryPosition() //food location, must be grid numbers, and in CSS always starts from 1, not 0! Use { x: umber, y: number } if you want specific location food to come
const DECREASING_RATE = 1 //how much snake decreases after eating food

export function update() 
{  //checking if snake is over the food
  if (onSnake(raspberry)) 
  {
    decreaseSnake(DECREASING_RATE)
    raspberry = getRandomRaspberryPosition() //this is new food spawn with random location, but not on top of snake
  }
}

export function draw(gameBoard) 
{ //draw(gameBoard) means it will draw food on gameboard
  const raspberryElement = document.createElement('div')
  raspberryElement.style.gridRowStart = raspberry.y //vertical location
  raspberryElement.style.gridColumnStart = raspberry.x //horizontal location
  raspberryElement.classList.add('raspberry')
  gameBoard.appendChild(raspberryElement)
}

//randomizing food location and not on top of snake
function getRandomRaspberryPosition()
{
  let newRaspberryPosition
  while (newRaspberryPosition == null || onSnake(newRaspberryPosition)) 
  {
    newRaspberryPosition = randomGridPosition()
  }
  return newRaspberryPosition
}

snake.js

// all the codes for snake goes in this JS file

import { getInputDirection } from "./input.js"

export const SNAKE_SPEED = 5 //snake speed. Moves per second
const snakeBody = [{ x: 13, y: 13 }] //snake location when starting game on grid (current grid size is 25 x 25)
let newSegments = 0
let negSegments = 0

export function update() 
{
  addSegments(), removeSegments()

  const inputDirection = getInputDirection()
  for (let i = snakeBody.length - 2; i >= 0; i--) 
  {
    snakeBody[i + 1] = { ...snakeBody[i] }
  }

  snakeBody[0].x += inputDirection.x
  snakeBody[0].y += inputDirection.y
}

export function draw(gameBoard) 
{ //gameboard for draw means it will draw snake on gameboard
  snakeBody.forEach(segment => 
    { //drawing snake inside gameboard 
      const snakeElement = document.createElement('div')
      snakeElement.style.gridRowStart = segment.y
      snakeElement.style.gridColumnStart = segment.x
      snakeElement.classList.add('snake')
      gameBoard.appendChild(snakeElement)
    })
}



export function expandSnake(amount) 
{
  newSegments += amount
}

export function decreaseSnake(amount)
{
  negSegments -= amount
}



export function onSnake(position, { ignoreHead = false } = {}) 
{
  return snakeBody.some((segment, index) => 
  {
    if (ignoreHead && index === 0) return false
    return equalPositions(segment, position)
  })
}

export function getSnakeHead() 
{
  return snakeBody[0]
}

export function snakeIntersection() 
{
  return onSnake(snakeBody[0], { ignoreHead: true })
}

function equalPositions(pos1, pos2) 
{
  return pos1.x === pos2.x && pos1.y === pos2.y
}

function addSegments() 
{
  for (let i = 0; i < newSegments; i++) {
    snakeBody.push({ ...snakeBody[snakeBody.length - 1] })
  }

  newSegments = 0  //stops adding new elements on snake otherwise it will grow nonstop from the first eaten food
}

function removeSegments()
{
  for (let i = 0; i < negSegments; i++) { //reversed < and ++
    snakeBody.pop({ ...snakeBody[snakeBody.length - 1] }) //reversed push to pop in this line atm
  }

  negSegments = 0
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...