I want to create a field of cells. The field has a size of 10x10. When reaching a maximum count of cells in a row, it should start a new row.
Currently all my cell divs are placed below.
function initGame() {
var mapSize = 10; // create a field of 10x10
var cellsPerRow = 10; // 10 cells per row
for (var x = 0; x < mapSize; x++) {
for (var y = 0; y < mapSize; y++) {
createCell(x, y); // create a cell on index x (horizontal) and y (vertical)
}
}
}
function createCell(x, y) {
// store this cell position to a data class
var cellDiv = $("<div></div>"); // create the cell div
cellDiv.addClass("cell"); // add some css
$(document.body).append(cellDiv); // add the cell div to the parent
}
.cell{
height: 50px;
width: 50px;
border-style: solid;
border-width: 1px;
border-color: black;
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body onLoad="initGame()">
</body>
Create wrapper for each 10 cell.
function initGame() {
var mapSize = 10; // create a field of 10x10
var cellsPerRow = 10; // 10 cells per row
for (var x = 0; x < mapSize; x++) {
$(document.body).append("<div>");
for (var y = 0; y < mapSize; y++) {
createCell(x, y); // create a cell on index x (horizontal) and y (vertical)
}
$(document.body).append("</div>");
}
}
function createCell(x, y) {
// store this cell position to a data class
var cellDiv = $("<div></div>"); // create the cell div
cellDiv.addClass("cell"); // add some css
$(document.body).append(cellDiv); // add the cell div to the parent
}
.cell{
height: 50px;
width: 50px;
border-style: solid;
border-width: 1px;
border-color: black;
background: red;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body onLoad="initGame()">
</body>
use display:inline-block; for .cells and to stop 10 each row add a <br> tag after 10 divs in row.
function initGame() {
var mapSize = 10; // create a field of 10x10
var cellsPerRow = 10; // 10 cells per row
for (var x = 0; x < mapSize; x++) {
for (var y = 0; y < mapSize; y++) {
createCell(x, y);
}
$(document.body).append("<br>");
}
}
function createCell(x, y) {
// store this cell position to a data class
var cellDiv = $("<div></div>"); // create the cell div
cellDiv.addClass("cell"); // add some css
$(document.body).append(cellDiv); // add the cell div to the parent
}
.cell {
height: 50px;
width: 50px;
border-style: solid;
border-width: 1px;
border-color: black;
background: red;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body onLoad="initGame()">
</body>
You can use absolute positioning and set for each of them css property. Here is the fiddle
function initGame() {
var mapSize = 10; // create a field of 10x10
var cellsPerRow = 10; // 10 cells per row
for (var x = 0; x < mapSize; x++) {
for (var y = 0; y < mapSize; y++) {
createCell(x, y); // create a cell on index x (horizontal) and y (vertical)
}
}
}
function createCell(x, y) {
// store this cell position to a data class
var cellDiv = $("<div></div>"); // create the cell div
cellDiv.addClass("cell"); // add some css
cellDiv.css({
left: Math.floor(x*50),
top: Math.floor(y*50)
});
$(document.body).append(cellDiv); // add the cell div to the parent
}
initGame()
.cell{
height: 50px;
width: 50px;
border-style: solid;
border-width: 1px;
border-color: black;
background: red;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
You can create a row div that contains multiple cell div
function initGame() {
const rows = 10;
const columns = 10;
for(let r=0;r<rows;r++){
let row = createRow(r);
for(let c=0;c<columns;c++){
createCell(row, r, c);
}
}
}
function createRow(rowNumber){
let row = document.createElement('DIV');
row.className += ' row'
$(document.body).append(row);
return row;
}
function createCell(domRow, rowNumber, columnNumber){
let column = document.createElement('DIV');
column.className += ' cell';
$(domRow).append(column);
}
.cell{
height: 50px;
width: 50px;
border: 1px solid grey;
background: tomato;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body onLoad="initGame()">
</body>
Related
So I'm building this app which is an implementation of the game "Mancala". In a position of the board there can be "seeds" (game's piece) which I chose to represent as images.
In the initial setup of the game, there are N seeds in each position of the board. I represent this as N equal images ("seed.png") printed randomly in the respective position.
I want images to overlap, so even when N is a big number, they will all fit in the position ("see image nrº1"). What I accomplished so far is a random distribution with little to none overlapping and some "seeds" are getting out of the circle.
This is the code I have, built in JavaScript:
function init_board() {
const board = document.getElementById("board");
for(let i = 0; i < 2; i++) {
const tr = board.insertRow();
if(i == 0) {
tr.insertCell().setAttribute("rowSpan", "2");
}
for(let j = 0; j < 6; j++) {
var x = tr.insertCell();
for(let k = 0; k < 20; k++) {
var img = document.createElement("img");
img.src = "images/seed.png";
img.height = "10";
img.width = "10";
img.style.position = "relative";
img.style.left = Math.floor(Math.random() * 7) + "px";
img.style.top = -7 + Math.floor(Math.random() * 14) + "px";
x.appendChild(img);
}
}
if(i == 0) {
tr.insertCell().setAttribute("rowSpan", "2");
}
}
With the following formatting:
#board {
margin-left: auto;
margin-right: auto;
position: relative;
top: 30%;
}
td {
width: 75px;
height: 75px;
border: 3px solid darkred;
border-radius: 40px;
background: antiquewhite;
}
table {
border: 5px solid darkred;
border-radius: 20px;
background: burlywood;
}
Image Nrº1 N=20: https://imgur.com/a/7aNVsUb,
Image Nrº2 where N=30 and the seeds change the size of the circle: https://imgur.com/a/2iHXwyd
Thank you in advance!
To apply width and height correctly to td tag, you need to make it an inline-block element.
td:not([rowspan="2"]) {
display: inline-block;
}
Your pen updated (with seeds=30): CodePen
I'm using JavaScript to create a stack of 16 boxes. I don't think I have the makeBox() function in the right place.
let makeBox = function() {
let box = document.createElement('div');
document.body.appendChild(box);
box.style.width = '28px';
box.style.height = '28px';
box.style.border = '1px solid black';
return box;
};
let makeGrid = function(numberOfRows) {
let y = 0;
let x = 0;
while (y < numberOfRows) {
x = 0;
while (x < numberOfRows) {
x = x + 1;
}
y = y + 1;
}
makeBox();
};
makeGrid(16);
I'm just getting one box in the browser. If anyone has any experience with this, if they could please help.
If you want to make a grid of boxes CSS Grid can help. It saves effort on creating nested loops. Just loop from 0 to the number passed in as the argument multiplied that same number, and create a box on each iteration. Then add it to the element that's been set up to control the grid.
I would also use a class for the box too.
function makeBox(x) {
const box = document.createElement('div');
box.classList.add('box');
box.textContent = x;
return box;
};
// The grid will be the argument (a number)
// multiplied by that number again, so you just need
// to loop from 0 to that number
function makeGrid(n) {
const grid = document.querySelector('#grid');
for (let x = 0; x < n * n; x++) {
grid.appendChild(makeBox(x));
}
};
makeGrid(16);
#grid { display: grid; grid-template-columns: repeat(16, 1fr); gap: 2px; }
.box { width: 28px; height: 28px; border: 1px solid black; text-align: center; }
<div id="grid"></div>
my following code essentially creates a number of boxes according to the input of the user.
However i want to ensure that when they are created, they all have a random colour.
I also want to ensure that for each new box created, it sets the margin-left of the box to be double the previous box’s margin (where the first box has margin-left 5px).
I have no idea how to do this!
function getNewRandomColor()
{
var myArray = ['red', 'green', 'blue'];
var rand = myArray[Math.floor(Math.random() * myArray.length)];
document.getElementById("container").style.backgroundColor = rand;
}
var empty = true;
function setup()
{
if (!empty)
{
remove();
}
size = document.getElementById("input").value
var container = document.getElementById("container");
// create boxes
for (var i = 0; i < size; i++)
{
// Create a box
var box = document.createElement("div");
// insert number
box.innerHTML = i+1;
// Add into the document
container.appendChild(box);
empty = false;
}
}
function remove()
{
// Get all the generated boxes
var boxes = document.getElementById("container").children;
// Iterate through all boxes
for (var x = 0; x < boxes.length;)
{
var bA = boxes[x];
bA.remove();
}
}
body {
font-family:sans-serif;
font-weight:700;
font-size:15pt;
}
#container div, div.selected {
width: 2em;
height: 1.5em;
float: left;
padding: 1em;
margin: 1vw;
padding-top:1.5em;
text-align: center;
transition: background 1s;
}
div, .unselected {
background: #a0aeef;
}
<input type="number" name="input" id="input">
<button onclick="setup();">Draw</button>
<button onclick="remove();">Remove</button>
<div id="container"></div>
You could only retrieve the array key and use it as a classname, style on the fly can be applied once the element is part of the dom of the document :
ex
function getNewRandomColor(e)
{
var myArray = ['red', 'green', 'blue'];
var rand = myArray[Math.floor(Math.random() * myArray.length)];
return rand;
}
var empty = true;
function setup()
{
if (!empty)
{
remove();
}
size = document.getElementById("input").value
var container = document.getElementById("container");
// create boxes
for (var i = 0; i < size; i++)
{
// Create a box
var box = document.createElement("div");
var rdmClass= getNewRandomColor();
box.setAttribute("class",rdmClass);
marginVar = 10*i;
box.setAttribute("style","--margR:" + marginVar + ";border:solid/* here you bg with hex value to be updated " );
// insert number
box.innerHTML = i+1;
// Add into the document
container.appendChild(box);
empty = false;
}
}
function remove()
{
// Get all the generated boxes
var boxes = document.getElementById("container").children;
// Iterate through all boxes
for (var x = 0; x < boxes.length;)
{
var bA = boxes[x];
bA.remove();
}
}
body {
font-family:sans-serif;
font-weight:700;
font-size:15pt;
}
#container div, div.selected {
width: 2em;
height: 1.5em;
float: left;
padding: 1em;
margin: 1vw;
padding-top:1.5em;
text-align: center;
transition: background 1s;
}
div, .unselected {
background: #a0aeef;
}
#container div{
margin-right:calc(var(--margR)*1px); /* updated from the style attribute added from js loop */
}
.red {background:red;}
.green {background:green;}
.blue {background:blue;}
<input type="number" name="input" id="input">
<button onclick="setup();">Draw</button>
<button onclick="remove();">Remove</button>
<div id="container"></div>
I am writing an HTML5 board game and I am having issues with jQuery's offset(). The grid of DIVs that make up the game board reside within a wrapper DIV that has CSS that sets overflow:scroll/width and height:100%. The game board itself is quite larger, so the scroll can be quite a bit horizontally and vertically.
The problem is that when I click on a DIV and try to move the player to that board piece, the player shifts around and is never in a consistent place relative to the board piece clicked.
Code:
$(".boardGridPiece").click(function(){
if(!$(this).hasClass("room") && $(this).hasClass("eligibleMove")){
playerStartX = $(this).offset().left;
playerStartY = ($(this).offset().top;
player.css("left", playerStartX);
player.css("top", playerStartY);
determineEligibleMoves($(this).attr("id"));
}
});
You can see that when a board piece is clicked, the offset of the board piece is grabbed and set to the player's X and Y.
CSS:
#boardWrapper {
position:relative;
width:100%;
height:80%;
overflow: scroll;
}
#theGame {
background-color: #fff;
height: 1080px;
width: 1920px;
}
Depending on where the player is relative to the current scroll view, when I click on a board piece he shifts around in a very inconsistent manner. Sometimes he's far left of where I click, or far up, etc.
What am I doing wrong? How do I take into account relative scroll position to get consistent positioning?
Here's a board for you to play with as an example. Also, my stab at the jquery is included as well. Basically, it finds where you clicked, calculated the px distance in float form, and animates the soldier to slide to his new position:
var black = '<td style="background-color:black"><div class="boardGridPiece"></div></td>';
var white = '<td style="background-color:white"><div class="boardGridPiece"></div></td>';
var squares = [black, white];
var grid = "";
for (var i = 0; i < 9; i++) {
grid += "<tr>";
for (var j = 0; j < 16; j++) {
grid += squares[(i + j) % 2];
}
grid += "<\tr>";
}
$('#gameboard').append(grid);
var gridSelected = $('#gameboard').find('tr:nth-child(2)').find('td:first').find('div');
gridSelected.toggleClass('position');
$('.boardGridPiece').click(function () {
$('.position').removeClass('position');
var gridSelected = $(this);
gridSelected.toggleClass('position');
var thisBox = $('.position');
var finalX = 0;
var finalY = 0;
for (var i = 0; i < 9.00; i++) {
for (var j = 0; j < 16.00; j++) {
var aBox = $('#gameboard').find('tr:nth-child(' + (i + 1) + ')').find('td:nth-child(' + (j + 1) + ')').find('div');
if (thisBox.get(0) == aBox.get(0)) {
finalX = j + 1;
finalY = i;
i = j = 16; // soft break
}
}
}
var overX = (finalX * parseFloat(1920))/16.00;
var downY = (finalY * parseFloat(1080))/9.00;
$('#player').animate({ left: overX, top: downY });});
html {
background-color:gray;
}
#gameboard {
margin: 100px;
height:1080px;
width:1920px;
border:1px solid black;
}
.boardGridPiece {
height: 110px;
width: 110px;
}
.position {
box-sizing:border-box;
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
border: 1px solid red;
}
#player {
position: absolute;
top: 120px;
left: 125px;
height: 200px;
width: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="gameboard" style=""></table>
<img id="player" src="http://img2.wikia.nocookie.net/__cb20110819034426/halo/images/7/74/ODST_Helljumper.png" />
I have a table created with javascript. I would like to change color of a cell to red, when you click on it. I know i should propably use onClick event. But I am not sure how to use it in this specific task.
var width = parseInt(prompt("Put width", "here"));
var height = parseInt(prompt("Put height", "here"));
function myFunction() {
var table = document.getElementById("chessboard");
for (var i = 0; i < height; i++) {
var row = table.insertRow(i);
for (var j = 0; j < width; j++) {
row.insertCell(j);
}
};
}
#chessboard {
border: 1px solid black;
border-collapse: collapse
}
td {
width: 40px;
height: 40px
}
tr:nth-child(odd) td:nth-child(even) {
background: black
}
tr:nth-child(even) td:nth-child(odd) {
background: black
}
<body onload="myFunction()">
<div>
<table id="chessboard"></table>
</div>
</body>
You can add an onclick listener to each cell which add a selected class to it. You also just need to track what was selected previously so you can remove the selected class from it:
var width = parseInt(prompt("Put width", "here"));
var height = parseInt(prompt("Put height", "here"));
// tracks the selected cell
var selectedCell = null;
// handles the clicks
function selectCell() {
// remove from previous if there is one
if (selectedCell != null) {
selectedCell.classList.remove('selected');
}
// mark cell as selected
selectedCell = this;
this.classList.add('selected');
}
function myFunction() {
var table = document.getElementById("chessboard");
for (var i = 0; i < height; i++) {
var row = table.insertRow(i);
for (var j = 0; j < width; j++) {
var cell = row.insertCell(j);
// bind the selectCell function to this cell
cell.onclick = selectCell.bind(cell);
}
};
}
#chessboard {
border: 1px solid black;
border-collapse: collapse
}
td {
width: 40px;
height: 40px
}
tr:nth-child(odd) td:nth-child(even) {
background: black;
}
tr:nth-child(even) td:nth-child(odd) {
background: black;
}
td.selected {
background: red !important;
}
<body onload="myFunction()">
<div>
<table id="chessboard"></table>
</div>
</body>
Add a click event to all cells.
First, you'll need to store the original color somewhere so that you can change it back to normal when clicked again.
To do that, you could make use of data-* attribute. Now, to assign the correct white and black colors to corresponding cells' data-color attributes, you could use this JavaScript equivalent,
row.children[j].setAttribute('data-color', ((i % 2 != 0 && j % 2 == 0) || (i % 2 == 0 && j % 2 != 0)) ? 'black' : 'white')
for this part of CSS,
tr:nth-child(odd) td:nth-child(even) {
background: black
}
tr:nth-child(even) td:nth-child(odd) {
background: black
}
Now, since the original colors are stored, you could simply extract the corresponding colors stored in the data-color attribute and change it back to normal if its backgroundColor is red.
var width = parseInt(prompt("Put width", "here"));
var height = parseInt(prompt("Put height", "here"));
function myFunction() {
var table = document.getElementById("chessboard");
for (var i = 0; i < height; i++) {
var row = table.insertRow(i);
for (var j = 0; j < width; j++) {
row.insertCell(j);
row.children[j].setAttribute('data-color', ((i % 2 != 0 && j % 2 == 0) || (i % 2 == 0 && j % 2 != 0)) ? 'black' : 'white')
row.children[j].addEventListener('click', function() {
this.style.backgroundColor = (this.style.backgroundColor == 'red') ? this.getAttribute('data-color') : this.style.backgroundColor = 'red';
});
}
};
}
#chessboard {
border: 1px solid black;
border-collapse: collapse
}
td {
width: 40px;
height: 40px
}
tr:nth-child(odd) td:nth-child(even) {
background: black
}
tr:nth-child(even) td:nth-child(odd) {
background: black
}
<body onload="myFunction()">
<div>
<table id="chessboard"></table>
</div>
</body>