Jump to content
  • Advertisement
Sign in to follow this  
  • entries
    7
  • comments
    6
  • views
    6746

About this blog

Syntax error

Entries in this blog

 

Animation Editor

So, I'm getting started on a 4E6 entry. My biggest gripe (and it's minor) with XNA as it exists now is the difficulty in working with the standard .Net Framework to build tools. Apparently this will all be cleaned up with XNA Game Studio Express 2.0, but it's somewhat annoying now.

However, while you can't yet drop an XNA game window onto a .Net form, you can create one separately. So that's what I'm doing.



That's my dead simple animation editor. You draw boxes around each frame you want, and then set the frame's origin. (In this case, I mean pivot point for rotation.) This information will be saved out into an xml layout that I've already built into the content pipeline. I'll be building a simple sprite editor next, then follow that up with a level editor.

Jesse Chounard

Jesse Chounard

 

More collision tests

Unsurprisingly, you don't get much done on a project when you only spend a few hours a week on it. But that's fine, as when I do feel like working on it, I'm having alot of fun.

I found a need for checking collisions with circles, so that's what I've been working on. I find it kind of sad that I've skipped over doing the low level graphics or audio systems by using XNA, but I'm still working on something that should be considered already solved.

Circles vs. Line Segment Collision:



If I add a little gravity, the circle slides nicely down the slope. And I'm handling the endpoints, so there's no gap, no matter which way you push the circle against the line. If anybody wants to see the source, just lemme know. It's not terribly complicated.

This stuff is all mostly still from the N tutorials. I just recently learned that a version of N is coming to xbox live arcade. Happy times.

On an unrelated note, I finished Bioshock last Sunday. (I didn't do much in my free time but play it once I got it.) Freaking fantastic. I'm looking forward to playing it again.

Jesse Chounard

Jesse Chounard

 

Collisions

Since posting my last entry, where I had a "playable" little platformer, I've had to go quite a bit backward to implement the features I want. (I put playable in quotes, because absolutely nothing happened when you collided with enemies. But you could jump around between platforms.)

I've done two things that I think are interesting.

1) I've played around the the XNA Content Pipeline. I made a simple animation file format (currently it's just XML) that the pipeline can load up automatically like it can handle textures or meshes. It's not useful yet, but it's a neat experiment on how to add something to the pipeline.

2) Collision detection research. The collision detection I was using before was simply checking Rectangle.Intersects, and then moving the character back to prevent the collision. That's not terribly exciting, and certainly doesn't help at all with sloped surfaces.

My plan is to use two methods of collision. Sprite vs. Platform collisions will be handled with the separating axis theorem (thanks for pointing that out Mr. Easily Confused), and bounding box plus nearly pixel-perfect collision for Sprite vs. Sprite collisions.

Now for some "exciting" screenshots. You control one of the red boxes, using the arrow keys to move, and the A and D keys to rotate. The other red box will push you away on collision (SAT collisions) and collision with the big 'C' looking texture (nearly pixel-perfect) will just change the background to yellow.



And here's the source code. It requires all of the XNA Game Studio Express stuff. I'm still trying to get my head fully wrapped around C#, plus it's just an experiment so don't expect the world's best code.


Jesse Chounard

Jesse Chounard

 

Time to have some fun

It's been over two years since I've written an entry here, and that's entirely too long. That said, I've discovered an even scarier time period. It's been over seven years since I wrote a video game for fun that I shared with anyone. (Has it really been so long? I suddenly feel very old.)

