Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 59 additions & 8 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,26 @@
z-index: 10000;
padding: 5px;
}
.speed-btn {
display: inline-block;
padding: 5px 10px;
margin: 0 2px;
cursor: pointer;
border: 1px solid #ccc;
background-color: #f0f0f0;
border-radius: 3px;
}
.speed-btn.active {
background-color: #4CAF50;
color: white;
border-color: #4CAF50;
}
.speed-btn:hover {
background-color: #e0e0e0;
}
.speed-btn.active:hover {
background-color: #45a049;
}
</style>
<script>
function getTheme() {
Expand Down Expand Up @@ -106,14 +126,11 @@
</select>
</div>
<div style="display: inline-block; margin-right: 10px">
<span>Mode:</span>
<select id="selectMode">
<option value="100">Easy</option>
<option value="75" selected>Medium</option>
<option value="50">Hard</option>
<option value="25">Impossible</option>
<option value="110">Rush</option>
</select>
<span>Speed:</span>
<button class="speed-btn" data-speed="1">1x</button>
<button class="speed-btn" data-speed="2">2x</button>
<button class="speed-btn" data-speed="3">3x</button>
<button class="speed-btn" data-speed="5">5x</button>
</div>
<button id="go_full_screen">Full Screen</button>
<br />
Expand Down Expand Up @@ -146,6 +163,40 @@
}

document.getElementById('go_full_screen').addEventListener('click', go_full_screen);

// Speed button handling
const speedButtons = document.querySelectorAll('.speed-btn');
const BASE_SPEED = 300; // 1x speed in ms

function setActiveSpeedButton(speed) {
speedButtons.forEach(btn => {
btn.classList.remove('active');
if (parseInt(btn.dataset.speed) === speed) {
btn.classList.add('active');
}
});
}

function getSpeedValue(multiplier) {
return Math.round(BASE_SPEED / multiplier);
}

speedButtons.forEach(btn => {
btn.addEventListener('click', function() {
const speedMultiplier = parseInt(this.dataset.speed);
setActiveSpeedButton(speedMultiplier);
// Update snake speed if game is running
if (window.mySnakeBoard && window.mySnakeBoard.setSpeed) {
window.mySnakeBoard.setSpeed(getSpeedValue(speedMultiplier));
}
setTimeout(function() {
document.getElementById("game-area").focus();
}, 10);
});
});

// Set default speed (1x)
setActiveSpeedButton(1);
</script>
</body>
</html>
2 changes: 1 addition & 1 deletion src/js/init.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const mySnakeBoard = new SNAKE.Board({
window.mySnakeBoard = new SNAKE.Board({
boardContainer: "game-area",
fullScreen: true,
premoveOnPause: false,
Expand Down
82 changes: 33 additions & 49 deletions src/js/snake.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const MOVE_RIGHT = 1;
const MIN_SNAKE_SPEED = 25;
const RUSH_INCR = 5;

const DEFAULT_SNAKE_SPEED = 80;
const DEFAULT_SNAKE_SPEED = 300; // 1x speed: 300ms

const BOARD_NOT_READY = 0;
const BOARD_READY = 1;
Expand Down Expand Up @@ -146,7 +146,7 @@ SNAKE.Snake =

const me = this;
const playingBoard = config.playingBoard;
const growthIncr = 5;
const growthIncr = 1;
const columnShift = [0, 1, 0, -1];
const rowShift = [-1, 0, 1, 0];
let prevNode;
Expand All @@ -159,27 +159,7 @@ SNAKE.Snake =
isDead = false,
isPaused = false;

const modeDropdown = document.getElementById("selectMode");
if (modeDropdown) {
modeDropdown.addEventListener("change", function (evt) {
evt = evt || {};
let val = evt.target
? parseInt(evt.target.value)
: DEFAULT_SNAKE_SPEED;

if (isNaN(val)) {
val = DEFAULT_SNAKE_SPEED;
} else if (val < MIN_SNAKE_SPEED) {
val = DEFAULT_SNAKE_SPEED;
}

snakeSpeed = val;

setTimeout(function () {
document.getElementById("game-area").focus();
}, 10);
});
}

// ----- public variables -----
me.snakeBody = {};
Expand Down Expand Up @@ -381,6 +361,27 @@ SNAKE.Snake =
newHead.col = oldHead.col + columnShift[lastMove];
newHead.row = oldHead.row + rowShift[lastMove];

// Wall wrapping logic - teleport snake to opposite side within playable area
// Playable area is 1 to numRows-2 and 1 to numCols-2 (excluding outer border)
const numRows = grid.length;
const numCols = grid[0].length;
const minRow = 1;
const maxRow = numRows - 2;
const minCol = 1;
const maxCol = numCols - 2;

if (newHead.row < minRow) {
newHead.row = maxRow; // From top to bottom
} else if (newHead.row > maxRow) {
newHead.row = minRow; // From bottom to top
}

if (newHead.col < minCol) {
newHead.col = maxCol; // From left to right
} else if (newHead.col > maxCol) {
newHead.col = minCol; // From right to left
}

if (!newHead.elmStyle) {
newHead.elmStyle = newHead.elm.style;
}
Expand Down Expand Up @@ -448,18 +449,6 @@ SNAKE.Snake =
return false;
}

//Checks if the current selected option is that of "Rush"
//If so, "increase" the snake speed
const selectDropDown = document.getElementById("selectMode");
const selectedOption =
selectDropDown.options[selectDropDown.selectedIndex];

if (selectedOption.text.localeCompare("Rush") == 0) {
if (snakeSpeed > MIN_SNAKE_SPEED + RUSH_INCR) {
snakeSpeed -= RUSH_INCR;
}
}

return true;
};

Expand All @@ -468,9 +457,8 @@ SNAKE.Snake =
* @method handleDeath
*/
me.handleDeath = function () {
//Reset speed
const selectedSpeed = document.getElementById("selectMode").value;
snakeSpeed = parseInt(selectedSpeed);
//Reset speed to default (1x = 300ms)
snakeSpeed = DEFAULT_SNAKE_SPEED;

handleEndCondition(playingBoard.handleDeath);
};
Expand Down Expand Up @@ -633,8 +621,12 @@ SNAKE.Food =
col = 0,
numTries = 0;

const maxRows = playingBoard.grid.length - 1;
const maxCols = playingBoard.grid[0].length - 1;
// Playable area is 1 to maxRows-1 and 1 to maxCols-1 (excluding outer border)
const maxRows = playingBoard.grid.length - 2;
const maxCols = playingBoard.grid[0].length - 2;

row = getRandomPosition(1, maxRows);
col = getRandomPosition(1, maxCols);

while (playingBoard.grid[row][col] !== 0) {
row = getRandomPosition(1, maxRows);
Expand Down Expand Up @@ -1191,16 +1183,8 @@ SNAKE.Board =
for (let row = 0; row < numBoardRows; row++) {
me.grid[row] = [];
for (let col = 0; col < numBoardCols; col++) {
if (
col === 0 ||
row === 0 ||
col === numBoardCols - 1 ||
row === numBoardRows - 1
) {
me.grid[row][col] = 1; // an edge
} else {
me.grid[row][col] = 0; // empty space
}
// All cells are empty space (0) - walls are now passable
me.grid[row][col] = 0;
}
}

Expand Down