Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Looking for a Game Tutorial

This thread is locked; no one can reply to it. rss feed Print
 1   2   3   4 
Looking for a Game Tutorial
Thomas Fjellstrom
Member #476
June 2000
avatar

I dunno, if you treat the "index" as an opaque "bitmap id", rather than an index then you can change the underlying implementation at any time and not have to worry about passing pointers around, or using string based hashing.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

J-Gamer
Member #12,491
January 2011
avatar

Quote:
J-Gamer said:

Thanks... I was wondering how you guys all do that :p

acc.js [github.com] :-X

I was actually talking about how to be able to copy both the text AND the link to the specific post ^^

I haven't studied Java yet, so I don't really understand the code ._.
I might look into it later, when I have some spare time to learn Java.

bamccaig said:

The object doesn't actually need to know what the image index refers to because (presumably) it will be passed in and set from the outside world by something that does know. Using indexes like that for your sprites isn't a terrible idea, but there are better ways to do it, especially in C++. For example, you could store boost::shared_ptr<BITMAP> and then store a copy of the sprite's smart pointer directly in your class. You could even load your sprites into a std::map<std::string, boost::shared_ptr<BITMAP> > so that you could later refer to them by name. That's generally how I have done it.

In the code we get to see, it's clear that he wants the function to know which number to return, probably based on some state parameters of the object itself.
I have to say I never used Boost, so I don't know how it works.

" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo
"If your body was a business, thought would be like micro-management and emotions would be like macro-management. If you primarily live your life with emotions, then you are prone to error on the details. If you over-think things all the time you tend to lose scope of priorities." - Mark Oates

Thomas Fjellstrom
Member #476
June 2000
avatar

J-Gamer said:

I was actually talking about how to be able to copy both the text AND the link to the specific post ^^

The forum auto links it most times.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

bamccaig
Member #7,536
July 2006
avatar

J-Gamer said:

I was actually talking about how to be able to copy both the text AND the link to the specific post ^^

That's actually specifically what it can do. :) Though it isn't perfect: it doesn't handle HTML properly [yet]. When it fails to quote, you can use a separate feature to just fill in the <quote name="user" src="uri"></quote> part though.

J-Gamer said:

I haven't studied Java yet, so I don't really understand the code ._.
I might look into it later, when I have some spare time to learn Java.

It's JavaScript, not Java. They are two completely different languages with little in common. In theory, you should be able to just drop it in and use it, but in practice having some JavaScript experience would come in handy because it isn't perfect. :) (ML also discourages its use because he doesn't want people abusing its convenience)

J-Gamer said:

In the code we get to see, it's clear that he wants the function to know which number to return, probably based on some state parameters of the object itself.

The object would just store its sprite index, or an animation, which itself would contain a set of indexes. That would be part of the object's state. The object doesn't physically need to know what those indexes mean. It can trust the outside world to give it the right indexes. Of course, it's not a perfect model, but it can work if you're careful.

A better model is probably storing an animation or a set of animations, each of which containing a set of smarter pointers to your sprites. :) That's a relatively complicated model though for beginner.

J-Gamer said:

I have to say I never used Boost, so I don't know how it works.

Boost is a very large C++ framework. The boost::shared_ptr<T> is a smart pointer that manages the memory for you automatically. Essentially, it just stores a copy-count/reference-count internally. When you make copies of it the count is incremented, and when those copies are destroyed the count is decremented. When the count reaches zero, the stored object is automatically destroyed, freeing the memory. It's entirely automatic.

