Posted by & filed under JavaScript, web developing.

Sometimes it can be difficult, for beginning developers to grasp the inner mechanics of a simple game. To help people understanding i created a very simple starting point for a canvas based game.

character-canvas

The code

You can download the code in this repo https://github.com/jeroenoliemans/canvasletter After downloading you can run “npm install” to install the dependencies and “webpack-dev-server” to run the code. By default the server will point to localhost:8080 .

First i will begin with a walkthrough of the code.The games consists of 2 classes the Character class is responsible for the character and the CharacterCanvas class is responsible for creating the Character instances, controlling these instances, stopping and starting the game and giving feedback over the scoring.

The Character

class Character {
    constructor() {
        this.characterX;
        this.characterY;
        this.characterChar;
        this.reset();
    }

    reset() {
        this.characterX = (Math.floor(Math.random()*(document.body.clientWidth)-30) + 15);
        this.characterY  = 0 - Math.floor(Math.random()*1000);
        this.characterChar = String.fromCharCode(97 + Math.floor(Math.random() * 26));
    }

    setyPos(newy) {
        this.characterY = newy 
    }
};
 
export default Character;

The Character has a reset method which moves the character back to the top on a random position if the user entered key matches the instances CharacterCode. The setY method is used, to position the Character instance from the CharacterCanvas class.

The CharacterCanvas

The CharacterCanvas has a few important methods:

  • createCanvas: creates the canvas and sets the defaults
  • createCharacters: this creates the Character instances and starts the game loop
  • startGameLoop: the actual game, which will be discussed in the next section

The game loop

startGameLoop() {
        this.clearCanvas();
        for(let i = 0; i < this.characters.length; i++) {
            let char = this.characters[i];
            this.ctx.font = '62px serif';
            this.ctx.fillText((char.characterChar).toString(), char.characterX, char.characterY);
            char.setyPos( char.characterY + this.velocity);

            // remove if off screen
            if( char.characterY > this.canvas.height ){
                this.characters.splice(i,1);
            }
        }
        
        // fontsize  for ui
        this.ctx.font = '36px serif';

        // start loop
        if(this.characters.length !== 0) {
            requestAnimationFrame(() => this.startGameLoop() );
        } else {
            this.isPlaying = false;
            this.ctx.fillText('GAME OVER', 50, 50);
            this.ctx.fillText('Hit space to restart', 50, 90);
            // write highscore
            if(this.score > this.getHighScore() ) {
                localStorage.setItem('textHighScore', this.score);
            }            
        }

        // display score
        this.ctx.fillText(`Score (${this.highScore.toString()}) : ` + (this.score).toString(), this.canvas.width - 250, this.canvas.height - 50);      
    }

This method clears the canvas,loops through all the available Character instances being hold in the this.characters array and updates their new position. If a character moves off screen than it is removed from the this.characters array. If there aren’t anymore characters left than the loop ends the game and displays ‘GAME OVER’.

The game is boring

It is, hence i kept the game to a bare minimum to improve fast understanding of the game mechanics. Nevertheless it is easy to make the game more interesting. We can improve the game or add the following features.

Create Levels

  • Multiply the velocity if the player reaches a score of 50, 100 ..
  • You can also use the modulus operator to create infinite levels

Add more difficult characters, with more speed and another color

  • Add a color property to the Character class
  • Add a velocityMultiplier property to the Character class, which defaults to 1
  • In the CharacterCanvas class multiply the velocity with the velocityMultiplier
  • Change the velocityMultiplier and the color of the Characters instances in the createCharacter method

What’s next

This game principle could be easily extended, with image sprites, to create a space invaders ore a tetris clone. And of course the code should be divided in more modules, for example modules for scoring, user events and configuration/constants.

Posted by & filed under html, JavaScript, web developing.

Last week I was given the task to create a collapsible datatable, which confronted me with some oddities in the dom which I wasn’t aware of.

Get the example at github-collapsible-table

I had given myself the following requirements

  • The code needs to be extensible
  • The table should be just a table, no extra markup
  • It should be easy to rewrite the table for a framework
  • Keep it simple
  • No jQuery
simple collapsible table

Vertical table headers

My first attempt was css transforms, easy to adjust and to implement. However the problem was that I needed extra markup to keep the header in the normal page flow. After some consideration is seemed to me that SVG is the best option, it is scriptable, stylable and it maintains the normal paqe flow. See the snippet below

<th>
  <svg xmlns="http://www.w3.org/2000/svg" width="16" height="150">
    <text text-anchor="end" transform="rotate(90, 12, 0) translate(160,10)">Vertical header
    </text>
  </svg>
</th>

cellIndex to the rescue

