Skip to content

Commit

Permalink
Merge pull request #12 from Yareaj/dev
Browse files Browse the repository at this point in the history
Support for custom maps
  • Loading branch information
Yareaj authored May 29, 2023
2 parents e8735bb + edbe96f commit c0c24fe
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 117 deletions.
25 changes: 25 additions & 0 deletions custom.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Sokoban Worlds</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/x-icon" href="assets/player/head.png">

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/addons/p5.sound.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/objetos/p5.quadrille.js/p5.quadrille.min.js"></script>

<!-- Retrieve the variables used across the whole project -->
<script src="globalVariables.js"></script>

<!-- Import the distribution of functions -->
<script src="functions/objects.js"></script>
<script src="functions/functions.js"></script>
<script src="functions/mapRenders.js"></script>

<!-- Retrieve the level processor -->
<script src="custom.js"></script>
</head>
</html>
34 changes: 34 additions & 0 deletions custom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
let submitButton, textArea;

function preload() {
// Load assets for render
backgroundImage = loadImage('./assets/images/menuBg.png');
levelButtonStyles = loadJSON('./assets/json/levelButtonStyles.json');
// Load buttons' fonts
loadFont('./assets/fonts/Fredoka-Medium.ttf');
}

function setup() {
createCanvas(500, 500);
submitButton = createButton('Submit');
textArea = createElement('textarea');

// Apply styles to the menu buttons
applyStyles(submitButton, levelButtonStyles);

// Apply styles to the text area
textArea.style('width', `${width-50}px`);
textArea.style('height', `${height/3}px`);
textArea.style('resize', 'none');
textArea.attribute('placeholder', 'Insert the custom level data');
textArea.attribute('required', true);
textArea.position(30, height/1.97);

// Position the submit button on the screen
submitButton.position(width/2.4, (height/1.95)+(height/3)+20);
submitButton.mousePressed(obtainLevelData);
}

function draw() {
image(backgroundImage, 0, 0);
}
89 changes: 12 additions & 77 deletions functions/functions.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,3 @@
// Actions based upon the key pressed
function keyPressed() {
// Prevent keys to take effects upon level pass
if (levelPass) {
return;
}

if (keyCode === UP_ARROW || key === 'w') {
playerMove('up');
} else if (keyCode === DOWN_ARROW || key === 's') {
playerMove('down');
} else if (keyCode === LEFT_ARROW || key === 'a') {
playerMove('left');
} else if (keyCode === RIGHT_ARROW || key === 'd') {
playerMove('right');
} else if (key === 'm') {
toMenu();
} else if (key === 'r') {
loadLevelString();
}
}

// Function to process a string into a map
function processMap(mapString) {
let processedMap = [];

mapString.forEach(row => {
processedMap.push(row.split(''));
});

// Loop to replace the map outline into something we can use!
for (let rowExpl=0; rowExpl<processedMap.length; rowExpl++) {
// Go through each cell and replace it with the needed properties for the builder
for (let cellExpl=0; cellExpl<processedMap[rowExpl].length; cellExpl++) {
processedMap[rowExpl][cellExpl] = processedMap[rowExpl][cellExpl].replace(/./, `${processedMap[rowExpl][cellExpl]}|${rowExpl}|${cellExpl}`);
}
};

// Loop to replace the array data into a quadrille builder!
for (let rowExpl=0; rowExpl<processedMap.length; rowExpl++) {
// Go through each cell and replace it with the block!
for (let cellExpl=0; cellExpl<processedMap[rowExpl].length; cellExpl++) {
const cellData = processedMap[rowExpl][cellExpl].split('|');
processedMap[rowExpl][cellExpl] = [ cellData[0], [ parseInt(cellData[1]), parseInt(cellData[2]) ] ];
}
};

return processedMap;
}

