Developer Diary: Space Swap – On Hold

It has been a while since my last post, what happened? Well as it turns out, my SYS366 teacher was right! If your projects don’t have some constraints, then it will take forever to complete, if it gets completed at all! So the game has been on hold for a while because of multiple reasons.

The game has been on hold because Clinton and I are simply too occupied with our school work that we have very little time to develop the game. With new assignments and tests every other week, there is very little time to do anything other than school work. However, this is not the only reason the game has been delayed.

We started the game as a way to learn more about game programming so there wasn’t any constraints. We didn’t have anything holding us back like time or money. This lead to us doing what we want when we wanted which many people would love but it doesn’t work. As my SYS366 teacher said “You need to have constraints or your project will never get finished” and I understand what he means because I now have firsthand experience. With school being more important than our fun little side game, we have obviously chosen to do school work before our game. So for now, since we don’t have any constraints, the game is on hold.

Do not worry though, the game will be completed I can assure you!  With school taking up so much time I’m sure we will complete our game during the Christmas holidays. And if anyone plans on starting their own project some time make sure to have some constraints. As much as we don’t like them they are necessary if you ever want to complete your project.

Developer Diary: Space Swap – Rockets and Stars

Do you like rockets? Do you like stars? Do you like both? Well I have some special news, rockets and starts have been added to the game! Since my last post several things have been added to the game including: generated levels, the players ship, input, rockets, blocks and parallax stars! The game will be completed before you know it! But let’s not get ahead of ourselves, I should explain what the new features are. I’ll start with the input.

We have made an input class which will get the players input for the game. So far the input has been used to maneuver through the menu and control the players ship. That’s about it for the input but what about the players ship? The players ship has been added to the game so we now have a working ship drawn onto the screen. With the input class completed the player can control the ship around the screen and shoot rockets! The rockets are fairly basic right now, they simply get drawn and shoot. There is no collision for them right now so they’re just for looks but they’re still rockets and they do shoot! The next step is to make them collide with the blocks.

Space Swap Rocket

Space Swap Rocket!

The blocks are also fairly basic right now, they are drawn on the screen but there is no collision detection for them either. They’re just for looks like the rocket but it makes it easy to visualize the game. They also make it easier to see how well the level generation is working. Clinton did the level generation and it’s looking pretty good so far. It procedurally generates levels based on a seed and the difficulty. It’s still very basic but it is one of the most important parts to the game so you can expect it to be greatly improved. The last thing that was added to the game is the parallax stars.

Space Swap level generation

Space Swap Level Generation With Rockets

You can’t have a space game without stars so we added stars using the parallax method. Parallax put simply makes objects further away move more slowly than the objects that are closer to the camera. It give a false depth perception to the stars and puts the final touch to our very basic but working prototype of the game. What else is left to do?

The game is half way complete, with everything basic laid out; all that’s left to do is to improve each feature and find some actual art! That’s about it for this big update, lots of work has been done to the game and at this rate it’s going to be done in no time!

Developer Diary: Space Swap – The Beginning

Study break is here which means I finally have some free time! These past few weeks have been very busy for me so I haven’t had a lot of free time to develop a new game. This break week is the perfect opportunity to start a new project.

My friend Clinton and I were thinking about developing a game during the break to gain more game programming experience. The first step would be to figure out what kind of game it would be and how it would play. As our ambitions grew bigger, the more complex the project became. We ended up scrapping a lot of our ideas to get the right combination. We settled with a 2D side-scrolling game set in space. With the basic game idea down, we had to start adding more features and game play elements. That is when Clinton found our idea online.

Clinton stumbled upon this blog post which had a simple but original game idea. You play as a space ship that can swap colors and shoot rockets. Obstacles move towards the ship and you have to shoot them in order to pass safely. What is unique about this game is how you can maneuver through the level. You can pass through blocks the same color as your ship, since you can swap the ship colors you can maneuver through the level a lot easier. There are also grey blocks which you have to destroy because you cannot pass through, however, the closer the color is to you ship color the more damage you will to do the block. With this exciting game idea Clinton and I started to lay out a basic design document.

The design document is a very poor design document, it is meant as a rough guideline to our game. The design document is as follows

