top of page

ChimaeraMechs Post-Mortem and General Info

Overview

Gallery

Playthrough Video

Code Examples / Explanations

What Went Right / What Went Wrong

Related Classes

ChimaeraMechs is a 2D side-scrolling platformer that features a lion/tank hybrid character with 3 usable weapons, the ability to feast on your foes and then turn their energy into a stunning roar. At the current level of development it features a boss character, 5 levels and a tutorial to teach you the basic mechanics. The game is supposed to have some quick reactions to kill enemies, but is not a reflex game. There are also a few jump puzzles that if completed may result in a early upgrade to a better weapon. Completion of each level only requires reaching the end, but killing the enemies in the way will result in a higher score.

The storyline for the game can be found on the home page of this site.

There are many classes that have contributed to my overall game design technique:

Fundamentals of Game Design - This class has contributed to my ability to design throughout the years and built a foundation of basic knowledge to build upon. Having to keep in mind the game factor and what that means to the user kept this design from turning into features without function.

Introduction to Programming C# (1301&2) - These two classes built my basic knowledge of both the c# languange and the XNA framework that MonoGame is based on. My general programming language started here, but I had to build up parts of the MonoGame sound to have it work the same way the previous XNA 4.0 sound did.

Introduction to Drawing - The concept drawings done were signifigantly better than they would have been without this class. The conceptual drawings were traced to create the first draft of Leo, and then re-made when I updated the graphics to Leo. In general this class helped me with the art assets seen in the game.

Science and Fiction (STS 2400 class) - When I chose my STS class, I was able to get into the science and fiction section which featured reading science fiction novels ranging from classics like Frankenstein to more modern evolutionary based books. Some of the ideas seen in the books from this class were what helped inspired the original design of this game (along with help of a teammate).

Digital Media and Interaction - Possibly the most helpful class for this project as it not only spawned the idea of the game (although it was not used at the time), but it also honed my C# abilities to be able to produce a more intensive project than in this class with one person less. I was able to use some of the fixes to MonoGame that we had implented in this class, but still had to fix some other issues that were seen in the sound.

What Went Right - There were many features I was initially concerned with in regards to implementation. Often I was able to program the design exactly how I thought it through in my head, and it would work on the first build. This of course becomes more common as your programming experience increases, but it is always a very good feeling nonetheless. One instance of this was the ability to implement a particle system from another project with minimal editing of the code required. Not only was I able to get a dynamic flame for my hero's jump, but I was later able to re-use the particle system to create the dust trail that follows the hero. With more time I had intended to expand the particle system to include some features for the boss due to the fantastic look of a particle system with minimal effort beyond the inital class construction.

 

As is stated in the earlier parts of my updates, this project was built using the Microsft platformer starting kit as the engine. The engine gave me tools such as the text level designer, graphics animator and the physics collision. There were some bugs in the kit, and not all the features were included in the basic version that I had downloaded (such as the vertical scrolling which had to be added on). I built a lot on top of the engine, however, and learned the code for the engine well enough that I could recreate it if neccesary. When I went to fix the bugs from the kit (one of the bigger ones being jumping), the fixes ended up working well and quickly which is unlike my usual experiences with attempting to fix others' buggy code. This could have been due to the neatness of the Microsoft code, or even just due to its general bareness and my ability to add as neccesary without causing other problems to arise. Starting with some basic code ending up being very useful in the long run due partially to the tools that were also including, but also allowed me to see how things were done (correctly) in the code already and mimic them in my own functions.

 

The biggest, and luckily very successful, changes done to the starter kit were done to the hero and the enemies. In the original kit, the hero can run and jump, enemies can patrol without falling off ledges and heros running into enemies results in instant death. I was able to change this into the ability for both the hero and enemy to attack each other, do damage and be defeated. This did not require much change to existing code which kept me from changing anything that caused backlash in other parts of the code. The additional code that was added, however, did not have any issues and many of the calls already being made for the hero and enemy were in a great position to call the additional methods added. Classes that were completely new to the kit included my weapon, bullet, boss, pickups, particle systems and math library.

 

What Went Wrong - One of the first issues I ran into was that of being able to shoot at any angle. Due to my testing platform, this feature was difficult to test and use due to not using a mouse. Instead, the shooting was changed to directly in front of you, which allowed for easier balancing in the levels and enemies. I would have preferred to use any-angle shooting, but the alternative provided a better game for the intention. This of course led to a slight redesign of the game vision itself as it now became a game in which enemies must be in front of the player as opposed to placed anywhere. This led the design to follow more of a retro and simplistic design that was a good project for a semester long course.

 

