Creating a canvas platformer tutorial part two

Wow, so its been a while since I’ve posted anything. I’ve been kind of busy, and was forcing myself not to post anything unless it was going to be part two of the tutorial. With that said lets begin! For all the code and fully working demo scroll to the bottom.

Last we left off we had a pretty complete demo where we could run and jump around the screen. Now we are going to add some objects that the player can actually collide into!

Lets add an array called boxes to hold the objects well be doing collision checks against, and lets block the player from falling out of the screen by using our objects.


var boxes = []

// dimensions
boxes.push({
    x: 0,
    y: 0,
    width: 10,
    height: height
});
boxes.push({
    x: 0,
    y: height - 2,
    width: width,
    height: 50
});
boxes.push({
    x: width - 10,
    y: 0,
    width: 50,
    height: height
});

The above code sets up three boxes to enclose our game world. If you remember from the last tutorial we are checking coordinates directly to keep the player within the bounds, however since we are adding collisions we can just let our collision function handle that for us.

Lets got ahead and add some logic to draw the boxes so you can see them. Add the following code to your update function between clearRect and ctx.fillStyle = “red”.


    ctx.fillStyle = "black";
    ctx.beginPath();

    for (var i = 0; i < boxes.length; i++) {
        ctx.rect(boxes[i].x, boxes[i].y, boxes[i].width, boxes[i].height);
    }

    ctx.fill();

You should now see some thick black boxes on the left, right, and bottom of your canvas. Now lets actually make the player collide against them!

So Im going to give a pretty brief primer of the collision method we are using. We are going to be checking two objects against each other, the player, and a box. We will do this by checking if they intersect. If they intersect then they must be colliding. Since we are working on a platformer we need one more piece of information, from which direction is the player colliding? Go ahead and add the below function, it does just that!

function colCheck(shapeA, shapeB) {
    // get the vectors to check against
    var vX = (shapeA.x + (shapeA.width / 2)) - (shapeB.x + (shapeB.width / 2)),
        vY = (shapeA.y + (shapeA.height / 2)) - (shapeB.y + (shapeB.height / 2)),
        // add the half widths and half heights of the objects
        hWidths = (shapeA.width / 2) + (shapeB.width / 2),
        hHeights = (shapeA.height / 2) + (shapeB.height / 2),
        colDir = null;

    // if the x and y vector are less than the half width or half height, they we must be inside the object, causing a collision
    if (Math.abs(vX) < hWidths && Math.abs(vY) < hHeights) {         // figures out on which side we are colliding (top, bottom, left, or right)         var oX = hWidths - Math.abs(vX),             oY = hHeights - Math.abs(vY);         if (oX >= oY) {
            if (vY > 0) {
                colDir = "t";
                shapeA.y += oY;
            } else {
                colDir = "b";
                shapeA.y -= oY;
            }
        } else {
            if (vX > 0) {
                colDir = "l";
                shapeA.x += oX;
            } else {
                colDir = "r";
                shapeA.x -= oX;
            }
        }
    }
    return colDir;
}

The code is easy to figure out if you stare at it for a bit, but Ill go ahead and give a quick explanation of whats going on. First we need to calculate the current vector from the center of our objects, which is done in the very beginning.

figure 1

The player and box object at their current positions ready to be checked to see if they are colliding.

The above image shows the player and one of our boxes. We can tell they aren’t currently colliding but lets step through to see how the function figures it out.

fig2

Showing the vector calculation and half width, half height calculations.

Above shows the values we end up with for the vector, half widths, and half heights. The function checks the absolute values of the vector to see if they are less than the half width, and half height. If they are there is a collision. As you see from above our vector needed an x component of 25 or less, along with the y. Since they our values were both 35 (remember we check the absolute value meaning the -35 turns to 35) that means we are too far away and are currently not intersecting.

Now lets take a look at an example where the player and the box are intersecting.

fig3

The player and the box are now intersecting since the vector components are less than the half width and half height.

The above uses the same dimensions for the box and player, all we did was move the player closer to the box. The values for the x and y component of the vector come out to less than 25, meaning a collision has occurred. Now using this information we can actually get which side the collision occurred on. To do this we need to first figure out the offset vector, meaning how far are we into the other object. The below illustration shows how we do that.

Calculating the offset vector after a collision has occured.

Calculating the offset vector after a collision has occurred.

So now we have the offsets, what do we need to do with them? First we check if the x components offset is greater than the y. If so that would tell us we either collided with the top or bottom of the object, because the assumption is the greater penetration is not actually *in* the object since we would have caught it much sooner. In our case the y offset is much greater meaning we collided with the left or right of the object and since our original vectors X is a positive number, it means it was on the left. If we were on the right side our x value would have came out positive due to the x coordinate of the player being greater than the x coordinate of the box.

Now we need to move the objects outside of each other, if we don’t then they will just go further inside one another. This is very easy since we already have the offsets, and since we determined we collided on the left side, we move our box to the left by 2.

Alright so you have this collision function.. what the heck do you do with it? All you need to do is add the following inside the drawing loop for your boxes.

var dir = colCheck(player, boxes[i]);

Now we need to add a couple more things before we can actually do anything with the collisions. Add the property grounded, and sliding to your player object and set it false initially. Since we are going to have different things to jump off of we need to know if we are on solid ground or not, or if we should keep falling raising. Your player object should now look like this.

    player = {
        x: width / 2,
        y: height - 5,
        width: 5,
        height: 5,
        speed: 3,
        velX: 0,
        velY: 0,
        jumping: false,
        grounded: false
    },

Lets go ahead and add the check to our jumping condition, change your jump key condition to the following.

    if (keys[38] || keys[32]) {
        // up arrow or space
        if (!player.jumping && player.grounded) {
            player.jumping = true;
            player.grounded = false; // We're not on the ground anymore!!
            player.velY = -player.speed * 2;
        }
    }

By looking at that you can see we can only jump if we are on the ground and are currently not jumping, and every time we jump set grounded to false. We also need to set grounded to false before we do the collision check every time so our player can fall off ledges, add the following right before the box loop.

    player.grounded = false;

Now lets go ahead and remove the following from your code, since we are going to be using our collision system instead of hard constraints when keeping the player in the canvas.

    if (player.x >= width - player.width) {
        player.x = width - player.width;
    } else if (player.x <= 0) {         player.x = 0;     }     if (player.y >= height - player.height) {
        player.y = height - player.height;
        player.jumping = false;
    }

We just removed what told us our player isn’t jumping anymore! We need to add some of that logic back in somewhere else! Add the following into your update function inside the box loop where you call the colCheck function.

       if (dir === "l" || dir === "r") {
            player.velX = 0;
            player.jumping = false;
        } else if (dir === "b") {
            player.grounded = true;
            player.jumping = false;
        } else if (dir === "t") {
            player.velY *= -1;
        }

As you can see from that, if the collision direction is on the left or right we stop the player from moving left or right, if its on the bottom we set grounded to true since our feet have touched some sort of ground, and if its top, we just reverse the current force of our jump since we hit our head on the ceiling. You could just as easily make velY 0 but it feels a bit floaty to me.

The last thing you need to do is put the following code right after the box loop.

    if(player.grounded){
         player.velY = 0;
    }

    player.x += player.velX;
    player.y += player.velY;

Delete the previous occurrence of player.x += player.velX, and player.y += player.velY. Go ahead and run it! If there are no errors the player should not fall through the world and should be able to run and jump around.. acting just like our previous demo!.. wait, so we did all that work just to make it like the last demo? Of course not, lets add some boxes right under the section where we declared our first set of boxes.

boxes.push({
    x: 120,
    y: 10,
    width: 80,
    height: 80
});
boxes.push({
    x: 170,
    y: 50,
    width: 80,
    height: 80
});
boxes.push({
    x: 220,
    y: 100,
    width: 80,
    height: 80
});
boxes.push({
    x: 270,
    y: 150,
    width: 40,
    height: 40
});

Now go ahead run around and jump!

The entire program should look like the following

(function () {
    var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
    window.requestAnimationFrame = requestAnimationFrame;
})();

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    width = 500,
    height = 200,
    player = {
        x: width / 2,
        y: height - 15,
        width: 5,
        height: 5,
        speed: 3,
        velX: 0,
        velY: 0,
        jumping: false,
        grounded: false
    },
    keys = [],
    friction = 0.8,
    gravity = 0.3;

var boxes = [];

// dimensions
boxes.push({
    x: 0,
    y: 0,
    width: 10,
    height: height
});
boxes.push({
    x: 0,
    y: height - 2,
    width: width,
    height: 50
});
boxes.push({
    x: width - 10,
    y: 0,
    width: 50,
    height: height
});

boxes.push({
    x: 120,
    y: 10,
    width: 80,
    height: 80
});
boxes.push({
    x: 170,
    y: 50,
    width: 80,
    height: 80
});
boxes.push({
    x: 220,
    y: 100,
    width: 80,
    height: 80
});
boxes.push({
    x: 270,
    y: 150,
    width: 40,
    height: 40
});

canvas.width = width;
canvas.height = height;

function update() {
    // check keys
    if (keys[38] || keys[32]) {
        // up arrow or space
        if (!player.jumping && player.grounded) {
            player.jumping = true;
            player.grounded = false;
            player.velY = -player.speed * 2;
        }
    }
    if (keys[39]) {
        // right arrow
        if (player.velX < player.speed) {             player.velX++;         }     }     if (keys[37]) {         // left arrow         if (player.velX > -player.speed) {
            player.velX--;
        }
    }

    player.velX *= friction;
    player.velY += gravity;

    ctx.clearRect(0, 0, width, height);
    ctx.fillStyle = "black";
    ctx.beginPath();

    player.grounded = false;
    for (var i = 0; i < boxes.length; i++) {
        ctx.rect(boxes[i].x, boxes[i].y, boxes[i].width, boxes[i].height);

        var dir = colCheck(player, boxes[i]);

        if (dir === "l" || dir === "r") {
            player.velX = 0;
            player.jumping = false;
        } else if (dir === "b") {
            player.grounded = true;
            player.jumping = false;
        } else if (dir === "t") {
            player.velY *= -1;
        }

    }

    if(player.grounded){
         player.velY = 0;
    }

    player.x += player.velX;
    player.y += player.velY;

    ctx.fill();
    ctx.fillStyle = "red";
    ctx.fillRect(player.x, player.y, player.width, player.height);

    requestAnimationFrame(update);
}

function colCheck(shapeA, shapeB) {
    // get the vectors to check against
    var vX = (shapeA.x + (shapeA.width / 2)) - (shapeB.x + (shapeB.width / 2)),
        vY = (shapeA.y + (shapeA.height / 2)) - (shapeB.y + (shapeB.height / 2)),
        // add the half widths and half heights of the objects
        hWidths = (shapeA.width / 2) + (shapeB.width / 2),
        hHeights = (shapeA.height / 2) + (shapeB.height / 2),
        colDir = null;

    // if the x and y vector are less than the half width or half height, they we must be inside the object, causing a collision
    if (Math.abs(vX) < hWidths && Math.abs(vY) < hHeights) {         // figures out on which side we are colliding (top, bottom, left, or right)         var oX = hWidths - Math.abs(vX),             oY = hHeights - Math.abs(vY);         if (oX >= oY) {
            if (vY > 0) {
                colDir = "t";
                shapeA.y += oY;
            } else {
                colDir = "b";
                shapeA.y -= oY;
            }
        } else {
            if (vX > 0) {
                colDir = "l";
                shapeA.x += oX;
            } else {
                colDir = "r";
                shapeA.x -= oX;
            }
        }
    }
    return colDir;
}

document.body.addEventListener("keydown", function (e) {
    keys[e.keyCode] = true;
});

document.body.addEventListener("keyup", function (e) {
    keys[e.keyCode] = false;
});

window.addEventListener("load", function () {
    update();
});
Check out this Pen!

Link to the code on jsfiddle

Posted in Canvas, Game Development, html5, Javascript, Programming, Tutorials, Web Development | Tagged , , , , | Leave a comment

Creating a canvas platformer tutorial part one

I’ve seen a few questions on Stackoverflow lately dealing with how to smoothly move an object around on the canvas. This will be the first part, of my first ever attempted tutorial series. So please bear with me as I can sometimes be very confusing (to myself included) when trying to convey any topics dealing with development.