Ship Switch: a single player, multi playing field variation on the side-scrolling shooter theme.

In Ship Switch,1 Ship, 2 Colors, 1 Field. The fields are identical except  in the color and behavior of the ships within. Obstacles appear and  scroll in typical side scrolling fashion, but the player must react  differently to these obstacles based on the color of each ship. The goal  is to simply scroll through the entirety of the level with both ships  intact. The challenge is in properly reacting to the conflicting  interpretations between the two fields.

A) Colors that match the ship color are passable.

B) Opposing colors are impassable and cannot be destroyed. Contact with these obstacles kills the player and ends the game.

C) Mid-tones can be shot and destroyed.

D) Darker mid-tones are easier for the dark ship to destroy and lighter mid-tones easier for the light.

E) Special blocks could be included to increase variety, difficulty,  and depth of play. This one, for example, would switch the positions of  the playing fields. The white ship would be forced to contact the  special block. Will the player think and react quickly enough to have  the black one contact it as well, thereby canceling out the effect?

Higher levels could include:

– More playing fields

– Faster scroll

– More obstacles

– Colors

– Tougher penalties from special blocks

MapGenerator
ParticleManager
– Particle
– Bloom… (maybe)

Some basic code thrown together in the design document. Nothing here is final or correct, it is simply a basis to visualize what would be needed for the game.

Player
{
    PlayerState state;
    PlayerColor color;
    Texture2D texture;
    Vector2 pos;
    Vector2 velocity;
    private Rectangle BoundingRectangle
    {
        get
        {
            int left = (int)Math.Round(Position.X * Tile.Width);
            int top = (int)Math.Round(Position.Y * Tile.Height);

            return new Rectangle(left, top, playerTexture.Width, playerTexture.Height);
        }
    }
    Draw();
    Update();
    LoadContent();
    CheckCollision();
    private readonly MapManager mapManager;
    private readonly ParticleEmitter particleEmitter;                
}

internal enum PlayerState
{
    None,
    Swapping,
    Dieing,
    CompletingMap
}
internal  enum PlayerColor
{
    Black,
    White
}   
Map
{
    12 tiles = 32 * 12  = 384 tall
    width: 1280 / 32 = ???
     0x0 = space
     0x64-0xC8 = range of colors
     (100, 200)

}
public const int TileSizeX = 32;... same with Y
Tile
{
    float color;
    //0 for black, 0.1-0.9 greys.., 1 for white 
    //0.9 -- easy for white, hard for black
    float opacity;

    Vector2 tilePosition;
    //stores tile x and y, not actual coordinates 
}

//Game Screen size
graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;

public struct Tile
{
    public char Type;
    public TileCollision Collision;
    public Color Color;
    public float Opacity;

    public static int Width = 32;
    public static int Height = 32;
        public Tile(char type, Color color, TileCollision collision, float opacity)
        {
        // Height = texture.Height;
        // Width = texture.Width;
            Type = type;
            Collision = collision;
            Color = color;
            Opacity = opacity;
        }
    public Tile(Tile t, float opacity)
    {
        this.Type = t.Type;
        this.Color = t.Color;
        this.Collision = t.Collision;
        this.Opacity = opacity;
    }
}

With our very basic design document finished, we started to work on the game right away. As some of you may have noticed from the little bit of code above, the game will be XNA based. After a little bit of work we got base classes finished and a menu screen.

space swap menuSpace Swap Main Menu

That’s about it! Tomorrow I will start working on the player and bullets and hopefully we can get a rough working game finished soon.

Using va_list to concatenate strings

Today in class we discussed how to give a function the functionality to take 1 or more arguments.
We were asked to use va_list to concatenate many strings.
This is what I came up with.

// Coded by Jesse Santos for OOP344
// 10/17/2011

#include <iostream>
#include <cstdarg>

using namespace std;

char* concat(char* des, ...);
int main(){
  char str[100] = "Fardad";
  cout<<concat(str, " ", "Soleimanloo", " ", "this", " ", "is", " ", 
	  "how", " ", "you", " ", "concatenate", " ", "many", " ", "strings!", 0);
  return 0;
}

