Category: Articles

Let’s make some noise! (and grids, and mazes (in HTML5))

This is just a little fun one. If you’ve seen randomly generated noise maps, or those mazes that are different every time you hit refresh, and wanted to know just how they work, then hey, i’m guess i’m here to show you. You’ll also learn a few basics about generating grids too.

That last one is probably the takeaway here that you’ll need the most. Grids show up in programming all the time, and i’ve rarely seen good explanations of them. Maybe there’s some good central location that everyone else uses but no one ever pointed it out to me. This is also a good intro for programmatically generating art. We’ll start with some basics for today’s lessons, and then set up something a bit more comprehensive later.

Prerequisites

Basic coding knowledge. You should know if/else statements, for loops and functions. You don’t necessarily have to know html syntax but it’ll help.

Making Noise

We’ve all seen random visual noise in some form. It’s the term we use for that weird cloudy static stuff.

TV adjustment needed

To achieve this effect, we need to do the following:

  • Create a grid.
  • Create a function that goes through each space of that grid.
  • In each space, decide at random whether to mark it as a white space or a black space.
  • In each space, mark the appropriate space.

That’s it. Doesn’t seem so hard, does it?

Let’s get Started.

If this is your first time playing with HTML5, take a quick moment to head over to the starter page to setup your canvas. Takes about a minute. See you in a mo.

First off, let’s get a few properties up and running.

const canvas = document.querySelector('canvas')
const c = canvas.getContext('2d')

canvas.width = 2048
canvas.height = 1152

const tileSize = 1

Nothing too special here. The top two canvas lines are requirements to get the script file speaking to the canvas in the way we want. We’re creating the noise on a 2d plane, so we want to ensure we’re constantly referring to it. That const c will allow us to do that.

The canvas width and height is going to determine the size of our noise field and eventual maze.

The tilesize is what it sounds like. The size of each tile in the grid. Each tile will be a square, so only one value is needed for width and height.

Next we’re going to create three separate functions that will help us create the noise field.

function Vector(){

}

function CreateTile(){

}

function CreateGrid(){

}

And at the bottom of all of that, we’ll have a method to the last function. This little line basically tells the rest of the program to start working (make sure it sits by itself and not within any of the curly brackets).

CreateGrid()

Let’s add to each of the functions one at a time.

Vector()

function Vector(){
return {x: 0, y: 0}
}

The Vector function is a lot simpler than it looks. It’s just used to store two values and then return them. We’ll be using this function when we’re creating the tiny lines that will make up our noise map.

Each line will have two points to it. A starting point, called lineStart, which has an x and y coordinate, and an ending point, called lineEnd, also with an x and y coordinate. These four values will allow us to create a single line using HTML5’s built in drawLine function.

We’re talking euclidean vectors here. Point A has an x and y value on the chart, as does point B. This determines magnitude. The order we use them determines direction.

CreateTile()

Next up comes creating each tile within our grid. We’re not really so much creating a tile in the grid at the stage. It’s more we’re reserving a point in the grid to print out a single tiny line, which will be one tiny spec in our noise field. CreateTile has three parts to it, and it’s doing most of the work, so it’s best we go through each bit one at a time.

Dump the following into the CreateTile function.

const randomNumber = Math.random()

if (randomNumber > 0.5){
} else {
}

The first property (the randomNumber bit) does exactly what it sounds like it’s doing. Each time CreateTile is called, a random number between 0 .0 to 1.0 is called. It remembers this number to choose an action using an if/else statement.

Now we setup creating the lines.

const lineStart = new Vector()
const lineEnd = new Vector()

lineStart and lineEnd are two vectors created by the Vector function we made a moment ago. With these two vectors you’ll be able to make any line. Let’s create one now. Here we’ll be making a Backslash (\) type of line. Put the following between the curly brackets if the randomNumber if statement

if (randomNumber > 0.75) {
    lineStart.x = tile.x
    lineStart.y = tile.y + tileSize
    lineEnd.x = tile.x + tileSize
    lineEnd.y = tile.y
}

Whoa! Take a moment if this throws you off. I won’t deny seeing something like this took my brain out for a moment the first time i saw it. Let’s take a moment to break down each line.

lineStart.x = tile.x

