Jump to content

  • Log In with Google      Sign In   
  • Create Account

ifthen

Member Since 26 Sep 2010
Offline Last Active Jul 09 2014 05:07 AM

#5044145 Vector MADNESS

Posted by ifthen on 18 March 2013 - 01:23 AM

As has been said, use std::vector::back() or vec[vec.size()-1], but ALWAYS check if the vector is not empty. Using either of those without checking for non-emptiness results in undefined behaviour and it will most likely overwrite sizeof(vectype) bytes before the start of vector data, corrupting the memory or causing a segmentation fault.

 

vec.at(vec.size()-1) throws an exception if the vector is empty, but it sacrifices speed and does not solve the problem except for alerting you instead of corrupting memory.

 

Paradigm Shifter: You, sir, have made my day.




#5037427 Projectile Class Format

Posted by ifthen on 27 February 2013 - 08:01 PM

Will every projectile be different? I do not think so, we can say that every projectile behaves according to its type. Make every projectile have some kind of reference to its type (enum, pointer, reference, ID...). That is 8 bytes overhead at most, which is perfectly okay. You then modify the enemy using the projectile type and are okay.




#5026561 What makes a good beat'em up game?

Posted by ifthen on 28 January 2013 - 04:43 PM

I think that what separates good beat'em games from bad ones (and not only beat'em, in fact) is strategy. In bad game, you just mash buttons / hold the FIRE button / whatever, but in good ones, you have to think (if only subconsciously). What is this enemy's strategy? How can I avoid his blows? What strategy should I use to defeat him?

 

Force a pause between blows, so a button masher does minimal damage. Make the enemy do attacks that cannot be blocked, so the player is forced to move. And make each type of enemy move according to some set of tactics (that can be even randomized a little if you are unforgiving). Be creative and make the tactics of every type of enemy different. The player may lose a few times, but he must learn. That way, a victory will be much sweeter, brought with blood and tears, than an easy one.

 

I don't think that your list must apply in every case; it is the standard of the current beat'em ups, but it is not the "holy grail". Experiment and find what you like.




#5016823 I have two functions that do the same thing. Which one is faster?

Posted by ifthen on 02 January 2013 - 02:28 PM

