disckitty.ca/gallery/code/cs488

CS488 - Assignment 1


We were required to implement the GUI of Tetris, while at the same time getting used to OpenGL syntax, and basic interactive methods (eg. rotation, scaling, etc). I extended this by having bevelled blocks, and creating 3D text for score keeping.

We were given a basic blue screen, and a couple of polygon triangles floating in 3-space to identify where the corners of the tetrominoes game *cough* tetris game were expected to to be located. With a quick couple of for-loops, I drew some wire frame lines to find out where all the cubes should be.

In Fine 328, I discovered that I really like to play with lights, and see how the different light influences the scene. Likely, it allows me to more easily depict whether or not something looks right. ie. If I know the shading should be correct, and it looks wrong, then something in the scene must be wrong. This becomes particularly apparent if you've got normals facing the wrong way, and half the image is incorrectly created. So, after some trial and error, and finally getting the hang of OpenGL's counter clockwise ordering of vertices on a face, I finally got all 6 sides to a box renderable. However with the light tossed in there, it immediately looked wrong. Turns out, one needs to tell OpenGL where the normals of a face are facing, else I guess it assumes all normals face the viewer.

It'd be about this time that I added in all the functional menus.

  • File: Basic actions
    • New Game - starts up a new game
    • Reset - resets the well orientation, and stops things from spinning
    • Quit Game - duh
  • Draw: Drawing settings
    • Wireframe - just the outline. Coloured as with face colouring
    • Face - faces to the blocks. Each piece has its own unique colouring.
    • Multicoloured - faces to the blocks. Each face on each block has its own unique colouring. (No accidentally randomizing to the same colour for me)
    • Bevel - added in. Adds a bit of dimension to the otherwise flat & boring blocks
  • Lighting: Turns lighting on/off
  • Buffering: Turns double buffering on/off
  • Game: Extra features
    • Pause - suspends game play
    • Speed Up/Slow Down - adjusts block speed
    • Auto Increase - automatically increases the speed after X rows are cleared
    • Keep score - shows the current score of the game
  • Help: Basic help & about items.

Course, I didn't add the game play options until after everything else was done, and I was bored. :P

Once basic lighting and blocks were in, I thought it was time to be rotating the scene. All the rotations are controlled by the mouse (game play - moving the blocks withing the game well - is controlled by the arrow keys). We were required to have some sense of 'gravity' --> if the mouse is still moving on release, then the object should keep spinning/rotating, with no change in speed over time, until the mouse stops it, or the rotations are reset. This was slightly tricky, as I needed to keep track of whether the mouse was still moving on release. I think I performed a quick hack to determine if it had zero velocity on release (ie. tracking the previously mouse motions prior to the release). This seemed to work out alright.

With the ablility to rotate, it was time to connect up the front end to the back end game engine. With a timer grabbing incrementing the game state, and the key inputs giving signals about how to affect the piece, all we had to do was render which block was in what square of the grid. No, we didn't need to adjust the logic of the game, and I didn't as I felt it was fine (though on reflectoin, I may have created a better randomization mechanism, as it always started with the same ruddy pieces each time... boring after testing tetris countless times.

With the basic face colourings in, I added in multicolouring (annoying to figure out what goo combinations of colourings would be, to ensure they're all distinct, especially with the light affecting the colours such that with the light on, sometimes the colours didn't look unique. In other words, I tried to choose unique colourings for each face. Unfortunately, with the light on, they sometimes didn't look as distinct from one another as I'd hoped. After severe tweaking, I decided it was sufficient, and moved onto more fun things. (Note: later, when I was working on my extensions, I noticed the fellow beside me, henceforth known as 'graphics boy', and significantly later descovered to be called Jason, had the most incredible multi-coloured system. Lights were rotating around, and the blocks were shimmering and the each face was itself a blend of multiple colours. At the time, I had no idea how to do that! About one or two assignments in (joint with CS798 - particularly with the isohedral tilings), I figured out how he'd done it. Not so hard to specifiy a colour at each vertex really...)

Fun things being bevelled blocks (make the blocks look more block-like). Actually, bevelling reminded me that faces have unique normals (ie. the lighting looked wrong), and a quick hack allowed for easy calculations (the use of GL_NORMALIZE, and combining the basic left/right/up/down/front/back normals of the adjacent faces to the glNormal command). Further, and finally, I spent until the early hours of the morning of the due date creating the numbers 0 - 9, and letters C, L, O, R, S, E, V in order to do some basic score keeping. 3D letters were created, as I couldn't figure out how to easily load in letters, and eventually determined it was too early in the morning to think smartly, so brute force would be the method of choice. I also added in an alpha-coloured (yeah alpha transparency stuff - just as much fun as working with lights) "start line". Twas a fun assignment I thought, and good for getting used to OpenGL.

Last Updated: January 14, 2008 - 12:46 AM (pro) (wood) (c) disckitty.ca