SFML community forums
Help => General => Topic started by: ChonDee on January 17, 2012, 07:26:07 am
-
Hi everyone,
As I have been browsing around about SDL, I saw SFML mentioned as a potentially better and more sophisticated API for certain purposes. I haven't had performance issues with my game in SDL yet, what made me try to convert to SFML is the scaling, rotation and some alpha blending features it has. Even though my game isn't crazy big, I have decided that I will first try to rewrite my very first working build, which I didn't divide to multiple cpp and header files yet, and was only about 1K lines.
After I have rewritten it successfully, and ran it in Debug (in Visual Studio 2010) I ran about 5FPS, or lower. After some searching around I saw it mentioned that the debug libraries are slower, I should use Release instead, so I did. When I ran that inside Visual Studio with F5 it was faster, but still unacceptable frame rate (60FPS is the target). When I just build an executable and run it outside VS it ran okay, but when I increased the particles drawn a bit, the performance dropped. When I compared the SDL build with the SFML build, the SDL one got better performance.
Since the SFML sample projects that I compiled with the exact same settings, in the same solution file ran with 1000+ FPS I have figured there must be something wrong with my code and I am probably misusing some expensive SFML calls.
Most of the game objects are added this way:
void World::explosion(int x, int y){
for (int i=0, r=((rand() % 100) -80); i < 120 + r ; i++){
int xx = x + rand() % 10 - 5;
int yy = y + rand() % 10 - 5;
Particle a(xx, yy, 6);
v_particles.push_back(a);
}
Every actual image is only loaded once, during the initialization, and every object only has a sprite associated with the image. The objects will be drawn later in the game loop.
Later I have discovered, that even if I don't draw the objects, don't use any SFML draw calls at all during the game loop, just have the c++ logic running, with vector.push_back loops, the frame rate drops drastically.
This would make me think that what I am doing is too expensive on the CPU, too many vector operations are going on, and this has nothing to do with SFML, but all this runs perfectly fine when I use SDL.
At this point I am not even sure what exactly to ask, or what information to provide. Is this something that has to do with my VS 2010 solution settings perhaps? How come the sample projects with the debug SFML library in visual studio (pong for example) runs 800+FPS, while my game only gets 1-5 with those settings?
I have removed event polling too and I have removed the clock to make sure I am not doing something bad with that, that would affect the frame rate.
It looks like that the c++ operations are the bottleneck, because the frame rate is the same even if I comment out the SFML draw lines, but with the exact same, unchanged logic, with the SDL solution and SDL calls runs just fine.
How should I try to tackle this problem, what do you guys think that causes this?
Let me know if you would need my settings, or parts of my code, or something
Thanks in advance
Here are the frame rates of the sample pong.cpp included with SFML, and with my project
All are compiled from the same VS 2010 solution file
pong | Debug configuration | Started with F5 (Start Debugging) : 130FPS
pong | Debug configuration | Started with CTRL + F5 (Start without Debugging) : 175 FPS
pong | Release configuration | Started with F5 (Start Debugging) : 700 FPS
pong | Release configuration | Started with CTRL + F5 (Start without Debugging) 1600 FPS
myGame | Debug configuration | Started with F5 (Start Debugging) : 0 FPS, didnt draw another frame for 20seconds
myGame | Debug configuration | Started with CTRL + F5 (Start without Debugging) : ~1 FPS
myGame | Release configuration | Started with F5 (Start Debugging) : 2-3 FPS
myGame | Release configuration | Started with CTRL + F5 (Start without Debugging) : 27 FPS
myGame with SDL calls, 60FPS fixed
-
Oh wow :shock:! That is a huge difference. I'm sure its something you are doing with SFML that is very expensive. The first thing I would do to tackle this is review your code and take things out until you figure out whats the bottleneck. If you can share some of the code we can probably find the problem.
Best of luck!
-
I have made an analysis with AMD CodeAnalyst for both the SDL and SFML implementation, and I have attached the relevant part of code that strains SFML, for both the SDL and SFML one.
Please take a look at it.
Thank you
This one is for the SFML code:
CS:EIP Symbol + Offset Timer samples
0xd33560 Particle::show 73.98
0xd31a70 Player::show_particles 13.12
0xd36150 std::_Remove_if<Particle *,bool (__cdecl*)(Particle)> 9.28
0xd37290 std::_Uninit_copy<Particle *,Particle *,std::allocator<Particle> > 0.9
0xd32800 World::show_stars 0.68
0xd36ed0 std::_Find_if<Star *,bool (__cdecl*)(Star)> 0.68
0xd363c0 std::_Remove_if<Star *,bool (__cdecl*)(Star)> 0.45
0xd32630 World::show_enemies 0.23
0xd32790 dead_s 0.23
0xd33410 Star::show 0.23
0xd34d60 main 0.23
11 functions, 82 instructions, Total: 442 samples, 100.00% of shown samples, 2.27% of total session samples
So the way I tested performance, since in this early version of my game there aren't many objects, I increased the particles coming out from the player's thruster (in both SDL and SFML, the same number)
In the SFML one it seems like this takes up everything.
Here is the code for Particle::show:
void Particle::show()
{
//Show image
if (initialized == false){
if (type == 1) part = p1;
else if (type == 2) part = p2;
else if (type == 3) part = p3;
else if (type == 4) part = p4;
else if (type == 5) part = bparticle;
else if (type == 6){
if ((rand() % 4) == 0)
part = p1;
else if ((rand() % 4) == 1)
part = p2;
else if ((rand() % 4) == 2)
part = p3;
else if ((rand() % 4) == 1)
part = p4;}
initialized = true;
}
if(alive)
{
part.SetPosition(x,y);
App.Draw(part);
//apply_surface( x, y, part, screen );
}
//Animate
//stuff here is not relevant, and its exactly the same in both
I'll put the same code here for SDL for comparison, so you won't have to scroll back and forth.
void Particle::show()
{
//Show image
if (part == NULL){
if (type == 1) part = p1;
else if (type == 2) part = p2;
else if (type == 3) part = p3;
else if (type == 4) part = p4;
else if (type == 5) part = bparticle;
else if (type == 6){
if ((rand() % 4) == 0)
part = p1;
else if ((rand() % 4) == 1)
part = p2;
else if ((rand() % 4) == 2)
part = p3;
else if ((rand() % 4) == 1)
part = p4;}
}
if(alive)
apply_surface( x, y, part, screen );
//Animate
And CodeAnalyst result for the SDL code, Particle::show doesn't strain it as much at all
CS:EIP Symbol + Offset Timer samples
0xc05ab0 Particle::show 7.09
0xc08530 std::_Vector_iterator<std::_Vector_val<Particle,std::allocator<Particle> > >::operator++ 4.8
0xc04fd0 apply_surface 4.77
0xc0a2a0 std::_Vector_const_iterator<std::_Vector_val<Particle,std::allocator<Particle> > >::operator== 4.64
0xc08170 std::vector<Particle,std::allocator<Particle> >::end 4.39
0xc0bd00 std::_Vector_const_iterator<std::_Vector_val<Particle,std::allocator<Particle> > >::operator++ 4.27
0xc0bc10 std::_Vector_const_iterator<std::_Vector_val<Particle,std::allocator<Particle> > >::_Vector_const_iterator<std::_Vector_val<Particle,std::allocator<Particle> > > 4.23
0xc0a140 std::_Vector_iterator<std::_Vector_val<Particle,std::allocator<Particle> > >::_Vector_iterator<std::_Vector_val<Particle,std::allocator<Particle> > > 4.16
0xc0bcc0 std::_Vector_const_iterator<std::_Vector_val<Particle,std::allocator<Particle> > >::operator* 4.15
0xc02cb0 dead_p 4.1
0xc0bc80 std::_Iterator_base0::_Adopt 3.98
0xc084e0 std::_Vector_iterator<std::_Vector_val<Particle,std::allocator<Particle> > >::operator-> 3.95
0xc0a1f0 std::_Vector_iterator<std::_Vector_val<Particle,std::allocator<Particle> > >::operator++ 3.73
0xc0bd50 std::_Vector_const_iterator<std::_Vector_val<Particle,std::allocator<Particle> > >::_Compat 3.57
0xc0a1a0 std::_Vector_iterator<std::_Vector_val<Particle,std::allocator<Particle> > >::operator* 3.53
0xc085e0 std::_Vector_const_iterator<std::_Vector_val<Particle,std::allocator<Particle> > >::operator!= 3.41
0xc0f1e0 std::_Remove_if<Particle *,bool (__cdecl*)(Particle)> 3.15
0xc11dd0 std::_Move<Particle &> 2.75
0xc13d7f _RTC_CheckStackVars 2.65
0xc017fd ILT+2040(__RTC_CheckEsp) 1.69
0xc0f8d0 std::forward<Particle const &> 1.65
0xc105d0 std::_Construct<Particle,Particle const &> 1.61
0xc03dc0 Player::show_particles 1.32
0xc02e70 Particle::Particle 1.11
0xc09df0 std::vector<Particle,std::allocator<Particle> >::_Inside 1.01
0xc0def0 std::_Cons_val<std::allocator<Particle>,Particle,Particle const &> 1.01
0xc0de50 std::addressof<Particle const > 0.95
0xc13030 std::_Destroy<Particle> 0.92
0xc081e0 std::vector<Particle,std::allocator<Particle> >::push_back 0.9
0xc12a00 std::allocator<Particle>::destroy 0.85
0xc0ed60 std::allocator<Particle>::construct 0.8
0xc13d54 _RTC_CheckEsp 0.8
0xc09ff0 std::vector<Particle,std::allocator<Particle> >::_Orphan_range 0.72
0xc120c0 std::_Dest_val<std::allocator<Particle>,Particle> 0.71
0xc0f860 operator new 0.63
0xc0190b ILT+2310(?dead_pYA_NVParticleZ) 0.22
0xc05890 Star::show 0.22
0xc0c860 std::_Vector_const_iterator<std::_Vector_val<Star,std::allocator<Star> > >::operator* 0.22
0xc013d4 ILT+975(_RTC_CheckStackVars 0.21
0xc09210 std::_Vector_iterator<std::_Vector_val<Star,std::allocator<Star> > >::operator++ 0.21
0xc047a0 dead_s 0.19
0xc08e40 std::vector<Star,std::allocator<Star> >::end 0.18
0xc0c8a0 std::_Vector_const_iterator<std::_Vector_val<Star,std::allocator<Star> > >::operator++ 0.18
0xc0102d ILT+40(??D?$_Vector_iteratorV?$_Vector_valVParticleV?$allocatorVParticlestdstdstdQBEAAVParticleXZ) 0.16
0xc0147e ILT+1145(?_Compat?$_Vector_const_iteratorV?$_Vector_valVParticleV?$allocatorVParticlestdstdstdQBEXABV12Z) 0.16
0xc10190 std::_Destroy_range<std::allocator<Particle> > 0.16
0xc01785 ILT+1920(??E?$_Vector_iteratorV?$_Vector_valVParticleV?$allocatorVParticlestdstdstdQAEAAV01XZ) 0.14
0xc01915 ILT+2320(?showParticleQAEXXZ) 0.14
0xc0c7f0 std::_Vector_const_iterator<std::_Vector_val<Star,std::allocator<Star> > >::_Vector_const_iterator<std::_Vector_val<Star,std::allocator<Star> > > 0.14
0xc0140b ILT+1030(??8?$_Vector_const_iteratorV?$_Vector_valVParticleV?$allocatorVParticlestdstdstdQBE_NABV01Z) 0.13
0xc0c8f0 std::_Vector_const_iterator<std::_Vector_val<Star,std::allocator<Star> > >::_Compat 0.13
0xc011bd ILT+440(??9?$_Vector_const_iteratorV?$_Vector_valVParticleV?$allocatorVParticlestdstdstdQBE_NABV01Z) 0.11
0xc011e0 ILT+475(??0?$_Vector_const_iteratorV?$_Vector_valVParticleV?$allocatorVParticlestdstdstdQAEPAVParticlePBU_Container_base0 0.11
0xc0164f ILT+1610(?apply_surfaceYAXHHPAUSDL_Surface 0.11
0xc01a87 ILT+2690(??E?$_Vector_iteratorV?$_Vector_valVParticleV?$allocatorVParticlestdstdstdQAE?AV01HZ) 0.11
0xc092c0 std::_Vector_const_iterator<std::_Vector_val<Star,std::allocator<Star> > >::operator!= 0.11
0xc0ad40 std::_Vector_iterator<std::_Vector_val<Star,std::allocator<Star> > >::_Vector_iterator<std::_Vector_val<Star,std::allocator<Star> > > 0.11
0xc01384 ILT+895(??C?$_Vector_iteratorV?$_Vector_valVParticleV?$allocatorVParticlestdstdstdQBEPAVParticleXZ) 0.1
0xc0171c ILT+1815(??$_MoveAAVParticlestdYA$$QAVParticleAAV1Z) 0.1
0xc091c0 std::_Vector_iterator<std::_Vector_val<Star,std::allocator<Star> > >::operator-> 0.1
0xc0ada0 std::_Vector_iterator<std::_Vector_val<Star,std::allocator<Star> > >::operator* 0.1
0xc01875 ILT+2160(??0?$_Vector_iteratorV?$_Vector_valVParticleV?$allocatorVParticlestdstdstdQAEPAVParticlePBU_Container_base0 0.08
0xc047f0 World::show_stars 0.08
0xc13610 std::forward<Particle> 0.08
0xc13ce8 SDL_UpperBlit 0.08
0xc013b1 ILT+940(??E?$_Vector_const_iteratorV?$_Vector_valVParticleV?$allocatorVParticlestdstdstdQAEAAV01XZ) 0.06
0xc0153c ILT+1335(?end?$vectorVParticleV?$allocatorVParticlestdstdQAE?AV?$_Vector_iteratorV?$_Vector_valVParticleV?$allocatorVParticlestdstd 0.06
0xc08b50 std::_Vector_iterator<std::_Vector_val<Bullet,std::allocator<Bullet> > >::operator-> 0.06
0xc09930 std::_Vector_const_iterator<std::_Vector_val<Enemy,std::allocator<Enemy> > >::operator!= 0.06
0xc01122 ILT+285(??2YAPAXIPAXZ) 0.05
0xc01320 ILT+795(??$_ConstructVParticleABV1stdYAXPAVParticleABV1Z) 0.05
0xc01627 ILT+1570(?_Adopt_Iterator_base0stdQAEXPBXZ) 0.05
0xc0a740 std::_Vector_iterator<std::_Vector_val<Bullet,std::allocator<Bullet> > >::_Vector_iterator<std::_Vector_val<Bullet,std::allocator<Bullet> > > 0.05
0xc0adf0 std::_Vector_iterator<std::_Vector_val<Star,std::allocator<Star> > >::operator++ 0.05
0xc0b340 std::_Vector_iterator<std::_Vector_val<Enemy,std::allocator<Enemy> > >::_Vector_iterator<std::_Vector_val<Enemy,std::allocator<Enemy> > > 0.05
0xc0b4a0 std::_Vector_const_iterator<std::_Vector_val<Enemy,std::allocator<Enemy> > >::operator== 0.05
0xc11f80 std::_Move<Star &> 0.05
0xc01230 ILT+555(??D?$_Vector_const_iteratorV?$_Vector_valVParticleV?$allocatorVParticlestdstdstdQBEABVParticleXZ) 0.03
0xc013e3 ILT+990(??$_DestroyVParticlestdYAXPAVParticleZ) 0.03
0xc014b5 ILT+1200(?_Inside?$vectorVParticleV?$allocatorVParticlestdstdIBE_NPBVParticleZ) 0.03
0xc019ec ILT+2535(??$_Cons_valV?$allocatorVParticlestdVParticleABV3stdYAXAAV?$allocatorVParticle 0.03
0xc01a9b ILT+2710(_SDL_UpperBlit) 0.03
0xc01ab4 ILT+2735(?_Orphan_range?$vectorVParticleV?$allocatorVParticlestdstdIBEXPAVParticle 0.03
0xc02760 Enemy::move 0.03
0xc037e0 World::show 0.03
0xc07930 SDL_main 0.03
0xc09830 std::_Vector_iterator<std::_Vector_val<Enemy,std::allocator<Enemy> > >::operator-> 0.03
0xc09880 std::_Vector_iterator<std::_Vector_val<Enemy,std::allocator<Enemy> > >::operator++ 0.03
0xc09f20 std::vector<Particle,std::allocator<Particle> >::_Tidy 0.03
0xc0aea0 std::_Vector_const_iterator<std::_Vector_val<Star,std::allocator<Star> > >::operator== 0.03
0xc0bb70 std::allocator<Particle>::allocator<Particle> 0.03
0xc0c320 std::_Vector_const_iterator<std::_Vector_val<Bullet,std::allocator<Bullet> > >::_Compat 0.03
0xc0ce30 std::_Vector_const_iterator<std::_Vector_val<Enemy,std::allocator<Enemy> > >::operator* 0.03
0xc11780 std::vector<Particle,std::allocator<Particle> >::begin 0.03
0xc12b80 std::_Cons_val<std::allocator<Particle>,Particle,Particle> 0.03
0xc0115e ILT+345(?construct?$allocatorVParticlestdQAEXPAVParticle$$QAV3Z) 0.02
0xc011db ILT+470(??0ParticleQAEHHHZ) 0.02
0xc01217 ILT+530(?enemy_moveWorldQAEXXZ) 0.02
0xc013c5 ILT+960(?_Compat?$_Vector_const_iteratorV?$_Vector_valVBulletV?$allocatorVBulletstdstdstdQBEXABV12Z) 0.02
0xc01451 ILT+1100(??0?$_Vector_const_iteratorV?$_Vector_valVStarV?$allocatorVStarstdstdstdQAEPAVStarPBU_Container_base0 0.02
0xc0145b ILT+1110(?destroy?$allocatorVParticlestdQAEXPAVParticleZ) 0.02
0xc01672 ILT+1645(??C?$_Vector_iteratorV?$_Vector_valVEnemyV?$allocatorVEnemystdstdstdQBEPAVEnemyXZ) 0.02
0xc017ad ILT+1960(??C?$_Vector_iteratorV?$_Vector_valVStarV?$allocatorVStarstdstdstdQBEPAVStarXZ) 0.02
0xc01893 ILT+2190(?_Compat?$_Vector_const_iteratorV?$_Vector_valVStarV?$allocatorVStarstdstdstdQBEXABV12Z) 0.02
0xc018d9 ILT+2260(??D?$_Vector_const_iteratorV?$_Vector_valVStarV?$allocatorVStarstdstdstdQBEABVStarXZ) 0.02
0xc03bf0 World::show_player 0.02
0xc04550 World::show_enemies 0.02
0xc06e30 Bullet::show 0.02
0xc07430 Collision_Detection 0.02
0xc08060 std::vector<Particle,std::allocator<Particle> >::~vector<Particle,std::allocator<Particle> > 0.02
0xc08100 std::vector<Particle,std::allocator<Particle> >::begin 0.02
0xc08c50 std::_Vector_const_iterator<std::_Vector_val<Bullet,std::allocator<Bullet> > >::operator!= 0.02
0xc09d80 std::vector<Particle,std::allocator<Particle> >::_Destroy 0.02
0xc0a510 std::vector<Bullet,std::allocator<Bullet> >::_Tidy 0.02
0xc0a7f0 std::_Vector_iterator<std::_Vector_val<Bullet,std::allocator<Bullet> > >::operator++ 0.02
0xc0a8a0 std::_Vector_const_iterator<std::_Vector_val<Bullet,std::allocator<Bullet> > >::operator== 0.02
0xc0abf0 std::vector<Star,std::allocator<Star> >::_Orphan_range 0.02
0xc0bfc0 std::vector<Bullet,std::allocator<Bullet> >::size 0.02
0xc0c220 std::_Vector_const_iterator<std::_Vector_val<Bullet,std::allocator<Bullet> > >::_Vector_const_iterator<std::_Vector_val<Bullet,std::allocator<Bullet> > > 0.02
0xc0c290 std::_Vector_const_iterator<std::_Vector_val<Bullet,std::allocator<Bullet> > >::operator* 0.02
0xc0ea20 std::_Allocate<Bullet> 0.02
0xc0ef70 std::_Unchecked<std::_Vector_val<Bullet,std::allocator<Bullet> > > 0.02
0xc0f0b0 std::_Rechecked<std::_Vector_val<Bullet,std::allocator<Bullet> > > 0.02
0xc0f100 std::find_if<std::_Vector_iterator<std::_Vector_val<Particle,std::allocator<Particle> > >,bool (__cdecl*)(Particle)> 0.02
0xc0f190 std::_Unchecked<std::_Vector_val<Particle,std::allocator<Particle> > > 0.02
0xc0f600 std::_Remove_if<Star *,bool (__cdecl*)(Star)> 0.02
0xc0fb50 std::forward<Bullet const &> 0.02
0xc117f0 std::vector<Particle,std::allocator<Particle> >::end 0.02
0xc11d40 std::_Find_if<Particle *,bool (__cdecl*)(Particle)> 0.02
0xc11ef0 std::_Find_if<Star *,bool (__cdecl*)(Star)> 0.02
0xc128a0 std::vector<Bullet,std::allocator<Bullet> >::_Ucopy<std::_Vector_const_iterator<std::_Vector_val<Bullet,std::allocator<Bullet> > > > 0.02
0xc13210 std::allocator<Particle>::construct 0.02
132 functions, 610 instructions, Total: 6224 samples, 100.00% of shown samples, 20.72% of total session samples
-
What version of SFML are you using? What class is 'part'? That code seems fine to me. What happens if you comment out?
part.SetPosition(x,y);
App.Draw(part);
EDIT:
Could you give the full class of Particle?
-
What version of SFML are you using? What class is 'part'? That code seems fine to me. What happens if you comment out?
part.SetPosition(x,y);
App.Draw(part);
sf::Sprite part;
Also, I commented the 2 lines out, so they aren't drawn here are the results
CS:EIP Symbol + Offset Timer samples
0x13d3560 Particle::show 60.92
0x13d6130 std::_Remove_if<Particle *,bool (__cdecl*)(Particle)> 21.2
0x13d1a70 Player::show_particles 12.18
0x13d3410 Star::show 2.22
0x13d2800 World::show_stars 1.42
0x13d6ed0 std::_Find_if<Star *,bool (__cdecl*)(Star)> 0.63
0x13d2790 dead_s 0.47
0x13d6960 std::vector<Bullet,std::allocator<Bullet> >::vector<Bullet,std::allocator<Bullet> > 0.32
0x13d6f50 std::_Uninit_move<Particle *,Particle *,std::allocator<Particle>,Particle> 0.32
0x13d6c90 std::_Find_if<Bullet *,bool (__cdecl*)(Bullet)> 0.16
0x13d7110 std::_Uninit_move<Star *,Star *,std::allocator<Star>,Star> 0.16
11 functions, 130 instructions, Total: 632 samples, 100.00% of shown samples, 2.49% of total session samples
So it still takes up most of the resources, without drawing the particles.
Here is the full particle class (without its methods)
class Particle
{
private:
//Offsets
int x, y, xVel, yVel, type, life; //type 1 to 4 fire, 5 laser, 6 explosion
//Current frame of animation
//int frame;
//Type of particle
sf::Sprite part;
bool initialized;
public:
//Constructor
Particle( int X, int Y, int Type );
//Shows the particle
void show();
//Checks if particle is dead
bool alive;
bool vel_set;
//bool dead();
};
Same with the SDL implementation, only there part is not sf::Sprite, but a pointer to a SDL_Surface
-
That seems fine to me also. You got something messed up somewhere :P
Later I have discovered, that even if I don't draw the objects, don't use any SFML draw calls at all during the game loop, just have the c++ logic running, with vector.push_back loops, the frame rate drops drastically.
The Particle class is actually being copied when its being pushed back. However I don't think that is why that would drop the frames.
Can you show me your main game loop? Can you also show the World?
I'm determined to find this >.<!
p.s. If you want you could just upload all of the code lol
-
Thanks for your help :)
I might have probably messed up, or doing stuff unoptimized, or whatever, what my concern is that the EXACT SAME code is running with the SDL version only with different display calls, (which I even commented out in SFML) and it runs fine and fast in my SDL solution, and runs really bad in the SFML one.
I am starting to think that it might be something to do with the VS configuration...
I'll upload the code for both versions, but be warned, it's quite messy here and there, as that was the earliest version of my project
-
No problem. I got nothing else to do at this time.. I can't sleep lol. Anyways you can upload the visual studio project with it make my job easier on figuring out whats up with it. Are you using SFML 1.6 or 2.0?
-
Here's the SFML version's code:
to make things easier you could just comment out everything other than show world, or show player, it will be just the same.
//#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
//#include <SFML/System.hpp>
#include <string>
#include <vector>
#include <time.h>
#include <list>
//#include <algorithm> // remove and remove_if
using namespace std;
//forward declare
class Enemy;
class Player;
class World;
class Particle;
//
//Screen attributes
const int SCREEN_WIDTH = 1280;
const int SCREEN_HEIGHT = 600;
const int SCREEN_BPP = 32;
// Create the main window
sf::RenderWindow App(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP), "Rectangle Wars");
sf::Image background_IMG;
sf::Sprite background;
sf::Image bullet_IMG;
sf::Sprite bullet;
sf::Image player_IMG;
sf::Sprite player;
sf::Image star_bright_s_IMG;
sf::Sprite star_bright_s;
sf::Image star_bright_m_IMG;
sf::Sprite star_bright_m;
sf::Image star_bright_l_IMG;
sf::Sprite star_bright_l;
sf::Image star_medium_s_IMG;
sf::Sprite star_medium_s;
sf::Image star_medium_m_IMG;
sf::Sprite star_medium_m;
sf::Image star_medium_l_IMG;
sf::Sprite star_medium_l;
sf::Image star_dark_s_IMG;
sf::Sprite star_dark_s;
sf::Image star_dark_m_IMG;
sf::Sprite star_dark_m;
sf::Image star_dark_l_IMG;
sf::Sprite star_dark_l;
sf::Image star_shooting_IMG;
sf::Sprite star_shooting;
sf::Image p1_IMG;
sf::Sprite p1;
sf::Image p2_IMG;
sf::Sprite p2;
sf::Image p3_IMG;
sf::Sprite p3;
sf::Image p4_IMG;
sf::Sprite p4;
sf::Image bparticle_IMG;
sf::Sprite bparticle;
sf::Image shimmer_IMG;
sf::Sprite shimmer;
sf::Image enemy_IMG;
sf::Sprite enemy;
sf::Image gameover_IMG;
sf::Sprite gameover;
//The frame rate
const int FRAMES_PER_SECOND = 60;
const int TOTAL_PARTICLES = 100 *20;
//handle input relies on these
const int DOT_WIDTH = 30;
const int DOT_HEIGHT = 30;
//The event structure
//SDL_Event event;
class Particle
{
private:
//Offsets
int x, y, xVel, yVel, type, life; //type 1 to 4 fire, 5 laser, 6 explosion
//Current frame of animation
//int frame;
//Type of particle
sf::Sprite part;
bool initialized;
public:
//Constructor
Particle( int X, int Y, int Type );
//Shows the particle
void show();
//Checks if particle is dead
bool alive;
bool vel_set;
//bool dead();
};
class Bullet
{
private:
friend void Collision_Detection(Player &p, World &w);
int x, y, type, life, erase_cooldown; //type 0 == player, 1 == enemy
vector<Particle> v_particles;
vector<Particle>::iterator v_particles_it;
public:
Bullet(int x, int y, int type);
bool alive;
bool to_erase;
void show();
void show_particles();
};
class Player
{
private:
friend void Collision_Detection(Player &p, World &w);
int x, y;
int recharge;
int xVel, yVel;
bool fire_on;
vector<Particle> v_particles;
vector<Particle>::iterator v_particles_it;
vector<Bullet> v_bullets;
vector<Bullet>::iterator v_bullets_it;
public:
Player();
//~Player();
void handle_input();
void move();
void show();
void fire();
void show_bullets();
void show_particles();
int x_coord();
int y_coord();
bool alive;
int killcount_1;
};
class Enemy
{
private:
friend void Collision_Detection(Player &p, World &w);
int x, y;
int recharge;
int xVel, yVel;
int type;
vector<Particle> v_particles;
vector<Particle>::iterator v_particles_it;
vector<Bullet> v_bullets;
vector<Bullet>::iterator v_bullets_it;
public:
Enemy(int Y);
bool alive;
void move(Player &p);
void show();
void fire();
void show_bullets();
void show_particles();
};
Enemy::Enemy(int Y)
{
alive = true;
y = Y;
x = SCREEN_WIDTH;
xVel = 2;
yVel = 0;
recharge =0;
}
void Enemy::move(Player &p)
{
//Move the dot left or right
x -= xVel;
//If the dot went too far to the left or right
if( ( x < 0 ) || ( x + DOT_WIDTH > SCREEN_WIDTH ) )
{
//move back
x -= xVel;
}
//Move the dot up or down
y += yVel;
//If the dot went too far up or down
if( ( y < 0 ) || ( y + DOT_HEIGHT > SCREEN_HEIGHT ) )
{
//move back
y -= yVel;
}
if (p.y_coord() > y)
yVel = +2;
if (p.y_coord() < y)
yVel = -2;
if (abs(p.y_coord() - y)< 5)
yVel = 0;
if (abs(p.y_coord() - y) < 50)
fire();
}
void Enemy::fire()
{
if (recharge > 25) {
Bullet a(x, y, 1);
v_bullets.push_back (a);
recharge = 0;
}
}
bool dead_b(Bullet b){
if (b.to_erase)
return true;
else
return false;
}
void Enemy::show_bullets()
{
v_bullets.erase(remove_if(v_bullets.begin(), v_bullets.end(), dead_b), v_bullets.end());
//Show bullets
for (v_bullets_it = v_bullets.begin(); v_bullets_it != v_bullets.end(); v_bullets_it++){
v_bullets_it->show();
}
}
bool dead_p(Particle p){
if (p.alive==false)
return true;
else
return false;
}
void Enemy::show_particles()
{
v_particles.erase(remove_if(v_particles.begin(), v_particles.end(), dead_p), v_particles.end());
//Show particles
for (v_particles_it = v_particles.begin(); v_particles_it != v_particles.end(); v_particles_it++){
v_particles_it->show();
}
}
Particle::Particle( int X, int Y, int Type){
type = Type;
x=X;
y=Y;
xVel=0;
yVel=0;
life = 0;
alive = true;
//part = NULL;
vel_set = false;
initialized = false;
}
class Star
{
private:
int type; //1=dark 2=medium 3=bright 4=shooting
int size; //1=small 2=medium 3=large
int x;
int y;
int xVel;
bool initialized;
sf::Sprite star;
public:
Star(int x, int y, int type, int size, int xVel);
void show();
bool alive;
};
Bullet::Bullet(int ix, int iy, int itype)
{
type = itype;
if (type == 0){
x = ix+30;
y = iy+15;
}
if (type == 1){
x = ix-30;
y = iy+15;
}
life =0;
to_erase = false;
erase_cooldown = 0;
alive = true;
Particle a(x, y, 5);
//v_particles.push_back(a);
}
class World
{
private:
friend void Collision_Detection(Player &p, World &w);
vector<Star> v_stars;
vector<Star>::iterator v_stars_it;
vector<Enemy> v_enemies;
vector<Enemy>::iterator v_enemies_it;
vector<Particle> v_particles;
vector<Particle>::iterator v_particles_it;
int frame;
public:
World();
void show();
void add_star();
void add_bullet(int x, int y);
void show_stars();
void show_enemies();
Player myPlayer;
void show_player();
void enemy_move();
// void show_bullets();
void show_particles();
void explosion(int x, int y);
};
World::World()
{
// X should not be a factor of screen_width, more like screen height
for (int i=0; i < (SCREEN_WIDTH/6) ; i++){
int randmX = rand() %SCREEN_WIDTH + 1;
int randmY = rand() %599 + 1;
int randmType = rand() %2 + 1;
int randmSize = rand() %2 + 1;
Star a(randmX, randmY, randmType, 1, 1);
v_stars.push_back (a);
}
//mid layer xVel 4
for (int i=0; i < (SCREEN_WIDTH/15) ; i++){
int randmX = rand() %SCREEN_WIDTH + 1;
int randmY = rand() %599 + 1;
int randmType = rand() %2 + 1;
int randmSize = rand() %2 + 1;
Star a(randmX, randmY, randmType, randmSize, 2);
v_stars.push_back (a);
}
//front layer xVel 8
for (int i=0; i < (SCREEN_WIDTH/30) ; i++){
int randmX = rand() %SCREEN_WIDTH + 1;
int randmY = rand() %599 + 1;
int randmType = rand() %2 + 2;
int randmSize = rand() %2 + 2;
Star a(randmX, randmY, randmType, randmSize, 4);
v_stars.push_back (a);
}
//front front layer xVel 8
for (int i=0; i < (SCREEN_WIDTH/50) ; i++){
int randmX = rand() %SCREEN_WIDTH + 1;
int randmY = rand() %599 + 1;
int randmType = rand() %2 + 2;
int randmSize = rand() %2 + 2;
Star a(randmX, randmY, randmType, randmSize, 8);
v_stars.push_back (a);
}
//foreground line star layer Xvel 15, Type 4
for (int i=0; i < (SCREEN_WIDTH/300) ; i++){
int randmX = rand() %SCREEN_WIDTH + 1;
int randmY = rand() %599 + 1;
Star a(randmX, randmY, 4, 1, 15);
v_stars.push_back (a);
}
}
void World::show(){
show_stars();
show_enemies();
show_player();
show_particles();
frame++;
}
void World::explosion(int x, int y){
for (int i=0, r=((rand() % 100) -80); i < 120 + r ; i++){
int xx = x + rand() % 10 - 5;
int yy = y + rand() % 10 - 5;
Particle a(xx, yy, 6);
v_particles.push_back(a);
}
}
void World::show_particles()
{
//remove/erase idiom
v_particles.erase(remove_if(v_particles.begin(), v_particles.end(), dead_p), v_particles.end());
for (v_particles_it = v_particles.begin(); v_particles_it != v_particles.end(); v_particles_it++){
v_particles_it->show();
}
}
void World::enemy_move() //commands all the enemies to take their move and gives them reference to the player object
{
for (v_enemies_it = v_enemies.begin(); v_enemies_it != v_enemies.end(); v_enemies_it++){
v_enemies_it->move(myPlayer);
}
}
void World::show_player(){
myPlayer.show();
}
void Player::show_bullets()
{
v_bullets.erase(remove_if(v_bullets.begin(), v_bullets.end(), dead_b), v_bullets.end());
//Show bullets
for (v_bullets_it = v_bullets.begin(); v_bullets_it != v_bullets.end(); v_bullets_it++){
v_bullets_it->show();
}
}
void Player::show_particles()
{
v_particles.erase(remove_if(v_particles.begin(), v_particles.end(), dead_p), v_particles.end());
for( int p = 0; p < TOTAL_PARTICLES/4 ; p++ )
{
int randmX = x - (rand() % 11) +2;
int randmY = y +14 + (rand() % 29) - 14;
const Particle a(randmX, randmY, 1);
v_particles.push_back(a);
}
for( int p = 0; p < TOTAL_PARTICLES/4 ; p++ )
{
int randmX = x - (rand() % 11) - 5 ;
int randmY = y + 14 + (rand() % 12);
int negm = rand() %2;
if (negm == 1)
randmY = randmY - (2*(randmY - (y+15)));
const Particle a(randmX, randmY, 2);
v_particles.push_back(a);
}
for( int p = 0; p < TOTAL_PARTICLES/4 ; p++ )
{
int randmX = x - (rand() % 11) - 11 ;
int randmY = y + 14 +(rand() % 7);
int negm = rand() %2;
if (negm == 1)
randmY = randmY - (2*(randmY - (y+15)));
const Particle a(randmX, randmY, 3);
v_particles.push_back(a);
}
for( int p = 0; p < TOTAL_PARTICLES/8 ; p++ )
{
int randmX = x - (rand() % 11) - 21 ;
int randmY = y + 14 +(rand() % 2);
int negm = rand() %2;
if (negm == 1)
randmY = randmY - (2*(randmY - (y+15)));
const Particle a(randmX, randmY, 4);
v_particles.push_back(a);
}
//Show particles
for (v_particles_it = v_particles.begin(); v_particles_it != v_particles.end(); v_particles_it++){
v_particles_it->show();
}
}
bool dead_e(Enemy e){
if (e.alive==false)
return true;
else
return false;
}
void World::show_enemies()
{
v_enemies.erase(remove_if(v_enemies.begin(), v_enemies.end(), dead_e), v_enemies.end());
if (rand() % 50 == 0){
int randmY = rand() %(SCREEN_HEIGHT - DOT_HEIGHT) +1;
Enemy a(randmY);
v_enemies.push_back (a);
}
for (v_enemies_it = v_enemies.begin(); v_enemies_it != v_enemies.end(); v_enemies_it++){
v_enemies_it->show();
}
}
bool dead_s (Star s){
if (s.alive==false)
return true;
else
return false;
}
void World::show_stars()
{
v_stars.erase(remove_if(v_stars.begin(), v_stars.end(), dead_s), v_stars.end());
//adding stars to the right of screen
//furthest, slowest layer xVel 1 dark or medium, small or medium
if (frame % 6 == 0){
int randmY = rand() %599 + 1;
int randmType = rand() %2 + 1;
int randmSize = rand() %2 + 1;
Star a(SCREEN_WIDTH, randmY, randmType, 1, 1);
v_stars.push_back (a);
}
//mid layer xVel 2
if (frame % 15 == 0){
int randmY = rand() %599 + 1;
int randmType = rand() %2 + 1;
int randmSize = rand() %2 + 1;
Star a(SCREEN_WIDTH, randmY, randmType, randmSize, 2);
v_stars.push_back (a);
}
//front layer xVel 4
if (frame % 30 == 0){
int randmY = rand() %599 + 1;
int randmType = rand() %2 + 2;
int randmSize = rand() %2 + 2;
Star a(SCREEN_WIDTH, randmY, randmType, randmSize, ((rand() % 4) +3));
v_stars.push_back (a);
}
//front front layer xVel 8
if (frame % 50 == 0){
int randmY = rand() %599 + 1;
int randmType = rand() %2 + 2;
int randmSize = rand() %2 + 2;
Star a(SCREEN_WIDTH, randmY, randmType, randmSize, ((rand() % 6) + 7));
v_stars.push_back (a);
}
//foreground line star layer Xvel 15, Type 4
if (frame % 30 == 0){
int randmY = rand() %599 + 1;
Star a(SCREEN_WIDTH, randmY, 4, 1, ((rand() % 15) + 10));
v_stars.push_back (a);
}
for (v_stars_it = v_stars.begin(); v_stars_it != v_stars.end(); v_stars_it++){
v_stars_it->show();
}
}
Star::Star(int ix, int iy, int itype, int isize, int ixVel)
{
x = ix;
y = iy;
type = itype;
size = isize;
xVel = ixVel;
initialized = false;
//star = NULL;
}
bool init()
{
// Create the main window
sf::Window App(sf::VideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP), "Rectangle Wars");
// Get a reference to the input manager associated to our window, and store it for later use
const sf::Input& Input = App.GetInput();
//sf::Clock Clock;
return true;
}
bool load_files()
{
//Load the dot image
//dot = load_image( "ship.png" );
//Load the background
if (!background_IMG.LoadFromFile("recwar/black.png"))
{
// Error...
}
background.SetImage(background_IMG);
if (!bullet_IMG.LoadFromFile("recwar/bullet.png"))
{
// Error...
}
bullet.SetImage(bullet_IMG);
if (!player_IMG.LoadFromFile("recwar/player.png"))
{
// Error...
}
player.SetImage(player_IMG);
if (!star_bright_s_IMG.LoadFromFile("recwar/starbright_s.png"))
{
// Error...
}
star_bright_s.SetImage(star_bright_s_IMG);
if (!star_bright_m_IMG.LoadFromFile("recwar/starbright.png"))
{
// Error...
}
star_bright_m.SetImage(star_bright_m_IMG);
if (!star_bright_l_IMG.LoadFromFile("recwar/starbright_l.png"))
{
// Error...
}
star_bright_l.SetImage(star_bright_l_IMG);
if (!star_medium_s_IMG.LoadFromFile("recwar/starmedium_s.png"))
{
// Error...
}
star_medium_s.SetImage(star_medium_s_IMG);
if (!star_medium_m_IMG.LoadFromFile("recwar/starmedium.png"))
{
// Error...
}
star_medium_m.SetImage(star_medium_m_IMG);
if (!star_medium_l_IMG.LoadFromFile("recwar/starmedium_l.png"))
{
// Error...
}
star_medium_l.SetImage(star_medium_l_IMG);
if (!star_dark_s_IMG.LoadFromFile("recwar/stardark_s.png"))
{
// Error...
}
star_dark_s.SetImage(star_dark_s_IMG);
if (!star_dark_m_IMG.LoadFromFile("recwar/stardark.png"))
{
// Error...
}
star_dark_m.SetImage(star_dark_m_IMG);
if (!star_dark_l_IMG.LoadFromFile("recwar/stardark_l.png"))
{
// Error...
}
star_dark_l.SetImage(star_dark_l_IMG);
//if (!star_shooting_IMG.LoadFromFile("recwar/star_shooting.png"))
{
// Error...
}
star_shooting.SetImage(star_shooting_IMG);
if (!p1_IMG.LoadFromFile("recwar/particle1.png"))
{
// Error...
}
p1.SetImage(p1_IMG);
if (!p2_IMG.LoadFromFile("recwar/particle2.png"))
{
// Error...
}
p2.SetImage(p2_IMG);
if (!p3_IMG.LoadFromFile("recwar/particle3.png"))
{
// Error...
}
p3.SetImage(p3_IMG);
if (!p4_IMG.LoadFromFile("recwar/particle4.png"))
{
// Error...
}
p4.SetImage(p4_IMG);
if (!bparticle_IMG.LoadFromFile("recwar/bparticle.png"))
{
// Error...
}
bparticle.SetImage(bparticle_IMG);
if (!shimmer_IMG.LoadFromFile("recwar/shimmer.png"))
{
// Error...
}
shimmer.SetImage(shimmer_IMG);
if (!enemy_IMG.LoadFromFile("recwar/enemy.png"))
{
// Error...
}
enemy.SetImage(enemy_IMG);
if (!gameover_IMG.LoadFromFile("recwar/gameover.png"))
{
// Error...
}
gameover.SetImage(gameover_IMG);
//If everything loaded fine
return true;
}
void Star::show(){
//determine type and size of star (only the first time)
//add bool for first init check
if (initialized == false){
if ((type == 1) && (size == 1)) star = star_dark_s;
if ((type == 1) && (size == 2)) star = star_dark_m;
if ((type == 1) && (size == 3)) star = star_dark_l;
if ((type == 2) && (size == 1)) star = star_medium_s;
if ((type == 2) && (size == 2)) star = star_medium_m;
if ((type == 2) && (size == 3)) star = star_medium_l;
if ((type == 3) && (size == 1)) star = star_bright_s;
if ((type == 3) && (size == 2)) star = star_bright_m;
if ((type == 3) && (size == 3)) star = star_bright_l;
if ((type == 4)) {star = star_shooting; xVel = 30;}
initialized = true;
}
star.SetPosition(x,y);
App.Draw(star);
//apply_surface( x, y, star);
x -= xVel;
if (x<0)
alive = false;
}
void Particle::show()
{
//Show image
if (initialized == false){
if (type == 1) part = p1;
else if (type == 2) part = p2;
else if (type == 3) part = p3;
else if (type == 4) part = p4;
else if (type == 5) part = bparticle;
else if (type == 6){
if ((rand() % 4) == 0)
part = p1;
else if ((rand() % 4) == 1)
part = p2;
else if ((rand() % 4) == 2)
part = p3;
else if ((rand() % 4) == 1)
part = p4;}
initialized = true;
}
if(alive)
{
//part.SetPosition(x,y);
//App.Draw(part);
//apply_surface( x, y, part, screen );
}
//Animate
life++;
if (type <= 4 && vel_set == false){
xVel = ((rand() % 10) +10) * (-1);
vel_set = true;}
if (type <= 4 && life>(2 + rand() % 5))
alive=false;
if (type == 5 && life> (20 + rand() % 11))
alive = false;
if (type == 5 && vel_set == false){
xVel = (rand() % 5) -2;
yVel = (rand() % 5) -2;
vel_set=true;
}
if (type == 6 && life> (20 + rand () % 11))
alive = false;
if (type == 6 && vel_set == false){
int randmX = rand() % 6;
int randmY = rand() % 6;
if ((rand() %2) == 0)
randmX = -randmX;
if ((rand() %2) == 0)
randmY = -randmY;
xVel = randmX;
yVel = randmY;
vel_set = true;
}
if (type == 6 && vel_set == true && xVel > 0 && (life % 5 == 0)){
xVel -= 1;
}
if (type == 6 && vel_set == true && xVel < 0 && (life % 5 == 0)){
xVel += 1;
}
if (type == 6 && vel_set == true && yVel > 0 && (life % 5 == 0)){
yVel -= 1;
}
if (type == 6 && vel_set == true && yVel < 0 && (life % 5 == 0)){
yVel += 1;
}
x = x+xVel;
y = y+yVel;
}
Player::Player()
{
//Initialize the offsets
recharge = 0;
x = 100;
y = 100;
fire_on = false;
alive = true;
killcount_1 = 0;
//v_particles.reserve(10000);
//Initialize the velocity
xVel = 0;
yVel = 0;
//Initialize particles
for( int p = 0; p < TOTAL_PARTICLES/4; p++ )
{
int randmX = x - (rand() % 11);
int randmY = y + (rand() % 31) - 15;
Particle a(randmX, randmY, 1);
v_particles.push_back(a);
}
for( int p = 0; p < TOTAL_PARTICLES/4; p++ )
{
int randmX = x - (rand() % 11) - 5 ;
int randmY = y + (rand() % 12);
if ((rand() % 2) == 1) randmY = randmY * -1;
Particle a(randmX, randmY, 2);
v_particles.push_back(a);
}
for( int p = 0; p < TOTAL_PARTICLES/4; p++ )
{
int randmX = x - (rand() % 11) - 11 ;
int randmY = y + (rand() % 7);
if ((rand() % 2) == 1) randmY = randmY * -1;
Particle a(randmX, randmY, 3);
v_particles.push_back(a);
}
for( int p = 0; p < TOTAL_PARTICLES/4; p++ )
{
int randmX = x - (rand() % 11) - 21 ;
int randmY = y + (rand() % 5);
if ((rand() % 2) == 1) randmY = randmY * -1;
Particle a(randmX, randmY, 4);
v_particles.push_back(a);
}
}
void Player::move()
{
//Move the dot left or right
x += xVel;
//If the dot went too far to the left or right
if( ( x < 0 ) || ( x + DOT_WIDTH > SCREEN_WIDTH ) )
{
//move back
x -= xVel;
}
//Move the dot up or down
y += yVel;
//If the dot went too far up or down
if( ( y < 0 ) || ( y + DOT_HEIGHT > SCREEN_HEIGHT ) )
{
//move back
y -= yVel;
}
}
void Player::fire(){
if (recharge > 10) {
Bullet a(x, y, 0);
v_bullets.push_back (a);
recharge = 0;
}
}
void Player::show(){
if (alive){
player.SetPosition(x,y);
App.Draw(player);
show_bullets();
show_particles();
}
recharge++;
if (fire_on)
fire();
}
int Player::x_coord()
{
return x;
}
int Player::y_coord()
{
return y;
}
void Enemy::show(){
//x -= 1;
//move();
if (alive){
enemy.SetPosition(x,y);
App.Draw(enemy);
show_bullets();
show_particles();
recharge++;
if (x<(-30))
alive = false;
}
//if (fire_on)
//fire();
}
void Bullet::show(){
if (alive){
bullet.SetPosition(x,y);
App.Draw(bullet);
if (type==0){
x += 25;
if (x>SCREEN_WIDTH)
alive = false;
}
else if (type == 1){
x -=15;
if (x<0)
alive = false;
}
}
else{
if (erase_cooldown >= 40){
to_erase = true;
}
erase_cooldown++;
}
show_particles();
}
void Bullet::show_particles(){
if (alive){
if (rand() % 10 == 0){
int randmX = x - ( rand() % 50);
int randmY = y + (rand() % 7) - 3;
Particle a(randmX, randmY, 5);
v_particles.push_back(a);
}
}
//Show particles
for (v_particles_it = v_particles.begin(); v_particles_it != v_particles.end(); v_particles_it++){
v_particles_it->show();
}
}
void Collision_Detection(Player &p, World &w)
{
//player's bullet and enemy collision
//player: 30 x 30
//bullet: 32 x 4
for (p.v_bullets_it = p.v_bullets.begin(); p.v_bullets_it != p.v_bullets.end(); p.v_bullets_it++){
int leftB, rightB, topB, bottomB;
leftB = p.v_bullets_it->x;
rightB = p.v_bullets_it->x + 32;
topB = p.v_bullets_it->y;
bottomB = p.v_bullets_it->y + 4;
for (w.v_enemies_it = w.v_enemies.begin(); w.v_enemies_it != w.v_enemies.end(); w.v_enemies_it++){
int leftE, rightE, topE, bottomE;
leftE = w.v_enemies_it->x;
rightE = w.v_enemies_it->x + 30;
topE = w.v_enemies_it->y;
bottomE = w.v_enemies_it->y + 30;
if(( bottomB <= topE ) || ( topB >= bottomE ) || ( rightB <= leftE ) || ( leftB >= rightE )){
//int a = 1;
}
else
{
p.v_bullets_it->alive = false;
w.v_enemies_it->alive = false;
w.explosion(w.v_enemies_it->x + 15, w.v_enemies_it->y + 15);
p.killcount_1++;
}
}
}
int leftP, rightP, topP, bottomP;
leftP = p.x;
rightP = p.x + 30;
topP = p.y;
bottomP = p.y + 30;
for (w.v_enemies_it = w.v_enemies.begin(); w.v_enemies_it != w.v_enemies.end(); w.v_enemies_it++){
for (w.v_enemies_it->v_bullets_it = w.v_enemies_it->v_bullets.begin();
w.v_enemies_it->v_bullets_it != w.v_enemies_it->v_bullets.end();
w.v_enemies_it->v_bullets_it++){
int leftB, rightB, topB, bottomB;
leftB = w.v_enemies_it->v_bullets_it->x;
rightB = w.v_enemies_it->v_bullets_it->x + 32;
topB = w.v_enemies_it->v_bullets_it->y;
bottomB = w.v_enemies_it->v_bullets_it->y + 4;
if(( bottomP <= topB ) || ( topP >= bottomB ) || ( rightP <= leftB ) || ( leftP >= rightB )){
//int a = 1;
}
else
{
p.alive = false;
w.v_enemies_it->v_bullets_it->alive = false;
w.explosion(p.x + 15, p.y + 15);
//w.v_enemies.erase(w.v_enemies_it++);
}}
}
}
int main( int argc, char* args[] )
{
bool quit = false;
bool running = true;
srand( time(NULL) );
//App.SetFramerateLimit(60);
//App.UseVerticalSync(true);
while (quit == false && running == true)
{
if( load_files() == false )
{
return 1;
}
bool player_dead = false;
World myWorld;
//While the user hasn't quit
while( player_dead == false )
{
if (myWorld.myPlayer.alive == false)
player_dead = true;
App.Clear();
myWorld.myPlayer.move();
myWorld.enemy_move();
myWorld.show();
Collision_Detection(myWorld.myPlayer, myWorld);
/*for( int p = 0; p < 1 ; p++ )
{
int randmX = (rand() % 11) - 21 ;
int randmY = (rand() % 2);
int negm = rand() %2;
if (negm == 1)
randmY = randmY - (2*(randmY - 15));
vector<int> vint;
vint.push_back(randmX);
}*/
//Update the screen
App.Display();
}
}
return 0;
}
-
Thanks, I'll upload the VS solution!
-
Alright, here is the solution file
http://www.megaupload.com/?d=HLFFZXNB
BTW I am using SFML 1.6
-
Maybe you could post a minimal (yet still complete) code that reproduces the problem?
http://www.sfml-dev.org/forum/viewtopic.php?p=36368#36368
BTW I am using SFML 1.6
Try SFML 2, you'll get a huge performance boost if you use the same image for all your particles.
-
Thank you for your comment, I'll try to replicate the problem somehow.
So far I don't quite understand it either, other than the same code runs faster in my SDL VS2010 project than in the SFML project, even if I don't even make the SFML display calls.
As soon as I figured out what causes this, I will switch to SFML 2, since I will be using a lot of particles and objects sharing the same sprites.
-
Okay so I changed the TOTAL_PARTICLES to 80. I think 1000 was way too much. I built it in release mode and it had no problem running at all. Is there a reason why you had the number so high?
With that number being 1000 you would be creating 875 particles per frame in the Player::show_particles() function alone! With it being 80 its only creating 70. Assuming I understood your code correctly :P
-
Okay so I changed the TOTAL_PARTICLES to 80. I think 1000 was way too much. I built it in release mode and it had no problem running at all. Is there a reason why you had the number so high?
Yes, there is
So the way I tested performance, since in this early version of my game there aren't many objects, I increased the particles coming out from the player's thruster (in both SDL and SFML, the same number)
Before I would rewrite my current progress, which is bigger than this early build, I wanted to be able to see how it would perform.
And it just bothers me so much that the particles stress the SMFL project much more, even without having them drawn, than the sdl one..
-
What consumes most of the CPU in SFML are calls to the Draw function. The fact that your program is equally slow even when you draw nothing, makes me think that you may have a problem in your own code -- which can be solved.
As soon as you provide a code which is minimal enough, we can start investigating and hopefully spot the problem.
-
Do you really want to create a new World object every frame?
-
Do you really want to create a new World object every frame?
I am pretty sure there is only one world object created altogether.
There are 2 while loops.
The inner one does whatever is happening every frame.
The outer one goes if the player dies and the level is restarted. This is when the world object is reinitialized.
-
You're right, I was a little fast there, sorry.
I downloaded your project, and it didn't take long to figure out that your two biggest culprits are Player::show_particles and Star::show.
There, that should help you come up with a minimal code that reproduces the problem.
I found the code pretty messy, so I didn't poke around for too long, but you do have a whole bunch of implicit casts that the compiler complains about. Maybe fixing those would be a good start.
Hope that helps! :)
-
You're right, I was a little fast there, sorry.
I downloaded your project, and it didn't take long to figure out that your two biggest culprits are Player::show_particles and Star::show.
There, that should help you come up with a minimal code that reproduces the problem.
I found the code pretty messy, so I didn't poke around for too long, but you do have a whole bunch of implicit casts that the compiler complains about. Maybe fixing those would be a good start.
Hope that helps! :)
Thank you,
Yes, the code is messy as this was my smallest, earliest build of the project that now is about 8K lines, divided into 20 header and cpp files, using a lot of images and sprites, I thought for my purposes of transitioning to SFML from SDL it will be okay if I try to convert this.
Obviously the show::particle took up most resources, especially since I (purposefully) increased the total particles shown 20x, to measure performance. In the SDL build it was going fine, here not so much.
on the gamedev forums I have actually been told, that the reason for this to strain SFML so much is because what opengl calls are made for each created particle, which is quite expensive.
They too suggested that I transition to SFML 2.0, as it is supposed to handle handle object sharing the same image much better, as Laurent also have told me about it earlier.
So now I am in the middle of trying to build SFML 2.0, then I will try to learn the new input functions.
After that I take a deep breath and rewrite my up-to-date build to SFML2.0.
Thanks for all your help, I won't go further into this particle drawing performance issue until I have fully transitioned my whole project to SFML 2.0.
-
on the gamedev forums I have actually been told, that the reason for this to strain SFML so much is because what opengl calls are made for each created particle, which is quite expensive.
If you don't draw there's no OpenGL call at all. Creating particles (at least the SFML part of it) consumes 0 CPU. Remember what I said above.
-
on the gamedev forums I have actually been told, that the reason for this to strain SFML so much is because what opengl calls are made for each created particle, which is quite expensive.
If you don't draw there's no OpenGL call at all. Creating particles (at least the SFML part of it) consumes 0 CPU. Remember what I said above.
I see.
I am not sure what must have been the issue, now I have built SFML 2.0 according to the tutorial, and started a new VS project, set it up to SFML 2.0 libraries, changed the sf::image to sf::Texture, and I do not have performance issues, but I am not increasing the particle count to unreasonable numbers either.
It seems like things are working right now, I'll figure out SFML 2.0's input, then rewrite everything.
EDIT:
Actually, just to test it, now I have set the particle count 20x higher, like I was testing with 1.6 before
With 1.6 I got 38 FPS
With 2.0 I am getting 120+FPS
-
Okay, so now I have made the keyboard inputs with 2.0's functions.
In the main loop for every frame I use this to poll for events:
while (App.PollEvent (Event))
{
//myWorld.myPlayer.handle_input();
//if (Event.Type == sf::Event::Closed)
//{
// App.Close();
//}
}
sf::Event Event; is created once, globally.
So my problem now is, that regardless of what is inside the poll loop, even if it is empty, like above, the performance drops significantly, the frame rate fluctuates between 20-60.
Am I doing the polling wrong?
-
Can you try to comment line 121 of src/SFML/Window/WindowImpl.cpp (ProcessJoystickEvents();) and recompile SFML?
-
Can you try to comment line 121 of src/SFML/Window/WindowImpl.cpp (ProcessJoystickEvents();) and recompile SFML?
Yes, that solved it!
Thank You
-
This problem is really annoying :?
-
This problem is really annoying :?
Is it happening consistently, or just on random installs?
-
It seems to happen randomly, on PCs that sometimes have a joystick connected (PCs where no joystick is used at all are fine).
-
It seems to happen randomly, on PCs that sometimes have a joystick connected (PCs where no joystick is used at all are fine).
I had a usb xbox 360 wireless adapter connected (the controller wasn't paired up with it) while i was experiencing the performance drop, in case it helps.
-
I had a usb xbox 360 wireless adapter connected (the controller wasn't paired up with it) while i was experiencing the performance drop, in case it helps.
I think it's enough to trigger the problem.
-
I've sugested once to put this function on a different thread and call it again when completed... Is there any reason to not do that?
-
I don't know, I haven't really thought about potential solutions. I'm afraid it will happen only in SFML 2.1.
-
I tried to replicate the problem and had some success.
I got it to go from >1000 + FPS, plugged in my 360 wireless receiver, nothing happened, turned on the gamepad and a few seconds later, FPS dropped to 20ish, but then it jumped right back up to 1000+ and I haven't been able to get the framerate to drop like that again.
If I can make it 100% replicable, I will try to bug hunt it, but this intermittent stuff... that's irritating. Is there a way to make this 100% reproducable?
Right now I used:
int _tmain(int argc, _TCHAR* argv[])
{
sf::Window app = sf::Window(sf::VideoMode(800,600,32),"test");
sf::Event event;
for(;;)
{
while (app.PollEvent(event))
{
if (event.Type == sf::Event::Closed)
app.Close();
if (event.Type == sf::Event::KeyPressed)
{
if (event.Key.Code == sf::Keyboard::Key::Escape)
app.Close();
}
}
sf::Uint32 elapsedTime = app.GetFrameTime();
if(elapsedTime == 0.0f) app.SetTitle("Lots");
else
{
std::ostringstream ost;
ost << 1000.f / elapsedTime;
app.SetTitle(ost.str());
}
app.Display();
}
}
That should be sufficient to cause the problem, right?
-
Is there a way to make this 100% reproducable?
It seems to be really random. Sometimes it happens just once, after plugging/unplugging a joystick, and then disappears the next time without changing anything.
-
A friend of mine also experienced the joystick/FPS drop problem in SFML2 and suggested I change the line 81 in JoystickManager.cpp from
JoystickImpl::IsConnected(i))
to
if (myConnectCheck++ % 5000 == 0) JoystickImpl::IsConnected(i))
and add a private unsigned int variable "myConnectCheck" to JoystickManager.hpp. The number "5000" above is somewhat "hackish" though, as it seems to depend on the framerate I think.
Is this a valid suggestion/"hack" for the time being? I did not experience the issue myself yet (no joystick :-) ), but I want to prepared.
-
It's very ugly and 5000 is too high (at 60 FP you'll check joysticks every 83 seconds). But it should be ok.
-
It's very ugly and 5000 is too high (at 60 FP you'll check joysticks every 83 seconds). But it should be ok.
Ok, maybe I wait for a better "official" solution and let the regular SFML libraries as they are now - at least until I have a project worth releasing, and worry about the problem then :)