11.03.2015

LMaGT 2 - Basic collisions with jQuery

In the last post, I ended with a couple static enemies, and a player that can move left and right. It's a pretty good start, but needs a bit more work before we can really call it a working prototype. The player needs to be able to shoot, and the enemies need to know they're being shot. The first part is easy, the second part has a couple harder bits but it can be done! Like last time, you can (click here) to get this project folder and follow along.

Before jumping in, it's worth pointing out that shooting bullets (or whatever else you'd like to call them) needs to be handled like player movement. A key-binding needs to be added for keyDown and keyUp, but doing it this way will fire a shot every frame the button is held down. You can leave it that way if you want, but I want a bit more control over the firing button. First, this gets added into the main.js file to detect that you're shooting:

var keyShoot = false;
var bulletWaitTime = 10; // Number of frames to wait
var bulletTimer = 0;        // Number of frames waited
function handleKeyDown(e) {
  if (e.keyCode == 32) {
    keyShoot = true;
  }
};

function handleKeyUp(e) {
  if (e.keyCode == 32) {
    keyShoot = false;
    bulletTimer = bulletWaitTime;
  }
};

function calculateInput() {
  // This bit keeps the player within the bounds of the screen
  var playerPos = parseInt($player.css('left').replace('px', ''));
  if (playerPos <= 30) {
    keyLeft = false;
    $player.stop().css({left: '30px'});
  } else if (playerPos >= ($gameArea.width() - $player.width() - 30)) {
    keyRight = false;
    $player.stop().css({left: $gameArea.width() - $player.width() - 30 + 'px'});
  }

  /* Left and Right movement functions go here! */

  if (keyShoot && bulletTimer >= bulletWaitTime) {
    createBullet();
    bulletTimer = 0;
  } else if (bulletTimer < bulletWaitTime) {
    bulletTimer++;
  }
};


When the spacebar is pressed down, a bullet element is created, bulletTimer is set to zero, and will tick back up towards bulletWaitTime each frame. Releasing the spacebar resets the timer, allowing another shot to be fired. You can also adjust the rate of fire by changing bulletWaitTime. Nice! Now that they're being detected properly, we can work on making it appear on screen, and moving. You can use this first bit for some basic css styling:

/* In main.css */
  .bullet {
box-sizing: border-box;
display: inline-block;
position: absolute;
margin: 0;
padding: 0;
width: 5px;
height: 20px;
background-color: gold;
border: 2px dashed white;
}

/* In main.js */
var bulletSpeed = 100;
var $player = '';
var $gameArea = '';

function createBullet() {
var bulletPos = {
left: $player.position().left + ($player.width() / 2),
top: $player.position().top - 30
};
$gameArea.append($('<div/>').addClass('bullet').css(bulletPos));
};

function moveBullets() {
$('.bullet').animate({
'top': '-=' + bulletSpeed
},{
duration: 100,
easing: 'linear'
}).dequeue();
};

function mainLoop() {
 calculateInput();
 moveBullets();
};

$(document).ready(function() {
$player = $('.player');
$gameArea = $('#game-area');
});


Bullets spawn in the #game-area relative to the player's position, centered just above the .player element. They animate the same way the player does, but instead of listening for input, moveBullets() gets called as part of the mainLoop() each frame. Before you can try it out, there's a little bit of cleanup to do. We can move the .player div out of the #player-box into the #game-area, and get rid of the #player-box completely. We can also consolidate the css, making a couple minor changes to set up for the next couple steps. This blog is more about function than design though, so I suggest checking the project folder for specifics. Now that things are cleaned up, you can try it out! The player moves and the bullets fire. This is also a good spot to try out different animation speeds, easing styles, different behaviours to make it your own. Once you've got it moving like you want, let's talk about collisions.

Said briefly, collisions are when 2 or more defined areas come in contact and/or overlap. For the purposes of this project, that means we need to know the boundaries of each enemy box and each bullet. It doesn't matter if the enemies overlap, but if a bullet shares any of the same space with an enemy, we need to know which ones are colliding and destroy them both. So where do we start? There's a lot of ways to do it, this is just one way I've come up with. It needs some fine tuning before it's perfect, but it works great for now.

function detectCollision() {
  $('.bullet').each(function() {
    var $bullet = $(this);
  var bulletPos = {
  top: $bullet.position().top,
  left: $bullet.position().left - 2,
  right: $bullet.position().left + $bullet.width() + 2,
  bottom: $bullet.position.top + $bullet.height()
  }; 
  var hit = false;

  $('.enemy').each(function() {
if (!hit) {
var $enemy = $(this);
var enemy = {
top: $enemy.position().top,
left: $enemy.position().left,
  right: $enemy.position().left + $enemy.width(),
  bottom: $enemy.position().top + $enemy.height()
};

  if (bulletPos.top <= enemy.bottom) {
if (bulletPos.right > enemy.left && bulletPos.left < enemy.right ||
bulletPos.left < enemy.right && bulletPos.right > enemy.left ) {
  hit = true;
  $bullet.remove();
  $enemy.remove();
  }
  }
  }
  });

  if (bulletPos.top < 0 - $bullet.height()) {
  $bullet.remove();
  }
  })
};

function mainLoop() {
  calculateInput();
  moveBullets();
  detectCollision();
};

Each frame, the positions of each bullet and each enemy are fetched and compared. By comparing opposite sides (bullet top to enemy bottom, etc) you can determine if 2 sides are overlapping, and call it a successful collision. The little bit at the end is another check to destroy bullets whenever they go offscreen. When you try this out, you'll see a new problem. Enemies are getting pushed to the left when destroyed. They need to be displayed absolutely, which means they need to be placed automatically. It also means we can get remove the ones we placed in the index.html, leaving 2 empty divs in a <section>. The css can be consolidated a bit more too, as seen in the project folder linked above.

Here's a simple enemy placement function. Based on the size of the #enemy-box and your .enemies, this will fills the area with as many enemies as it can, while maintaining even spacing between them. It only needs to be called once (for now) during the $document.ready section. Like the previous function, this is a rough draft for testing, and will be fine tuned later.

function propagateEnemies() {
  var $enemybox = $('#enemy-box');
var enemySize = 100 + (15 * 2); // Tile size, plus spacing on both sides

var x = Math.floor($enemybox.width() / enemySize);
var xSpacing = ($enemybox.width() % enemySize) / (x + 1);
var y = Math.floor($enemybox.height() / enemySize);
var ySpacing = ($enemybox.height() % enemySize) / (y + 1);

for (var j = 0; j < y; j++) {
for (var i = 0; i < x; i++) {
var position = {
'top': (j * enemySize) + 15 + (ySpacing * 2) + 'px',
'left': (i * enemySize) + 15 + (xSpacing * 2) + 'px'
};
$enemybox.append($('<div/>').addClass('enemy').css(position));
  }
  }
};

$(document).ready(function() {
window.addEventListener('keydown', handleKeyDown, true);
window.addEventListener('keyup', handleKeyUp, true);
$player = $('.player');
$gameArea = $('#game-area');
propagateEnemies();
setInterval(mainLoop, 1000 / fps);
});

That's a good spot to end on. I like how it's coming together so far. The next entry will be the introduction of the navbar, and  'levels' that can be loaded from html content.

10.27.2015

LMaGT Part 1 - Building a skeleton

After some reflection, I realize the dungeon crawler is going to be a much larger project that I had planned. I've come up with a lot of ideas, and it needs more time and attention than I can give it. A more pressing matter is a dire need to update my main portfolio. Click here to check it out.

I built it from scratch while I was still attending Codify Academy. At it's core, it has some cool things I'm happy to have implemented. Outside of that, it's severely lacking in actual content and direction. When I wrote the last entry, I had planned on using the Dungeon Crawler as an interactive portfolio piece. Since it's growing in scope (or at least potential), I've come up with another way to make an interactive portfolio game.