What we will be making

What do I need to know?

What do you need to know before reviewing this tutorial? Not much really, a pretty basic understanding of JavaScript is required, and know what the canvas element is would be helpful.

Lets draw something!

We are going to need a few things to start out with. We need a way to track the player object, we need a game loop to update logic and draw onto the screen, and we need to handle user input. So lets get started!

The first thing well do is create the canvas element we’re going to use and get something drawn on it.

Use following markup to create the canvas element.


Something fancy

    <canvas id="canvas"></canvas>

If you want you can add a border to the canvas element via css just so we know where its at on the screen.

Now add some js to get the player onto the screen.

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    width = 500,
    height = 200,
    player = {
      x : width/2,
      y : height - 5,
      width : 5,
      height : 5
    };

canvas.width = width;
canvas.height = height;

// draw a small red box, which will eventually become our player.
ctx.fillStyle = "red";
ctx.fillRect(player.x, player.y, player.width, player.height);

If you run what you have you should have something that looks like the following.

What you should have after the following code.

What you should have after the following code.

AWW YEAH GOT SOMETHING ON SCREEN WHAT!?

Ok maybe I’m too excited about that I don’t know, regardless your dude is on the screen and I can tell he wants to get moving.

The game loop and requestAnimationFrame

Now we need to add the game loop! If you’re pretty new to canvas and making things move with canvas in particular you may of seen examples using setTimeout, or setInterval. DON’T USE THESE! They were great when that’s all we had but for anything that requires constant rendering you want to use requestAnimationFrame. requestAnimationFrame is much better in a few ways, I wont go into all of them but here is a good place to start reading why you should use it. We will add a shim that was popularized by Paul Irish, which will use requestAnimationFrame on all browsers that support it, and fall back to good ol setTimeout on browsers that do not support it.

Add the following to the top of your js.

(function() {
    var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
    window.requestAnimationFrame = requestAnimationFrame;
})();

How are you supposed to use it? Its actually quite easy. Lets throw our rendering code into a function, well call it update since we will also place our update logic here as well. Note, this isn’t a best practice but we are just doing it for the tutorials sake. Generally your rendering portion, and code that controls entities updating would be seperate so you could add things such as delta timing to control the rendering. However lets keep it simple!

Change the portion in your js that draws your player to the following.

function update(){
    // draw our player
    ctx.fillStyle = "red";
    ctx.fillRect(player.x, player.y, player.width, player.height);
    // run through the loop again
    requestAnimationFrame(update);
}

We also need a way to get our game loop kick started, so add a load event listener for the window to the end of your js file.

window.addEventListener("load", function(){
  update();
});

Now run the code!!!! heh, it still looks the same doesn’t it? Alright lets add something to make it a bit more appealing.

Handling keyboard input from the user

So now we have our game loop, and our player object, all we need now is a way to get the player moving! We will do this by tracking key presses by the user, and moving our player accordingly.

First we need to add a few more properties to our player object, update your player object to the following.

    player = {
      x : width/2,
      y : height - 5,
      width : 5,
      height : 5,
      speed: 3,
      velX: 0,
      velY: 0
    }

As you can see we have added velocity variables for horizontal and vertical movement, and a speed variable. The velocities will be added to our current position, and the speed will control how fast we are able to go.

Next lets add an array named keys right after the player object.

    keys = [];

So your variable declarations should now look like this.

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    width = 500,
    height = 200,
    player = {
      x : width/2,
      y : height - 5,
      width : 5,
      height : 5,
      speed: 3,
      velX: 0,
      velY: 0
    },
    keys = [];

Its time to add the keyboard events. If you have never dealt with the canvas element before, and keyboard events, you’ll be disappointed to learn you can not tie keyboard events directly to the canvas element. So for the sake of this tutorial we will just bind them to the body.

Add the following.

document.body.addEventListener("keydown", function(e) {
    keys[e.keyCode] = true;
});

document.body.addEventListener("keyup", function(e) {
    keys[e.keyCode] = false;
});

This is where the keys variable comes into play. Basically what this does is every time you touch, or hold a key down the element in the array at the same position as the keycode will be set to either true or false. Using this method it allows us to track multiple keys at one time rather than trying to handle key presses individually.

