Software design principles and software structures in the IT Systems Development Life Cycle

This blog post will explain the role of software design principles and software structures in the IT systems development life cycle. It will also explain the importance of the quality of code that includes the readability, robustness, efficiency among other characteristics.

Stages of Development Life Cycle:

There are 8 known stages during the software development cycle; these are as follows (in chronological order):

  1. Determining the problem scope
  2. Gathering the requirements
  3. Writing the specification
  4. Designing the solution
  5. Coding and design
  6. Testing the program code
  7. Writing the documentation
  8. Reviewing and maintaining the solution

These 8 stages together form the software development cycle from the initial finding of the problem, to the maintaining of the solution, be it by the primary developer, or by someone alien to it through the use of the documentation created. This 8 stage model can easily be implemented into a development cycle such as rapid application development, spiral model, or waterfall model.

Scope – Stage 1:

The first stage is to determine the boundaries of the problem. By first figuring out the scope of the problem, you can effectively start thinking of what the solution will have to interface with. The problem scope includes the core problem, as well as all other issues that may arise due to the problem, even if it is a long connection link between the causation of the issue. If the creator of the solution is unable to fully understand the problem, or not take into account the entire scope of the issue, then their solution could potentially break other parts of the system that were working previously. If it is a new solution being built from scratch then they should also take into consideration on future advances/upgrades within the system so that during the maintenance stage minimal work is required to upgrade the system.

Gathering Requirements – Stage 2:

Once the solution scope has been determined, it is then necessary to gather all the desired requirements. This information is usually gathered from the body that currently has the problem with their system. This document is not very technical, as it should cover what the solution should do in layman’s terms, as a brief over view of the underlying problem, and the requirements for the final outcome. There are various ways to gather information, this includes questionnaires, interviews, and through observation.

Questionnaires is an effective method of gathering information from a client relating to simple questions regarding the issue and possible solution. The questions listed will often be fairly simple, either “yes” and “no” answers (closed questions) or offer some degree of opinion for the input (open questions). A questionnaire is an effective manner as it can gather mass amounts of results in a short time. Questionnaires however only provide limited information, to gather more information rish material, an interview could be taken place.

An interview allows a much more indepth analysis of the problem, and gives the opportunity to gather information on how the solution should work, this includes input methods processing and the output methods that the solution should provide. An interview can be made with one person, or within a group, and can also get the opinions of both the managing director who has the problem, while also gaining the opinion of the lower tier workers who handle the data. This is a benefit as it gives a better understand and specific requests on how the solution should handle the problem. An interview can also provide an open discussion with the technical board who originally setup the system that needs a solution.

Another method of gathering information is through observation of the current situation where the problem occurs. This allows the obsever to see errors in the system as they take place realtime, documenting them which will provide better understanding of the problem, and also aid in the designing of the solution to create a more efficient solution. The observer may also be able to look at current documents related to the problem such as examples of input to be processed and the output produced, which can be used to compare and contrast in the design of the new input and output methods.

Specification – Stage 3:

The next step is to start writing on the specification. The specification is a technical document that covers the specific desired outcome of the solution, as well as how the software is to run and interact with the user/other interfaces. This document usually accompanies with the requirements document in stage 2.

This document will include exact specifics of the solution, and is used as a mark-up scheme to determine when the solution is complete. The document can potentially hold a limitless amount of specifications of minute detail (which is to be advised when creating the document) including what the solution is to be able to run on (operating system/hardware).Whether the solution is to be cross platform between UNIX/Windows, the hardware limits such as CPU speed, available RAM and disk space.

Naturally software should be written with efficiency in mind; however when there are limits on hardware, extra care has to be taken so that these limits are kept without bound. A classic example is when older systems have small amounts of RAM, and the desired outcome is to operate on a file larger than what can be stored in the RAM, then the solution would have to be able to break up the byte code of the file into small enough chunks to fit in the RAM to operate on. The same can apply to the processing power of a CPU in the specification, often more lower level programming languages are to be used to capitalise on processing power, removing dependencies on the system such as the CLR (common language runtime) which requires more resources to run a solution written in (for example) Java or C#, where as if the solution is to be written in C/C++ (or in some cases assembly) then more resources of the system can be used for the solution.