It's similar to Galaga or Space Invaders. The player controls a ship along the bottom of the screen, and shoots at stuff. In this case, the 'stuff' is the content of my portfolio. Individual letters, pictures, headlines; each separate element on the page can be destroyed. Each section can be loaded/reset by clicking the nav bar buttons. The main interface should also be optional for browser compatibility, so everything has to work outside of 'interactive' mode, and should be responsive in both 'standard' and 'interactive' modes.

If you want to follow along, here's the project folder that covers this post. It's a pretty barebones template I've cobbled together with the base elements of the game in place. Here's a quick look at the index.html:

<body>
<section id="game-area">
  <div id="enemy-box">
    <div class="enemy"></div> <div class="enemy"></div>

    <div class="enemy"></div> <div class="enemy"></div> <br/>
    <div class="enemy"></div> <div class="enemy"></div>

    <div class="enemy"></div> <div class="enemy"></div> <br/>
    <div class="enemy"></div> <div class="enemy"></div>

    <div class="enemy"></div> <div class="enemy"></div> <br/>
    <div class="enemy"></div> <div class="enemy"></div>

    <div class="enemy"></div> <div class="enemy"></div> <br/>
  </div> 

  <div id="player-box">
    <div class="player"></div>
  </div>
</section>
</body>
Not a whole lot here. Just a thing that moves and shoots, and some things to shoot at. There's not a lot to talk about in the main.css either. For now, the enemies and player are colored boxes, to be replaced later. The main.js has a lot going on though, so I'll break it into a few pieces. Going through it chronologically, it flows like this:

var fps = 30;  //Target frame-rate

$(document).ready(function() {
    window.addEventListener('keydown', handleKeyDown, true);
    window.addEventListener('keyup', handleKeyUp, true);
    setInterval(mainLoop, 1000 / fps);
});

function mainLoop() {
    calculateInput();
    detectCollision();
};
Still pretty straightforward. First, set up listeners to bind keys to movement, then use setInterval() to manage the main loop. Then inside the loop, player input gets applied before bullet collision is detected. I've got some ideas on how to handle collisions, but I'm saving that for the next entry. For now, lets take a look at the event handlers and calculateInput().

var keyLeft = false;
var keyRight = false;
var playerSpeed = 25;

function handleKeyDown(e) {
  if (e.keyCode == 37 || e.keyCode == 65) {
  keyLeft = true;
  }
  if (e.keyCode == 39 || e.keyCode == 68) {
  keyRight = true;
  }
};

function handleKeyUp(e) {
  if (e.keyCode == 37 || e.keyCode == 65) {
  keyLeft = false;
  }
  if (e.keyCode == 39 || e.keyCode == 68) {
  keyRight = false;
  }
};

function calculateInput() {
  // Move right
  if (keyRight && !keyLeft) {
  $('.player').animate({
  'left': '+=' + playerSpeed
  },{
  duration: 200,
  easing: 'easeOutQuint'
  }).dequeue();
  }
  // Move left
  if (keyLeft && !keyRight) {
  $('.player').animate({
  'left': '-=' + playerSpeed
  },{
  duration: 200,
  easing: 'easeOutQuint'
  }).dequeue();
  }
}
The handleKey functions listen for both WASD and arrow keys, but I've trimmed vertical movement. Later, I'll add a listener for firing bullets here. In calculateInput(), you can see how the player element moves by changing it's left position based on which key you press. The duration and easing give the movement a smoother feel. You can try out different timings and easings to find one that works for you.

The last call to deQueue() is important. When a key is down and the animation is called, it gets called each frame that the key is held down. At 30 frames per seconds, an average keystroke would send 4 animation calls. These animations stack (queue) until each call has completed, and the player element will keep moving long after you've stopped pressing the key. By dequeueing the animation, the 'next' frame doesn't have to wait to process, and your player will handle more like you'd expect.