#SelectExpand
1typedef boost::shared_ptr<int> IntPtr; 2typedef boost::shared_ptr<ALLEGRO_BITMAP> AlBitmapPtr; 3 4{ 5 { 6 IntPtr i(new int(5)); 7 } // The int is deleted here automatically. 8 9 AlBitmapPtr b; 10 11 { 12 AlBitmapPtr b2( 13 al_load_bitmap("./path/to/file.bmp"), 14 al_destroy_bitmap); 15 16 b = b2; 17 } 18} // The ALLEGRO_BITMAP is destroyed here automatically.

It's a bit like garbage collection, except that it works immediately instead of waiting some indeterminate amount of time and checking for objects that can be freed. The downside is that it can't handle cyclical references, so you do need to pay some attention if you end up creating those.

gnolam
Member #2,030
March 2002
avatar

I said:
gnolam said:

Also: the code you're giving us shouldn't even compile...

Quote:

masked_blit(Sprite[Object->GetImage()], Buffer, Object->GetFrame() * Object->GetW(); Object->GetStance() * Object->GetH(); Object->GetX() - Camera->GetX(); Object->GetY() - Camera->GetY(); Object->GetW(), Object->GetH());

I was referring to the semicolons. :P

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

J-Gamer
Member #12,491
January 2011
avatar

bamccaig said:

It's JavaScript, not Java.

:-[ I should have know that at least...

" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo
"If your body was a business, thought would be like micro-management and emotions would be like macro-management. If you primarily live your life with emotions, then you are prone to error on the details. If you over-think things all the time you tend to lose scope of priorities." - Mark Oates

Gabriel Campos
Member #12,034
June 2010
avatar

gnolam said:

I was referring to the semicolons.

Oh..yes, I dont realized...
The function works nicely after I declared pure virtual...
if dont it says..undefined reference to vtable in cObject..or something like this...
Strange . ..

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

The function works nicely after I declared pure virtual...
if dont it says..undefined reference to vtable in cObject..or something like this...

It's because every function you declare has to also be defined. Also, you should note that every base class that has virtual functions should also have a virtual destructor. This is so that the appropriate destructors get called for the derived classes.

/// In Base.hpp

class Base {
protected :
   Data d;
public :
   Base() : d() {}
   virtual ~Base() {}
   virtual void DoSomething();
};

/// In Base.cpp

void Base::DoSomething() {/*...*/}

Gabriel Campos
Member #12,034
June 2010
avatar

But why to put in the destructor??
I couldnt understand this part of the code

#SelectExpand
1/// In Base.hpp 2 3class Base { 4protected : 5 Data d; // Couldn understand 6public : 7 Base() : d() {} // Couldn understand 8 virtual ~Base() {} 9 virtual void DoSomething(); 10}; 11 12/// In Base.cpp 13 14void Base::DoSomething() {/*...*/}

Other thing I want to learn is..why use this implementation on the constructor code of some object, something like player..

#SelectExpand
1class cPlayer{ 2 cPlayer(int x, int y) : (x, y); // can someone explain to me?

I want to thanx evebody too.. Since this post I learned a lot about OOP.. ;D

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

But why to put in the destructor??

This is so that the appropriate destructors get called for the derived classes.

I couldnt understand this part of the code

Data is just a made up class, used for an example.

#SelectExpand
1class Data { 2private : 3 int i; 4 float f; 5 char c; 6public : 7 Data(); 8 Data(int _integer , float _float , char _char); 9}; 10 11Data::Data() : 12 i(0), // call int constructor for integer type 13 f(0.0f), // call float constructor for float type 14 c('\0') // call char constructor for char type 15{} 16 17Data::Data(int _integer , float _float , char _char) : 18 i(_integer), 19 f(_float), 20 c(_char) 21{}

The code in the constructor after the semicolon and before the braces is called an initialization list. It gives the member variables of the class an initialization value. Always initialize the members of the class before using them. If you don't, then their starting values are undefined, and hold the value of whatever was left over in memory from before.

An example of what not to do :

Data::Data() {
   printf("i = %i , f = %f , c = %c" , i , f , c);// Could print anything
                                                  // because i , f , and c are
                                                  // uninitialized
}

Gabriel Campos
Member #12,034
June 2010
avatar

Well, couldnt understand yet...But I got a c++ book from a good university here, so I will study all this part. . . ;D
But lets go to another game concept question, How to make a lot of stages and add enemies there.. My solution is this, but I think its a little weird.. :P

#SelectExpand
1 2int main(){ 3 init(); 4 Stage01(); 5 Stage02(); 6 Stage03(); 7 deinit(); 8} 9END_OF_MAIN(); 10 11int Stage01(){ 12 // Here I create the objects 13 cPlayer Player(200, 200); // x, y, parameters 14 cEnemy Enemy[10]; // and on and on 15 16while(inGame){ 17 // the game code 18} 19} // end of Stage 20 21 22int Stage02(){ 23 // Here I create the objects again 24 cPlayer Player(100, 250); // x, y, parameters 25 cEnemy Enemy[6]; 26 27while(inGame){ 28 // the game code 29} 30} // end of Stage

So, this is the right way to do this??
Or should create all objects, lets say..make them global... and use it??
Create a method to put them in the right stage and position?? ???

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I would use something like this. You can set up the current stage in the CreateStage function, and then just run the current stage in main.

#SelectExpand
1class Stage { 2private : 3 BITMAP* stage_map; 4 BITMAP* buffer; 5 cPlayer Player; 6 vector<cEnemy*> Enemies; 7 cCamera Camera; 8 9public : 10 Stage() : stage_map() , Player() , Enemies() {} 11 ~Stage() {Free();} 12 void Free() { 13 if (buffer) { 14 destroy_bitmap(buffer); 15 buffer = 0; 16 } 17 if (stage_map) { 18 destroy_bitmap(stage_map); 19 stage_map = 0; 20 } 21 for (int i = 0 ; i < Enemies.size() ; ++i) {delete Enemies[i];} 22 Enemies.clear(); 23 } 24 void SetStageMap(BITMAP* bmp) { 25 if (!bmp) {return;} 26 if (stage_map) {destroy_bitmap(stage_map);} 27 stage_map = bmp; 28 } 29 bool Update(double tsec) { 30 // collision testing goes here 31 Player.Update(tsec); 32 for (int i = 0 ; i < Enemies.size() ; ++i) { 33 Enemies[i]->Update(tsec); 34 } 35 Camera.CenterOn(Player.CX() , Player.CY()); 36 } 37 void CheckInputs() { 38 Player.CheckInputs(); 39 for (int i = 0 ; i < Enemies.size() ; ++i) { 40 Enemies[i]->CheckInputs(); 41 } 42 } 43 void Draw(BITMAP* dest) { 44 int camx = Camera.X(); 45 int camy = Camera.Y(); 46 int camw = Camera.W(); 47 int camh = Camera.H(); 48 blit(stage_map , buffer , camx , camy , 0 , 0 , camw , camh); 49 Player.Draw(buffer , -camx , -camy); 50 for (int i = 0 ; i < Enemies.size() ; ++i) {Enemies[i]->Draw(buffer , -camx , -camy);} 51 blit(buffer , dest , 0 , 0 , 0 , 0 , buffer->w , buffer->h); 52 } 53 54 void SetPlayerStats(/*...*/); 55 void AddEnemy(cEnemy* enemy) { 56 Enemies.push_back(enemy); 57 } 58}; 59 60 61Stage* CreateStage(int stage_num) { 62 Stage* new_stage = 0; 63 switch (stage_num) { 64 case 1 : 65 return new Stage(/*... parameters ...*/); 66 break; 67 case 2 : 68 new_stage = new Stage(); 69 /* Alter the new stage here */ 70 return new_stage; 71 break; 72 default : 73 Error(); 74 break; 75 } 76 return new_stage; 77} 78 79/// In main 80 81int stage_num = 1; 82Stage* current_stage = CreateStage(stage_num); 83 84while (playing) { 85 current_stage->Draw(screen); 86 current_stage->CheckInputs(); 87 current_stage->Update(time_passed); 88 if (current_stage->StageComplete()) { 89 delete current_stage; 90 ++stage_num; 91 current_stage = CreateStage(stage_num); 92 } 93 if (current_stage->GameOver()) {playing = false;} 94} 95 96if (current_stage) {delete current_stage;}

Gabriel Campos
Member #12,034
June 2010
avatar

Hmm... So you are telling me to make all the game in a class and there make a system to load the maps and the enemies..??
So in the main function I only call the functions of this class...But I make my map based on tiles... I will look more detailed this in home..thanx

 1   2   3   4 


Go to: