Simple Grid Based Movement
Published: 2022-03-18 16:48:38

### 1.) Set up initial files
- Create your HTML, JS, and CSS files
- Create initial HTML structure and link JS and CSS files

![initial setup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pulp3evqclxxj3nohc93.png)

### 2.) Create and Display your Sprite
HTML
```
    <body>
        <div id="sprite"></div>
    </body>
```
CSS
```
#sprite {
    background-color: black;
    height: 20px;
    width: 20px;
    position: absolute;
    /* Initial coordinates of sprite */
    left: 100px;
    bottom: 500px;
}
```

### 3.) Add an `addEventListener` for keydown events

```
// set equal to sprite's initial cooridinates
let position = {
    x: 100, 
    y: 500
};
// dimensions of the sprite
size = 20;

document.addEventListener('keydown', (event) => chooseDirection(event));

function chooseDirection(event) {
    // if key pressed = an arrow key --> change position
    switch(event.key) {
        case 'ArrowRight':
            position.x += size;
            sprite.style.left = position.x + 'px';
            break;
        case 'ArrowLeft':
            position.x -= size;
            sprite.style.left = position.x + 'px';
            break;
        case 'ArrowUp':
            position.y += size;
            sprite.style.bottom = position.y + 'px';
            break;
        case 'ArrowDown':
            position.y -= size;
            sprite.style.bottom = position.y + 'px';
            break;
    }
}
```
That's it! Now using the arrow keys (or whatever keys you want!), you can move the sprite all across the screen.


## Extras!
### - Change based on window size

```
window.addEventListener('resize', displaySprite)

function displaySprite() {
    // remove any previous sprite
    document.querySelector('body').innerHTML = '';
    
    const sprite = document.createElement('div');
    sprite.id = 'sprite';
    document.querySelector('body').append(sprite);

    sprite.style.height = size + 'vmin';
    sprite.style.width  = size + 'vmin';
    sprite.style.left   = position.x + 'vmin';
    sprite.style.bottom = position.y + 'vmin';
}
```
By changing from `px` units to `vmin` units, we can dynamically change the size of the sprite.

For Example:
`sprite.style.bottom = position.y + 'px'` --> `sprite.style.bottom = position.y + 'vmin'`


![changing window size](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b8abgu70axndodbj0x2s.gif)

### - Add a Grid

```
function displayGrid() {
    const grid = document.createElement('div');
    grid.id = 'grid';
    document.querySelector('body').append(grid);

    let cellClass = 'darkerTile';
    let isDark = true;

    for(let i = 0; i < gridSize; i++) {
        const column = document.createElement('div');
        column.className = 'column';
        grid.append(column);

        for(let i = 0; i < gridSize; i++) {
            (isDark) ? cellClass = 'darkerTile' : cellClass = 'lighterTile';
            isDark = !isDark;
        
            const cell = document.createElement('div');
            cell.className = cellClass;
            cell.style.height = size + 'vmin';
            cell.style.width = size + 'vmin';
    
            column.append(cell);
        }
    }
}
```
Don't forget the CSS!
```
#grid {
    display: flex;
    position: relative;
    width: fit-content;
    border: 2vmin solid darkgreen;
}

.darkerTile {
    background-color: green;
}

.lighterTile {
    background-color: lightgreen;
}
```
If your having trouble with your sprite aligning to your grid:
- try making your sprite the child of your grid element, and setting the grid's position to relative
- make sure your starting position aligns with the grid
- make sure all size related units are tied to the same variable

### - Add border collision to contain your sprite

```
const bounds = {
    min: 0,
    max: (gridSize - 1) * size
};

function chooseDirection(event) {
    switch(event.key) {
        case 'ArrowRight':
            isAtBorder('x', 'max') ? null : move('x', 'left', true);
            break;
        case 'ArrowLeft':
            isAtBorder('x', 'min') ? null : move('x', 'left', false);
            break;
        case 'ArrowUp':
            isAtBorder('y', 'max') ? null : move('y', 'bottom', true);
            break;
        case 'ArrowDown':
            isAtBorder('y', 'min') ? null : move('y', 'bottom', false);
            break;
    }
}

function isAtBorder(axis, boundary) {
    return (position[axis] === bounds[boundary]) ? true : false;
}

function move(spriteAxis, windowAxis, moveMaxy) {
    (moveMaxy === true) 
    ? position[spriteAxis] += size
    : position[spriteAxis] -= size;

    sprite.style[windowAxis] = position[spriteAxis] + 'vmin';
}
```

### - Change your sprite's appearance
Instead of a div, change your sprite to an img and mess around with different sources.

## Final Product

![final](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9lhoa1s1fxkwn4waa5xg.gif)