Other factors that should be taken into consideration during the creation of this document are the time limit and financial costs. A solution should be able to be made around these boundaries, and also allows the developer to make clear priorities on the separate tasks within the solution. Common practice is for a programmer/team to create an elements list that contains all the tasks to produce a solution, and then assign each task a complexity value, and work on the hardest/most time consuming task first, then work down through the list.

Other parts of the document may include a data input dictionary and a data processing dictionary. This part of a document is usually a tabular structure that shows a variable name, what type of value that variable will hold, what the format of the variable is, and the value if it’s the data input dictionary, or a process instruction for the data processing dictionary.

This following table is an example of a data input dictionary:

Identifier Name

Data Type

Format

Value

user_input_conductor_id

Character

 

 

user_input_ticket_type

Character

 

 

TOTAL_STATIONS_CENTRAL_LINE

Integer

 

24

STATIONS_CENTRAL_LINE

Character

 

*LIST OF TRAM STATION NAMES*

MINIMUM_FARE

Real

2 Decimal Places

0.25

OAP_FARE

Real

2 Decimal Places

0.00

INPUT_CHAR_LIMIT

Integer

 

30

INPUT_CHAR_LIMIT_NUMBER

Integer

 

5

 

This following table is an example of a data process dictionary:

Indentifier Name

Data Type

Format

Calculations

adult_cost

Real

2 Decimal Places

no_of_adults * no_of_stops * ticket_type_value

number_of_oaps

integer

 

number_of_oaps + 1

stops_travelled

integer

 

user_input_station_destination_number – user_input_station_departure_number

young_children_cost

Real

2 Decimal Places

( ( stops_travelled * YOUNG_CHILDREN_FARE ) * ticket_type_formula ) * number_of_young_children

children_cost

Real

2 Decimal Places

( ( ( stops_travelled * CHILDREN_FARE ) * ticket_type_formula ) + MINIMUM_FARE ) * number_of_children

Both these tables share the same variable names to create a direct correlation and help understand what variables mean and how they are to be interpreted in the solution.

Solution Design – Stage 4:

Designing the solution is a crucial element during the creation. The design can be done in a variety of ways, and can be understood/created by a party that does not need to know how to program, as long as their design is logical and efficient, the programmers are able to decipher the design and translate it into a working solution.

There are limitless types of designing a solution, although the most popular types of design are through flowcharts or Jackson structure diagram. These 2 design techniques can easily determine the hierarchy and structure of how the solution should be programmed, providing clear relationships between differing components and scopes that reside within the problem. It can also be used to solve design problems before programming can even begin.

With efficient design, it can be used to allocate tasks to certain team members/programmers that are more situated for the job. For example this type of encapsulation can be used to allocate a task of database querying and entry to some one more experienced, while another member is able to work on the algorithms. As both programmers are working from the same solution design, their work can be merged together easily.

Below is the example of a Jackson structure diagram:

 

Below is an example of a flowchart diagram:

 

Coding – Stage 5:

Once the solution design is complete, work can then commence on the programming of the solution. The solution should be professionally programmed to be sufficient for the solution. This includes making sure that the specification is strictly followed and that all the inputs and outputs are valid and accurate. Not only should the program work, but it should also contain fail safes within the source code to prevent against errors such as illegal user input, making sure that the program does not crash or potentially corrupt any data already on the system which may be irreversible.

The source code itself should be of a satisfactory quality in the sense that other programmers in the future are able to modify/append to the solution to accompany any new requested features or bug fixes. This quality can be assured that the source code follows basic standards such as robustness, efficiency, reliability, usability, portability, maintainability and readability; all of which will be discussed later within this document.

Testing – Stage 6:

Testing the solution for bugs within the code is a vital point within the solution development cycle. It is a key stage where the program should be vigorously tested for errors, and to deliberately try to crash the program, or make it behave in a way that is not desired/intended. It is common for a majority of bugs to be tested during the previous programming stage, as the programmer is compiling code; errors are bound to show up. Depending on the integrated development environment (IDE) there are various tools at the programmer’s disposal to fix bugs within their code. Such features include breakpoints, tracers, and variable watching.

Breakpoints allow the programmer to explicitly stop all execution of a program once a certain line of source code is reached. This allows the programmer to jump into the source code during program execution and probe at variables on the stack to check their value. They are then able to run each statement line by line to determine where the exact error is being generated from. During this line statement by line statement interactivity, they can then trace calls within the program to understand the exact functioning of the program. This tracing is useful to follow the flow of code, and variables being passed.