This is the first part of the first vector we called earlier. If we think of it on a graph, this is the x value of where you want your line to start. Don’t worry about where tile.x came from for now. That will show up in the CreateGrid function shortly, but it’s purpose will be to tell the line where on the grid it should be drawn.

lineStart.y = tile.y + tileSize

This is the same as the x coordinate. Remember we’re making a backslash here, so we add the tileSize to the y coordinate.

    lineEnd.x = tile.x + tileSize
    lineEnd.y = tile.y

These two lines cover the opposite point of the tile, which makes sense since it means we’re going top left to bottom right. Each tilesize has the same width and height, so we can use the tileSize value regardless of which axis we’re using.

For this example, assume x and y equal zero, and tileSize has been set to one.

Got a general idea of it? Good, let’s add a forward slash to that else statement.

else {
    lineStart.x = tile.x
    lineStart.y = tile.y
    lineEnd.x = tile.x + tileSize
    lineEnd.y = tile.y + tileSize
}

This sholdn’t require too much extra explanation. The lineStart Vectors denote a point in the bottom left. The lineEnd Vectors denote a point in the top right. Together they make a forward slash.

Then we just need to draw the line. Dump the following after the else statement.

c.beginPath(); 
c.moveTo(lineStart.x,lineStart.y);
c.lineTo(lineEnd.x,lineEnd.y);
c.stroke();

These four little methods are the standard HTML5 for drawing a line. Each part should be self explanatory and we only need to use these the once so we don’t have to worry too much about this.

CreateGrid()

Pop the follow into your CreateGrid function and let’s go through it a bit at a time.

for (let i = 0; i < canvas.width; i += tileSize) {
    for (let j = 0; j < canvas.height; j += tileSize){
        const tile = new Vector()
        tile.x = i
        tile.y = j
        CreateTile(tile)
    }
}

The two for loops here are how your grid will be create. Notice that the second statement of each for loop refers to the canvas width and height, and that the third statement refers to the tile size. The loop starts at the top left (essentially zero), creates a column of tiles the total of the canvas height, then moves along one row on the grid and creates the next column. It repeats this until the width of the canvas is reached.

Next we call a new Vector called tile. Since it’s a Vector it has an x and y that can be returned. We can use the i and j values in the for loop and set them as the x and y values. Why you ask? Because we’ve been incrementing the for loop using tileSize, meaning everytime i and j are incremented, they’re now set as the next part of the grid. If your tile size was set to four, they would go up the grid as 0,4,8,12,16… This simple grid lets us create perfect grids every time with a lot less coding.

After this, it’s just a case of using the CreateTile function with our tile vector. Now when create grid is called, it uses the tile vector as its reference point for drawing the appropriate line.

Good to go.

Let’s run that code and see what we get.

Not bad. We made some noise using nothing but our words. We could probably make it a bit noiser though. Let’s add some more types of line to our CreateTile function. Replace the current CreateTile with the one below.

function CreateTile(tile){
const randomNumber = Math.random()
const lineStart = new Vector()
const lineEnd = new Vector()

if (randomNumber > 0.75) {
    lineStart.x = tile.x
    lineStart.y = tile.y + tileSize
    lineEnd.x = tile.x + tileSize
    lineEnd.y = tile.y
} else if ( randomNumber > 0.5 && randomNumber < 0.75){
    lineStart.x = tile.x
    lineStart.y = tile.y
    lineEnd.x = tile.x + tileSize
    lineEnd.y = tile.y + tileSize
} else if ( randomNumber > 0.25 && randomNumber < 0.5){
    lineStart.x = tile.x
    lineStart.y = tile.y
    lineEnd.x = tile.x
    lineEnd.y = tile.y + tileSize
} else {
    lineStart.x = tile.x
    lineStart.y = tile.y
    lineEnd.x = tile.x + tileSize
    lineEnd.y = tile.y
}
//drawLine (lineStart.x, lineStart.y, lineEnd.x, lineEnd.y)
c.beginPath(); 
c.moveTo(lineStart.x,lineStart.y);
c.lineTo(lineEnd.x,lineEnd.y);
c.stroke();
}

Again, don’t panic if that looks complicated. We’ve added three things. First, we’ve added some else if statements to allow for more types of lines. Before, there was a 50/50 chance between two types of noise. Now, there are four types of noise, each with a 25% chance of being used for each tile.