Alright onto adding the actual interaction! Add the following code to the top of the update function.

 // check keys
    if (keys[38]) {
        // up arrow
    }
    if (keys[39]) {
        // right arrow
        if (player.velX < player.speed) {                         player.velX++;                  }          }          if (keys[37]) {                  // left arrow                  if (player.velX > -player.speed) {
            player.velX--;
        }
    }

The above code checks which keys are set to true, and if they are increases or decreases the players velocity. There’s also a check that limits the speed of the player to the speed variable to make sure the player doesn’t go too fast.

Its time to actually move the player, add the following code after the code you just added.

    player.x += player.velX;
    player.y += player.velY;

Now if you go ahead and run your code, the player will actually move! But wait!! Don’t run it yet, we need one more check in place. The next bit of code takes care of that, add it right after the player movement.

    if (player.x >= width-player.width) {
        player.x = width-player.width;
    } else if (player.x <= 0) {
        player.x = 0;
    }

The above code will make your player stop and not go outside of the canvas. Now go ahead and run your code, your player should now run back and forth. Pretty badass amiright?! Ok maybe not that awesome. You probably are noticing the player keeps moving when you let up on the arrow key, whats up with that?

Instead of making the player just stop immediately, lets add some friction to our players movement. Go ahead and add a friction variable under the keys var, set it to 0.8, you can play with this to create more or less friction, a lower number makes you slide less, a higher number makes you slide more.

    friction = 0.8;

Now add the following code in your game loop right after you check the keys.

    player.velX *= friction;

Go ahead and run your code, your player should now stop when you let go, with a bit of a skid. Play with the value to increase or decrease how much your player slides around.

Time to get jumping!

What good is a platformer without jumping? Well.. I’m sure you could come up with some interesting games not using the jumping mechanic.. but that’s besides the point!

You probably already know what we need to do to get our player to jump, we need to modify the players velocity on the y axis, every time we hit the desired key.  Jumping can be tricky, there are a few gotchas when dealing with it.