Outside of the IDE however, testing for bugs within a program requires a more vigorous approach; this is the stage that is commonly referred to black box/white box testing. This type of testing is done by creating a table listing of inputs at a specific location within the program execution, the desired outputs, and the actual outputs. Black box testing can be done by anyone, as they do not need to know the actual inner workings of the program itself. The test strategy includes going through each location within the program testing it multiple times with a wide range of input types to report back to the programmer to fix, potentially increasing the robustness of program when they are fixed. For example when the program asks for a name, the individual testing the application should try inputting various entries such as their actual name, a numeric value, blank text, an exceptionally long string of text, special characters, among other inputs, and document what happens to the program after each input. This document is then passed back to the programmers to implement a fix for the issues. The programmer should decide on an appropriate course of action to fix the bug, it is common that some input bugs (such as only requesting a 7 character length of numerals) can be fixed by implementing an out of range exception if any more or less digits are inserted, and requesting the input again.

Below is an example of white box/black box testing:

Test No.

Test Purpose

Test Data

Expected Results

Actual Results

Action

1

Check if 7 digits is a valid ID.

1234567

Valid ID, accept and continue Accepts input and continues  

4

Check if 7 non digits are valid ID.

abcdefg

Invalid ID, decline and request again Declines input and requests again  

5

Check if name in for format “A.Aa” is a valid name.

J.Sharpe

Valid Name, accept and continue Accepts input and continues  

10

Check if name in for format “*.*” is a valid name. where ‘*’ is a special character.

:.@#{}&

Invalid Name, decline and request again Declines input and requests again  

11

Check if date day is equal to 1 or more, and less than or equal to 31

11

Valid date day, accept and continue Accepts input and continues  

12

Check if date day is equal to 1 or more, and less than or equal to 31

-30

Invalid date day, decline and request again Declines input and requests again  

 

Testing for bugs can potentially take an infinite time scale, so it is important that bugs are properly prioritised, such as program crashing being top tier, while small problems such as GUI alignment are lower tier.

Documentation – Stage 7:

There are 3 types of documentation that are to be created after the solution is made. These are:

  • Internal documentation
  • Technical documentation
  • User documentation

The internal documentation is implicitly expressed through the source code itself. This is done by the use of appropriate variable, function names, including well commented sections on what each function does (briefly). The common rule of thumb in source code comments is to document why something is being done, as opposed to how it is done. This is because the source code itself shows how something is done, but why that method of choice is made is unknown unless a comment on why is present. There are also other factors to take into consideration such as indentation, and following the house style to aid in the reader to understand the flow of the source code; this will be discussed in further depth later within this document.

Below is a code snippet showing how comments can express what is happening within the code:

Selec All Code:
//Calculate the relevant costs for each individual on the bus.
 
young_children_cost = ( ( stops_travelled * YOUNG_CHILDREN_FARE ) ) * number_of_young_children;
 
children_cost = ( ( ( stops_travelled * CHILDREN_FARE ) ) + MINIMUM_FARE ) * number_of_children;
 
adults_cost = ( ( ( stops_travelled * ADULT_FARE ) ) + MINIMUM_FARE ) * number_of_adults;
 
oaps_cost = ( ( ( stops_travelled * OAP_FARE ) ) + MINIMUM_FARE ) * number_of_oaps;
 
//The above variables will be used in the display of the receipt.

 

The technical documentation is focused for future developers of the solution, so that they can understand all the clear works on the program itself. The following should be included within the documentation:

  • Purpose of solution
  • User requirements
  • Input, output and processing requirements
  • Test plan (white box/black box testing)
  • Solution design (flow charts, structure model)
  • Hardware and software requirements
  • Class schemer
  • Complete source code
  • Future recommendations

Technical documentation is vital for another team of programmers to pick up the project and carry on with work fluently. This not only reduces production times, but also makes sure that everyone new to the project can also get onto the same level of knowledge as to what is to be expected. The technical documentation can also be used by system admins and engineers when installing the solution, making sure that everything is setup correctly and that all components are compatible and adjust current configurations to fit the solution.

The final user documentation is designed for the end user, who may not be as technologically knowledgeable on the solutions inner workings, and only needs to know basic installation, how to start the program, and over view on how to use the program effectively. This includes:

  • Instructions on how to install
  • How to use the program (including screenshots)
  • An explanation of error messages
  • Contact details for technical support

Maintaining – Stage 8:

The final stage of the solution is to review it and maintain it. The reviewing process is just a matter of evaluating the solution, comparing it to the initial user requirements that were documented during the requirements and specification stages. Ensuring that all the criteria are met and that the program is working as planned within the intended system. The reviewing stage is also an opportunity to document potential improvements to the code for a future release.

Maintaining the code is an on-going task that has the time span of the entire solutions life time. It involves, not only fixing future bugs that are found, but also manipulating the code to work with new future hardware/software upgrades on the system that the solution interacts with. Maintenance does not necessarily have to be done by the original authors of the solution, as the technical documentation will also be available at this stage.

Readability of code:

The readability of code ties into multiple areas, more importantly for the internal documentation and the maintenance stages. As mentioned previously, source code can have an increased readability by using basic techniques such as applying indentation, appropriate variable names, following house style, and commenting the source code.

Code should initially be written to be self-explanatory, reducing the need for comments. This can be done by declaring explicit variable names, that is human readable and that can easily be translated to what the value of that variable may hold. A simple example is for each for loop, use a variable called counter which is the iterator value that gets updated every run through the loop. It is common to see this variable be called something such as “i”; however this does not convey a meaning in the code to a human reading it at a glance.

 

Another technique is to not abbreviate variable or function names, unless of course it would break up human readability. When source code is compiled to machine code, the variables name can no longer be extracted. This can be achieved by breaking up words with an underscore like so:

 

Selec All Code:
                int station_departure_number;

 

With the exception of the variable name:

 

Selec All Code:
                int number_of_oaps;

 

Where an unabbreviated version would be:

 

Selec All Code:
                int number_of_old_age_pensioners;

 

Which could arguably be considered an unnecessary long variable name.

