Circular Tetris

Mouse with scroll wheel



This is an implementation of Circle Tetris we all designed two weeks ago, and I finished implementing this week. It took a party of friends coming to my apartment to motivate completion. It does pretty much everything Tetris should except have Tetrominoes themselves, that is pieces composed of multiple blocks.

Game mechanics: The current game play mix is optimized to begin at a slow speed, increasing until the max speed, which happens each block touches the bottom, and is fairly quick maxing out at the fifth block. While this may seem a bit too fast, I deliberately chose this speed to make it somewhat challenging, otherwise it is too easy. When I was selecting the sound effects, I rejected about 20 different sounds I tried until settling on the current free ones – they needed to sound like a “satisfying” BOOOM OOMPH for landing, and SNAPPY CLICKS for rotation. Actually I still haven’t settled on a ring clearing sound – I’ll take suggestions. Adding random colors increases the difficulty somewhat, but negligibly — really it’s just one color purple that to me seems to blend into the background too much.

Implementation: This was completed with the utmost jam mentality, in the sense that it was rapidly completed as rapidly as possible with as many shortcuts as I wanted. Overall my code structure isn’t too terrible, visible here on my github, however it’s all in one single file (BAD!/GOOD!), uses magic numbers liberally such as 0 means no blocks, 1 means blocks, 11.125 means the offset in degrees necessary for base rotation, and so on. But with just a dozen or so such instances, out of 500+ lines code, I think overall it’s still quite readable to the layman coder. It took me 6 hours to get the basic descending blocks mechanic working, and a few more hours to make the outer ring disappear.

To the more novice coders: Can you understand how a 2D array is used to represent this game? It’s quite easy. Think of it like a spreadsheet of 0s and 1s representing the positions of blocks. If a 1 is present a block is drawn. But how can that be applied to circle? Well — just imagine wrapping each column around the circle. So x-axis wraps along the circumference, and the y-axis extends out the radius. One issue I had that slowed me down was I kept mixing up my index order. Since it’s declared private int[][] gridActiveBlocks; oftentimes x would be first, and y second. But since it’s designed backwards I got confused sometimes debugging.

gridActiveBlocks = new int[13][];
for (int i=0; i<gridActiveBlocks.Length; i++){
gridActiveBlocks[i] = new int[16];
}

The rest is calculated with simple trigonometry we were taught in highschool around grade 10, just plain old SOHCAHTOA. When you think about it, every possible position about a circle can be represented with triangles. The base rotation is 11.125 degrees, and every column requires an additional rotation of 22.5 degrees. These numbers are easily derived from knowing a full circle is 360 degrees, and there’s 16 columns.

a22.5 a11.125

To the more experienced coders: Dante suggested different data structures such as doubly linked lists but it just seemed like work for no reason to when simple vanilla 2D arrays with potentially hedges could do the job. Ultimately to solve one problem he switched my data type to jagged arrays instead — I had to refactor my function names and logic placement a bit for my code to still make semantic sense, but it was his fastest way of solving my problem. I still used enumerations and Dictionaries. I have to admit I’ve become a fan of inlining, I’ve learned to use it now specifically in cases where I have a high degree of confidence that code won’t screw up, because debugging inlined code just a disaster waiting to happen. I also found it essential for fun gameplay to implement coroutine to speed up the sound execution of the swoosh significantly, called with StartCoroutine("Swoosh"); Without that the sound effect was disastrous, it would only play once during a whole bunch of clicks / rotations.

ss

Evolution:


What’s next?
Well, I’d like to implement a leaderboard that stores everyone’s scores on our website, and lets people enter custom name acronyms. That would be pretty cool and the ratio of work-to-showoff value seems like it’ll have a good payoff, so it’s high on my todo list. I could use suggestions for SFX for when a ring clears, I’ve found nothing satisfactory yet after browsing for an hour solid just SFX: my inadequate search terms and lack of sites hinder my progress. I’d like a separate mode selection for this as-is deployed now, as well as a version with all Tetronimo shapes: Z S L J O I T. Mere icing on the cake features-creeps include: pausing, scalable fonts, touchscreen playable, contiguous-color deletions, flashing colors before deletion. The fonts need to be based on percentages, not pixels. Thus it’s necessary to learn how to implement Unity Skins though, which should be easy enough. All of which I’d love to develop, given the right motivation i.e. teamwork with someone enthusiastic about coding those with me. Just contact me and ask!

Credit:

  • Daria Anikanova: game concept
  • Dante Camarena: for embracing it with his usual passion
  • Morgan Brandt and Jordan Sparks for the art asset creation
  • Ian Nastajus: all coding of this Unity implementation

Videos:

Latest http://youtu.be/vKyGzxgiszk, and a recent but older build here: http://youtu.be/amEUBZ6Bh-U

 

Code:

The code is available here on the GitHub repository.git_sml Feel free to download, experiment with making changes, learning how it works. And we’d love to see what you come up with.

Nastajus

About Nastajus

Recommended resources -- Moderate coders benefit from this: http://unitypatterns.com/ -- Intermediate version control: SourceTree -- Beginner version control: Github for Windows or Mac

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>