Next we’ve added two new types of line. The first is simply a vertical line. The second is just a horizontal. Why not try mentally mapping one using the chart below.

Now refresh the page and see how your noise has changed.

If you’ve gotten lost in the code somewhere, here’s the complete script for you to steal.

The noise is now grainier than it was before, getting it closer to that old television static look.

And now for the big reveal, because, as some of you may have already guessed…

You’ve been creating a maze all along.

You may have been suspecting it with the backslash and horizontal lines, but the noise we’ve been creating is actually a really big maze with really tiny walls.

Don’t believe me (geez)? Try changing your tileSize variable at the top of your code from 2 to 24, and then refresh the page again.

There you go. One maze, or rather, infinite mazes. It’ll change each time you hit refresh.

Now technically, these aren’t true mazes. There’s no start or end point, or even a definite correct solution. We’ll add that in another time. This is more Maze art.

Playaround

The whole code is in place now. Feel free to add to it. You could try changing the size of the tiles or canvas, change the random number probability to make some lines more likely than others. You can even try adding more types of line if you’re up for figuring out some more complex paths. Have fun and let me know what you think of this tutorial in the comments below.

Setting up HTML5 in, like, five seconds

Intro Intro words words scroll down until you get to the instructions you’re actually looking for (i know why you’re here :).

As long as you have a web browser like Chrome and a notepad editor, then you’re already setup to use HTML5.

To run things on a html canvas, you need the following:

An index.html file

A Javascript file

You can make these without installing anything.

Open up your notepad editor. I recommend Sublime Text but if you just want to get started, you can use the default text editors.

  • Windows users: Click on the Windows icon and type Notepad
  • Mac users: Open up TextEdit through the Finder

Save the empty text file in the folder where you want your project to be. Click File > Save As and name the file ‘index.html’. Ensure you remove the .txt part

In the new index.html file, copy and paste the text below:

<body>

<canvas></canvas>

<script src=index.js”></script>

</body>

Click the drop down to change it from a ‘Text Document’ to ‘All files’

Save the file.

Next, create a new text file and use Save As to call it ‘index.js’ (again removing the .txt part).

That’s it. That’s everything you need to run your HTML5 program. Now, whenever you want to run your program, you just need to drag and drop the index.html file into your web browser, and it will automatically run (if you do it now, you’ll get a blank screen, because we haven’t added anything yet).

A few extra things worth mentioning

While we’re here, that is.

Troubleshooting

When working on a program, mistakes are basically mandatory. You will always make some. Your web browser has a feature for detecting these and telling you what’s gone wrong. You can access it by right clicking the space where your program runs and selecting ‘Inspect’.

This will bring up the developer console. By default it will bring up the Elements tab, which will show you your code. If you click on the Console tab, it will show any errors that the program is trying to tell you. The most important part of these is usually the line number, telling you on what line of the page you can find the error, allowing for much easier correction.

SublimeText

I recommended it earlier, and i’ll do so again. Using a powered up text editor will allow you to access your code a lot easier. If you’ve downloaded it already, follow the steps below.

With nothing else open but Sublime, click File > Open Folder

Locate the folder where you created your index files earlier and then select Open Folder.

Sublime will open your folders up across tabs, meaning you can easily switch between the two at anytime.

If you need to expand the number of files in the folder, Sublime will update accordingly, so you won’t have to worry about finding them.

Why make games in HTML5?

I’ve been playing with HTML5 recently, and pretty impressed with what it can do. I’ve been making games in things like GameMaker and Unity for years, but always felt that, for all the tools that come out of their respective boxes, both systems can have some pretty impressive limitations.

See, i’ve made Games!

That’s not fair. It’s not that they’re limited. It’s that they’re uninformative. You can have several games under your belt made through either system and still be totally clueless about really simple mechanics. Until recently i had to admit i had no real idea how movement mechanics work, or even colliders, even though i’ve being using both for years.

That was the problem. I had been using them. I hadn’t been making them. In fact there was a lot of functions and techniques and general practices that i had just ‘been using’, but very few i had actually made. And hey, i have this blog, why not use it to chart my course of learning some real basic stuff that i should have learnt years ago. If i’ve screwed up learning these basics, then i bet there are other script kiddies out there who have made the same blunder, so if any of this is a help to you, i’m more than happy to help correct your course a little bit.

HTML5

If you’re used to Unity or Gamemaker or even Construct 3, then you may have gone through your game making journey using less code than you thought. It’s great that it’s possible to make games without using a single line of code, but it become should become clear pretty early on that code is vital to get what you want. Even if you are spending most of your days in the code mines, you may still find yourself copying and pasting most of your work and then tweaking the bits you may need to tweak until it works. One of my own personal sins is stealing the code from youtube videos or github repositories, and then just hitting it until it works the way i want it to.

Don’t get me wrong. There’s nothing wrong with borrowing code and adjusting it to make it work with the system you’re creating. It can help with a lot of problem solving and critical thinking skills that are vital for becoming a programmer. But one thing you don’t tend to get from a lot of tutorials is the actual knowledge behind them. For me, i know it’s more a case of ‘that’s the answer i need, copy and paste it into my work’ with little chance of the required knowledge actually sticking in my brain. I may have learned something, but it was more how to find the answer, rather than how to build the answer.

Working in HTML5 helps a lot with this. HTML5 is capable of running 2D and 3D games, but you have little to none of the tools that come packaged with something like Unity. You get a few helpful draw and animate style functions to get the canvas working, but that’s it. Everything else – colliders, triggers, animation cycles – you’ll have to build these yourself, and that’s great. Finally, you get to figure out all those things that ‘just work’ for yourself.

On top of this, HTML5 is already for you to use. If you have a web browser, you already have it. You just need a notepad application of some sort. I recommend Sublime Text. It has code autocomplete, tabs for different files and an easy browse system, as well as tons of other nifty features that i really need to learn at some point.

What’s the advantage of all this?

I mean, why bother right? If programs like Unity just allow you to Add Component > 2D Box Collider, then why bother learning how to build one yourself? It’s not like we need to know literally everything that a computer does.

First of all, some of us like to learn stuff we’re never going to use.

Second of all, it can be important to learn how a tool you’re always using works, because maybe that tool isn’t always going to work for every situation you need it for. Maybe it’s useful to know how that tool works so you can recreate a minor variant. Unity’s colliders are very robust, but there’s a few outside the box situations that might call for you creating a collider of your own.

Finally, there’s going to be a day where you want to create a game that doesn’t rely on something like Unity. Maybe you want to go back to basics and create something in Pico8. Maybe you want to publish a game and not have to give Unity a share of the profits. Maybe you figure it’s time to start using Godot. Suddenly, things work differently in the different system, and you’re thrown for a loop that this other language seems to insist you know how to create an animation loop. It’s better to be prepared for that sooner rather than as you fumble through the program trying to find the ‘do it for me’ button.

Let’s get started

So i hope some of this is useful for someone somewhere. Leave a note in the comments if there’s something you want me to cover, or just let me know what you think of it all so far.

Success

What is it with the brain’s heuristics? Shortcuts are great and all but it’s like it’s the brain’s ultimate goal to eventually be able to do nothing and to do it the most stubborn, insufferable way possible. Hell I can make it do nothing with a knife and about thirty seconds of searing pain followed by an eternal silence. That way seems a lot easier, were my goal be to accomplish the apparent ultimate thrill of pure nothingness.

But that’s my brain’s goal. My goal is… well, I guess that’s hazy. Defining your terms when it comes to success seems obvious. This is what I consider to be success, and I shall be successful once I have reached these terms. Simples, right? Yet here I am, lolly-gagging and procrastinating over that simple idea. What is my definition of success? How do I reach it? I’m basically repeating myself here. Maybe it makes me sound more clever than I actually am. Maybe I’ll fool myself into thinking I actually am successful. Maybe the success was inside of me all along, right next to the sandwiches i ate earlier.

Yes. Let’s follow that delusion. I am successful. Why wouldn’t I be? I have a house (under a mortgage). I have a car (sold to me used at just over a thousand pounds along with some uncertain rattlings less than fifty miles later). I even have a girlfriend that I didn’t have to pick up at the local internet. Yes, I am successful. I must be right. There are people in other countries, people even in this country, that would kill to have these things. Literally murder people. People have died over a pair of shoes (citation needed). If I own things that are worth more than a pair of shoes, I should be able to measure that as some kind of success, right?

