Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Gibgezr

Pages: [1] 2 3
1
Graphics / RenderImage : unexpected segfault...
« on: April 08, 2011, 04:28:38 pm »
Quote from: "Laurent"
Where do you see a sprite??

Anyway, the image is returned by copy, it's not a reference to the render-image's internal one. So as long as the calling code stores the result it's fine.


Doh! That's what I get for reading too quickly, lol.

2
Graphics / RenderImage : unexpected segfault...
« on: April 08, 2011, 04:08:08 pm »
Looking at your code, you are creating the RenderImage as a temporary local variable in your function, then passing back a Sprite that uses it. The problem is that your RenderImage is then destroyed when the function returns, so the Sprite is no longer valid (it is based on a now deleted RenderImage).

Right?

3
Graphics / Runtime failure at Draw()
« on: April 07, 2011, 07:14:47 pm »
Yeah, do what Fred is suggesting, currently you create a sf::Sprite in the Init() and then it goes out of scope at the end of Init() and the memory is freed, and your m_Background pointer now points to freed memory.

4
General / Drawing tilemap is lowering my fps to a crawl
« on: April 05, 2011, 08:52:34 pm »
The thread below has example code that demonstrates one way of doing it:
http://www.sfml-dev.org/forum/viewtopic.php?t=4376

5
Graphics / Blank (white) Sprite -- can I pass a SubRect?
« on: April 05, 2011, 08:49:04 pm »
Quote from: "Nexus"
From a design point of view, there is also a third option: A class that stores the render window and has a function Draw(const Player&). Like this, you can decrease coupling between logical and graphical elements. In a good design, the player doesn't know how to draw himself. He is just an abstract object which interacts with game logics. He can of course still store rendering information, but he doesn't use them himself.

The advantage of this separation lies in the fact that the rendering parts of the program aren't spread over all classes. Rather, you have a central instance which is in charge of graphical representation and has the full control over it. This makes modifications in the rendering system a lot easier. You can overload the function for different types and work more generically. Besides, game elements become more lightweight when they don't bear any graphical responsibilities.


This is an excellent concept. It's usually referred to as the Model-View-Controller paradigm (I always call it the Controller-Model-View paradigm, which seems like a more natural ordering of the program architecture to me, and is the way the folks I used to work with referred to it in the 80's).

A quote from Wikipedia:
"The goal of MVC is, by decoupling models and views, to reduce the complexity in architectural design and to increase flexibility and maintainability of code."

It really works, too.

6
Graphics / Blank (white) Sprite -- can I pass a SubRect?
« on: April 02, 2011, 01:08:59 am »
Creating a new sf::Sprite every frame of your game for each animator object is a bad idea. I would design it with the animator class returning a pointer to its sprite, then just using the pointer to adjust the sprite's position and draw it.

I would also go so far as to make the pointer a public variable in the animator class; an accessor function really adds nothing but overhead to the class design in this case (why do we need data hiding for a sf::Sprite object?). As it is likely that the animator class could get used for drawing literally thousands of sprites per frame, removing even function-call overhead is a worthy optimization, in my mind at least.

While I am busy showing my old-school realtime C/Assembly programmer biases, another change I would make is to not bother passing the reference to the RenderWindow in to the player Draw() function...unless you actually are going to support multiple RenderWindows. It's not a real speed optimization, by why pass around a variable that actually remains static for the lifetime of the app? I'd just store a pointer to the RenderWindow in any object that needed it. That is just a style/design preference of mine, so I'm just kvetching at this point, but passing parameters means storing/loading/restoring registers. Where it gives you any flexibility that you might actually use, it's worth it, but for something with practically nil usage, why bother?

tldr; don't allocate new objects every frame of your game if you don't need to, and watch function-call overhead for things you may do hundreds/thousands of times per frame. And yes, I am an old buzzard.

7
Graphics / sf::Sprite::SetImage - distorted rendering
« on: April 02, 2011, 12:26:58 am »
Quote from: "devlin"
Quote from: "Tank"
But for sf::Sprite it's not so obvious, because SetSubRect() is not an elemental feature (design-wise). In my opinion it's more like "I set this image, so I want to see this image." :)

I respectfully disagree.

Image as a sprite sheet seem the most natural connection to sf::Image from sf::Sprite - and it's far more maintainable to keep colour- or look-variations (for example: after grabbing a powerup) for the same sprite in different images and swap between them by setting a new image while maintaining subrects for say the current animation.


Hmm, but this may not be a very good idea for a realtime application, as changing Images causes an OpenGL statechange, which is very expensive i.e. slow. Optimally, you would put ALL cells for that sprite on the same image, and just adjust the SubRect for the "powerup" versions. A great way to do that is to lay the sprite cells out in an organized fashion on the Image, for example putting the powere-up versions directly below their "non-power up" counterparts. Then, you adjust the SubRect by calculating it with code that uses a powerup flag, like so:
Code: [Select]