However in some cases such as in scripting languages, it is common to have 2 versions of source code. One version being the fully documented copy, and another being minified and compressed. This is very common in JavaScript files that the end user of a website downloads. As they do not require all the comments and full length variable names. Take for example jQuery [http://jquery.com/], a JavaScript library containing many functions for developers to use. There is a minified version that is 32KB file size, used for publishing, and a development release of 247KB which contains all the same functionality, however has more meaningful variable names and comments.

By applying indentation to source code, it also improves the readability, specifically for the quick determination of where a scope ends and begins. Take for example this generated image that highlights different scopes with different colours, each new scope is given an extra indent:

 

It is visibly clear through the use of indentation the scope of various statements. Rather than if all the source code was written on the same vertical line.

Making sure the all programmers within the solution also follow a particular house style, allows each other to easily look at code and instantly decipher it. This keeps consistency with source code for when reading it.

Quality of code:

The quality of code can include a range of characteristics, although the most important aspects of the code are to be robust, efficient, reliable, usable, portable, and maintainable.

Robust, efficient, and reliable can all fall into the same category when writing source code. It is vital that the program being created is not prone to errors, faults, and can be relied upon to produce results when being run. The robustness can be determined through test cases on trying to deliberately crash the program in any possible way, and then to fix any of those bugs. Common problems could be allowing illegal input which could corrupt memory of the application within RAM, which in turn holds a high chance of problems to occur when that data is being accessed again.

The efficiency of source code can be determined by how much computer resources the program uses when it is being run. Having source code that does unnecessary calculations, or takes an unnecessary long time to run can be considered to be inefficient. A good example is when sorting algorithms are created. An efficient algorithm is able to sort a series of items in a time scale of O(n log n), however a bad sorting algorithm would sort the items in  O(n2) time scale; known as Big O Notation. Thus if the program was to sort a series of shipping items from largest serial number to smallest, as more shipping items are added to the list, it causes the time scale to sort it logarithmically. Some sorting algorithms will be able to sort a list of 100,000 items in just a few milliseconds, however if the source code does unnecessary calculations, the time to sort could soon increase to minutes; thus efficiency is a key factor to take into consideration during the code run time.

The reliability of the program is to make sure that the same results are to be produced every time when given the same input values. This can be tested through test cases, where an input can be given to the program and to a human to solve, and comparing the results multiple times, with multiple inputs for both the human and the computer program. This will offer high validity that the program calculates the correct values using the same algorithm used. If a program does not always output the same answer, then invalid data could be introduced to the system, which could potentially corrupt the data and worse cause, cause database errors. This is extremely important in situations such as handling finances (such as in a bank), making sure that all calculations are correct.

Usability and portability can fall into the same category. When writing a program that does the same task multiple times at different stages, it would be wise to have that task written out once, and then keep reusing it. In programming this is often called creating a function or procedure. By the creating of functions and procedures it allows programmers to divide and conquer a problem. At later dates it will also allow the portability of the code to other platforms/systems as the functions can be reused or may only need slight alterations. If the programmer does not take this into account when writing the source code then they are potentially creating a vender specific solution, which could cause problems in the future if the system ever has to change slightly.

The maintainability of code is important so that in the future, bug fixes can be produced and also extra features can be implemented easily. Although the maintainability of code is not source code specific, as it also requires clear technical documentation to be present as well. For some older legacy applications or open source programs, this is not the case as either the documentation is missing, or is not professionally created and of limited use. It is then up to the programmer to be able to decipher the source code to understand what is going on. As mentioned previously this can be easily achieved by using simple techniques such as indentation and commenting.

Android Development

I  recently got an ASUS Slider android tablet, it’s essentially a 10.1inch touch screen tablet with a slide out keyboard. This morning I gave a shot at making a small application for it. Setting up the development software was very time consuming, mostly because of all the downloads and installing that needed to be done. Things that needed to be installed included the android SDK tools, and some SDK platforms; all of which I intergrated into eclipse with the plugins provided. While they were installing I was familiarising myself with the android documentation.

Once the everything was installed and running, I created my first hello world style application. First switching my tablet to debug mode over the USB, and allowing it to install applications from an unknown source, I created my first app, and launched it on my tablet. the results are as follows:

image

A simple hello world application.

It did confuse me at first how android applications are developed, they use an XML styling approach, rather than a programatic style where everything is hand coded. My next step is to further understand how activities work, then I can make the button change the colour of the text.

C++

Well I’ve started college and we’re learning C++. So recently I’ve been playing around creating many toy applications to get to grip with the language. What I particularly enjoy about the language is that it’s so easy to compile code for on the go. Compared to when I made simple games in C# using XNA, I needed to have Visual Studio installed on the machine along with XNA framework and if I wasn’t making games, I needed the .NET framework to make C# applications. However with C++ I can carry code::blocks around on a memory stick and be able to compile a program on any computer.

I’ve only being toying with the standard library, and like a good boy I try to avoid limiting my programs to one platform (windows) by not including the windows.h header. I still don’t completely understand how the standard library files are laid out, and don’t know a fraction of the available members I can use, but I guess that only takes time.

For a bit of content in this post I give you a simple pyramid ascii maker program. Input a number and it outputs a pyramid of “*”.

image

The source code is very simple, just getting the number of lines as an input, then using string.append() to format the pyramid.

Selec All Code:
#include <iostream>
 
using namespace std;
 
int main()
{
    int numberOfLines;
    int numberOfSpacesMade;
 
	string stringInject;
 
	cout << "How many lines to create: ";
    cin >> numberOfLines;
 
    numberOfSpacesMade = numberOfLines;
 
	for ( int i = 0; i < numberOfLines; i++ )
	{
		stringInject = "";
 
		stringInject.append( numberOfSpacesMade, ' ' );
		stringInject.append( ( numberOfLines - numberOfSpacesMade + 1 ) * 2, '*' );
 
		cout << stringInject << endl;
 
		numberOfSpacesMade--;
	}
 
    return 0;
}

C# Dev Blog

Well I haven’t updated in a while, but that doesn’t mean I haven’t been unproductive. Instead of jumping back into the game with a new design, I went back to reading C# 4.0 Pocket Reference, and I’m learning more syntax tricks and functionality of C# I didn’t think was possible before. So I plan on finishing the book, then re-reading it.

I don’t have any new content relating to my game, however I do have a slight treat, since I started programming again I’ve compiled my own little (big) list of bookmarked pages on a whole range of subjects. To save time I just opened it up in bookmarks viewer and saved it as a html file. You can view it here.

XNA Game Dev Blog #7

As I expected, I didn’t get round to do ANY coding today. However it has been a rather educational day for me. From yesterday I talked about how my code is getting a complete mess, and that I should refactor it, so I’ve been looking at a few sources today. 1 Website I was reading through was the MSDN library on XNA Framework Class Library. When I first saw this just shy of 2 weeks ago, I had nearly no idea what was going on. Looking back on my moving car, I was just guessing what methods to use based on looking at other peoples code and reading a few tutorials. The MSDN was just loads of jibberish, and that all I ever used it for was to see if I’m using a method right. So today I started looking through the XNA framework, and lots of it made sense since I’ve played around with most of the methods in SpaceShooter. I also came across this blog post, where they have created class diagram images of the XNA framework, very handy to flick through and see how everything is interlinked.

The second main source I was looking at was the source code of Net Rumble from the App Hub catalog. I chose Net Rumble to look at because it has distinct features that are similar to my game. Both have ships, move around, lasers/projectiles with upgrades, and collision. What I learned from Net Rumble, after looking at how the game works (which I’m still looking into), is that parts of the code have their own Draw calls, and LoadContent, something I thought that could only be done from the main game file, and how XNA games progressively loaded content such as the next level was some form of black magic. After cross referencing how Net Rumble is written, and looking back at the MSDN library, it’s all starting to make sense how they did it.

So today, I’m starting to learn how the XNA framework works, and how to take advantage of it all, (if not all then some of it). Also that class diagrams are brilliant to see how code is structured.

As for content for today, is my class diagram of my SpaceShooter:

As you can see, not very clear to understand what’s going on. It also shows just how bad the Game1 class is getting. It may be a while before my next blog post, but hopefully it will be about finishing the code refactoring.

XNA Game Dev Blog #6

Today I got round to adding explosions to the alien ships, as well as adding a semi upgrade to the ship. Other things done is the background shifting slightly with the player movement. Look pretty cool and a lot better than previously just having the background scroll along the Y axis.

My code is starting to get messy again, and I’m in desperate need to get it all organised again before I work on anything new. Everything up until today my code was reasonably manageable. Then when I added explosions, more code riddled into the main Game method for the creation of the animations when an alien ship is destroyed. Then when I added upgrades more functions came into the main game file with the collision checking, and setting new values of what the current upgrade the player has.

What I need to do is make a way for the player to call the add laser method by itself rather than the main game method, that way I can push most of the code onto the playership class. It would also help if I found a way to use the Draw method outside of the main game file too, however I’m not sure that’s possible. I’ll have to look into some examples on the App Hub Catalog and see how some of those projects do it. I wont be adding anything else until I sort my code out though, other wise I will seriously regret not doing it later on.

Here’s a video though of the current build:

 

Once I do refactor my code however, I plan on doing a list of things:

  • Add all upgrades (including the sprites that go on the playership visually)
  • Add more aliens (different size, different health, perhaps ones that fire lasers back)
  • Add a HUD of current health, scoring and general updates on the game (like what upgrade you picked up)

Later down the line, and probably the last thing I will do is create the menu screen, options, highscores etc.

XNA Game Dev Blog #5

Well I got animations working, both looping and non looping. It was surprisingly easy. All I needed to do was create a rectangle bound of the current section of the texture I want to draw, then every iteration where current game time – past game time > next frame, add on the sprite width to the bounds X axis. Here’s another animated gif of it working: Left is a non looped animation, right is looped.
This is the animation sprite sheet used: I put a red border on the edge of each sprite. 64×64 for each section.
You’ll also notice that the alien space ships move slightly different to previous posts too. A lot less predictable than before, for the better. Implementing the current objects to have animations is rather simple too. The animation class derives from the baseObject class, and if needs be I can just make my current object classes inherit from the animation class, add in the extra arguments and it’s done; everything will still work as before.

 

The next task is to add explosions for when a ship blows up. Then perhaps upgrades. After that probably move onto extra enemies, then scoring.

XNA Game Dev blog #4

To follow on from yesterday’s post, I got a bit done today. I got round to making the lasers and collisions collide with each other after playing around a bit. I also changed the playership slightly, to give it less of an advantage. I removed the side large cannons, of the ship and plan on making them an upgrade option. So now the ship looks like this to start with:Had a slight epiphany while I was doing the collision detection. Originally I was doing:

Selec All Code:
1
2
3
4
5
6
7
if  ( laser.pos.x >= alien.pos.x & laser.pos.x + width <= alien.pos.x + width )
{
	if  ( laser.pos.Y >= alien.pos.Y & laser.pos.Y + height <= alien.pos.x + height )
	{
		//Collision detected
	}
}

This code looks very messy and is so easy to make an error in the logic, and even harder to find it. So instead what I did was create 2 Rectangle objects that represent the bounds of the alien and projectile, then checked if they intersect, like so:

Selec All Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
for ( int i = 0; i < projectiles.Count(); i++ )
{
	for ( int j = 0; j < aliens.Count(); j++ )
	{
 
		if ( projectiles[ i ].Active && aliens[ j ].Active )
		{
			Rectangle rectangle1 = new Rectangle( ( int ) projectiles[ i ].Position.X, ( int ) projectiles[ i ].Position.Y, projectiles[ i ].Width, projectiles[ i ].Height );
			Rectangle rectangle2 = new Rectangle( ( int ) aliens[ j ].Position.X, ( int ) aliens[ j ].Position.Y, aliens[ j ].Width, aliens[ j ].Height );
 
			if ( rectangle1.Intersects( rectangle2 ) )
			{
 
				//aliens[ i ].Active = false;
				aliens[ j ].health--;
 
				projectiles[ i ].Active = false;
			}
		}
	}
}

If I can find a way to post code to a blog that doesn’t mess up the white space formatting and maybe has syntax highlighting for C# I’d paste the actual code. But until then here’s the current solution file for you to view the code yourself. Some classes aren’t used and I’m sure some things could be done better.

Small “error” that started bugging me for a good 30 minutes is the movement. While developing this game I noticed that for some reason, I could move in an angle by pressing the up and left arrow together, and same with down and right, and every variation in between. However when I implemented the shooting with the space bar, I was able to move up and right while shooting, but not up and left. I spent ages looking over the code for some syntax error, until it dawned on me that I’m developing on a laptop. This might not sound like an issue at first, but my laptop’s keyboard is recognised as a PS/2 connection, which if you’re familiar with one for gaming, does not support multiple key press detection as a USB one would. To prove that it was indeed the laptop that is causing the error, I plugged in my old logitech G11 USB keyboard and played the game, and as expected, movement was perfectly fine!

Here’s a small animated picture of the current game in action though:

Next to do is add animations, although for this I’ll have to create my own animation class to work through a sprite sheet at a set speed. I’m worried that if I create these animations I may have to redo a bit of my current drawing code of the baseObject class to support it and keep things modular. I’ll do explosion animations first and then see what I need to do to get the animation class to work with my current objects on the screen such as the player and alien ships. I may not add animations for the lasers as they are so small anyway and fly past the screen.

There’s no set objective yet, or scoring/ending of the game, the aliens just keep respawning and you have to keep shooting. Also there’s no collision between the aliens and the player ship.

Here’s a download link for the current solution though.

XNA Game Dev blog #3.1

Talking about my previous blog post. I searched around a bit and found it I can change/disable the colour key, by just right clicking on the image, going into properties and disabling the colour key. This will save me a lot of time recolouring the images. Here’s an image of where to disable it, highlighted orange:

XNA Game Dev blog #3

Well I spent most of today re-doing all of my code. Now it correctly supports deriving from classes. Before I just had a class for each object, each one was self contained, until today I finally learned the correct way to create inheritance with classes. I created my baseObject class, which has just the 2 basic functions as of now. The constructor function which has parameters for the viewport, texture and position and then the draw method which is just a basic spritebatch.Draw(texture, position, Color.White);

Doing all of this recoding has made the game so much more easier to work with, and I’m getting very comfortable with the C# syntax. I finally got shooting of lasers done (although no collision detection yet). While playing around with the shooting, I thought it would be a good idea to be able to cycle through your weapons that you want to fire, rather than firing everything all at once. The way lasers are done is when the space key is pressed down, it then checks if the player can shoot (if x amount of seconds have passed since the last shot) then adds a new instance of the laser object to a List. The List is the only reference point of the laser object, and will also make it easier looping through all the lasers to draw/update and soon check for collisions. Not only this but it will make it easier removing the laser object as I just have to call the List.RemoveAt() method, (correct me if i’m wrong) removing the reference point, passing it onto the garbage collection.

Funny error I came across when testing out the alien ships, the pink colour I used in the original alien ship, is the colour XNA uses to mark as transparent. So upon drawing the aliens only part of the ships were showing. As seen in the below image:

So now I’ll have to recolour the alien ships. I still have to add the flame effect back onto the player ship for when it’s moving forward, hopefully try get it animated as well. I will probably do the same for the lasers, as right now you can’t really see them, so I may play with sprite effects later. But first I’m going to get the game to a playable state with an actual goal. Then to start re-organising my code and making it more efficient which I should have really done while I was coding it all.