Right?

What else? I have a good job. Pays me over twenty thousand English pounds a year. I assume that’s good. I mean I’m not a millionaire but I’m in a position where I can put money aside at the end of each month, just long enough for me to watch it quickly disappear shortly afterwards when something else goes wrong. It’s in IT, one of the leading industries. I’m respected in my workspace, enough that people come over to me to ask for favours and advice all the goddamn time. I must be doing something right if the senior managers come to me to ask me for stuff, right?

Right?

I have an adorable cat. She’s staring at me right at this moment, , rolling on her back and waiting patiently for me to fuss her endlessly, as is her only desire in life beyond snatching my hand at an unsuspecting moment and digging her claws in.

Speaking of cats, I have a great family. I’m not making my own, but my parents are great and my sister does okay I guess and she keeps making more nieces and nephews for me to play around with. I also have lots of cousins and aunts and uncles and other people i sort of know who can apparently tolerate me at get-togethers.

What else? Hobbies. Yes. I have hobbies. I’m kind of eclectic when it comes down to them, but writing, drawing, video games (playing and making), keyboard, house decorating, masturbating, gardening, exercise, jogging, martial arts, electronics. I have lots and lots of hobbies and they keep me entertained/distracted for hours at a time. So many in fact that I’m probably forgetting to list a few. Adventures and traveling. Those as well. I do it all. I’m about to take up water skiing, and I’m going to take part in the Wolf Run in a few months time. Maybe you’ll see me there. I’ll be the one at the back.

But I guess this is all more stating what I do and what I have. Do these make me successful? Some view obtaining these as a measure of success. And I suppose if I didn’t have them, maybe I would too.

But I apparently don’t. I do at times. Those lucid but deluded moments where I sit happily and contemplate how lucky I am in my privileges. I mean, I can’t deny my privilege. I’m white, British, male, I suppose middle class, heterosexual, blond, muscular (fat). That last one is probably the only one I worked hard for. I’ve lived quite a lucky life. Being born in Ethiopia would probably make all these ramblings seem like the most amazing things ever. But I wasn’t, and they don’t.

Oh, dancing. Also, dancing.

So, in simple terms, what is success for me? I guess it’s a feeling of satisfaction. I’m a worker at heart. I like to think I’ve got a lot done. And I’m happy when I do that. To me, writing a thousand words (yes I am keeping track) is apparently a lot more satisfying to me than writing one really good sentence. Not that I don’t mind it. A single sentence sounds a lot grander than two pages of ranting. It can have more comedy value, can be more ominous and all sorts of other cools things that would get lost among a mishmash of words. To me satisfaction is exhaustion. You only know you’ve worked hard when you’ve collapsed after it and can agree you’ve done a job well good. I kind of feel satisfied with having written the last two pages in one go, even as the cat tried to paw my hand into a more fussible position.

So does that mean success is just keeping myself busy? Such a proposition feels kind of lame. I could spend hours trying to turn one large rock into smaller rocks with a hammer and consider it a job well done. I once spent an hour lying on my back with my arms raised in the air to see if I could really do it (i could). Maybe that is success. The people of the past were limited in their technological achievements yet I imagine a lot of them still felt like they had achieved something, even as they did die of polio.

But could I really be happy with deciding that my success is determined by the delusion of achievement. Again, it’s lame. I could have done the bare minimum for my entire life and then said ‘you know, I least I did it my way’ and that could somehow be considered a success. That would be stupid. Wouldn’t it? I don’t know.

Analyze anything long enough and you’ll most likely kill the meaning behind it. Maybe that’s a proof in itself. By analyzing something for an extremely long time you’ll most likely render it void of all meaning. By doing so, maybe you’re proving that all concepts are indeed meaningless. It would be a hard answer to truly accept, but maybe that’s a problem in itself. We don’t like ‘everything is meaningless’ as an answer, so we disregard it and try to find a new one. Yet if we were to analyse anything long enough and find that the answer always came back to the existence of bananas, would that seem a more tangible, if somewhat bizarre, answer and as such would be a little more acceptable? The meaning of life is bananas, and not the crazy kind. Just the simple herb fruit thing. Sure it sounds like nonsense, but we’d probably be a little more accepting of it than utter nihilistic meaninglessness.