// Change the level ID
function increaseId() {
levelId = levelId + 1;
Expand All @@ -67,31 +17,6 @@ function nextLevel() {
loadLevelString();
}

function mapReload() {
// Reset the level's mechanics
levelMap = null;
playerQuad = null;
mapData2dArray = null;

// Reset control variables
placedTargets = 0;
stepsTaken = 0;
levelPass = false;
successAudio = true;

// Reset object's variebles
boxesQuadrilles = [];
targetQuadrilles = [];
renderBlocks = [ targetQuadrilles, boxesQuadrilles ];

// Hide the buttons
menuButton.hide()
nextButton.hide()

// Reload the level
setup();
}

// Go to the menu
function toMenu() {
window.location.href = "./index.html";
Expand All @@ -103,6 +28,16 @@ function initiateLevelPlay() {
}

// Go to the custom landing page!
function customLevelLoad() {
console.log('Here relies the custom level loader!');
function toCustom() {
window.location.href = "./custom.html";
}

function obtainLevelData() {
customLevelString = textArea.value();

if (!customLevelString) {
return alert('Please insert level data');
}
localStorage.setItem("mapId", customLevelString);
initiateLevelPlay();
}
45 changes: 11 additions & 34 deletions functions/levelHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,16 @@ function preload() {
loadFont('./assets/fonts/Fredoka-Medium.ttf');
loadFont('./assets/fonts/Fredoka-Regular.ttf');

// Import the map string into the global variable
mapOutline = loadStrings(`./assets/levels/level${levelId}.txt`);
const referrer = document.referrer.split('/')
const lastReference = referrer[referrer.length-1];

// Import the map string into the global variable
if (lastReference == 'custom.html') {
mapOutline = localStorage.getItem("mapId").split('\n');
} else {
mapOutline = loadStrings(`./assets/levels/level${levelId}.txt`);
}

// Load the buttonStyles JSON file
buttonStyles = loadJSON('./assets/json/levelButtonStyles.json');
}
Expand All @@ -54,37 +61,7 @@ function setup() {
mapData2dArray = processMap(mapOutline);

// Set the map's standard
for (let rowIt=0; rowIt<mapData2dArray.length; rowIt++) {
for (let cellIt=0; cellIt<mapData2dArray[rowIt].length; cellIt++) {
const cellData = mapData2dArray[rowIt][cellIt];

// Set the player starting coordinates into the map
if (cellData[0] == '@') {
playerPos.row = cellData[1][0];
playerPos.col = cellData[1][1];
} else if (cellData[0] == '+') {
// Player position definiton
playerPos.row = cellData[1][0];
playerPos.col = cellData[1][1];
// Create the target
targetQuadrilles.push( [ createQuadrille([ images.blocks.boxTarget ]), cellData[1].toReversed() ] );
} else if (cellData[0] == '$') {
boxesQuadrilles.push( [ createQuadrille([ images.blocks.box ]), cellData[1].toReversed() ] );
} else if (cellData[0] == '*') {
boxesQuadrilles.push( [ createQuadrille([ images.blocks.boxSecured ]), cellData[1].toReversed() ] );
targetQuadrilles.push( [ createQuadrille([ images.blocks.boxTarget ]), cellData[1].toReversed() ] );
} else if (cellData[0] == '.') {
targetQuadrilles.push( [ createQuadrille([ images.blocks.boxTarget ]), cellData[1].toReversed() ] );
}

// Set all cells but walls to be the background color
if (cellData[0] == '#') {
levelMap._memory2D[rowIt][cellIt] = images.blocks.wall;
} else {
levelMap._memory2D[rowIt][cellIt] = color('#2f4f4f');
}
}
}
renderFullMapQuadrilles();

nextButton = createButton('Next');
nextButton.position((width/2)+textWidth('Menu')-textWidth('Next'), (height/2));
Expand All @@ -109,7 +86,7 @@ function draw() {
for (let singleIt=0; singleIt<renderBlocks[arrayBlockIt].length; singleIt++) {
drawQuadrille(renderBlocks[arrayBlockIt][singleIt][0], {
x: renderBlocks[arrayBlockIt][singleIt][1][0] * Quadrille.CELL_LENGTH,
y: renderBlocks[arrayBlockIt][singleIt][1][1] * Quadrille.CELL_LENGTH,
y: renderBlocks[arrayBlockIt][singleIt][1][1] * Quadrille.CELL_LENGTH
});
}
}
Expand Down
88 changes: 88 additions & 0 deletions functions/mapRenders.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Reset a level's canvas
function mapReload() {
// Reset the level's mechanics
levelMap = null;
playerQuad = null;
mapData2dArray = null;

// Reset control variables
placedTargets = 0;
stepsTaken = 0;
levelPass = false;
successAudio = true;

// Reset object's variebles
boxesQuadrilles = [];
targetQuadrilles = [];
renderBlocks = [ targetQuadrilles, boxesQuadrilles ];

// Hide the buttons
menuButton.hide()
nextButton.hide()

// Reload the level
setup();
}

// Function to process a string into a map
function processMap(mapString) {
let processedMap = [];

mapString.forEach(row => {
processedMap.push(row.split(''));
});

// Loop to replace the map outline into something we can use!
for (let rowExpl=0; rowExpl<processedMap.length; rowExpl++) {
// Go through each cell and replace it with the needed properties for the builder
for (let cellExpl=0; cellExpl<processedMap[rowExpl].length; cellExpl++) {
processedMap[rowExpl][cellExpl] = processedMap[rowExpl][cellExpl].replace(/./, `${processedMap[rowExpl][cellExpl]}|${rowExpl}|${cellExpl}`);
}
};

// Loop to replace the array data into a quadrille builder!
for (let rowExpl=0; rowExpl<processedMap.length; rowExpl++) {
// Go through each cell and replace it with the block!
for (let cellExpl=0; cellExpl<processedMap[rowExpl].length; cellExpl++) {
const cellData = processedMap[rowExpl][cellExpl].split('|');
processedMap[rowExpl][cellExpl] = [ cellData[0], [ parseInt(cellData[1]), parseInt(cellData[2]) ] ];
}
};

return processedMap;
}

// Render all of the quadrilles into the canvas
function renderFullMapQuadrilles() {
for (let rowIt=0; rowIt<mapData2dArray.length; rowIt++) {
for (let cellIt=0; cellIt<mapData2dArray[rowIt].length; cellIt++) {
const cellData = mapData2dArray[rowIt][cellIt];

// Set the player starting coordinates into the map
if (cellData[0] == '@') {
playerPos.row = cellData[1][0];
playerPos.col = cellData[1][1];
} else if (cellData[0] == '+') {
// Player position definiton
playerPos.row = cellData[1][0];
playerPos.col = cellData[1][1];
// Create the target
targetQuadrilles.push( [ createQuadrille([ images.blocks.boxTarget ]), cellData[1].toReversed() ] );
} else if (cellData[0] == '$') {
boxesQuadrilles.push( [ createQuadrille([ images.blocks.box ]), cellData[1].toReversed() ] );
} else if (cellData[0] == '*') {
boxesQuadrilles.push( [ createQuadrille([ images.blocks.boxSecured ]), cellData[1].toReversed() ] );
targetQuadrilles.push( [ createQuadrille([ images.blocks.boxTarget ]), cellData[1].toReversed() ] );
} else if (cellData[0] == '.') {
targetQuadrilles.push( [ createQuadrille([ images.blocks.boxTarget ]), cellData[1].toReversed() ] );
}

// Set all cells but walls to be the background color
if (cellData[0] == '#') {
levelMap._memory2D[rowIt][cellIt] = images.blocks.wall;
} else {
levelMap._memory2D[rowIt][cellIt] = color('#2f4f4f');
}
}
}
}
22 changes: 22 additions & 0 deletions functions/movement.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,26 @@ function playerMove(direction) {

stepsTaken += 1;
sounds.step.play();
}

// Actions based upon the key pressed
function keyPressed() {
// Prevent keys to take effects upon level pass
if (levelPass) {
return;
}

if (keyCode === UP_ARROW || key === 'w') {
playerMove('up');
} else if (keyCode === DOWN_ARROW || key === 's') {
playerMove('down');
} else if (keyCode === LEFT_ARROW || key === 'a') {
playerMove('left');
} else if (keyCode === RIGHT_ARROW || key === 'd') {
playerMove('right');
} else if (key === 'm') {
toMenu();
} else if (key === 'r') {
loadLevelString();
}
}
12 changes: 6 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,7 @@ function setup() {
createCanvas(500, 500);
customLevelButton = createButton('Custom Level');
levelListButton = createButton('Play');
}

function draw() {
image(backgroundImage, 0, 0);


// Apply styles to the menu buttons
applyStyles(levelListButton, menuButtonStyles);
applyStyles(customLevelButton, menuButtonStyles);
Expand All @@ -27,5 +23,9 @@ function draw() {

// Add listeners for button actions
levelListButton.mousePressed(initiateLevelPlay);
customLevelButton.mousePressed(customLevelLoad);
customLevelButton.mousePressed(toCustom);
}

function draw() {
image(backgroundImage, 0, 0);
}
1 change: 1 addition & 0 deletions play.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<script src="functions/objects.js"></script>
<script src="functions/movement.js"></script>
<script src="functions/functions.js"></script>
<script src="functions/mapRenders.js"></script>

<!-- Retrieve the level processor -->
<script src="functions/levelHandler.js"></script>
Expand Down

0 comments on commit c0c24fe

Please sign in to comment.