In the next post, I'll get bullets and destructible enemies working, and start setting up the navbar,

8.13.2015

Let's make a game together.

I've recently started putting together an idea for a new game. I've also wanted to make time to do some writing, so why not do both? This is going to be the first part of a longer series about developing a browser game with Html5 and AngularJS. Most of it will serve as a way for me to keep my thoughts and ideas together and work out problems. We'll learn how to do this together.

First, here's a list of all the ideas I want to contain in this project:
  • It's a roguelike-ish dungeon crawler, run on JavaScript and drawn to the canvas. Player data can be stored on Firebase.
  • There will be multiplayer elements, but wont be a 'multiplayer game'. There will be a common lobby for all active players to trade and sell items, but players will be dungeon crawling alone.
    • I like the idea of possibly/randomly finding another player's corpse with their loot.
    • Maybe have 2 chat channels. One for the lobby, one for global chat. Or, at least add player-to-player messaging.
    • Put a shop in the lobby, but markup the prices. 
  • Dungeons are procedurally generated, increasing in size, difficulty, and reward with depth. There's a LOT of room for creativity here, in terms of adding things to be generated.
  • Loot is also randomly generated. All equipable items (weapons, armor, boots, helmet, accessories) can be randomly enchanted or cursed. There should also be sets of unidentified items.
  • Players will have some basic stats to manage, but once they die, they lose their stats, inventory, and level progress.
On one hand, it's kind of a lot of stuff to work out. On the other hand, most of it will be generated content, so it's more a matter of making a couple really good generators first, and tie them together with a good UI. Granted, that's still a huge oversimplification, but those are going to be what drive this game so it's a good place to start. In the next post, I'll start setting up the project and outlining the general flow and design of the game.

7.07.2015

Revival!

It's been far too long since I've posted an update to anything here, but I should start getting back into the habit.

So where has all the time gone? Work, mostly. All of this was just something I could mess with in my off-time, and when that dried up so did this. No further updates to Omni, or the Tower project, but I'm not completely empty handed.

After years of meandering, I'm finally making a push to change my career and make this stuff my primary focus. Last fall I found Codify Academy, attended, learned, and graduated earlier this year. Web development is a bit of a shift from game development, but I ended up with an affinity for JavaScript which can help me do both. As such, this blog is going to be more focused on general development, and whatever I happen to be working on.

And that's not all! Along with my github repo expanding, I also now have a portfolio and a working app called Conclave (currently in open beta). Conclave is my first big project since finishing the Academy. It's a social platform built for the Academy, so mentors, students, and alumni have a central place to talk, share code, help with questions, communicate, and collaborate. It's built on AngularJS and Firebase, and will be a common topic on here as I talk about the ins and outs of how it works (and how to make your own!).

Feelin' good to be back.

- r.h

4.25.2014

The calm after the storm.

It's been well over a year since the last update, which is just terrible. And for that year, a whole lot of 'not much' got accomplished with Omni. So what happened?

  • Unemployment, so all my free time went into job hunting.
  • New job, so free time got focused on that.
  • Marriage, which takes a LOT of planning.
  • Honeymoon planning, which is to be expected.
  • Holiday stuff, which is always a mess, regardless of planning.
  • Finally the year rolled over, and I found the time to actually work on the game.



I had also made a self-imposed rule that I wouldn't post here again until I had something to show for it. I've been working pretty solid for the last couple months, so here's what I have so far:

  • A menu skeleton, complete with functional buttons.
  • Re-Re-Re-Re-Optimized Unicycle, Bicycle, and Big-Wheel vehicle models
  • The start of a brand new Character Controller
  • A rigidbody version of the Unicycle, that is (mostly) self balancing and has some movement.
  • A github repository
  • A potential partner, as a friend of mine may be able to lend some time and help with the core coding.

So what then now? Hopefully, more frequent blog updates. Some about actual game progress, probably a few how-to posts with some code snippets, theory, I dunno. I plan on writing up a proper post in the next day or two about the movement module I cobbled together (Spoiler alert: it's a simple and common idea, but not exactly intuitive). 

In the mean time, here's a little something.
Unfortunately, I don't have a splash image, or even a logo.

1.19.2013

This woulda been part two.

Part Two to the previous entry (regarding the animation dilemma) is long overdue. In fact, it went long enough that the problem sort of worked itself out. Partly. There's still a matter of practical implementation (actually doing it and making it work), but so far my current method of problem solving is working out alright. I basically keep looking at it, reading books and articles, watching tutorial videos, scrapping and restarting, and then eventually everything starts working. Then I scrap it once more to have a good working version.

Since the last entry, I've redone the Unicycle 4 times and it'll probably need at least a couple more fixes to get it just right. I was working on doing a whole custom Controller, Motor, and Camera scripts but I got the stock scripts working pretty well. Unity upgraded from 3.5 to 4.x now, and it's given me a few new things to play with and learn. One of those new things is improved scripting, and it works right out of the box so far. I'll have to tamper with the camera controls, but the vehicles actually move pretty well so far.

One of the other nice things about the new Unity is it comes with Mecanim: an animation studio. I've not had a chance to try it out yet, but it looks pretty extensive. There's a good chance I'll use it instead of the stock Blender Animation studio, but who knows. Lately, I've been more concerned with getting the controls working at all to worry about the model animation.

Another nice thing happened, Adobe Photoshop CS2 is now free to download and use for everyone! The way I understand it, it's too old to install properly on 64bit systems so Adobe dropped support for it, I guess to dissuade people from buying it. Anyway, supposedly there's an easy fix to install it on 64bit systems, so now I get free Photoshop to use. I really wasn't liking Gimp.

Here's where I stand now. Actually seeing it laid out is sorta disappointing, but not disappointing enough to stop me.


  • Unicycle Model is complete. I fixed the Blender -> Unity conversion problem, redesigned the UVMaps so people can do custom textures easier. The Tire-Treads UVMap needs to be redone, but it's functional as-is. 
  • The Bicycle Model rough draft is done, but needs to be redone from the ground up. The shape is alright, but it needs to be made a LOT more efficent. Then UVMapping, then texturing. 
  • The controls actually work. The model faces the right direction and moves like it's supposed to. No animation is attached yet.
  • A very very simple test level is set up. The platforms are simple enough that they can be created, moved, retextured, and manipulated in Unity on demand. 
  • Music software is ready, but I'm still looking for better options. Still need to get a usb-to-midi cable and do some sample loops.
And that's pretty much it for now. The next thing to work on is getting the camera to move the right way, setting the speed/drag/friction settings for the vehicle, and expand the test level a little. Then I'll look into animation. After all that's squared away, I'll work on redoing the bike, getting it set up, and see about adding sound and/or music.

The next entry is going to be about fixing some of the Blender to Unity bugs I've run into, because it was damned hard to weed through the internet to find the answers I needed. They seem to be common issues, and I want to just lay out the answers very plainly for anyone else that's having them.

12.12.2012

Decisions, Decisions Pt.1

Prologue: This is Part One of a bigger issue. It was originally one long post, and has since been edited for brevity.

I've had a new issue come up. Maybe issue isn't quite the right word though, quandary sounds like it might be more accurate. I need to make my models animated, there's two different ways to do it, and I'm not sure which one is the better choice. Unfortunately, it's not as clear cut as it sounds. Both have bigger implications further than 'do the animations, save, and apply'. The issue at it's core is whether the animations should either be

* Done in Blender, then imported to Unity, or
* Done entirely in Unity, by way of scripted events

Normally, this is a matter of personal preference; whichever program you're more comfortable in is what you use and you get roughly the same result. The result I'm looking for is controlling the way my models move in various situations: specifically I need an idle state (doing nothing), walking (moving slowly), running (moving fast), and death/respawn. This particular situation has an issue with what happens after you do the animation; how do you handle the movement and physics of these objects? This changes depending on which way you go, so let's just look at both cases individually to see what happens.

Animating in Blender, Importing to Unity
Animating in Blender is a little convoluted to explain, but pretty straightforward to do. In the animation window you select what frame you want to end at, position your object(s) at the beginning, reposition them how you want them to end up, and Blender does the rest. It's called Linear Interpolation, and the easiest way to explain it is that Blender measures the position, rotation, and scale of the object at the beginning and end of the sequence, then changes all the values linearly to turn State 1 into State 2 over a set amount of time. You can take it a bit further and change the Bezier curves too. Those are the "line" part of "linear"; it's a visual way to see how the changes move over time. For example, if the beginning is 0% and the end is 100%, maybe you want it to dip up to 110% right before it settles at the end. You can do that!

Rest assured, there's several dozen horizontal lines going on here. See all that stuff on the left?

Curves can get tricky though. Each possible value has it's own curve you can alter. That means for each object (the unicycle, for example, is 11 objects), you can alter Location, Rotation, and Scale for each of the 3 axes. There's also transparency, diffusion, shaders, and a few other traits that can all be changed in animation. If you're keeping count, that a minimum of 132 possible traits to be altered for an animation for a single (simple) object. If you were doing an entire scene, not only do you have to keep track of however many other multiple objects in the scene but also the camera, lighting, and the headaches involved with staging the scene properly. Thankfully I'm not, and most of my animations will be pretty simple.

Give it a little flourish!

Now let's skip ahead a bit and assume I've got my unicycle's 4 animations done and ready. Once I go back to Unity everything will be there waiting for me. All I have to do is write some scripts to say 'if this is happening, play this animation', then make sure they all work. A little fine-tuning later, and that's pretty much it.

It doesn't lurch forward yet, but look at it go!


Animating in Unity through scripts
This one's completely different, obviously. I still have to tell it 'if this is happening then do this' but I have to specify what 'do this' means. Like with most scripting problems, there's a dozen or so different ways to do it, but I only know one or two. Here's a (very dirty) quick pseudo mockup of what 1 animation state would look like for a "running" unicycle:

if (getButtonDown == "Right") {
   xVelocity = vehicleSpeed + xVelocity;
   if ((xVelocity > thisSpeed) && (xVelocity < thatSpeed) {
      gameObject.wheelAssembly.rotate (0, (xVelocity * 3.60), 0);
      gameObject.pedalLeft.rotate (0, (xVelocity * -3.60), 0);
      gameObject.pedalRight.rotate (0, (xVelocity * -3.60), 0);
      gameObject.yFrame.rotate (0, ((xVelocity / 10) * 3.60), 0);
      gameObject.yFrame.transform (localX + (xVelocity / 15), localY + (xVelocity / 15), 0);
      gameObect.seat.transform (localX + (xVelocity / 12), localY + (xVelocity / 12), 0);
   }
}

You can see sort of what's going on here. If the player is pushing 'Right', then increase speed. If the horizontal speed of the object is in a certain range, the wheel assembly rotates around, the pedals rotate backwards (to stay parallel to the ground), the frame tilts and lurches forward, and the seat moves to match the frame. Since this is being written from scratch, I can make it as versatile as I want. I could probably get the walking and running animations under the same set of conditions, I can change the values to fit whatever I need to on the fly (as opposed to going back and forth between programs testing values). I can also use this as a template for vehicles later. Copy, Paste, change a few variables around, and my next vehicle is animated and ready to go too. It takes a little more creative thinking to solve, but could easily save a lot of time.



There is a common issue to both choices though, and that's trying to make the animations and their physical movement line up properly. The appearance of sliding around just looks bad, as does awkward wheel-spin. While a big part of that is just tweaking the animation so things match up, an equal amount is handled by the physics in the game itself. That's for the next section though; it has it's own pair of choices to decide between.