molehill mountaineer

Members
  • Content count

    71
  • Joined

  • Last visited

Community Reputation

595 Good

About molehill mountaineer

  • Rank
    Member
  1. Arkanong part 6: batching draw calls

    Once again I must apologize for how long it took to post this - There are many things competing for my time so this journal doesn't always get the tender love and care it should. I've managed to find a few spare hours so I'm going to show you how I batched the draw calls for my game objects. Up to this point every game object has been in charge of drawing itself - that is, each object has its own texture and draw() function which loads and then renders the sprite. The object manager loops over all the objects and calls Object->draw() for every one of them. This approach is fine if your game doesn't have that many objects but ideally you should try to batch your draw calls because they are computationally expensive. Batching draw calls means that you only call draw() once for every texture rather than once for every object. So if you have 50 objects which use 2 textures (e.g. 25 blue balls and 25 red balls) you will only have to call draw() twice instead of 50. Since we're only calling draw() once for every texture, we need a way to tell the renderer where the texture is to be applied (that is, what objects will be using this texture). Luckily SFML has a class which does exactly this: the vertex array A vertex is a (graphical) point which has the following datamembers: - a position (x and y coordinates) - a color (I won't be using this since I'm drawing textures) - a pair of texture coordinates (which determine the part of the texture you want to use) Every game object consist of a number of these vertices - a triangle would have 3, a rectangle 4 (which is why it is commonly referred to as a 'quad'). So really they are just the "corners" of your object with a bit of extra information attached. The texture coordinates in particular are handy because you can use them to make draw calls more efficient. Let's say that I put the "red ball" and "blue ball" textures in a single texture called "balls". By specifying the texture coordinates so that only the left or right half of the texture is drawn I can "cut out" a piece of the image and apply it to my game object. If I did this I would be able to render all 50 blue/red balls with only one draw call since they are drawing off the same texture. You can see an example of this technique in the link I provided above. Even when you specify texture coordinates the renderer will not automatically know how to display the vertices. 4 points could be a 'filled in' rectangle or 4 lines or really just 4 single points - you might even draw the objects with a texture one minute and press a button later to display everything as lines to produce a 'wireframe' effect. So in order to draw a texture using vertex arrays we will need to provide the following to the renderer: - The texture (duh) - The collection of points that use this texture (i.e. all the corners that make up the objects that use this texture) - The way that they should be drawn (Quad, line, point respectively meaning 'filled in', 'wireframe' and 'single points'. There are other so-called primitive types but for now just knowing about quads will suffice) The textures are kept in a map inside a new managing class called TextureManager. If you're not familiar with the map datatype, it's a way to store key/value pairs similar to the way primary keys work for a database. The texture is associated with a unique string value (in this case, the name of the texture). If you'd like to know more check out the wikipedia articles on associative arrays and associative containers. The game objects store their own vertices and a string that corresponds to one of the key values from the texture map. For example: the texturemap might contain a texture with key-string "blue ball". Every game object that uses this texture would have the datamember textureName set to "blue ball". When the renderer want to draw the blue ball texture it loops over all the objects and collects the vertices that belong to objects with textureName set to "blue ball". In pseudocode, the steps taken to render all the textures look like this: - Loop over the different textures - Create a vertex array to store the points of all the objects that use this texture - Loop over all the game objects - If object::textureName equals texture key-string: collect the vertices for this object and add them to the vertex array - end of game object loop - call draw() with the current texture and the vertex array- end of texture loop Here's what that looks like in code. Though the syntax might be a little confusing it's really just following the steps I outlined above. void TextureManager::drawAllTextures(std::vector& objectList){ std::map::const_iterator textureIterator = m_textures.begin(); //loop over all textures while (textureIterator != m_textures.end()) { //vertex array for the current texture sf::VertexArray* vertexArray = new sf::VertexArray(sf::Quads); //collect all vertices which use this texture std::vector::const_iterator objectIterator = objectList.begin(); while (objectIterator != objectList.end()) { //if the object uses this texture //retrieve object's tranformed vertices into vertexArray if ((*objectIterator)->getTextureName() == textureIterator->first) { (*objectIterator)->getTransformedVertices(vertexArray); } ++objectIterator; } //draw the current texture and move on drawTexture(textureIterator->first, vertexArray); ++textureIterator; }} The method 'getTransformedVertices()' retrieves the (transformed) points that make up the object in question. If you don't understand what the word 'tranformed' means it's a way of 'positioning' the object in a certain place. The object knows its own points in a local frame of reference (my toes are 1.7 meters below my head and 0 meters in front of my nose) - transforming these points places them in the 'global' space of the game (my toes are 10 meters away from the nearest crosswalk and 100 meters below the top of that building). It's outside of the scope of this article to explain this properly so if you don't understand what I'm talking about I strongly recommend that you learn more about the use of matrixes in game development. You could start here. The benefit of working this way is that I don't have to recalculate all the points every time an object moves. I simply have to adjust the transformation matrix which 'places' the vertices in the game world. The same goes for scaling and rotation so it's a pretty neat trick to have in your toolbox. Once all the points for the current texture have been collected, the texture is rendered in the following piece of code:void TextureManager::drawTexture(std::string name, sf::VertexArray* vertices){ sf::Texture* texture = m_textures.at(name); if (texture != 0) { sf::RenderStates renderstate; renderstate.texture = texture; m_pRenderWindow->draw(*vertices, renderstate); }} First I attempt to retrieve the texture to verify that it exists (drawing textures that don't exist is not a good idea). Then I create a renderstate which will hold the rendering information. A renderstate is just a way to pass along information to the renderer - you might want to manipulate blending modes for example. Since I'm only interested in drawing rudimentary textures for now I simply set its texture datamember. Finally I pass the vertex array and renderstate to SFML which will take care of the drawing for me. Ok guys, that's it for now. Keep in mind that I am a relatively inexperienced game programmer which means that all the code in this journal should be taken with a grain of salt. If you think you know a better way to batch draw calls - you probably do and I'd love to hear about it in the comments section! Thanks for reading and as always you can download the code in its current state here.
  2. Arkanong development shots

    Screenshots detailing the development of my first game arkanong.
  3. C++ Primer - CodeBlocks

    Sales_item.h is a header file which you'll find in folder "1" of the .zip you linked to. Most likely the problem is because code::blocks starts looking for this file from a different "starting point" (= working directory) than visual studio. I'm not familiar with this IDE but I think you could try copying the header file to the directory where the *.cbp (= project file) is located. EDIT: also take a look at this
  4. If you're just starting out I would strongly advise you to forget about 3D games for now. Making games takes a huge amount of work so adding the additional complexities of 3D mathematics and rendering just needlessly steepens the learning curve which will kill your motivation. I wouldn't even touch directX or openGL until you've made a few games with simpler API's such as SDL, SFML or allegro.  If you don't know how to code even a simple tetris game you really have no business starting a 3D project, boardgame or otherwise.    You say you have a theoretical understanding of C++, I don't mean to sound blunt but that's just not going to cut it. The same principle as stated above applies: you're making things harder by trying to put together a game when you should just be learning how to think like a programmer   So, to summarize: first learn c++ for a couple of months, then make a few small games with user-friendly API's and after you can starting looking at directX or openGL tutorials     That said, if you absolutely must code a 3D directX project, Frank Luna's book is pretty good.
  5. Programming for the web is similar enough to programming stand-alone applications, with a few twists. As with anything you're going to want to pick a language, get the fundamentals down and then start with a few *small* projects to get your feet wet.   I'm not much of a web-developer, but html5 would be my choice for a beginner:   step 1) [url=http://www.w3schools.com/html/html5_intro.asp] learn html5[/url]   step 2) [url=http://www.stanford.edu/class/msande91si/www-spr04/readings/week1/InternetWhitepaper.htm] know how the web works[/url]   step 3) [url=http://www.html5gamedevelopment.com/]make games[/url]   step 4) ???   step 5) profit!
  6. Your game is a dime a dozen

    You can't expect original ideas to spring fully formed in your mind - everything is a derivative in one way or another. Metal gear's stealth mechanic was a combination of technical restrictions and Hideo Kojima having just watched 'the great escape', for example.    I keep a notebook that I fill with clippings, quotes and the occasional drawing and make a point to look through it all regularly - the idea is that come into contact with things you wouldn't normally think of in order to make connections that you otherwise wouldn't have. One example might be that you're designing a character and come across a picture for a carburator which gives you the idea to give that character a mechanical heart.   As it happens, in this book there are a few quotes which are relevant to your issue:   "to find the answer one must first understand the question"   "extraordinary products are merely side effects of good habits"   "the object of painting a picture is not to make a picture - however unreasonable that may sound. The object, which is back of every true work of art, is the attainment of a state of being, a state of high functioning, a more than ordinary moment of existence. The picture is but a by-product of the state, a trace, the footprint of the state" (robert henri)   "I do not always know what I want, but I do know what I don't want.” (stanley kubrick)   ..by which I mean to say that you should just worry about making games for now. Then, when the game is done think about what you like and don't like about it and why. Then make the next game a little bit better. The quote by robert henri pertains to shutting off your inner critic and "going with the flow" - if you are criticizing your own work while you are making it you will also be afraid to play around and experiment, which will prevent you from gaining fresh perspectives.   Don't consider what you're making as something which other people have to like - think of it as a toy which you're messing around with and try to remember what was fun and what wasn't. Then use that for your next project.  Don't think of making something as "putting the good bits in" but as "taking the bad bits away". And as always the golden rule is to keep your nose to the grindstone - mastery takes practice.
  7. To make the game a bit more interesting we're going to add a few hexagonal barriers in the playing field. This object is different from the paddle and balls in that it doesn't have a 'regular' shape. This means that using a rectangular or circular hitregion will not cover the object properly. Now, I could fudge the dimensions of the hexagon a little and consider it a circle for the purposes of collision detection, but where's the fun in that? Luckily I found a neat little algorithm online which detects collisions between a circle and a line segment. Here's how it works: - make a vector which represents the line segment. We will call this vector d and form it by subtracting the start of the line segment from the end of the line segment. linevector = endPoint - startPoint => d = l - e - make a vector from the center of the circle to the start of the line segment. We'll call it vector f and form it by subtracting the circle's position from the start of the ray. We'll use this later on to simplify the equation. centerToStartPoint = start - center => f = e - c - combine the two following equations: a) p = e + t*d This equation locates the collision point on the line segment by starting from the first point (e) and 'moving' along the vector (d) by a certain percentage (t). In other words, if you have a line that starts at (4,0) and ends at (10,0), and a collision occurs in the middle of the line (= 50%) t will be 0.5 and p will be equal to (9,0). b) (x - h)[sup]2[/sup] + (y - k)[sup]2[/sup] = r[sup]2[/sup] This equation uses the pythagorean theorem to represent circle 'touching' the collision point. (h,k) is the center of the circle it basically means that if you take the distance from the collision point to the centre of the circle it will be equal to the radius (r) of the circle. Now we're going to combine these two equations to end up with our actual collision detection formula: 1 ) first expand equation number two. You'll end up with the following: x[sup]2[/sup] - 2xh + h[sup]2[/sup] + y[sup]2[/sup] - 2yk + k[sup]2[/sup] - r[sup]2[/sup] = 0 2) now, in the first equation the points p, e and vector d consists of two components (x and y). So we 'split' it into: x = e[sub]x[/sub] + td[sub]x[/sub] y = e[sub]y[/sub] + td[sub]y[/sub] Then you substitute the x and y variables in step 1 with these ones. You'll end up with this: ( e[sub]x[/sub] + td[sub]x[/sub] )[sup]2[/sup] - 2( e[sub]x[/sub] + td[sub]x[/sub] )h + h[sup]2[/sup] + ( e[sub]y[/sub] + td[sub]y[/sub] )[sup]2[/sup] - 2( e[sub]y[/sub] + td[sub]y[/sub] )k + k[sup]2[/sup] - r[sup]2[/sup] = 0 expand => e[sub]x[/sub][sup]2[/sup] + 2e[sub]x[/sub]td[sub]x[/sub] + t[sup]2[/sup]d[sub]x[/sub][sup]2[/sup] - 2e[sub]x[/sub]h - 2td[sub]x[/sub]h + h[sup]2[/sup] + e[sub]y[/sub][sup]2[/sup] + 2e[sub]y[/sub]td[sub]y[/sub] + t[sup]2[/sup]d[sub]y[/sub][sup]2[/sup] - 2e[sub]y[/sub]k - 2td[sub]y[/sub]k + k[sup]2[/sup] - r[sup]2[/sup] = 0 group => t[sup]2[/sup]( d[sub]x[/sub][sup]2[/sup] + d[sub]y[/sub][sup]2[/sup] ) + 2t( e[sub]x[/sub]d[sub]x[/sub] + e[sub]y[/sub]d[sub]y[/sub] - d[sub]x[/sub]h - d[sub]y[/sub]k ) + e[sub]x[/sub][sup]2[/sup] + e[sub]y[/sub][sup]2[/sup] - 2e[sub]x[/sub]h - 2e[sub]y[/sub]k + h[sup]2[/sup] + k[sup]2[/sup] - r[sup]2[/sup] = 0 write as dotproducts, where d = line segment, c = centre of circle => t[sup]2[/sup]( d DOT d ) + 2t( e DOT d - d DOT c ) + _e DOT _e - 2( _e DOT_c ) + _c DOT _c - r[sup]2[/sup] = 0 => t[sup]2[/sup]( d DOT d ) + 2t( d DOT ( e - c ) ) + ( e - c ) DOT ( e - c ) - r[sup]2[/sup] = 0 remember that e is the starting point of the line segment, and that we have a vector f which is the vector from the start of the line to the center of the circle (f = e - c) -> we can use this to further simplify the equation => t[sup]2[/sup]( d DOT d ) + 2t( d DOT f ) + f DOT f - r[sup]2[/sup] = 0 After we've simplified the formula as much as possible we ended up with the following: t[sup]2[/sup] * (d DOT d) + 2t*( f DOT d ) + ( f DOT f - r[sup]2[/sup] ) = 0 where: f is the vector from the centre of the circle to the starting point of the ray d is the vector representing the line itself r is the radius of the circle t is the 'percentage' of the line at which is the collision occurs If you look closely, you will see that this equation is of the form where: a = d DOT D b = 2 * f DOT d c = f DOT f - r^2 This is a quadratic equation, which means we can solve it by using the quadratic formula!sf::Vector2f lineVector = p_rayEnd - p_rayStart; sf::Vector2f centreToStartOfRay = p_rayStart - ballPosition; float a = (lineVector.x * lineVector.x) + (lineVector.y * lineVector.y); float b = (2 * ((centreToStartOfRay.x * lineVector.x) + (centreToStartOfRay.y * lineVector.y))); float c = ((centreToStartOfRay.x * centreToStartOfRay.x) + (centreToStartOfRay.y * centreToStartOfRay.y)) - (ballRadius * ballRadius); //calculate discriminant to determine if collision has taken place float discriminant = (b*b) - 4 * a*c; If the discriminant if greater than or equal to zero, then the circle has collided with the ray at some point. Calculate the solution to the equation by using the quadratic formula and you will end up with the 'percentage' values which in turn can be used to find the coordinates of the collision point. Now, these calculations consider the line as being infinitely long so we need to check if these percentages are between 0 and 1 (= 0% to 100% of the line). If they are greater or lesser than these values then the collision was either before or after the two points which make up the line segment. //one or more collision points with entire ray //(meaning also past the actual corners of the hexagon) if (discriminant >= 0) { //determine t1 & t2 //(this is the 'percentage' along the ray at which the collision point can be found) discriminant = sqrt(discriminant); float t1 = (-b - discriminant) / (2 * a); float t2 = (-b + discriminant) / (2 * a); //if the 'percentages' are between 0 and 1 there are //one or more collisions points within the actual line segment //(meaning contained between the two corners) if ((t1 >= 0 && t1 = 0 && t2
  8. Programmers talk "Alien"

    Ah my mistake, they used to be free but it seems they switched to a subscription format - pity!   There's still the whole wide internet at your disposal though, here are a few links to help you get started:  (remember that shopping around for a resource that suits your learning style is part of the process so always keeps google at the ready)   http://en.wikiversity.org/wiki/Introduction_to_Computer_Science http://math.hws.edu/eck/cs124/javanotes6/ http://www.deansdirectortutorials.com/Lingo/IntroductionToProgramming.pdf     EDIT: I see that you've clarified your initial question. Learning how to write an engine is mostly writing the code that you would be able to reuse in your next project (your next game will also need input, sound, graphics, etc -- this code is called the engine because it 'drives' the game and is usually seperated from the game logic to make it easier to reuse).   So, rather than google "how to build a game engine" you should take a look at tutorials for graphics libraries (directx, opengl, sfml, sdl, ...) since this is primarily what your engine will be doing. If you click the link for the directx tutorials below you will see example code that runs a gameloop, constructs a window and draws stuff onscreen - just add input and sound and you've got an engine! http://www.directxtutorial.com/LessonList.aspx?listid=11   Obviously I'm simplifying things a bit here - constructing an engine also requires careful planning (if your code is a mess and the game code isn't seperated properly you will have a difficult time reusing the code).     Now I wouldn't recommend directX for a beginner, since it can be quite daunting. In fact I would forget about making an engine altogether and focus first on learning the principles of good software design. This means learning about datatypes, design patterns and writing a few small programs to get a hang of them.   http://www.tenouk.com/Module2.html http://sourcemaking.com/design_patterns http://www.oodesign.com/     Once you feel confident that you know how to write good code and structure it logically it's time to make a few small games using beginner-friendly API's such as SFML. This will enable you to get familiar with how to use a game engine without having to actually write out everything. This step is very important! I did it the dumb way and just started writing a directX engine - the result is it took me way too much time, the design was sloppy and the performance wasn't great. Not very motivating I can tell you! Yes, I learned alot but I could have used that time to make 6 games in SFML so trust me on this one.   http://www.sfml-dev.org/tutorials/2.1/ http://www.gamefromscratch.com/page/Game-From-Scratch-CPP-Edition.aspx   After writing a few games you will have some experience under your belt and now you can start thinking about how to write your own engine. Start by taking a look at the source code of other engines (SFML is open source, for a start) and planning everything out on a piece of paper (this is where your experience with design patterns is vitally important and it's also the reason you shouldn't make engines unless you've made few games - how would you know which classes the engine needs if you don't know how to use one?).     EDIT: also, don't worry too much about doing things the most efficient way possible your first go around - get it to work first. Your only goal for now should be to get the code to do what it's supposed to, the rest will come naturally from experience. I have never made a program that didn't require some googling and self-education along the way.
  9. Programmers talk "Alien"

    If you're going to learn about computing you should get used to abbreviations because you're going to have to get to know a boatload of them (dslam, lan, isp, tcp, udp, rfc, gui, cli, the list is seemingly endless).   I can understand why you would find it frustrating but there is a good reason why people use this "alien language" - if I say to somebody "I made my main engine class a singleton" I can describe in 7 words what's going on rather than the more difficult to understand "I made a class which serves as an central administrative point for all subsystems with a private constructor, it can have only one instance and  is globally accessible". Don't worry though, you live in an age where things can be researched in a matter of seconds (programmers in the eighties had to use paper manuals, now that's a pain!). So google everything you don't understand and if you still don't get it try the gamedev chat, it's full of knowledgeable people who will be happy to help you.   Also, if you're going to ask questions you should try to be a bit more precise: what terms don't you understand and what should the tutorials you're asking for be about? If you're looking for introductions to programming you could try udacity.com (intro to computer science would be my choice).