Okay another question. I am implementing your suggestions but I have a problem. I do not know if it would be efficient for me to include the data type Map as a variable in Entity.
The best way is to use a reference (it doesn't copy the data of object, but you use it in same way as an object, unlike a pointer). Making a reference a class member is a bit tricky (requires initializer lists), but this code does it:
//file Entity.h
#pragma once
//forward declaration of a map
//in C++, you can declare a class many times,
//but define it only once!
class Map;
class Entity {
  public:
    //you have to make a constructor with an initialization list
    //because the reference, unlike a pointer, must be defined at its initialization
     Entity(Map & _map) : map(_map) {
      //your constructor, blah blah blah
    }
    //note you can also use Entity(Map & map) : map(map) {...}, it has the same effect
    //(refer to footnote 1)
    void foo();
    protected:
      Map & map;
};

//file Map.h
#pragma once
#include "Entity.h"
class Map {
  void bar();
  //you can pass the current object as a parameter to a function using this
  Entity thisMapEntity() {
    return Entity(this);
  }
};

//file Entity.cpp
#include "Entity.h"
#include "Map.h"
Entity::foo() {
  //note you couldn't define foo in Entity.h,
  //because class Map wasn't defined yet,
  //just declared 

  //calls the entity's map's function "bar"
  map.bar();
}
Footnote 1


#5016651 Tiled based game/rpg with more than 1 player on a tile?

Posted by ifthen on 02 January 2013 - 05:56 AM

Targeting a player seems fine to me. You just have to use precise picking, so you don't get a false positive.

 

I think that the issue with splitting tiles is that you currently can make a world in which the tile is so small that 2 characters would not even fit there physically. See Runescape: The tiles are (based on my estimate) 1x1 metre squares, so the distance between them is (expert mathematics) 1 metre, which is roughly the distance people stand next to each other without feeling uncomfortable (personal space). If you were to allow two people on the same tile, it would imply that they are in a close relationship to each other (or wrestling smile.png ). If you have larger tiles (for example 4x4), you can always split them for precise measurements.

 

An important thing to consider is whether the characters are tile-locked. If they aren't, you can do just fine by not allowing them to get too close to each other. If they are, my last paragraph applies.




#5016644 I have two functions that do the same thing. Which one is faster?

Posted by ifthen on 02 January 2013 - 05:18 AM

Please read a book about C++. You are calling a METHOD (as opposed to function). A method belongs to an object. Therefore, you can access a pointer to object you are calling your method from using keyword 'this'. So you can write
void Entity::turning(char facing1, vector<Tile> mv) {
    if (this->is_swing_hoe == false) {
                            if(this->facing != facing1) {
            this->facing = facing1;            this->wait_time = 0;
        }
        else if (this->can_pass(this->facing,mv,this)&& this->wait_time > 3) {
            this->frame = 1;            this->move_animation = true;
        }
    }
}
and 'this' will correspond to 'hero' if you call it like
hero->turning('d',mv);
Even better, you can remove all the 'this->' from above code. Your compiler knows that in methods, if you write a name of a variable you declared in the class of the object, that is the variable to use (if you didn't write a conflicting declaration in the method, of course).

You also should not pass a std::vector variable by value (that means, not using a pointer or, preferably, a reference). Why? Because your program needs to make a new copy of that vector. That means it must manually copy all the objects (in your case, tiles) your std::vector stores.
In fact, if you think about it, what should the Entity know? It should know on which map it is and its position. If you implement the Map class (which should probably have a vector of tiles), you can use something like
void Entity::turning(char facing1) {        
//not sure what THIS code does, but it is yours, so I won't modify it (except showing the 'OOP way')
    if (is_swing_hoe == false) {
        if(facing != facing1) {
            facing = facing1;
            wait_time = 0;
        }
        //suppose that map can extract all the needed information from the entity using getters
         else if (map->can_pass(this, facing1)&& wait_time > 3) {
            frame = 1;
            move_animation = true;
        }
    }
}
Voila! The function is much more readable. As a rule of thumb, you should always think twice before starting working on a new feature. How will I represent it? Who (which class) will use it? How should I implement it? If you ask and answer all the questions that come to your mind, you will find yourself writing much cleaner (and bug-free) code.


#5010603 Considering move to C++

Posted by ifthen on 14 December 2012 - 07:35 AM

Yes, OOP can lead to unnecessary abstractions in hands of an inexperienced programmer. Functional programming can lead to overcomplicated, not understandable and unclean code. None of these pitfalls is a reason not to use these paradigms, just a reason not to use libraries which abuse them.


#5010232 Considering move to C++

Posted by ifthen on 13 December 2012 - 08:36 AM

std::string and std::vector. I cannot overestimate their importance in managing code. String gives you a lot of clean functions (eliminates the most of buffer overruns), has its operators overloaded (that means no more concat) and is not zero-terminated (you can store whatever you like there). (C++ streams are also good for these reasons excluding the last one.) Vector gives you an easily resizable array and it stores its size for you, so no more arraysize integers. Both of them most definitely ease the development process.


OOP is great, but not everything is an object. That is why I do not like languages thet shoehorn OOP to situations where it does not work. C++ does not force you, however – it lets you choose.

There is clearly no reason nowadays why would not someone want to use C++ (except in circumstances where the STL is nonexistent). I would recommend you to switch.


#5006583 Help!How to draw all the objects in only one DrawPrimitive() call?

Posted by ifthen on 03 December 2012 - 07:02 AM

Hello Alan, welcome to Gamedev.
Answers to your questions:
1. DrawPrimitive() – it takes a buffer of vertices and draws the specified primitive (the first parameter). If you are rendering, for example, three triangles, DrawPrimitive() draws one triangle defined by points (counting from zero) 0, 1, 2, second triangle defined by points 3, 4, 5 and third triangle defined by 6, 7, 8. What the people tried to tell you is that you should put those points into one continuous (without gaps) buffer and call DrawPrimitive() once instead of calling it for every triangle.
2. Two different objects (like human or ball) should be drawn with one DrawPrimitive() each (there is a technique called instancing to go around that, but that is a very advanced topic). An important thing is that every object should (ideally) have only one texture, so you can draw it in one function call. It becomes problematic with more textures.


P.S.: Your written English is actually quite good (you get the point across and that is what counts Posted Image ).


#5006009 Variables within strings? (C++)

Posted by ifthen on 01 December 2012 - 05:17 AM

There is a C++ type for doing exactly this. Its name is std::stringstream. Usage example:
[source lang="cpp"]#include <sstream>//declare it somewherestd::stringstream ss; //internal string empty at beginning//usagess << "You, along with your " << numFriends << " friends, set up camp..."; //append this to the internal stringstd::string setUpCampLabel = ss.str(); //get a copy of stringbuilder internal stringss.clear(); //clear the internal stringss << "You were eaten by a bear!";std::cout << setUpCampLabel << std::endl <<ss.str(); //it is possible to print the internal string directly[/source]


#5005431 OpenGL 2D Book

Posted by ifthen on 29 November 2012 - 02:11 PM

OpenGL is a 3D graphics library. The only way to make OpenGL "2D" is to set up ortographic projection, but there is no functionality to deal with 2D rendering techniques like sprites or tiles. You would need to code all of that yourself, which is a super overkill.

Use SDL (OpenGL windowing library that has, among other extending functionality, support for 2D rendering) or DirectDraw (Windows only).


#5004313 Not quite sure where to start when it comes to drawing an array of sprites.

Posted by ifthen on 26 November 2012 - 02:56 PM

You should take a look at inheritance in C#. Look at classes and interfaces. You could do something like
[source lang="csharp"]interface GameObject { void draw();}abstract class Food : GameObject { protected boolean isEaten = false; abstract protected void eatenResponse(Snake eater); void eaten(Snake eater) { isEaten = true; eatenResponse(eater); }}class GoodFood : Food { void draw() { if (!isEaten) { //draw a sprite of good food } } protected void eatenResponse(Snake eater) { eater.grow(3); //the snake grows a lot and gets a score from it in his own function }}class GoodFood : Food { void draw() { //... } protected void eatenResponse(Snake eater) { eater.kill(); //poison is good for you }}[/source]

That way, you can just put every drawable object in a loop and do something like
[source lang="java"]//initList<GameObject> gameObjects = new ArrayList<GameObject>();Snake snake;gameObjects.add(snake); //OK if Snake inherits from GameObject...//food spawn routinegameObjects.add(new GoodFood()); //OK if GoodFood inherits from GameObject, which it does...//game loopfor (GameObject gameObject : gameObjects) { gameObject.draw(); //every GameObject has a draw() method, no need to cast if (snakeSomehowTouchedTheObject(snake, gameObject)) { //you can handle eating this way Food food = gameObject as Food; //you can do this if (food != null) { //is gameObject of type / inheriting type Food? food.eaten(snake); } //or even better this way (if you define the functions and modify the classes accordingly) for (GameObject gameObject2 : gameObject) if (gameObject.touches(gameObject2)) { gameObject.touched(gameObject2); gameObject2.touched(gameObject); } }}[/source]

Be warned, however, that inheritance, although making many things easier, is not a principle that can be used everywhere seamlessly (eg. networking). Professional programmers know at least functional and OOP programming well, you should learn both of these code styles if you want to "go with the wave".


#5001616 Impotant! Books to start learning video game programming ! I need it...

Posted by ifthen on 16 November 2012 - 01:29 PM

You have to think about your long-term goals. Do you want to
a) make games quickly (the goal is important),
b) learn a programming language and make a game with it (the goal and path to it are both important),
c) learn a programming language to understand how the computers work and then, maybe, start making a game one day in the distant future (the path is important)?

Look at those options and try to answer honestly. Now, let's see:
a) Use some of the "makers" available. It depends on which genre should the game be. Unity 3D is good for large-scale 3D. UDK (Unreal development kit) is good for indoor FPS games like Doom or Unreal. I've liked RPG Maker when I tried it (the target genre should be apparentPosted Image ). Game Maker is most suitable to 2D games.
b) I would suggest C# as it isn't AS (notice the capital letters) difficult as low-level languages like C++. You should be able to do "something" in 2 years.
c) ANSI C or C++ seems like a good entry point for this. You will need a lot of time and patience, but after a 5+ years, you should be able to program almost everything you wish (but be aware that the time needed to do it will still be in years).