void spriteObject::animate(float timePassed)
{
timeSinceFrameAdvance += timePassed;

if (timeSinceFrameAdvance >= timePerFrame)
{
currentFrame++;
timeSinceFrameAdvance = 0;
//could instead do timeSinceFrameAdvance -= timePerFrame,
//can be a tiny bit smoother under erratic framerates

animate(currentFrame);
}
}

void spriteObject::animate(int frameToGoTo)
{
currentFrame = frameToGoTo;

if (currentFrame > totalFrames)
currentFrame = 0;

// Set the sprite's image to the current frame of animation
theSprite->SetSubRect(sf::IntRect(
currentFrame*cellWidth,
powerup*cellHeight,
cellWidth, cellHeight);
}


You want to design for as few statechanges as possible (they are dreadfully slow in OpenGL), so you try and batch all your drawables by putting them into as few Images as possible, and drawing all of the ones that are sourced from the same Image before moving to ones that are sourced from another Image. Proper design of the spritesheets (Images) will aid the coding significantly, and the only real issues are Image size and the development headaches around "having a lot of art in one asset".

8
General / SFML2 and VS2008 warning: LNK4098
« on: April 01, 2011, 05:42:37 pm »
I get a lot of warning LIB4099's as well, and I can't even get rid of them with the old:
#pragma warning disable 4099

Of course, I'd rather fix them than just hide them, but no clue what to do to fix them. I think in SFML 2 these are gone, btw, it's just in SFML 1.6, so it really doesn't matter.

9
Graphics / Help on Asteroids Game!
« on: April 01, 2011, 05:35:14 pm »
Here is some example code:

Simple shot class:
Code: [Select]

class Shot
{
public:
Vect2d pos; //position in pixels of the shot
Vect2d motion; //direction and speed of the shot
float distance_travelled; //how far the shot has travelled over it's lifetime so far

Shot(void);
};


to collide shots with things, do something like:
Code: [Select]

bool Ship::CheckShotCollision(Asteroid* theAsteroid)
{
for(int i = shots.size() - 1;i >= 0; --i)
{
//did we collide?
if( (shots[i]->pos - theAsteroid->pos).LengthSqr() <= theAsteroid->radius_squared)
{
//we collided with this shot
delete shots[i];
shots.erase(shots.begin() + i);
return true;
}
}

return false; //if we got here, no collision
}


Make a list of shots somewhere (like in a Ship class)
Code: [Select]

float time_since_last_shot;

std::vector<Shot *> shots;


To fire a new shot, do something like:
Code: [Select]

bool Ship::Shoot(void)
{
if(shots.size() >= MAX_SHOTS) return false;
if(time_since_last_shot < TIME_BETWEEN_SHOTS) return false;

//add a new shot
Shot *nshot = new Shot();
//create its motion vector from the ship's facing angle
nshot->motion.x = -sin(angle);
nshot->motion.y = -cos(angle);
nshot->pos = pos + nshot->motion * 16.f; //move the shot to the front of the ship
nshot->motion *= SHOT_SPEED; //scale the motion up to speed
shots.push_back(nshot);

time_since_last_shot = 0.f;
return true;
}


To draw them, do:
Code: [Select]

for(int i = 0; i < theShip.shots.size(); ++i)
{
theShotsSprite->SetPosition(theShip.shots[i]->pos.x, theShip.shots[i]->pos.y);
App->Draw(*theShotsSprite);
}

10
Graphics / Sending variables to the screen
« on: April 01, 2011, 03:35:20 pm »
Here is how I am currently handling a lot of my input; this is a simple example, not perfect code by any means:

Code: [Select]

void Game::DoInput(void)
{
if(App->GetInput().IsKeyDown(sf::Key::Left)) turn_left = true;
else turn_left = false;

if(App->GetInput().IsKeyDown(sf::Key::Right)) turn_right = true;
else turn_right = false;

if(App->GetInput().IsKeyDown(sf::Key::Up)) thrust = true;
else thrust = false;

if(App->GetInput().IsKeyDown(sf::Key::Space)) fire = true;
else fire = false;
}

void Game::DoPhysics(float time_passed)
{
if(turn_left) theShip.angle += TURN_SPEED * time_passed;
if(turn_right) theShip.angle -= TURN_SPEED * time_passed;

if(fire) theShip.Shoot();

if(thrust) theShip.Thrust(time_passed);

theShip.Update(time_passed);
theAsteroid.Update(time_passed);

//slow down the ship a bit
for(int partialseconds_passed = time_passed * 10000.f;partialseconds_passed >= 0; --partialseconds_passed)
theShip.motion *= 0.99999;

//collision detection
if(theShip.CheckShotCollision(&theAsteroid))
{
//reset the asteroid
float rand_angle = rand()%360;
rand_angle /= 57.2957795f; //convert from degrees to radians
theAsteroid.motion.x = -sin(rand_angle);
theAsteroid.motion.y = -cos(rand_angle);
theAsteroid.motion *= ASTEROID_SPEED;
theAsteroid.pos.x = 30;
theAsteroid.pos.y = 30;
}

}

void Game::DrawLevel(void)
{
App->Clear();

theShipSprite->SetRotation(theShip.angle * 57.2957795f);
theShipSprite->SetPosition(theShip.pos.x, theShip.pos.y);
App->Draw(*theShipSprite);

theAsteroidSprite->SetPosition(theAsteroid.pos.x, theAsteroid.pos.y);
App->Draw(*theAsteroidSprite);

for(int i = 0; i < theShip.shots.size(); ++i)
{
theShotsSprite->SetPosition(theShip.shots[i]->pos.x, theShip.shots[i]->pos.y);
App->Draw(*theShotsSprite);
}
}


The Game::Run() function DOES NOT CHANGE from the one I posted before; nothing is added to it's event handling loop. If I was tracking mouse movement, I would probably add that into the event loop of Game::Run(), just because it's simple.

So, with the code above, my Game::Logic playstate looks like:
Code: [Select]

case PLAY1:
{
DoInput();
DoPhysics(time_passed);
DrawLevel();
}
break;


By doing things this way, I can easily have totally different DoInput() functions for different game states, like DoInputPlay2() etc., if they are required. Also, I have followed the cardinal rule of application/game programming by following the CONTROL/MODEL/VIEW paradigm, and seperating my CONTROL (inputs) from my MODEL (physics and rules) from my VIEW (rendering). That's why the DoInput() function only sets flag variables but doesn't act on them, and the DoPhysics() function doesn't know anything about any input events, it just acts on these flag variables that allow the CONTROLLER to communicate to the MODEL "what the player wishes to do". Keeping the three parts of the program compartmentalized like this is very important for large projects, in my experience.

Looking at the above (quickly-written) code, I would improve it by making a Ship::Turn() function, among other things. Anyway, I hope this is helpful.

11
Graphics / Sending variables to the screen
« on: April 01, 2011, 03:16:03 pm »
Here is an example of a simple skeleton code architecture to base a game on, pay special attention to the Game::Run() and Game::Logic() member functions:

Code: [Select]

#include "Game.h"

Game::Game(void)
{
App=NULL;
// Create the main rendering window
App = new sf::RenderWindow(sf::VideoMode(800, 640, 32), "TileMap Example");

//hide the mouse cursor in the window
App->ShowMouseCursor(false);

GameState = STARTUP;

stateTime = 0;//not used in the current code, but included for time-based state changes later,
                //like displaying a graphic for a few seconds

the_map = new Map(App);
}

Game::~Game(void)
{
delete the_map;

delete App;
}

void Game::Run(void)
{
while (App->IsOpened())
    {
        // Process events        
        while (App->GetEvent(Event))
        {
            // Close window : exit
            if (Event.Type == sf::Event::Closed)
{
                App->Close();
return;
}
        }
       
//perform our game logic
//App->Clear(sf::Color(0, 0, 0));
Logic(App->GetFrameTime());

// Display window contents on screen
App->Display();
    }
}

void Game::DrawLevel(void)
{
the_map->DrawMap();
}

void Game::DoPhysics(float time_passed)
{

}

void Game::Logic(float time_passed)
{
switch(GameState)
{
case LOAD1:
{
the_map->LoadMap("data/Level1.txt");
GameState = PLAY1;
}
break;

case PLAY1:
{
//perform the game's physics calculations
DoPhysics(time_passed);

DrawLevel();
}
break;

case STARTUP:
{
the_map->SetScreen(0, 0, 10, 8);
GameState = LOAD1;
}
break;
default:
break;
}//end switch
}

12
General / Help with sprite movement/collision logic
« on: April 01, 2011, 03:03:51 pm »
A simple improvement to the kludge would be, after a collision is detected,  to loop backwards adjusting the ship position from it's current towards it's old position, on pixel length at a time. Stop the loop when no collision is detected.

13
General discussions / C++ scripting in SFML games
« on: April 01, 2011, 02:52:24 pm »
Lua is very popular in the game programming community:
http://www.lua.org/

14
General discussions / vertical sync
« on: March 19, 2011, 06:52:36 pm »
An ugly kludge that you can do is to simply only perform the rendering code if a certian amount of time has passed. This won't lock you to the monitor refresh rate, but it will allow you to do multiple calls to your physics loop etc in between calls to the rendering loop, on systems where the physics etc is running quite fast. I have done something simple like that in the past to lockmy framerate down to "no more than 60fps" for example. It's not ideal, but if the main consideration is not wasting time drawing frames that will never be seen, it helps.

15
Graphics / Multiple images on one sprite
« on: March 18, 2011, 03:10:08 pm »
You need RenderImage, which is only available in SFML 2. A RenderImage allows you to draw on an Image.

Pages: [1] 2 3
anything