I needed to have a proper way to get track of the current clicked cell and it column index. Luckily JavaScript provides a native property element.cellIndex.

Rowspan messing up

One thing to notice is that each subsequent rowspan decreases the cellIndex by one. This needs to be compensated for, in the main script loop. The script loops through all the toggle elements and creates an array with their corresponding cellIndexes. On toggle click these cellIndexes are used to get the cells between two toggle elements and push them into an array. This array can be used to manipulate the cells ( hide/ show ).

Disadvantages

Since each cell is manipulated independently it is not possible to create an block animation. If that is a requirement than markup should be added to create containers for the cells.

Posted by & filed under CSS, html, web developing.

The web is getting more diverse and websites needs to be more adaptable than ever. In my opinion it is necessary to reduce breakpoints and let the content decide and define the layout of webpages.

I created a very simple fluid layout, with new css technologies, just to see if a fluid page is already feasible in modern browsers. I have used flexbox, vw units en css variables.

fuid-layout

CSS Variables

See the example below the :root pseudo selector is an analogy to the global scope in JavaScript. You could also for example scope the variables to a “.module” class name.

:root {
    --main-color: #EFECCA;
    --accent-color: #A7A37E;
    --accent-color-middle: #E6E2AF;
    --title-color: #002F2F;
    --interactive-color: #046380;
    --text-color: #696969;
}

One breakpoint…

Still one breakpoint left, at first relative units and flexbox did the trick. One breakpoint for better mobile view and more readable font-sizes on small screens is still included.

fluid-mobile

Conclusion and concerns.

I still have my concerns for a full blown webpage. There will always be third party content, like adds and other embedded content which will not stretch easy. However it is perfectly possible to create a pleasing layout with very little and mainable CSS. I even found it pleasant to be working with plain CSS afters years of .less and .scss. I predict a comeback for CSS with CSS-variable, flexbox and CSS gridlayout arround the corner. And with HTTP2 and modern bundlers like Webpack the need for css compilers might diminish in the future.

You can get the code at https://github.com/jeroenoliemans/wonderolie/tree/master/LessBreakpoints for further experimentation, I only tested it in Chrome 49 and beyond.

Posted by & filed under JavaScript, web developing.

After reading the documentation and having watched some of the excellent egghead.io videos about redux I wanted to create something to get a deeper understanding. My main goal was to create a simple application, with some sort of API connection. To keep it simple (read no authentication), I chose for the github connection.

Result

The result, is a simple github-browser. Enter a username to receive a list of repos, click one of the repos to view the repo details and urls.

github-browser

React Redux experience

I still have lot to learn, but I do have a deeper understanding about Redux and I can see the advantages of the immutable states in Redux. It will be more easy to grasp a complex application because of the single state. Besides reduced complexity it will also be more easy to implement cool functionalities like ‘undo delete item’. I would advice to invest in es6 (spread operator and class ) before diving into Redux. You can watch the source and clone it here.

https://github.com/jeroenoliemans/github-browser

Posted by & filed under JavaScript, web developing.

Recently at work I needed to implement a message queue. I like the pattern and I think I will need it more often in the future. I recreated the message queue with a class for personal reference and study purposes.

message-queue

I absolutely like some of the new features: for example proper ‘this’ binding with the arrow functions and parameter defaults in function.

Code

you can see the full code below, or get the example from my github account

/**
 * MessageQueue create notification messages
 */
class MessageQueue {


    /**
     * constructor optional container and delay
     */
    constructor(container = document.getElementById('messageContainer'), delay = 5000) {
        this.messageQueue = [];
        this.container = container;
        this.delay = delay;
    }

    clearMessages() {
        this.container.innerHTML = '';
    }

    displayMessages() {
        let messageFrag = document.createElement('div');

        // clear
        this.clearMessages();

        for (let index = 0; index < this.messageQueue.length; index++) {
            let message = document.createTextNode(this.messageQueue[index].text);
            let flash = document.createElement('div');

            flash.classList.add('flash-message');
            flash.classList.add(this.messageQueue[index].msgType);
            flash.appendChild(message);

            messageFrag.appendChild(flash);

        }
        this.container.appendChild(messageFrag);
    }

    remove() {
        this.messageQueue.shift();
        this.displayMessages();
    }

    /**
     * add messages optional type (CSS class)
     */
    add(message, type = 'error') {
        let msg = {
            text: message,
            index: this.messageQueue.length,
            msgType: type,
        };

        setTimeout(() => this.remove(), this.delay);

        this.messageQueue.push(msg);
        this.displayMessages();
    }
}

Feel free to modify and extend the code, to run the code you need to install babel-cli and run the following watch statement

babel messagequeue.js --watch --out-file messagequeue-compiled.js