Abandon the idea that you will be able to code a game in a short amount of time; you will fail. A game (engine) programmer should have 5+ - 10+ year experience with programming.

On the other hand, you are still young, so if you persist, you will find a new and interesting world of programming. The one where everyone bows to your every command (unless it's invalid, of course) Posted Image


#4999602 Specular mapping GLSL

Posted by ifthen on 10 November 2012 - 03:44 AM

I think that it is okay, the lightMatrix looks like the only pitfall. It should be the same as the modelview matrix.

Look at it this way: the fragment shader needs to know only three things for calculating lightning (for point light) – the position of the fragment (variable), the normal of the fragment (variable) and the position of the light (uniform). All of them must be in the same coordinate space.

(The normals use another matrix because of scaling. If you call glScalef(1,1,0.5), the normals must be scaled by the opposite because of stuff. The normal matrix preserves the rotation, doesn't have translation (the normals are true vectors, not positions) and corrects the scaling. Take note, however, that object space normal multiplied by the normal matrix is in eye space.)

(That also means you don't have to compute lightning in eye space, it can be done in object space too; that would mean that you can have a static light source, not one moving with the camera, without performing additional matrix calculations on the CPU. But you would have to you wanted a light static to camera. It really depends what to use on whether the light is carried by the cameraman (e.g. flashlight) or not (e.g. a chandelier).)

Other than that, it looks good to me.


#4998044 So I've learned C...

Posted by ifthen on 06 November 2012 - 09:00 AM

I would like to point out to the OP that the path to mastering a programming language (or a paradigm) is steep. Ask yourself: which concepts don't I understand completely? The memory management? Casting? The preprocessor? Bit shifts? Floating point numbers? String management? The standard library? Think about those. Don't assume that you know the whole foundation of C. Read about those concepts that you don't understand perfectly and experiment. Understand that learning language and mastering it to use it effectively are two entirely different things.

About C++ and Java – I personally think that it is easier to switch from a low-level language to a high-level one. It's like "hey, great libraries, rapid and easier coding, hooray!" as opposed to "man, there is no garbage collector, screw the memory management". But it is your call.




PARTNERS