Another big issue (that never was fully resolved) were the issues with Monogame + Windows 8.1 + VS 2013 and how sound worked. To get any sounds to work, they have to be converted from their wma/wav format (mp3 seemed to cause issues) to the xnb 'compiled' format. This can not easily be done and required a seperate (luckily found in my last semester) program to do the conversions. Just converting sounds, however, was not enough to get them working properly. The method for songs and soundeffects slightly differed, but the general tasks were similar. Both required both the original file and the converted xnb file to be placed into the output (bin folder) content prior to running the program. Due to debug and release mode having different content folders, the files were required in both for debug and release to run properly. The main difference in the song and soundeffect issues seemed to be that soundeffect xnbs had to be included in the project, but songs have to include the xnb and the original file (with both set to copy to output folder). When songs were made to play (using the standard MediaPlayer.Play method), they would do so without an issue, but when a song was stopped and a new song attempted to be played (such as changing of states), the first song will restart and play until completion before the start of the next song. Since most of my sound changes were done near the end, there wasn't enough time to resolve the issue or create a work around.

 

With working along, I was able to be involved in every process of the programming which was good due to my somewhat limited skills in that area compared to others at my same level. This meant that there was lots of time spent resolving problems that were relatively minor, but would take some reaserch or 'tinkering' with the code until they could be fixed. This also would often result in me not being able to spend as much time and effort on the art and design side as I would like. Many weeks I would be fixing issues until the due date and then trying to get the weekly art updates done in the last evening or two. This resulted in both not getting the time they required to be the best quality possible, but for a single developer game, I am happy with the overall results. There were some problems that I only overcame by asking for assistance (usually online but occasionally of classmates) and this often resulted in a slightly better understanding than the often quoted "Why did that work?". The constraints also limited the amount of the overall design that could be implemented in the timeframe. Many of the things left out were relatively minor, but would require art, sound and some re-do of large code areas to be considered complete. Such things include the coin pickups (which are relatively useless currently) were going to be replaced with health, roar and ammo pickups. This would have also required implementing an ammo system (and doing a minor amount of testing due to only 5 short levels being implemented). I was able to include a boss as originally intended, but was unable to put the effort into the AI that I had originally planned. The full centaur body and movement was removed due to issues with the melee enemy cutting into the time, but was replaced with a predictable up and down turret-like motion. The levels were are smaller than planned (mostly in time frame although also in physical span), but most likely would have required including vertical scrolling to make the levels more manageable to create. Luckily I was able to prioritize the features I wanted or needed and this allowed me to simplify any features I hit a time or skill constraint on.

 

