Welcome to Part 2 of “Making a Rainbow in ScriptCraft”. Take a look at Part 1 below if you haven’t already and them come back here. If you’re read Part 1, you can download the script by clicking here.
Approaches to Drawing the Rainbow
You might imagine that drawing a rainbow is just drawing a series of arcs, one inside the other. If you do that though, you’ll probably find that there are gaps between some of the arcs. Look at the diagram here:
The red circle fits perfectly inside the blue, but there are little gaps between the red and the green circles. Gaps won’t look brilliant in our rainbow so what can we do to avoid them?
What we can do is to scan across every single block that’s going to be in the rainbow and figure out what colour it should be based on how far it is from the centre. If we did that in the diagram above, the overall shape would be the same, but the little gaps would be red or green instead of empty. This is the approach our script takes.
If you’re interested, Walter Higgins uses a different technique in his built-in rainbow function. Run it and see: starting from the outside of the rainbow, he draws arcs a little thicker than he wants, and lets the ones inside them intersect a little bit. It’s more efficient (in terms of run speed) than my approach, but maybe not quite as flexible.
Array of Colours
At the top of the script, there is an array of colours. An array is a special type of variable that holds more than one value at a time.
// Colours for the rainbow var colours = [blocks.wool.red, blocks.wool.orange, blocks.wool.yellow, blocks.wool.lime, blocks.wool.lightblue, blocks.wool.blue, blocks.wool.purple];
The first item in the array we can get with colours, the second with colours and so on. Conveniently too, we can use colours.length in the code to know how many things are in the array without having to assume it’s always going to be seven. If you wanted to edit the script so it read:
// Colours for the rainbow var colours = [blocks.iron, blocks.gold, blocks.diamond];
It would still work and give you a three bar rainbow made of iron, gold and diamonds. Cool? I think so. Hopefully this helps convince you of how convenient arrays can be.
Credit where it’s due: I borrowed the rainbow colours from Walter Higgins as he’d already gone to the trouble of figuring out which MineCraft colours were closest to the classical rainbow colours of red, orange, yellow, green, blue, indigo and violet. No point re-inventing the wheel! [Ok, I did come up with my own first and then discovered he’d done it better but whatever…]
The script contains two functions. The main function rainbowk and a second function called get_block. Why? The simple answer is, it’s a lot neater; easier to read and easier to understand. You never have to use more than one function, but if your code gets long and complicated you’ll eventually lose track of what is going on unless you break it up into simpler chunks.
The function rainbowk is the one we call from inside MineCraft and it’s the only one added to exports. It takes two arguments – the inner radius and the bar thickness. Inner radius decides how wide the inside of the rainbow is and bar thickness determines how wide each bar is. It scans over all blocks in the rainbow, one row at at time and from the ground up. At each block it calls get_block to figure out what block at that position should be.
The function get_block isn’t exported, so we couldn’t call it from inside MineCraft, but we can and do call it from inside rainbowk. It works out how far the block we are considering is from the centre of the rainbow, using the technique discussed in Part 1, and decides what the block type should be. The block type will either be one of those from the colors array if the location is inside the rainbow or blocks.air if outside the rainbow.
I showed the script to my nephew who attends CoderDojo Athenry in the Scratch Beginners group. He wanted to know what the “biggest” one he could make was. Well, there is no actual biggest but he decided to make a pretty huge one. He specified an inner radius of 50 blocks and a bar thickness of 12 blocks. For those wondering what the total width of that is, it’s this:
Two hundred and sixty eight blocks wide! It’s half as tall, so 134 blocks high. The total number of blocks inside the rainbow is 268 x 134 = 35912! It took about three quarters of an hour to build 🙂
Here it is utterly dominating a village! It was hard to get this much in the screenshot and keep a sense of scale 🙂
Thanks to everyone who’s read this post. Hopefully you’ll download the script and give it a try. I’ll be delighted to answer any questions on it at next Saturday’s session or indeed at any CoderDojo Athenry session in the new year.