First we need to add something to the player object to let us know if we are currently jumping or not.

    player{
        /* all the other properties previously entered
        jumping : false
    }

Next we need to make the player jump when a key is pressed. This is pretty simple, we just add another check where we check for left and right arrow keys. We also need to set the players velocity to a negative value to make them into the air, and set the jumping property to true.

    if (keys[38] || keys[32]) {
        // up arrow or space
      if(!player.jumping){
       player.jumping = true;
       player.velY = -player.speed*2;
      }
    }

If you run the code now your player should jump, and fly away! So lets reign him in a little. We need to add gravity into the mix, or simulate it anyway. Lets add a gravity variable to our variable declarations at the top of the code. You can play with this value to make your player jump on the moon if you want! The lower the number the higher or “floatier” the jump.

    gravity = 0.3;

Now to use gravity we need to add the following line within the update loop. Add it right after the line that applies friction to the horizontal movement we did earlier.

     player.velY += gravity;

One more thing until we are “done”, we need to make sure the player doesn’t fall through the screen, and we need to reset the jump property when the player hits the ground. So lets add a boundary check right after we check the horizontal location of the player inside of the update function.

    if(player.y >= height-player.height){
        player.y = height - player.height;
        player.jumping = false;
    }

Go ahead and run it! You should have a little dot that runs back and forth and jumps like a bauce!! Check out the full source below.

Pen to mess around with

Full source

(function() {
    var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
    window.requestAnimationFrame = requestAnimationFrame;
})();

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    width = 500,
    height = 200,
    player = {
      x : width/2,
      y : height - 5,
      width : 5,
      height : 5,
      speed: 3,
      velX: 0,
      velY: 0,
      jumping: false
    },
    keys = [],
    friction = 0.8,
    gravity = 0.2;

canvas.width = width;
canvas.height = height;

function update(){
  // check keys
    if (keys[38] || keys[32]) {
        // up arrow or space
      if(!player.jumping){
       player.jumping = true;
       player.velY = -player.speed*2;
      }
    }
    if (keys[39]) {
        // right arrow
        if (player.velX < player.speed) {             player.velX++;         }     }     if (keys[37]) {         // left arrow         if (player.velX > -player.speed) {
            player.velX--;
        }
    }

    player.velX *= friction;

    player.velY += gravity;

    player.x += player.velX;
    player.y += player.velY;

    if (player.x >= width-player.width) {
        player.x = width-player.width;
    } else if (player.x <= 0) {         player.x = 0;     }     if(player.y >= height-player.height){
        player.y = height - player.height;
        player.jumping = false;
    }

  ctx.clearRect(0,0,width,height);
  ctx.fillStyle = "red";
  ctx.fillRect(player.x, player.y, player.width, player.height);

  requestAnimationFrame(update);
}

document.body.addEventListener("keydown", function(e) {
    keys[e.keyCode] = true;
});

document.body.addEventListener("keyup", function(e) {
    keys[e.keyCode] = false;
});

window.addEventListener("load",function(){
    update();
});

Part two will focus on colliding with objects, and actually building a little world for our player to interact with.

Posted in Canvas, Game Development, html5, Javascript, Programming, Tutorials, Web Development | Tagged , , , , | 8 Comments

Rainbow bright bookmarklet

Went a little crazy with a friend of mines bookmarklet he made that would randomly change the colors of all elements on a page.

Gist

Just drag this link to your bookmarks and click it on any random page to enjoy the show

Rainbow Bright Bookmarklet

Posted in html5, Javascript, Programming, Web Development | Leave a comment

Snowfall 1.6

Repo on Github
Download Jquery Snowfall 1.6
View the plugin in action

You can now use images for snowflakes!

// jQuery vs
$(document).snowfall({image :"images/flake.png", minSize: 10, maxSize:32});

// purejs vs
snowFall.snow(document.body, {image : "images/flake.png", minSize: 10, maxSize:32});

Invoking the snow

    $(document).snowfall();
    $('#elementid').snowfall({flakeCount : 100, maxSpeed : 10});
    $('.class').snowfall({flakeCount : 100, maxSpeed : 10});

Snowfall Methods

    // stopping the snow
    $(document).snowfall('clear');
    $('#elementid').snowfall('clear');
    $('.class').snowfall('clear');

Options currently supported with default values

options = {
	flakeCount : 35,		// number
	flakeColor : '#ffffff', // string
	flakeIndex: 999999,		// number
	minSize : 1,			// number
	maxSize : 3,			// number
	minSpeed : 2,			// number
	maxSpeed : 3,			// number
	round : false,			// bool
	shadow : false,			// bool
        collection : 'element'          // string
};

Example

Posted in Canvas, html5, Javascript, Programming, Web Development | Tagged , , , | 15 Comments

Retroships.com

I decided to create a small project this weekend, using node, and nodejitsu.com. The concept was really simple, to generate a 2d ship that could be used in games, or any programs really. The project turned out pretty well check out http://retroships.com/. The ships are generated via node-canvas, and displayed to the user. The stars are done with standard client side canvas. Im sure Ill be creating a few more micro sites like this, and possibly a full on app for procedural graphic generation at some point.

As for retroships.com features there’s a few more things I need to add such as the ability to pick different ship styles, an option for seeds, and the ability to get only the ship graphics from a simple url such as retroships.com/generate?type=2&seed=blah.

As for using nodejitsu, its great, setup was *really* simple. I’m looking forward to the paid tiers so I don’t have to worry about my site just suddenly ceasing to function. The only issue I had was with deploys. I had to deploy 2-3 times due to errors with node-canvas.

Posted in Canvas, Game Development, html5, Javascript, node.js, Programming, Web Development | Leave a comment

Super Simple Wave Simulators

So I have been really into wave sims lately. It all started with an excellent tutorial posted here. I tried my hand at a JS one first using canvas which turned out pretty awesome.

Check it out on codepen as well.

Then I tried something else a bit crazy and decided to do the same thing with only html/css. It turned out pretty cool, not as interactive as the JS one but the effect is still nice. I could see this being used on the bottom of a website.

Also a link on codepen.

Posted in Canvas, css3, Game Development, html5, Javascript, Programming, Web Development | Leave a comment

My sons first game Dark Slayer

My son Jacob decided to learn how to program. He followed the great tutorial from Lost Decade Games, and added his own flare to it. He added enemies that shoot, player health, and the game can also end. So proud of him for making it. I helped with a few small things, but the majority was done by him. His brother Gavin also helped with art along with their sister Gabi.

Check out Dark Slayer

Posted in Canvas, Game Development, Gaming, Javascript, Programming, Web Development | 4 Comments

2d Metaballs with canvas!

I read this great article on creating 2d metaballs with XNA. I never really looked into the concept behind them, but after reading that they seemed pretty simple. I decided to try my hand at it using javascript and canvas. The results were pretty awesome (well in my opinion anyway).

Quick attempt at explaining my understanding at metaballs without butchering them

The basic concept is to use a radial gradient, and set an alpha threshold that will be filtered. For example any pixel with an alpha lower than 150 will be set to an alpha of 0. This gives the metaball effect because when the gradients overlap, the areas that are normally hidden now have their alpha values added which brings them above the threshold.

One way to achieve this using canvas and javascript

So basically what I do is create a bunch of points, and set their velocities, positions and sizes.

1 2 3 4 5 6 7 8 9 10
for(var i = 0; i < 50; i++){
var x = Math.random()*width,
y = Math.random()*height,
vx = (Math.random()*8)-4,
vy = (Math.random()*8)-4,
size = Math.floor(Math.random()*60)+60;
points.push({x:x,y:y,vx:vx,vy:vy, size:size});
};
view raw gistfile1.js This Gist brought to you by GitHub.

Next I draw each of these onto a temp canvas

1 2 3 4 5 6 7 8
var grad = tempCtx.createRadialGradient(point.x, point.y, 1, point.x, point.y, point.size);
 
tempCtx.beginPath();
grad.addColorStop(0, 'rgba(' + colors.r +',' + colors.g + ',' + colors.b + ',1)');
grad.addColorStop(1, 'rgba(' + colors.r +',' + colors.g + ',' + colors.b + ',0)');
tempCtx.fillStyle = grad;
tempCtx.arc(point.x, point.y, point.size, 0, Math.PI*2);
tempCtx.fill();
view raw gistfile1.js This Gist brought to you by GitHub.

Then finally I read the pixel data, filter the alpha based on a threshold I set, and put the filtered data back onto the main canvas to be displayed.

1 2 3 4 5 6 7 8 9 10 11 12
function metabalize(){
var imageData = tempCtx.getImageData(0,0,width,height),
pix = imageData.data;
for (var i = 0, n = pix.length; i <n; i += 4) {
// Checks threshold
if(pix[i+3]<threshold){
pix[i+3]=0;
}
}
ctx.putImageData(imageData, 0, 0);
}
view raw gistfile1.js This Gist brought to you by GitHub.

Check out the demo with added features or the jsfiddle to play around with.

Posted in Canvas, html5, Javascript, Programming, Uncategorized, Web Development | Tagged , , | 2 Comments

Turning canvas games into executables


This is something I’ve been looking to do for the longest time. The closest I ever got was using Adobe Air. I didn’t like that solution though because it left all of your assets out in the open. Recently a friend reminded me about QT something I haven’t touched in a few years. After looking over some of their webkit examples I realized I could load in embedded resources.. making self contained canvas games.

I tested out my theory using the Fancy Browser sample, and just modifying it to load an embedded html, which include all the code for the game.

So far it works great. I need to do some more tests, such as finding out what dependencies the executable requires, and also what kind of performance I get (QT5 will include V8). This is still pretty cool in my opinion, just another way to monetize HTML5 games :) …. or even… HTML5 screen savers!

Posted in Canvas, Game Development, html5, Javascript, Programming, Web Development | Tagged , , | Leave a comment

JEST another HTML5 Game Framework

I’ve been coming up with small games and demos using canvas for a couple of years now, and over that time I’ve created a framework for doing so. You can see examples in some of my earlier blog posts such as the SOPA game, and the SHMUP thats been in development for a while. Today I decided to pretty some of it up a bit and post it on github. Minified it comes in at only 31k, and provides quite a bit of functionality (I am biased though).

Here is a link to the github repo and the first of many demo’s Ill be posting.

Posted in Game Development, html5, Javascript, Programming, Web Development | Tagged , , , , | Leave a comment