Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

124 Neutral

About Eskapade

  • Rank
  1. Eskapade

    GLM obj loading + GLSL

    Quote:Original post by MantisTobaganMD The model rendering calls from GLM of course use fixed functionality. I'm not sure why you say "of course", but.. Quote: If I wanted to apply a simple GLSL shader that does per pixel lighting to a model (with a texture), how would I even go about that without tearing up the existing GLM code? Or is there no easy way to do this. I don't know the GLM code base, but if it's designed well, the mesh data should be separate from the rendering code (data-driven approach). You will then have to replace all fixed pipeline functionality in the rendering code with shaders. It's not complicated though. Look up some GLSL book and you'll get a texture shader running in no time. Then you can enhance it to implement phong shading for example. If you don't want to learn the math behind it, you can essentially copy paste its code.
  2. Depending on which OpenGL version you use and whether you use shaders, you might want to look for the term "instancing". It uses the same geometry with different parameters (e.g. transformation matrix), that could optimize your batch rendering aswell. Some more obvious optimizations would be to sort by texture id (and shader id). Say, you have 3 textures: grass, concrete, sand. You will also have a container storing all tiles of a level, sort it by the texture id. Draw all grass textured tiles first, then all concrete textured tiles, then all sand textured tiles. This saves you a lot of texture rebinding. Depending on how much your upper layers cover, it could be useful to turn on depth testing and draw the upper layers first, then the lower layers. This could potentially save a lot of fragments (pixels) to be processed because depth testing sorts them out. If that's not the case, you can turn off depth testing, draw the lower layers first, working your way upward (painter's algorithm). Hope that helps!
  3. Eskapade

    Creating objects on the fly

    Quote:Original post by wicked357 I did a quick little whip up in SFML to check it out, how does this look or should I look at maybe a different way to doing this? *** Source Snippet Removed *** Yeah, that will work. However, you limit yourself to 10 objects right now. You can take a container that can grow (or shrink) during runtime. For example an std::vector which is an array that will be reallocated with a bigger size if its limit is reached, or a linked list, etc.
  4. Eskapade

    Do you write helper tools?

    Quote:Original post by Zahlman Quote:Original post by BinaryToshokan I was sitting around one day writing get and set methods with and on update event. Needless to say I got tired of typing(copy paste & modify) Aalfkjdslfkjskfjsajdlf. That was supposed to be your warning sign that maybe the approach you are taking to the code design is not such a good one. What are you gaining from all these get and set methods? Please don't say "encapsulation"; I've been hearing this joke for many years and it just isn't funny any more. I don't want to make you cry, Zahlman. But when I tried to look up a solution to a problem with my new gamepad for my PC, I stumbled upon an article by someone who wrote a program to bind buttons on his gamepad to get/set insertion macros etc, putting the gamepad next to his keyboard.. I raged dearly.
  5. Eskapade

    Lustre of materials and objects

    Quote:Original post by Sagenth It is theoretically possible to have just as much realism with the shaders would it not? Or at that point, for shaders, it would be actually slower than using the ray tracing? In general it's much easier to implement effects like reflection in raytracing, but optimizing them is much more difficult, because graphics cards weren't designed for ray tracing in the first place (which might change in the future). In raster graphics you really just fake the effects to the extent that they look believable to make them realtime. It is more difficult to create these effects with a rasterizer if you want absolute realism.
  6. Eskapade

    Lustre of materials and objects

    If you want more realism and don't care about real-time graphics you're better off with raytracing for example. But for raster graphics shaders are the way to go, yes. These are quite advanced effects. I don't know about your experience in programming, but it's going to be very difficult if you're still a beginner.
  7. Eskapade

    [web] Html Help?

    Do you mean you want BBCode like [youtube][/youtube]? You will need to write a string parser for that in a dynamic language (PHP, Python, javascript, ...). HTML is just a markup language, it's not able to do such things without some help. In my code I do something like this: match = re.search(r'(?:http://)?(?:(?:www\.)?(?:youtube\.com/(?:v/|watch\?v=)))?([A-Za-z0-9_]{4,})', code) if not match: return '[Invalid Youtube link]' id = match.group(1) return "<object class='video' type='application/x-shockwave-flash'> <param name='movie' value='http://www.youtube.com/v/" + id + "' /> <a href='http://www.adobe.com/go/EN_US-H-GET-FLASH'> <img src='/data/noflash.png' alt='Flash needed for Youtube' /> </a> </object>" This code uses Regex to find a youtube video ID in a given string and replaces it. To parse BBCode you probably want to create a recursive parsing function. Just google for all these keywords. If you just want to embed a youtube manually, use the <object>...</object> part above
  8. Eskapade

    When is it really worth it?

    Do you realize that game maker was also probably made in C++ or a comparable language? The reason your friend made the program much faster than you is because he stood on the shoulders of giants. Someone wrote (good) code so that your friend had it easy while you worked from the ground up. For reasons why you should use C++ (or similar) instead of game maker? Game maker is limited. If it doesn't have a certain feature, you can't do it. Maybe it features a scripting language to extend it, but that will have its limits too and be too slow for computation intensive features.
  9. Hey Dandi, sorry for the late reply (and thanks to jyk for replacing me :P). I don't have time to look through your code right now (cs and med exams, jobs..), but I wrote a quick SDL, GL, SDL_image, SDL_ttf CMake example script for you: // CMakeLists.txt CMAKE_MINIMUM_REQUIRED(VERSION 2.8) PROJECT(TheGame) SET(TEXTURE_DIR ".") SET(SOURCE_DIR ".") FILE(GLOB SOURCES "${SOURCE_DIR}/*.cpp") FILE(GLOB HEADERS "${SOURCE_DIR}/*.hpp") FILE(GLOB TEXTURE_FILES "${TEXTURE_DIR}/*.jpg" "${TEXTURE_DIR}/*.png" ) CONFIGURE_FILE(config.h.in "${PROJECT_BINARY_DIR}/config.h") FIND_PACKAGE(OpenGL REQUIRED) FIND_PACKAGE(SDL REQUIRED) FIND_PACKAGE(SDL_image REQUIRED) FIND_PACKAGE(SDL_ttf REQUIRED) FILE(COPY ${TEXTURE_FILES} DESTINATION "${TEXTURE_DIR}") INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR} ${OPENGL_INCLUDE_DIR} ${SDL_INCLUDE_DIR} ${SDLIMAGE_INCLUDE_DIR} # ${SDLTTF_INCLUDE_DIR} ) ADD_EXECUTABLE(TheGame ${SOURCES} ${HEADERS}) TARGET_LINK_LIBRARIES(TheGame ${OPENGL_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} # ${SDLTTF_LIBRARY} ) // main.cpp #include <SDL/SDL.h> #include <SDL/SDL_opengl.h> #include <cstdlib> #include <ctime> #include <iostream> #include <stdint.h> const unsigned short initialWindowWidth = 640; const unsigned short initialWindowHeight = 480; struct ColorRGB { uint8_t r, g, b; }; void draw(const ColorRGB& currentColor) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glColor3ub(currentColor.r, currentColor.g, currentColor.b); glBegin(GL_QUADS); glVertex2f(-1.f, -1.f); glVertex2f( 1.f, -1.f); glVertex2f( 1.f, 1.f); glVertex2f( 1.f, -1.f); glEnd(); } ColorRGB createRandomColor() { ColorRGB color = {rand() % 256, rand() % 256, rand() % 256}; return color; } int main(int argc, char **argv) { if(SDL_Init(SDL_INIT_VIDEO) < 0) { std::cerr << "Cannot init SDL." << std::endl; return 1; } SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, true); if(!SDL_SetVideoMode(initialWindowWidth, initialWindowHeight, 0, SDL_OPENGL)) { std::cerr << "Cannot create OpenGL context." << std::endl; return 2; } std::srand(std::time(0)); bool gameRunning = true; SDL_Event sdlEvent; ColorRGB currentColor = createRandomColor(); while(gameRunning) { while(SDL_PollEvent(&sdlEvent)) { if(sdlEvent.type == SDL_QUIT) gameRunning = false; else if(sdlEvent.type == SDL_KEYDOWN) currentColor = createRandomColor(); } draw(currentColor); SDL_GL_SwapBuffers(); } std::cerr << "Thanks for playing." << std::endl; return 0; } // config.h.in #ifndef CONFIG_H #define CONFIG_H #define TEXTURE_DIR "@TEXTURE_DIR@" #endif I'm sure you can figure this out, otherwise google a bit. Create these 3 files in a directory, open the CMake GUI, select that directory as the "source" and any other directory as "build". Configure, configure again (this is so you can see which variables changed and confirm them), generate. You know have project files for your IDE. This script will also create a config.h files in your build directory, according to the config.h.in template. This is useful to use variables from the CMake configuration run in your code (I used TEXTURE_DIR here in case I want to IMG_Load(TEXTURE_DIR "/image.jpg") for example). Sorry I can't help you more right now! Hope you have fun. And next time I see this thread I want a game, not an engine :P
  10. Eskapade

    Design of input system

    What are you going to do though if you you want to bring up a menu (options, save, load game) while you are playing and the menu is transparent, so the game can be seen in the background? You would still need to render the previous state (top-most state on the stack being the menu, the one before the in-game state). Let's say you also want some things to still move while you're in the pause menu (water keeps moving, birds continue flying their rounds), now you would also need to update the previous state in addition to the menu's state.
  11. Quote:Original post by Dandi8 My main concern (besides making the code work right + performace stuff) is automation, if I may say so. I want to be able to write a 2D game engine that I will be able to reuse many times in order to create content simply and efficiently. ... Basically, I want to create the best possible 2D game creation environment possible that would suit me :P Ofc that's impossible so let's say 'great game engine that I can use to create 2D games with easily'. While it's good that you think about a solid tool box to use for future games, you should not overdo it. You're running into the danger of creating a game engine while you actually want to create a game. Here's a commonly cited article about this: http://scientificninja.com/blog/write-games-not-engines Try to finish a first simple game. This game is really cool as it is already, try to polish it. Add bullets that move in a sine-wave instead of a straight line, add comets that rain from the sky in addition to the big laser you have right now.. go nuts! Try to make the game fun, that's the most important to the player/customer. When you start your second game and you try to reuse the old code you WILL realize where you've gone wrong and will learn from your mistakes. You will do "code refactoring" (tryin to fit old code into your new project). There you will realize what was incredibly stupid. So get a simple game working first, you can create your adventure game later, and it will be that much more awesome. Quote:Original post by Dandi8 I used ii because i is already taken up by a font var and was conflicting. Every time you do that a sad panda is born. When you create nested loops with loop variables i, ii, iii, iii you will at some point think "wait.. what was iii again?" and get nasty bugs. You might understand that code right now, but what if you read it again for your next game in a year? It would be smarter to call the variables "currentEnemy", "currentEnemySprite", "currentBoundingBox" for example (pulled out of my magic hat again). I just use i for single loops and i, j for very, very abstract things where names don't really apply (sorting algorithms or such). Quote:Original post by Dandi8 That's what the width and height factors are for here. I draw as if I was drawing on a 1024x768 window and then resize stuff to fit any resolution desired. I'm kind of proud of it, actually ^^ Still, will have to look into optimizing it. Ah I see, you can do that of course! Good solution. But still, don't hardcode the 512 in case you want to release your game on a game boy for example and need to base the resolution on something else. Quote:Original post by Dandi8 And a couple questions about the encapsulation thingy: -If I were to put Init() in a class, what class should I put it in? [/quote] What would the benefit of putting init into a class be? You don't need to put everything into classes to say "herp derp, I'm using OOP (object oriented programming)!". The init function should probably just tell some objects "hey guys, we're initializing. Everybody reset to an initial, clean state and prepare for some gaming!". It should not be copying memory around and doing other low-level stuff itself, as such there's nothing for it to encapsulate/hide -> free function. However, the level for example will potentially have to keep a couple of containers of things only it should have access to, or others can only get access to if it allows them (through methods of that class), therefore these containers should not be public/global -> you need a class. Quote: -Should I add functions like LoadTexture and DrawTexture into their own Graphics class? -Similarly, should I add DoGravity, HandleAnimation(), HandleBullets() etc. into their own Game class? A class should only have one "responsibility". When you see a class called "class DatabaseQueryValidator" what do you think it does? Its responsibility is to ensure that database queries are valid. What's "class TextureCache" for? It caches textures in memory (caches = keeps track of recently used textures for quicker reusability). What does "class Graphics" do? I have to say I can't tell from the name. I can imagine a lot of things of course, but I can't nail it down. Think of the precise responsibility and think of a good name for it. If you can't come up with a good name then you probably don't know what it's supposed to do yourself. Example of a good usage of OOP: Have a class Renderer (responsibility: be able to draw things). It will have various render-methods: renderSprite(..), renderBackground(...), renderMesh(..), renderLevel(Level& level) and other render-related functions like clearScreen(), resizeScreen(). Some of these methods will need access to the textures. Should class Renderer have functions to load textures? That would be a new responsibility, so no. So we create a class TextureCache which has the responsibility of loading textures and keeping track of them. When we tell the renderer to draw a sprite we tell it renderer.drawSprite(playerSprite, textureCache) and the renderer will now know of the texture cache. Advantage? If you realize your idea of managing textures was stupid, you only need to change TextureCache now and the renderer will still work. Objects should also collide with each other, so we need to do collision detection.. Should the renderer do collision detection? New responsibility, no. TextureCache? Wait, that doesn't have anything to do with that! If you had created a class "Game" earlier that had a very general responsibility like "uh, make a game work?" you might have ended up throwing drawing code, texture loading code and object collision code into that. Clear design makes this mistake very obvious now. So should LoadTexture() and DrawTexture() go into a class "Graphics"? Ask yourself what the implied responsibilities are.
  12. Quote:Original post by Dandi8 What do you mean 'pool of loaded textures'? That may be something to remember for later. Right now you're simply loading all textures you need once during initialization, which is fine because you know exactly which textures you're going to need. By a "pool" I simply mean that you do a little book keeping which textures you already loaded 1. LoadTexture(".foo.png") 2a. If foo.png is already saved with a valid OpenGL texture ID in the array "loadedTextures", then simply return that texture. 2b. If foo.png is not loaded already, load the file foo.png and store the Texture struct in the array loadedTextures, then return the texture. This way if you load 100 stickmen for example, you will only have loaded the texture once, even if you call LoadTexture separately for each. Quote:Original post by Dandi8 And vertex arrays? I'm currently guessing what immediate mode is XD Just search for such keywords on the internet, you're bound to find something quickly. The problem with immediate mode (glBegin(..) ... glEnd()) is that A) it's deprecated, it will disappear so you shouldn't rely on it anymore B) it's slow. The poor guy who has to implement the OpenGL functions for you has the problem that he can't tell whether you're going to define a normal next, maybe a coordinate or a texture coordinate, maybe you're doing something else entirely (call glClear() although you're not allowed to for example). That makes it hard to optimize. Also calling one function for each vertex is a lot of overhead ("extra work for the program"), although that's not so bad for single quads. Quote:Original post by Dandi8 Sorry, I'm a noob to that stuff :( So we're here to help! Your program compiled flawlessly, just a warning when compiling with -Wall: for(int ii=0; ii<Text.length()+1; ii++) length() returns an unsigned int (to be more precise, size_t). You might as well use unsigned ii. Comparison between unsigned and signed ints can expose you to a few bugs. The unsigned int may be larger than a signed int can hold A signed int's maximum numbers is 2^16 - 1 = 65.535. Bits can be either 0 or 1, so 2 possibilities. Therefore you can have 2*2.....*2*2 (2^16) different states for the whole 16 bit number. We do -1 because 0 is one of these numbers, reducing the maximum by one. An unsigned integer is 2^32 - 1 = 4.294.967.295 Bits at maximum. That maximum is higher than the 65.535 of a signed int. If your text length is bigger than 65535, this loop will repeat infinitely, because the signed int wille always be smaller than the unsigned int. When the signed int reaches 65535 and ii++ is called, it will "overflow" and become the smalles number it can, which is negative. Also: please use proper loop variable names. ii will become very confusing once you write more complex loops. Quote:Original post by Dandi8 Stuff I intend to fix: -refactoring the drawing code in main - but could you elaborate on that? I'm not sure what functions/classes I would split that to. I already have a ton of functions in main. And what do you mean with the timer? Imagine this: your game will feature complicated artificial intelligence, level loading, huge masses of textures, networking, joystick support and all other fancy things in the future.. at some point you will lose control of your code, because everything is everywhere. It will be hard to fix things because everything can possibly change everything. So what you try is to make a clear separation between things that can't possibly have anything to do with each other. If I, as a foreigner to your code, look at it, I can say "oh his collision code doesn't work.. I'll check out the collision code" (pulled that example out of my magic hat). But when I realize you mix other things into that code I will have to check your drawing and sound code too, which should not be the case. Look at your main.cpp and ask yourself "WHY is this line of code here, WHICH component does it belong to, WHAT does it try to achieve?" and you should be able to come up with an answer yourself. But yes, that's something you will need experience in which only comes when you think about these things yourself first, so I won't spoil the fun yet :] Quote:Original post by Dandi8 -magic numbers ---- although I tried to minimize my numbers' magic as much as I could I'll take random example how to think about this: smallText.DrawOneLine("NEW GAME", (512 - (smallText.GetLengthPixels("NEW GAME", 64) / 2)) *widthFactor, 350*heightFactor, 64*widthFactor); Why did you calculate the number, which component does it belong to, what does it try to achieve? You calculated it because you need to position text on screen, it belongs to the new game text and it tries to center it somewhere. How about calling it newGameLabelTopLeft? In addition, 512 should not be hardcoded. I guess 512 is half of the window width. What if you want to change the resolution of the window in the future (which you probably will)? You should be able to change this value when the window is resized. You also save a lot of calculations by only calculating these variables when something has changed (initialization, window resize here). Quote:Original post by Dandi8 -That std::string thingy ---- could you explain that a bit more? And those non-POD types? Read about POD types here first: http://en.wikipedia.org/wiki/Plain_old_data_structure Read about pass by value and and pass by reference here: http://en.wikipedia.org/wiki/Pass_by_value#Call_by_value Now consider these two versions of a functions which is given a string and has to decide whether the first letter is capitalized: bool doesSentenceStartCapitalized(std::string s) { return s.size() > 0 && s.at(0) >= 'A' && s.at(0) <= 'Z'; } This function looks innocent, but if s were the content of a book you would realize that this function is slow for some reason. When you call std::string story = "There once was..... The End."; bool isGoodStory = doesSentenceStartCapitalized(story); You will have the string saved in the variable "story" in the global scope. Once you call the function you pass it the string "by value". That means that the function will copy "story" into its own variable "s". It will check the first letter, return the result, the destructor of "s" is called and you now only have the text in "story" again. Wouldn't it be great if the function would just look at story's first character? You can, by passing by reference (you point to the memory address of story) bool doesSentenceStartCapitalized(std::string& s) { if(s.size() > 0) { s.at(0) = 'X'; return && s.at(0) >= 'A' && s.at(0) <= 'Z'; } return false; } Now s is the same thing as story and you don't copy the memory, great! But wait.. the function changed story? Seems like someone made a programming mistake. Surely a mere check whether the text is capitalized at the beginning should not be able to change it? That's why you use const std::string& instead, the string will be immutable ("can't be changed"). Quote:Original post by Dandi8 How is there no need to make SDL_Surface* screen global? That way I can refer to the screen in any file I want. Am I not right? Only make things global when pretty much everyone is guaranteed to need access to the data and if it's safe to change it. Your collision code shouldn't need to access screen for example. But it potentially could, as a foreigner to your code I can't tell whether it does before I looked at that code. If screen is not global, I have a guarantee that your collision code does not use it when it's not explicitly told to do so (by passing screen as argument in collision functions). Also, let's say you implement a function that draws on your screen, you were drunk and introduces a bug (because you never create bugs when you're sober). The drawing function messes up the variable and changes screen to 0 because of some error.. Now all other functions using screen are in danger if they didn't check screen for a null pointer (which they wouldn't have to if they had a guarantee that no one can set screen to 0 just like that). Quote:Original post by Dandi8 How do I distinguish c from C++ code (regarding basicfunc)? What I mean is that while you use C++ syntax, you don't "think" in C++. You use practices from C. You have not understood the concept of data encapsulation yet, for example. You use free functions (functions that don't belong to classes) even where you use data that should be hidden as private member variables. SDL_Surface* screen could belong to a renderer class for example, and all access to screen can be controlled by it. Free functions should only be used for.. managing logic of your program, if that makes sense? For example I would use a void prepareLevel() function that loads the next level file, positions all enemies, resets the computer players' AI (artificial intelligence) and such, but I would not make loadLevel() a free function, but stick it into a "class Level" instead, because it will handle a lot of data that should only be changed with its permission. Changed the "width" variable of the level? class Level should always know that because it will have to resize the level, for example. You just reduce the chance that foreign coders can mess up your code and protect yourself from destroying something by accident, too. Quote:Original post by Dandi8 Could you give me an example of over-engineering? You want to get rid of a spider, so you build a laser cannon and should it, instead of picking the poor thing up and throwing it out of the window (my girlfriend is prone to this behavior). Quote:Original post by Dandi8 Is there a better way to handle my animation? What are you trying to achieve, what are you unhappy with? Putting the straw man's textures into one big texture ("texture atlas/sprite sheet") is really good already. I don't know which feature you want to extend upon your current animation. [/quote] What about my text class/functions? [/quote] I don't have much time to look through it right now, but it seems like you could simplify a lot of it. For example you use rows like "carriage += ((A_WIDTH) + TEXT_SPACE) * (float(charWidth) / float(CHAR_WIDTH));" a lot. You could calculate most of that formula once, save it in a variable and use that variable to replace that part of the formula in all of your lines. It would make the code more readable and if you solved an error in that formula it would correct all lines. Quote:Original post by Dandi8 And could you tell me something about compiling for other platforms? I haven't done that yet. It's fun. I don't know what to answer, that's a very general question.. :P By the way, try to enter a game over check that restarts the game after a button press. Would make your game more playable already. And a cool charging laser sound! F*** yeah!
  13. Just tested your program on Mac OS X, worked flawlessly! However, my compiler complained about A) #include <sdl.h>, it should be SDL.h. Windows' file system isn't case sensitive, but others are. You might want to rename it to the proper case. B) text.cpp line 233: ifstream only accepts const char* as file name, not std::string. Change the argument to the ifstream constructor to x.c_str(). Does that really compile under Windows? By the way, I realized you're copying non-POD types ("more complicated things than int and other built-in types"). Rarely will you want to pass an std::string by value, because it will create a copy of it. If you don't need a copied instance of the string, just use a function prototype like void foo(const std::string& x). This will use the same string you passed as argument instead of copying it and working on the copy (faster, uses less memory for huge strings).
  14. Quote:Original post by Dandi8 So that will enable me to do what...? Have my source code VC++ independent? I'll probably start tearing up through its docs later but while we're here - is it haz a crash course? And is it free for commercial use? Thx :) Yes, it's free for commercial use. Check out cmake.org for the docs and google "cmake sdl" for some help on that, it's pretty straight forward. You create a text file with some infos what you want "find sdl, find opengl, use these source files, create a binary named so-and-so..", then use the cmake program to create project files for various visual studio IDEs, makefiles, eclipse and some others. It's especially useful because it will find all the libraries and headers for you automatically (and if it doesn't it will inform you and let you specify the locations yourself). Glad to help
  15. Had a quick look at the code.. When initializing member variables in a constructor, don't do Laser::Laser(){ Laser::active=false; Laser::charging=false; Laser::canShoot=true; } but Laser::Laser() : active(false), charging(false), canShoot(true) {} Don't define destructors and constructors if they don't do anything actually. In the implementation of a method it's not necessary to write the namespace of the class explicitly, e.g. void Bullet::Spawn(..) { Bullet::alive = 0; } You can just write alive = 0 instead, as you're in the local scope. Makes the code more readable. BasicFunc.h/cpp are essentially C-code with a .cpp file extension. It breaks encapsulation by exposing variables like SDL_Surface* screen. There's no need to make this global. The code should be refactored into own files (collision, timing, texture loading in one file is a not very logical). Make the timer member variables unsigned to double the amount of time you can track. The way you implemented texture loading, you can load textures multiple times. You might want to consider having a "pool" of loaded textures and point to these textures instead of loading them again, if they don't need to be manipulated by one object (in which case it would be legitimate to load a texture multiple times). Otherwise you waste memory. You shouldn't use immediate mode. While vertex buffer objects might be a little overkill for quads, consider using vertex arrays. Do you define texture width and height as floats so you can avoid integer division as in "frameWidthOffset=1/(texture.Width/frameWidth);"? Just cast instead. Consider writing such statements like "1.f * frameWidth / texture.Width" instead (it's equivalent) to keep precision. bool randBool(){ static bool FirstRun = true; if (FirstRun){ FirstRun = false; srand((unsigned) time(NULL) * 48645625); //Randomize using time and a big random number } return rand() > RAND_MAX / 2; } The "big random number" doesn't change anything and you should only call srand once at the beginning of your program and remove this check from randBool. Also consider return rand() % 2 instead. Refactor the drawing code in main() into own functions/classes, it's also a little hard to follow because you use globals a lot where you don't need to (textures are fine in the global namespace for simplicity I guess, but why not move the timer inside the main() scope and pass the passed time to functions that need it?). You have a lot of "magic numbers". You shouldn't hardcode all those numbers in main(), and most of the calculations in main could be done once during initialization instead of every loop (1024*widthFactor etc). So it's a little untidy, but I see no big flaws and I like that you're not over-engineering things! Seems like it would be fun to play, but I can't test it right now.. although I might create a makefile really quickly cause it looks funny :) Keep up the good work!
  • Advertisement

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!