According to this page I submitted a game called Bugz for the Spritelib contest. (GDNet's first contest.) It's a pretty gross ripoff of the dropped-block games that were already old news in those days. I didn't do very well, and I don't recommend you download it. (However, you should go grab Happyland Adventures from Free Lunch Design. It was great at the end of the contest as one of the winners, and Johan ended up adding quite a bit to it. There was even a pretty good sized mod group for it.)

A few years ago I designed a prototype Voltron Gameboy Advance game for the company I work for. (Yeah, I work for the company who created Voltron. There's a huge Voltron statue in the lobby.) Sadly it didn't end up going anywhere, but it gave me the chance to play around with GBA hardware and get paid for it.

Since then, I got swept up in the idea of turning my game development into a business, and started trying to develop some casual games that I could make a few bucks on. The problem is that I don't even like most casual games. What's the point of developing games I don't like? I could just write database applications for alot more money. The guys over at the indiegamer forums have spent so much time arguing over whether or not it's okay to clone Bejeweled and laugh their way to the bank. I find the idea kind of sick, actually. But who am I to judge? The people playing those games don't seem to mind.

In the end, I find I'm jealous of people like Stompy. His games are silly fun, people are playing them, and he's having a good time writing them. So I've made a decision. Game development is officially just a hobby for me again, and I'm going to enjoy it, dammit!

First game project is going to be a simple platformer in XNA. And I think it's only fitting that I'm using graphics from Spritelib. Here's a little screen of what I've got so far:



And here's one a little zoomed in, because it's hard to make out what's in there:



I'll post a demo of the first level when I get that far. But no promises on a timeline. This is just my hobby, after all. :)

Jesse Chounard

Jesse Chounard

 

Dihydrogen monoxide is good for you

If you haven't already, I recommend you read the article"Creating a Generic Object Factory" by Robert Geiman. One of the iterations of the object factory he created was very similar to the factory code I had written, but I liked his implementation a bit better, so I'm using something nearly identical to his code.

The only major difference is that I opted to make each factory into a singleton. If you want a factory of type Shape, you could obtain it like so:

ObjectFactory *pShapeFactory = ObjectFactory::Instance();
And if you wanted to register a Square to be creatable as "square":

pShapeFactory->Register("square");
And finally, creating a square:

Square *pSquare = (Square*)pShapeFactory->Create("square");
Pretty simple, really. For more information, read the article, and have a look at my factory code. (I'll link to it below.)

Now, what does this have to do with the XML stuff I've been talking about? Well, I wanted to be able to take a look at the TiXmlElement's value (the name of the tag) and immediately know what kind of object to create. Without a huge if/then tree or switch statement that had knowledge of every single type I might ever create, that was a problem. This is no problem if I use a generic object factory.

We just need a factory of the base type, which is XmlObject, now that all my XML ready classes support the same interface, then register each type to the name I'm using for the tag, and away we go.

ObjectFactory *pXmlObjectFactory = ObjectFactory::Instance();
pXmlObjectFactory->Register("level");
pXmlObjectFactory->Register("enemy");

XmlObject *pUnknownXmlObject = pXmlObjectFactory->Create(xmlElement.Value());




The problem, now, is that I have no idea what I'm pointing to. Is it a Level? Is it an Enemy? Is it something else registered in some dll code somewhere? What do I do with whatever I've just loaded? How I'm handling the problem is some very simple run time type information. (Just a "what kind of object are you?" function. Which is not in the code I've uploaded. The xmltest.cpp is braindead simple.)

If anybody has any ideas for a better way to do this, I'd love to hear it. (That's a major reason for me sharing it.)

Here's the latest versions of everything:
factory.h
xmlutil.h
xmlutil.cpp
xmltest.cpp

On a happy note, completely unrelated to these entries, I asked my girlfriend to marry me yesterday. She said yes. Happy happy!

Jesse Chounard

Jesse Chounard

 

Phase 3, profit

I've designed a simple interface for classes to add XML access.

class XmlObject
{
public:
XmlObject(void) { }
virtual ~XmlObject(void) { }
virtual bool ToXml(TiXmlElement&) { return false; }
virtual bool FromXml(TiXmlElement&) { return false; }
};




Just inherit from XmlObject, and then implement ToXml and FromXml. I thought initially to make the function pure virtual, but there's no reason a class shouldn't just overload the load function, if they don't have any interest in saving. If the save function does get called, it'll just fall down to the base class and return false. No harm done.

I also thought about making the constructor protected, to prevent anyone from allocating XmlObject instead of a derived class. Other than preventing someone from compiling something I can't see any use for, is there any real reason to do it?

A third thought I had was to have a third function, which is a different version of ToXml that returned a TiXmlElement. This would eliminate the need for the calling function to create a TiXmlElement in their scope. Also, two of the utility functions I wrote were overloaded operators for + and +=. If I just return the element, I can do stuff like this:

TiXmlElement xmlSave = class1.ToXml() + class2.ToXml();

The problem I have with that, is I really prefer having the option to return a success flag. Most of the code I write for work is in C, so throwing exceptions isn't my first thought when I'm coding on my own. Obviously that's something I need to work past, because exceptions seem to the right way to do handle these error conditions.

I modified my test classes to use this interface, and uploaded the new files. I also remembered to upload the XML file I'm using to test with, as I forgot that last time.

text.xml

Next time I'll get to the reason I wanted this uniform interface, other than my craving for uniformity.

Jesse Chounard

Jesse Chounard

 

First adventure in XML

I recommended to The Forgotten Mindset that XML would be a good file format to use for his game data. You see, I recently read the article here that introduced me to TinyXml. What I ran into, and the only problem I had with that article, is that TinyXml seems best suited to stuffing lots of information into attributes and not the text elements between open and close tags. And while it works, most resources I've read have called it bad form.

For example, this is frowned upon:
"100" direction="1" name="The first level">
"10" y="54" id="Enemy001">








while this seems okay:

100
1
The first level

10
54
Enemy001








While there's nothing stopping you from reading in the second example in with TinyXml, there's no mechanism included for searching for and converting the text nodes like those that exist for attributes. So, I set out to write it.

I could have (and may still) modify TinyXml's source to include the features I desire. For now, however, I've written a seperate utility-function module.

xmlutil.h
xmlutil.cpp
xmltest.cpp

Specifically, see the functions named FirstChildText, and NextSiblingText. I tried to follow the mechanisms built into TinyXml.

Each class that I want xml access for just needs to be smart enough to read and write itself to a TiXmlElement. Here's the code that loads and writes back out the second xml example above. (From xmltest.cpp)

int main(void)
{
TiXmlElement xmlElement("");

if(!xml::ReadXml("test.xml", xmlElement))
{
std::cout "Couldn't read input file: test.xml\n";
return 1;
}
Level level;

if(!level.ReadXmlElement(xmlElement))
{
std::cout "Couldn't read level\n";
return 1;
}

xmlElement = level.WriteXmlElement();

if(!xml::WriteXml("testoutput.xml", xmlElement))
{
std::cout "Couldn't write output file: testoutput.xml\n";
return 0;
}

return 0;
}


Jesse Chounard

Jesse Chounard

Sign in to follow this  
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!