char* concat(char* des, ...){
  va_list args;
  va_start(args, des);
  char* str;

  while(str = va_arg(args, char*))
	strcat(des, str);

  va_end(args);
  return des;
}

Improving a queue

Just added a few things that adds a lot more functionality. If anyone sees anything wrong or would like to optimize further, please post below.

// main.cpp
// Queue
//
// Originally coded by Mike Kim
// Modified by Jesse Santos on 13-10-12
// Added clear()
// Added insert()
// Added removeAt()
// Added _size and size()
// Optimized the destructor
#include<iostream>
using namespace std;

class Queue;

class QNode{
	int _data;
	QNode* _next;
	QNode(int data, QNode* next){
		_data = data;
		_next = next;
	}
	friend class Queue;
};

class Queue{
	QNode* _head;
	QNode* _tail;
	unsigned int _size;
public:
	Queue();
	virtual ~Queue();
	void add(int data);
	unsigned int size();
	void clear();
	void insert(int data, int index);
	int removeAt(int index);
	int remove();
	bool isEmpty();
};

Queue::Queue(){
	_head = 0;
	_tail = 0;
	_size = 0;
}

Queue::~Queue(){
	clear();
}

void Queue::clear(){
    QNode* toDel;
    while(_head){
        toDel = _head;
        _head = _head->_next;
        delete toDel;
    }
    //Resets all values
    _head = (QNode*)0;
    _tail = (QNode*)0;
    _size = 0;
}

unsigned int Queue::size(){
	return _size;
}

//Adds data to the end of the queue
void Queue::add(int data){
	QNode* temp = new QNode(data, 0);
	if(isEmpty()){
		_head = temp;
		_tail = temp;
	}else{
		_tail->_next = temp;
		_tail = temp;
	}
	_size++;
}

//Inserts data anywhere in the queue (useful for adding things in reverse)
void Queue::insert(int data, int index){
	if(index > _size){
		add(data);
		return;
	}
	if(isEmpty()){
		add(data);
		return;
	}

	QNode* temp = _head;
	int curIndex;
	for(curIndex = 0; curIndex < index-1; curIndex++)
		temp = temp->_next;

	if(curIndex){
		QNode* ins = new QNode(data, temp->_next);
		temp->_next = ins;
	}else{
		QNode* ins = new QNode(data, _head);
		_head = ins;
	}
	_size++;
}

//Removes an element from the beginning of the queue
int Queue::remove(){
	QNode* temp = _head->_next;
	int ret = _head->_data;
	delete _head;
	_head = temp;
	_size--;
	return ret;
}

//Removes any element for anywhere in the queue
int Queue::removeAt(int index){
	if(isEmpty()){
		return 0;
	}
	if(!index){
		remove();
		return 0;
	}

	QNode* temp = _head;
	int curIndex;
	for(curIndex = 0; curIndex < index-1; curIndex++)
		temp = temp->_next;

	_size--;
	if(curIndex){
		QNode* previous = temp;
		temp = temp->_next;
		QNode* next = temp->_next;
		int ret = temp->_data;
		delete temp;
		previous->_next = next;
		return ret;		
	}else{
		_head = temp;
		temp = temp->_next;
		QNode* next = temp->_next;
		int ret = temp->_data;
		delete temp;
		_head->_next = next;
		return ret;
	}
}

bool Queue::isEmpty(){
	return(!_head);
}

int main(){
	Queue Q;
	for(int i=0; i<100; i+=10){
		Q.insert(i,0);
	}
	cout<<"Size after insert: "<<Q.size()<<endl;
	for(int i=0; i<100; i+=10){
		Q.add(i);
	}
	cout<<"Size after adding: "<<Q.size()<<endl;
	Q.insert(1234, 0);
	Q.insert(5678, 6);
	Q.insert(1564, 15);
	cout<<"Size: "<<Q.size()<<endl;
	Q.removeAt(9);
	Q.removeAt(1);
	Q.removeAt(0);
	cout<<"Size: "<<Q.size()<<endl;
	while(!Q.isEmpty()){
		cout<<Q.remove()<<" ";
	}
	cout<<endl<<"Size: "<<Q.size()<<endl;
}