View Full Version : Arrow Engine
Cipher
07-24-2008, 07:36 PM
Well, over the last year I have been working on writing a rudimentary game engine in C++ using the SDL. I have been trying to follow in the footsteps of Ken Silverman, by writing a raycasting engine from scratch. However, I haven't really gotten to the fun part yet. Right now I just have basic wall blocking and map loading, and a basic overhead renderer. The only borrowed code is the well-known Bresenham line algorithm.
So, here is the source to my engine, dubbed "Arrow." What I'm asking is an programmer with some free time to briefly look over my code, and comment on it before I begin writing the renderer. I have no means to judge the quality of my own work, being only 17 and lacking real programming experience, so any comments or suggestions from someone with experience would extremely helpful.
Also, note that I'm not releasing this under the GPL, but if you really want to use my horrible code, go ahead.
Sorry about the lack of comments.
Bad Sector
07-25-2008, 03:46 AM
A screenshot? Executable? :-)
theHunted
07-25-2008, 04:47 AM
In my humble opinion that looks like pretty damn good code. Wondering what other people say about this but I only have some very minor nit picks.
Negatives:
- Singletons, even though they are part of the popular Design Patterns books and lectures may as well be considered anti-patterns. In fact the way you use them is perfectly fine, I'm just mentioning this because one might tend to overuse them where they actually aren't necessary at all. You could've simply created that one single instance of Game in the main() function manually. But then again I guess it might be a good idea to restrict other people that eventually start using your code from being able to create a second instance. So that's where the singleton is a good thing. Just don't use it because you are too lazy to add a proper structure to your code and just need a quick access to some object. Again in your case the way the singletons are used seems perfectly fine. I'm just sharing some thoughts here.
- Overuse of "inline". You seem to be using inline for everything. Do you have a fond knowledge of what inline does and how it works? Unless you are really well informed about this topic you can do more harm than good with the use of inline. There's really no need to have everything inlined. It doesn't magically make your code run twice as fast. Instead it will bloat your code. As a rule of thumb you really should not inline anything that is more than 2 lines of code and even there you don't really need it. Also I've never ever seen anybody inlining a constructor.
- The angle class seems like a bit of an overkill to me. The only really new thing it introduces is the "normalize()" method and the 2 const defines as far as i can see. Instead you should try to stick with the commonly used system of radian angles and only do a single conversion from degrees to radians at the very beginning of your pipeline wherever the degrees angle comes from. Once you got the angle in radians you can always work with that from there on.
Positives:
+ Very clean code. Very little amount of lines of code that are removed using the "//" which is a good thing.
+ Well there's not a lot of inheritance present here but it is used well where it is used. E.g. The render abstraction is a good thing for having multiple different rendering strategies in place for easy switching between them. What you've created there is known as the "Strategy pattern" just in case you didn't know it yet ;)
+ Very high level C++. You make extensive use of the STL containers and types and that's a very good thing. Lot's of people are still using c style arrays which is a horrible thing to do in 99% of the times.
theHunted
07-25-2008, 05:06 AM
Oh, I just found the first true negative point. In surface.cpp on line 25 you really should not use the binary shift operator just to compute the value that is mulitplied by 2. Stuff like that really does not make you look cool, and that's probably the only reason why you have that code. Just use "*= 2" instead and get rid of the comments that say what "<<= 1" does.
Oh, and from an algorithmic and performance point of view you might want to rewrite the angle normalize method. It's really not hard to come up with a code that computes the same thing without the loop. The problem I see with this is that the loop is running an undefined amount of times depending on the input. One day by accident you might plug in a very high number and might be wondering why computation starts taking so long. Here's a simple code that computes the "normalized" angle for positive numbers in a constant time independent from the input:
float angle = 730.5f; //Sample input. Should yield 10.5 when normalized.
int factor = static_cast<int>(angle) / 360;
angle -= (factor * 360);
For negative numbers the code might look a bit different as the method of floor-rounding by using an integer cast might not be what you need. I'm sure you'll be able to figure that out on your won when running a couple of tests with numbers like -0.4, -0.5 and -0.6.
Sayantan
07-25-2008, 06:59 AM
*cough* ... JC, I didn't know you where into programming. :o
Cipher
07-25-2008, 08:57 AM
Thank you so much for your comments and suggestions. They were very reassuring. I'll be sure to take out most of the inlining. I never liked how inlining put code in the .hpp anyway.;)
Oh, and as per request, here's a screenshot of the overhead renderer.
The red line represents a portal, AKA, a boundary between sectors. This is useful because most of the time you only have to check things in your current sector. This is the approach used by the BUILD engine.
Jinroh
07-25-2008, 12:29 PM
I started doing something similar not too long ago. I'm glad that I'm not the only one who still likes raycasting.
Your's looks cool Cipher. I shold finish mine. Last I left off I was redoing the viewing frustrum.
http://mypage.mtaloy.edu/~jjnst1/newshot.png
http://mypage.mtaloy.edu/~jjnst1/box.png
Those are two old screenshots I had lying around.
Keep it up Cipher, this really makes me want to finish mine lol.
szevvy
07-30-2008, 06:12 PM
Just on pure code? Just a few things to do with formatting, take 'em or leave 'em:
1. Don't mix tabs and spaces. I've got tabs set to 2 spaces, so things don't line up nicely for me.
2. Breaking a line on column 80 isn't a hard rule, in some cases it makes your code harder to read;
for (Sector::ConstWallIter i = sector_->wallBegin(); i != sector_->wallEnd();
i++) {
is one such place.
3. If you have an if statement with only one statement:
if (sector_ == &wall.sideA())
sector_ = &wall.sideB();
put braces around it anyway. It prevents you from doing things like this:
if (a == b)
//a--;
//commenting out the line above cause it doesn't work
b++ // <--- hoe noes! this will only run if a == b!
I also tend to drop my opening braces on a new line, but that's a personal thing.
Other than that, looks cool.
Altered Reality
08-02-2008, 01:37 PM
1. Don't mix tabs and spaces. I've got tabs set to 2 spaces, so things don't line up nicely for me.
I never use tabs at all. I only use spaces to indent: every space means a level of indentation. My code tends to look like this:
#include <stdio.h>
int main(void)
{
int a, b;
printf("Enter two numbers: ");
scanf("%d%d", &a, &b);
if (b)
{
printf("%d\n", a/b);
return 0;
}
else
printf("... cannot divide by zero\n");
return 1;
}
2. Breaking a line on column 80 isn't a hard rule, in some cases it makes your code harder to read;
I never follow that rule. I only break lines when I have very complex conditions that would create extremely long lines (in that case I align every condition under another) and I never break parameter lists in function headers, even if they DO create extremely long lines.
I never use tabs at all. I only use spaces to indent: every space means a level of indentation. My code tends to look like this: <snip>
I was unfortunate enough to work professionally with one person who indented code that way (more or less). It's an absolute pain in the ass to use that kind of indentation 8 hours a day. Everybody else complained, righly so. Please, use at least for 4 spaces or, better, 8 spaces or 1 tab to indent code. It improves readability a lot when you are tired at the end of the day.
My two cents.
Samji
08-03-2008, 08:41 AM
I have to agree with rg8. Using tabs is a lot more flexible than using hard spaces. Use spaces if you want in your solely self-maintained code, but if you're collabarating, chances are, you won't be very popular.
We all have our style though and when you collabarate, you of course have to come to compromise. For example, BSD vs One true brace style for blocks.
if(a == 2)
{
std::cout << "BSD style" << endl;
}
if(a == 2) {
std::cout << "One true brace style" << endl;
}
I prefer one true brace style, but if the consesus on a particular piece of source code was to use BSD style, I would use that. Inconsistency is much worse that no using my prefered style.
theHunted
08-03-2008, 08:51 AM
8 spaces seems like a bit of an overkill to me. I've seen 2, 3 and 4 spaces and they all worked fine when using an editor with proper syntax highlighting.
At the end of the day the most important rule is to adopt to the coding style that was used in a project before you joined. Don't try to establish your own coding style. It doesn't help anybody and only makes things harder to maintain.
@Samji & rg3: There's one big advantage of spaces over tabs. They always look the same on _any_ editor. When using tabs it completely depends on the settings of the editor on how your code will look like in the end (e.g. how many spaces are inserted for a tab). I guess that can be taken as a good thing as well as a bad thing. Personally I would rate it as a good thing, but that's just me.
@Samji: From my experience chances are equal to find spaces or tabs for indentation. The only true way to make yourself unpopular is to use the opposite indentation method.
Samji
08-03-2008, 12:01 PM
Enough of tabs vs spaces. We should discuss the Arrow engine. :P
Automuse
08-04-2008, 08:45 AM
Yeah, re-write it in BASIC and x86 Assembly so I understand whats going on - I never got into C++! :p
The bit-shift to multiply or divide by two is a hack from decades ago to save a few precious processor cycles - back then a single multiply or divide operation was MUCH slower than an add or subtract, which was slower than a bitshift. Now that you've got gigahertz to throw at your project you don't have to worry...
If you find your framerate too low for your liking, give me a shout or look up any of Michael Abrash's writings on optimization. My very first raycaster ran at 2 frames per second on a 486DX-33, I learned assembly just to make it go faster! :)
Altered Reality
08-04-2008, 10:44 AM
I was unfortunate enough to work professionally with one person who indented code that way (more or less). It's an absolute pain in the ass to use that kind of indentation 8 hours a day.
Interesting, I had the exact same experience, except the other way around, having to revise code with a lot of indentation. The only rule the person who originally wrote the code seemed to follow was "the more you indent, the better it looks". This resulted in lines almost filled with spaces, with the real code so far to the right I had to repeatedly scroll the text left and right to read it. The first thing I did when I loaded his code was to fix it so that one level of indentation equals one space. It was a lot more legible for me, because I didn't need to scroll back and forth to read it.
At the end of the day the most important rule is to adopt to the coding style that was used in a project before you joined.
If the project is passed to me and the original code was a mess, that's exactly what I will NOT do.
Side note: my point was not to create a tabs vs. spaces debate, but to remark that 1 space is not enough to highlight blocks of code properly when your eyes and mind are tired at the end of the day.
Cipher
01-02-2009, 10:08 PM
Hey, sorry to resurrect an ancient thread, but I've just about accomplished everything I wanted with this project. It now includes wall gliding, better collision detection, and a finished raycasting renderer a la Wolfenstein 3D (no textures yet, though). Screenshots and source code forthcoming if anyone shows interest.
peoplessi
01-03-2009, 05:32 PM
Hey, sorry to resurrect an ancient thread, but I've just about accomplished everything I wanted with this project. It now includes wall gliding, better collision detection, and a finished raycasting renderer a la Wolfenstein 3D (no textures yet, though). Screenshots and source code forthcoming if anyone shows interest.
Sure thing, it would be fun to see :) It always very interesting to see projects from start to finish.
jimbob
01-03-2009, 06:06 PM
i always wondered how you start to program a engine, i mean litteraly where do you start?
i wish i could program so i could write my own little game engine or something. :)
i`d love to see your screenshots and see what you came up with :D
i always wondered how you start to program a engine, i mean litteraly where do you start?
i wish i could program so i could write my own little game engine or something. :)
i`d love to see your screenshots and see what you came up with :D
with a main that has:
while (continue){
//do nothing
}
jimbob
01-14-2009, 10:49 AM
i can do that. :p
but that piece of code doesn't make much sense to me. i can do a bit of coding in duke3d :p and a slight bit in unrealscript, a bit of PLC programming and thats about it.
theHunted
01-14-2009, 11:46 AM
...
but that piece of code doesn't make much sense to me. i can do a bit of coding in duke3d :p and a slight bit in unrealscript, a bit of PLC programming and thats about it.
Well what he tried to say was that at the core of any game engine there has to be an infinite loop that keeps running. The loop typically polls user input first, then processes the input to update player models and environment, then do the rendering and so on. Once all that is done one single frame was generated and displayed on the screen and the whole thing starts all over.
Here's a little article that's part of a game engine tutorial that explains this a little better: http://www.directxtutorial.com/Tutorial9/A-Win32/dx9A1.aspx
On a sidenote: while(continue) doesn't work assumming it was supposed to be C or C++ code. while(true) or while(1) however does. Sory for the useless rant :/
jimbob
01-14-2009, 12:06 PM
ok, that explains it. so it works similar to a PLC program wich simply runs line for line and looks at what it needs to do until it reaches the last line and then loops back to the first line.
ok, that explains it. so it works similar to a PLC program wich simply runs line for line and looks at what it needs to do until it reaches the last line and then loops back to the first line.
if you want to learn how an engine's created try reading the source from Irrlicht / Ogre3d both are free for use, and they are awesome.
sorry for the c++ confusion i've been too much time into Java now.
darkportrait
02-17-2009, 06:17 PM
the code looks pretty clean! i hope you continue and work on the raycasting engine you may want to look at for some other engines like the wolf3d engine for refrence on rendering techniques but it does look good
Rider
02-23-2009, 06:13 PM
So when will we get the screenshot/sourcecode we where promised? :p
Cipher
02-24-2009, 09:16 PM
Sorry, just been really busy. I'll post stuff soon. :P
smithy1185
05-19-2009, 02:23 AM
Don't want to bug you but I figured since its been a few months and you might have forgetten.:)
Arexx
05-22-2009, 01:30 AM
Where to start programming a game/game engine? Well, for me, I start without programming at all. Start with a pencil and paper, or windows notepad and start to make notes on what you want your game to be, how you wish to do it. Start out with really general ideas and gradually fill in the details on how to do it with pseudo code. If you plan it out well enough, it will save you a lot of time when you actually sit down and start programming.
If you don't know how to program in C++, it may look a little complex, especially if you start by looking at someone's code. I suggest grabbing a book on the subject or google it, there are free tutorials online that teach it. It's not as complex as you may think at first. A good book I bought one time was C++ For Dummies. :) It was actually a pretty good book on the subject.
Start off simple, create simple games and work your way up gradually. Start with maybe a text game... followed by maybe Pong, then Breakout, and Pacman. Then maybe a Super Mario style platform game etc...
vBulletin® v3.8.7, Copyright ©2000-2012, vBulletin Solutions, Inc.