Most of my 'what went wrong' boiled down to using XNA (through the fan made Monogame) which is somewhat between being phased out completely and being updated to run on the newest versions of Visual Studio and Windows. This was a software I was familiar with that helped re-expose me to the game loop based design prevelant in many common design engines. Due to the issues with XNA, I do not intend to pursue this project for my next level of Studio and will instead look towards UDK or Unity. XNA has always been an easy way to get 2D onto the screen quickly with the power of the C language behind it. Now that it has become less effective in producing release quality games at the same standard as most indie companies, it is also becoming less used. By using Unity or UDK, I hope to still be able to make 2D games when I want to, but with a graphical implementation that compliments my design style much better than text lines of code.

  1. The first code sample that I put a good amount of effort into was my boss'es triple shot ability. The ability itself fires 3 projecticles from the bosses position with the middle projectile firing straight ahead and the other 2 firing at 30deg above and below the middle projectile. I knew this would require some trigonometry and I graphed the image to make sure to clarify it all in my head.

            public void TripleShot()

            { 

                arrow1pos.X = arrow2pos.X = arrow3pos.X = pos.X - 64; 

                arrow1pos.Y = pos.Y - smallArrowTex.Height - 70;

                arrow2pos.Y = pos.Y - 70;

                arrow3pos.Y = pos.Y + smallArrowTex.Height - 70;

                tripleShot = true;

            }
    This first portion is the method that is called by the boss when the decision logic chooses the triple shot ability. The method is simple and merely sets the positions to a point hidden by the boss'es sprite and sets a boolean to prevent more than one triple shot to be active at a time.
    ​  
      if (tripleShot)

                    {

                        sprite.PlayAnimation(attack);

                        arrow2pos.X -= 3;

                        arrow1pos.X = arrow3pos.X = arrow2pos.X;

                        arrow1pos.Y -= .57f;

                        arrow3pos.Y += .57f;

                        if (arrow2pos.X < level.cameraPosition)

                        {

                            tripleShot = false;

                            arrow1rect = new Rectangle();

                            arrow2rect = new Rectangle();

                            arrow3rect = new Rectangle();

                        }

                        else

                        {

                            arrow1rect = new Rectangle((int)arrow1pos.X, (int)arrow1pos.Y, 10, 10);

                            arrow2rect = new Rectangle((int)arrow2pos.X, (int)arrow2pos.Y, 10, 10);

                            arrow3rect = new Rectangle((int)arrow3pos.X, (int)arrow3pos.Y, 10, 10);

                        }

                    }

    This is in the boss'es update method and is only called while triple shot is active. The X position is linear with a speed of 3pixels per frame and the angled shots are tied to the middle shot for the X position. The value for the Y position [.57] was what I had to calculate (and I decided to hard code it due to the limited scope of this project). The Y position is being altered by the ratio of Y:X when there is a 30deg angle between the two of them. The X positions being tied together allowed me to use tan(30deg) = y / x to solve for the Y position. This is where I had decided not to include the equation due to making only 1 possible angle and not intending to reuse the code elsewhere in the project. The idea for this code came from my original code for allowing the hero to shoot anywhere on the screen (using the Y:X ratio to determine the angle at which the player is shooting). The code following the Y position modification is first checking if the arrows should be removed from the screen (when going off the screen to the left) and if not, then creates a hitbox at the head of each arrow that matches in size to the arrowhead.

    if (tripleShot)

                    {

     

                        spritebatch.Draw(smallArrowTex, arrow1pos + new Vector2(smallArrowTex.Width / 2, smallArrowTex.Height / 2), null, Color.White, .52f, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0.0f);

                        spritebatch.Draw(smallArrowTex, arrow2pos, Color.White);

                        spritebatch.Draw(smallArrowTex, arrow3pos + new Vector2(smallArrowTex.Width / 2, smallArrowTex.Height / 2), null, Color.White, -.52f, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0.0f);

                    }
    This final portion is the draw part of the triple shot ability.with the most important part being the ".52f" and "-.52f". The overall draw call is one of the many overloaded options available with the XNA framework. The .52f is the rotation portion of the draw method and required converting the 30deg required by design into radians required by the method. I would have converted this on the internet, but  didn't have access at time and instead had to do the equatio 180 / pi = 30 / x

  2. The second portion of code that required math and effort was the algorithm used to shake the camera when the roar skill is used.

    private void ShakeCamera(Viewport viewport)

                {

                    if (shake == false)

                    {

                        originalpos = cameraPosition;

                        radius = 30.0f;

                        randomAngle = rand.Next(360);

                        offset.X =  (float)Math.Sin(randomAngle) * radius;

                        float maxCameraPosition = Tile.Width * Width - viewport.Width;

                        cameraPosition = MathHelper.Clamp(cameraPosition + offset.X, 0.0f, maxCameraPosition);

                        shake = true;

                    }

                    else

                    {

                        radius *= .9f;

                        randomAngle += (150 + rand.Next(60));

                        offset.X =  (float)Math.Sin(randomAngle) * radius;

                        float maxCameraPosition = Tile.Width * Width - viewport.Width;

                        cameraPosition = MathHelper.Clamp(cameraPosition + offset.X, 0.0f, maxCameraPosition);

                        if (radius < 2)

                        {

                            hero.isRoaring = false;

                            shake = false;

                        }

                    }

                }
    This algorithm should theoretically work in a circular motion (with a radius of 30 being the maximum distortion amount), but is only applied in the horizontal axis due to only the horizontal scrolling being included. First a random angle is decided (between 0 and 360) and then the sin of the angle is multiplied by the radius to give the overall offset (only set in X to be horizontal, offset.y = math.cos(angle)*radius). After the first iteration (when shake is false), the radius is reduced and the new angle is locked to the opposite side to prevent the shaking from getting "stuck". The shake is re-iterated until a minimum radius is reached upon which the shaking stops and the camera returns to it's original location.

Please note the sound in the video is not game music and is produced by my recording software. For all correct musics and soundeffects, please download and play. See "what went wrong" for notes on issues with the music in XNA/Monogame.

bottom of page