Mind you, maybe this is all me being broken. There are people out there who probably analyse everything to an insane extent and come up with the idea that everything is God and the meaning of existence is to waste time worshiping him. I guess it’s more fulfilling than to waste time believing in nothing. At least, if nothing is all you do.

And people do do this. Overanalyse everything to come up with the answer to god that is. There’s a great YouTube video of Kirk Cameron overanalyzing a banana and pointing out how it’s shape, size, texture and ability to go rotten is proof of a great designer. He goes on to show how the banana perfectly demonstrates itself as a direct creation of god for mankind to eat. It is easy to hold, stays covered until ready to be eaten, super tasty, self disposing and even tells you when it’s ready to eat by its colour. Yes, through this analysis, it’s quite easy to come up with the idea that someone made the banana to be eaten.

which is why it’s kind of amusing to know that that’s why man used artificial selection to do it in the first place.

Getting a little off-topic, an actual banana is so bizarre to look at and be told it’s called a banana that I didn’t entirely believe it when I saw one. They’re actually kind of oval. Tough to access and apparently the pips in them are large and obtrusive when trying to devour it. The banana of today was made by humans taking the time to focus on the growth of one banana over another, and repeating selecting them until they came out a way that suited us. It’s actually kind of impressive how one can keep a hobby for several generations like that. We do it for dogs too. Still kind of hard to see why evolution deniers exist in the first place. You think they would have fell into the ‘god used evolution as a system argument by now’. Hell, even the Pope’s done that.

Success is a banana
it occurs to me that I didn’t plan to use the bananas = meaning thing and that Kirk’s banana example at the same time. I guess one just kind of led into the other

Of course, none of this tells me what success is. It clarifies it a bit. At the very least, success is a concept determined by humans themselves rather than some intrinsic concept of the universe. Jupiter does not care about your personal accomplishments and most likely neither does the man three doors down from you.

Hell, in a way I’m not even sure if success is a concept that all people desire. It seems like everyone is trying to make their way in this world. People want to become a big shot, or a player or a contender. every field has its experts that have other people pay them money to be awesome in. Success is universal to man, it seems. Dogs have it too I guess. They seem pretty happy when they’ve got the stick and been able to return it to you, or perhaps they’re only happy because they know it leads to treats. Maybe we’re all just Pavlovian devices, getting off at our ability to do tasks that the universe has inadvertently taught us are good tasks to do. Doing nothing more than following simple desires for pleasures that are then mixed in with other simple desires for pleasure. Simple desire over simple desire compounded against one another, on top of one another, merging with one enough. Kind of makes me think of sex. Hell, are not Sexual fetishes nothing more than certain desires going in a different direction to what other people think are normal. I don’t know. I’m just robbing all these concepts of meaning really. Perhaps I should stop here. I’m certainly not getting anywhere.

Perhaps success is just being better than your fellow human. I seem to remember a time when my friend showed me his blog. In it was multiple entries depicting his trips around the world. The guy likes his Germany, and several of the entries describe his life where he abandoned his current life and went to live over there for a while. He spun a few tales of odd events that happened to him and generally gave his opinions of how he felt there. And I remember actually feeling quite jealous. Not because of his adventures, but because he had taken the time to write about them. And that’s kind of what I want to do. Write about stuff. Tell stories. From his words, I felt a torrent of enviousness that made me feel that I wanted to emulate his actions and write about my own experiences. And it was around then that I remembered.

I had written six fucking novels at this point.

Why was I feeling jealous of my friend? What he did was cool, I’ll admit that. I’m not trying to rock his own concept of accomplishment, but I had done a lot more that what he had written there. I easily had several hundred thousand words out of me at that point. Yet there I was being kind of sort of jealous.
Maybe humans are just morons. Achieving greatness in one stroke and then wishing we had our friend’s ability to play the kazoo really well in the next. Maybe we shouldn’t be trying to achieve success. Maybe we should be trying to destroy our goal of accomplishing it, so we free from time wasting jealousies or this hour wasted contemplating it and writing… two thousand two hundred and five word articles on it, and can get on with doing something fucking worthwhile instead.

I’m done.

© 2024 workHate Inc.

Theme by Anders NorénUp ↑