Theres this thing that i dont fully understand. Im using this tutorial: http://lazyfoo.net/SDL_tutorials/lesson08/index.php and i in here we first set up some surfaces with text and then asign their value to the message and then for some reason we have to reset the message value to 0 in order for the program to quit properly, but if i dont set up the surfaces with text from the start and just set up the message myself when coding the event itself, i dont need to reset it and everything works just fine, whats the deal? I think i wasnt very clear but i think it should not be hard to understand if you see the tutorial i gave you.
sfuo 111 Practically a Master Poster
He sets it to NULL (or 0) because that way he doesn't reprint the same message constantly. Whenever you press a key message becomes non-NULL and it redraws and this has nothing to do with the program quitting.
nuclear -9 Junior Poster in Training
Well, when i use the method in the tutorial and dont set it to 0, when i try to quit the program it just freezes, works fine when doing my way. By the way, when i use the tut method, the message appear for half a second and dissapears, it worked last time, dont know whats the problem.
sfuo 111 Practically a Master Poster
I'd have to look at the source code you were running. The download-able code on his website doesn't seem to have any problems. The message flashing part makes me think that you had apply_surface( 0, 0, background, screen );
outside of the message != NULL
check.
As for the freezing part I'm not sure because I'd have to look at what you had.
nuclear -9 Junior Poster in Training
void eve()
{
while( run == true)
{
while( SDL_PollEvent(&event) )
{
if ( event.type == SDL_QUIT )
{
run = false;
}
if ( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_UP: message = Up; break;
case SDLK_DOWN: message = Down; break;
case SDLK_RIGHT: message = Right; break;
case SDLK_LEFT: message = Left; break;
}
}
}
blit(back,screen,0,0);
if ( message != 0 )
{
blit(back,screen,0,0);
blit(message,screen,100,300);
message = 0;
}
SDL_Flip(screen);
}
}
I see that if i remove the blit before the "if ( message != 0 )" it works fine, why is that? Oh and one more question, why when we use key states, we see lets say text for the time we are holding a key down, but when we use the method i posted earlier in the tut, it changes permenantly, it seems fine, but shouldnt the values change permenantly using key state method too? Key state tut: http://lazyfoo.net/SDL_tutorials/lesson10/index.php
Edited by nuclear because: n/a
raptr_dflo 48 Posting Pro
No values in your code are "changing permanently". When a key is pressed, an event is triggered, you catch the event, and you assign a value to your message variable. As soon as you blit your message, you set your message variable back to 0. That doesn't look permanent to me. If you wish to keep the displayed message visible, then (as you noticed yourself), don't blit the background over top of it every time through your while(run) loop. In fact, you shouldn't call SDL_Flip(screen) until there's actually a change to bother with.
So if you want the displayed message to persist until the next keystroke:
if ( message != 0 )
{
blit(back,screen,0,0);
blit(message,screen,100,300);
SDL_Flip(screen);
message = 0;
}
If you want to clear the message if you press any key other than up/down/left/right, then create a fifth non-zero value to assign to message as a default in your switch() statement at line 14.
nuclear -9 Junior Poster in Training
When i use the keys in event based method, how can i make the messages dissapear after i let go of the key, because in the key state method its done easily and cant understand why it doesnt work the same way on event based method.
sfuo 111 Practically a Master Poster
What you would need is a check for when the even is SDL_KEYUP and then set the message to 0 there rather than after the message is displayed.
void eve()
{
while( run == true)
{
while( SDL_PollEvent(&event) )
{
if ( event.type == SDL_QUIT )
{
run = false;
}
if ( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_UP: message = Up; break;
case SDLK_DOWN: message = Down; break;
case SDLK_RIGHT: message = Right; break;
case SDLK_LEFT: message = Left; break;
}
}
if ( event.type == SDL_KEYUP )
{
switch( event.key.keysym.sym )
{
default: message = 0; break; //set message to 0 when key is released (this is if any key is released)
}
}
}
blit(back,screen,0,0); //always draw the background
if ( message != 0 ) //draw the message if there is one
blit(message,screen,100,300);
SDL_Flip(screen);
}
}
nuclear -9 Junior Poster in Training
Since i dont want to flood the forum with new topics, i will just ask all of my SDL questions here. Its not exactly a problem but something i dont understand, i initialized the font in the Global:
TTF_Font* font = TTF_OpenFont("lazy.ttf",30);
And later i was doing some timing stuff and i was getting an error that something was not found, then i set the font to NULL and initialized it in the other function and then the program worked perfectly, why is that? I basicly did the exact same thing, but just initialized the font not in the Global but elsewhere. And one more thing im unsure of is that when i do something in the event thats based on some variable and lets say it was set to 0 ( the variable ) first, and lets say if i press and hold the Up key, the value of that variable will be changed, but after i release the Up key, the value is changed back to 0, seems good and all, but when i try to do something based like that on a simple console app, the value doesnt change back, why is that?
Edited by nuclear because: n/a
raptr_dflo 48 Posting Pro
As far as the font issue, it doesn't look as though the problem is with loading the font, but what you do with the returned font-handle after that point. I'm also not entirely sure what you mean by "in the Global" ... you can't call functions outside of main() or other functions, so you should be within the scope of -some- function when you call TTF_OpenFont(). And if you've coded your line exactly as you provided it above, then you've also created a local variable at that point, which won't exist in some other function when you try to use it. If this isn't entirely clear, try posting more of your code, and I'll be able to tell exactly what went wrong.
Then, if by "simple console app", you mean something that doesn't use SDL, then you don't have the same event-loop at your disposal, though there are still platform-specific ways to get at the same information (which is what SDL uses internally so that it is portable across multiple operating systems). Otherwise, post the smallest amount of code that demonstrates the problem, and again, we'll be happy to take a look. Unfortunately, despite many years of software development experience, I still can't read your screen from way over here! ;-)
nuclear -9 Junior Poster in Training
I thnk you already answered the Global thing questions, i was calling a function outside of any other function, in the Global scope that is, but when i did that in a function it worked perfectly. Thanks to you, now i know that i cant call functions in the Global Scope :)
By Global Scope i mean like this:
#include "stdafx.h"
#include <iostream>
int x = 5, y = 10;
void bye()
{
}
void hi()
{
}
int main()
{
char f;cin>>f;
return 0;
}
I created a variable which will be available for all of my created functions below.
About the app question, its not exacly a problem, but something i would like to understand, so lets say in SDL we do this :
message = 0;
while( run == true)
{
while( SDL_PollEvent(&event) )
{
if ( event.type == SDL_QUIT ) { run = false; }
if ( event.type == SDL_KEYDOWN )
{
if ( event.key.keysym.sym == SDLK_UP )
{
message = Up;
}
And the value only changes when i am holding the UP key, when i let go of it, it changes back to 0 ( its just a part of the code ), but when i try to do something based on this using iostream, the value doesnt reset in the Next loop, it just stays 5 no matther how many loops i go through, like this:
int x = 0, y = 1;
while(true)
{
if ( y == 1 )
{
x = 5;
}
cout << x << endl;
y++;
char z;cin>>z;
}
Edited by nuclear because: n/a
raptr_dflo 48 Posting Pro
For you first example, when you say "it changes back to 0 ( its just a part of the code )", I assume you mean there's additional code you haven't included (but is relevant to the behavior we're discussing) which reads something like:
if ( event.type == SDL_KEYUP )
{
if ( event.key.keysym.sym == SDLK_UP )
{
message = 0;
}
...
}
Also, to clarify, the value doesn't change "while you're holding the key", it changes to Up
when you first press the key (which generates a key-down event) and changes back to 0 when you release the key (which generates a key-up event). It doesn't do anything in between the time you press the key and release the key unless you also track key-repeat events (like when you hold down a key in a text-editor and after a short pause it starts repeating).
Then as far as your second example, why would you expect the value of x to go back to zero? Very little happens "automatically" in programming, and if it does, it's for a reason and -should- be well documented (though documentation is often not nearly as clear or as complete as it should be -- that's a different issue). But your variables shouldn't change value out from under you. If you tell x it should now have the value 5, it should keep that value until you tell it you want it to have some other value. You don't do that in your code, so there you go.
If you added additional code after line 8, then it would do what you expect:
int x = 0, y = 1;
while(true)
{
if ( y == 1 )
{
x = 5;
}
else {
x = 0;
}
cout << x << endl;
y++;
char z;cin>>z;
}
nuclear -9 Junior Poster in Training
I thought about these questions and red your answers and it seems very clear and simple now, the problem with the font was that i was calling the function, before i declared it and it is now clear about the 0 thing. At this time i dont have any more questions, thanks for quick and helpful answers.
nuclear -9 Junior Poster in Training
SDL_FillRect(screen,&screen->clip_rect,SDL_MapRGB(screen->format,0,0,0));
if ( timer == true )
{
stringstream time;
time << "Watch: " << SDL_GetTicks() - start;
timing = TTF_RenderText_Solid(font,time.str().c_str(),c);
blit(timing,screen,200,200);
SDL_FreeSurface(timing);
}
SDL_Flip(screen);
Taken from a tutorial: http://lazyfoo.net/SDL_tutorials/lesson12/index.php
This part of the code is from the main loop and i would like to ask why do we keep cleaning out the Surface
SDL_FreeSurface(timing)
, is it really necessary? By the way, i dont fully understand the part in the tutorial about the
time << "Timer: " << SDL_GetTicks() - start;
, dont understand the explanation of the " - " thing in the tutorial, dont know, maybe my english is simply not good enough :)
Edited by nuclear because: n/a
raptr_dflo 48 Posting Pro
As far as the surface, from the SDL reference for TTF_RenderText_Solid(): "Returns: a pointer to a new SDL_Surface. NULL is returned on errors." This means the function has allocated a new SDL_Surface object to render the text onto, and it is the caller's responsibility (yours, in this case) to free the allocated object when you're done with it. Otherwise you have a memory leak (as the loop allocated more and more of these surfaces without giving them back) and eventually the program crashes.
The "-" thing is a simple subtraction. SDL_GetTicks() probably returns large and relatively meaningless numbers (but a bigger one each time), so what you want instead is how many have gone by since you started. You capture the first value into variable "start", and then later find out how many ticks have gone by by subtracting that first value from the current value returned.
nuclear -9 Junior Poster in Training
About the " ...- start ", in this tutorial its there so when we press the "s" key and when we press it again, the timer starts from 0, so ok, i get that, we subtract the time we have from the same time value so we get a 0 seconds, when we start the timer again by pressing s, but my question is, shouldnt the subtraction work on every loop? It seems that it only subtracts one time and just ignores the " ...- start " line after. All in this tut: http://lazyfoo.net/SDL_tutorials/lesson12/index.php
raptr_dflo 48 Posting Pro
For convenience, I'm posting the main() routine from the tutorial (as provided in the download link), so we can refer to the same line numbers:
int main( int argc, char* args[] )
{
//Quit flag
bool quit = false;
//The timer starting time
Uint32 start = 0;
//The timer start/stop flag
bool running = true;
//Initialize
if( init() == false )
{
return 1;
}
//Load the files
if( load_files() == false )
{
return 1;
}
//Generate the message surface
startStop = TTF_RenderText_Solid( font, "Press S to start or stop the timer", textColor );
//Start the timer
start = SDL_GetTicks();
//While the user hasn't quit
while( quit == false )
{
//While there's an event to handle
while( SDL_PollEvent( &event ) )
{
//If a key was pressed
if( event.type == SDL_KEYDOWN )
{
//If s was pressed
if( event.key.keysym.sym == SDLK_s )
{
//If the timer is running
if( running == true )
{
//Stop the timer
running = false;
start = 0;
}
else
{
//Start the timer
running = true;
start = SDL_GetTicks();
}
}
}
//If the user has Xed out the window
else if( event.type == SDL_QUIT )
{
//Quit the program
quit = true;
}
}
//Apply the background
apply_surface( 0, 0, background, screen );
//Apply the message
apply_surface( ( SCREEN_WIDTH - startStop->w ) / 2, 200, startStop, screen );
//If the timer is running
if( running == true )
{
//The timer's time as a string
std::stringstream time;
//Convert the timer's time to a string
time << "Timer: " << SDL_GetTicks() - start;
//Render the time surface
seconds = TTF_RenderText_Solid( font, time.str().c_str(), textColor );
//Apply the time surface
apply_surface( ( SCREEN_WIDTH - seconds->w ) / 2, 50, seconds, screen );
//Free the time surface
SDL_FreeSurface( seconds );
}
//Update the screen
if( SDL_Flip( screen ) == -1 )
{
return 1;
}
}
//Clean up
clean_up();
return 0;
}
It looks to me like the subtraction time << "Timer: " << SDL_GetTicks() - start;
(line 79 above) is being performed every time through the while( quit == false ){...}
loop, as long as the running
flag is true.
nuclear -9 Junior Poster in Training
Yes, and the thing i dont understand is this, when we press "s" while the timer is running:
//If a key was pressed
if( event.type == SDL_KEYDOWN )
{
//If s was pressed
if( event.key.keysym.sym == SDLK_s )
{
//If the timer is running
if( running == true )
{
//Stop the timer
running = false;
start = 0;
}
When we press "s" again:
else
{
//Start the timer
running = true;
start = SDL_GetTicks();
}
So the start variable has SDL_GetTicks value and it subracts:
time << "Timer: " << SDL_GetTicks() - start;
So my question is, shouldnt it subtract from the "start" value every loop? It seems that it only activates once, when i press "s" two times, but after that, the time timer starts running as if theres no "- start" line. Its as if the "start" value takes the SDL_GetTicks value and then sets to 0 after it does his thing, but its not.
Edited by nuclear because: n/a
raptr_dflo 48 Posting Pro
Its as if the "start" value takes the SDL_GetTicks value and then sets to 0 after it does his thing
What makes you think this is the case?
From the tutorial description text:
So if you started the timer when SDL_GetTicks() was 10,000 and now SDL_GetTicks() is 20,000, it will return 10,000 meaning 10 seconds have passed since the timer started.
Meaning SDL_GetTicks() is returning values in units of milliseconds, not seconds. Perhaps this is the source of confusion? Since the code calls the rendered text-surface "seconds", it might be more obvious if you convert to the expected units:
...
time << "Timer: " << (SDL_GetTicks() - start)/1000; // or use 1000.0 to see fractions of seconds
seconds = TTF_RenderText_Solid( font, time.str().c_str(), textColor );
...
nuclear -9 Junior Poster in Training
I think i understand what my problem was, thats that for now, thanks again
nuclear -9 Junior Poster in Training
One thing not so clear on : http://lazyfoo.net/SDL_tutorials/lesson14/index.php
By the way this tutorial relates to : http://lazyfoo.net/SDL_tutorials/lesson13/index.php
So i dont actually understand this line:
SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );
From what i get get_ticks() always return 0 value since every loop we basicly subtract two same values and if lets say the frame rate is set to 20, then it will delay for 20 milliseconds.
I dont event know how to explaint it exacly what the problem is, i would appreciate if anyone could write down the actual values of an example instead of the line i showed before.
raptr_dflo 48 Posting Pro
Do you understand the methods in the Timer class from lesson13? Timer::get_ticks() does -not- always return 0. If you don't believe that, write some simple code that creates a timer instance, starts/stops/pauses/unpauses it, and prints out the value returned from get_ticks() a bunch of times throughout. Then go back to the code and see why the printed values are what they are.
From what i get get_ticks() always return 0 value since every loop we basicly subtract two same values
Where on earth are you coming up with that logic? As long as the timer is running, get_ticks() subtracts the STARTING value of SDL_GetTicks() from the CURRENT value of SDL_GetTicks(). Are you under the impression that SDL_GetTicks() returns the same value every time you call it? What would be the point of that? Try:
for (int i = 0; i < 100; ++i)
cout << SDL_GetTicks() << endl;
nuclear -9 Junior Poster in Training
Yes i do understand the Timer methods, i know it can return different values, and i dont think that SDL_GetTicks() always return the same value, i think that we simply dont understand eachother :) . Where i said get_ticks always return 0, i ment that in the the main loop we start our timer ( in the frame rate lesson ), so every loop the startTicks sets to SDL_GetTicks() and int that case get_ticks should return something close to 0 every time since we subtract the current time from the startTicks ( which transforms into current time aswell ). So the part im not sure of if get_ticks return around 0 every time in THIS CASE and if those few millisecond close to 0 have anything to do with out frame rate.
Well, as you can see im not fluent in English so its hard for me to point out the problem more clearly but i do appreciate that you are still trying to help.
Edited by nuclear because: n/a
raptr_dflo 48 Posting Pro
Hi nuclear, sorry I've been so long getting back to you.
I think I finally understand what you're talking about, and agree it generally doesn't make sense to call fps.start() each time through the loop, but I see why LazyFoo is doing it: the work that is done between the call to fps.start() and the call to fps.get_ticks() takes a small but non-zero amount of time, so fps.get_ticks() will presumably return a small number of milliseconds (possibly even zero on a fast enough machine). The line
SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() );
then tells SDL how long to wait before resuming the loop:
1000 (units of ms/s) divided by FRAMES_PER_SECOND (units of f/s) gives a value in units of milliseconds-per-frame, so if fps.get_ticks() tells us how many milliseconds have expired so far, then the difference is how many remaining milliseconds we should wait to maintain the frame-rate.
Restarting the timer each time means you don't have to maintain the previous value of get_ticks(). An alternative approach is something like:
fps.start();
unsigned long prev_ticks = 0;
while ( quit == false )
{
...
unsigned long current_ticks = fps.get_ticks();
if ( cap == true && current_ticks - prev_ticks < 1000 / FRAMES_PER_SECOND)
{
SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - (current_ticks - prev_ticks) );
}
prev_ticks = current_ticks;
}
If you're always maintaining the desired frame-rate (and as currently implemented, FRAMES_PER_SECOND doesn't change), you could also use the frame counter variable 'frame' to compute how many ticks should have expired by now:
fps.start();
while (quit == false)
{
...
unsigned long expected_ticks = (1000 / FRAMES_PER_SECOND) * frame;
unsigned long current_ticks = fps.get_ticks();
if ( current_ticks < expected_ticks )
{
SDL_Delay( expected_ticks - current_ticks );
}
}
Keep in mind that using the frame-count this way means that if you turn off frame-rate-capping, then the frame-counter will increment much more quickly, and when you turn it back on, expected_ticks will be quite large compared to current_ticks, and the next frame won't render until the same time it would have rendered if frame-rate-capping were left on. Similarly, if you can dynamically change the frame-rate, then this computation of expected_ticks will be wrong. But instead, you could do expected_ticks += 1000 / FRAMES_PER_SECOND;
There are other options as well, depending on your actual needs, but I hope this helps clarify what's going on in the demo.
nuclear -9 Junior Poster in Training
I understand, thank you, now theres another thing, now im at: http://lazyfoo.net/SDL_tutorials/lesson21/index.php
The thing is that i always get something like this - my dot moves to the edge of the camera (the one we set up) and the dot just gets stuck there and after a while going to the same direction, the dot goes forward. I cant find whats wrong in my code i can see that the dot actually reacts to the camera but in a wrong way, heres my code:
//Pre
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include <sstream>
#include <string>
using namespace std;
//.
//Global
SDL_Surface *screen= 0,*background= 0,*dot= 0;
const int screenW= 640,screenH= 480;
const int dotW= 20,dotH= 20;
SDL_Color c= { 255,255,255 };
SDL_Event event;
bool quit= false;
//-------------------------------------
const int levelW= 1280;
const int levelH= 960;
SDL_Rect camera= { 0,0,screenW,screenH };
//.
//Dec
bool init();
SDL_Surface *optimize(string filename);
void blit(SDL_Surface *source,SDL_Surface *destination,int x,int y,SDL_Rect *clip= 0);
void eve();
void clean();
//.
//Collision
bool collisionCheck(SDL_Rect A,SDL_Rect B)
{
int topA,topB;
int bottomA,bottomB;
int leftA,leftB;
int rightA,rightB;
topA= A.y;
bottomA= A.y+A.h;
leftA= A.x;
rightA= A.x+A.w;
topB= B.y;
bottomB= B.y+B.h;
leftB= B.x;
rightB= B.x+B.w;
if ((topA>=bottomB)||(bottomA<=topB)||(leftA>=rightB)||(rightA<=leftB))
{
return false;
}
return true;
}
//.
//Class:
class timer
{
public:
timer();
void start();
int getT();
private:
int startT;
};
class fManager
{
public:
fManager();
//Cap:
void capStart();
void cap();
//Show Cap:
void showCapStart();
void showCap();
void cFrameI();
private:
//Cap:
int CAP;
timer o;
//Show Cap:
int cFrame;
timer M,S;
};
class objects
{
public:
objects();
void wallShow();
protected:
SDL_Rect wall;
};
class Dot
{
public:
Dot();
void dotEvent();
void dotMove();
void dotShow();
void setCamera();
private:
int x,y;
int xVel,yVel;
};
//.
//Player:
//Constructor
Dot::Dot()
{
x=0,y=0;
xVel=0,yVel=0;
}
//Dot move
void Dot::dotMove()
{
x += xVel;
if( ( x < 0 ) || ( x + dotW > levelW ) )
{
x -= xVel;
}
y += yVel;
if( ( y < 0 ) || ( y + dotH > levelH ) )
{
y -= yVel;
}
}
//Set Camera
void Dot::setCamera()
{
camera.x = ( x + dotW / 2 ) - screenW / 2;
camera.y = ( y + dotH / 2 ) - screenH / 2;
if( camera.x < 0 )
{
camera.x = 0;
}
if( camera.y < 0 )
{
camera.y = 0;
}
if( camera.x > levelW - camera.w )
{
camera.x = levelW - camera.w;
}
if( camera.y > levelH - camera.h )
{
camera.y = levelH - camera.h;
}
}
//Dot Show
void Dot::dotShow()
{
blit( dot, screen, x - camera.x, y - camera.y );
}
//Dot Eve
void Dot::dotEvent()
{
if (event.type==SDL_KEYDOWN)
{
switch(event.key.keysym.sym)
{
case SDLK_UP: yVel-= dotH/2; break;
case SDLK_DOWN: yVel+= dotH/2; break;
case SDLK_LEFT: xVel-= dotW/2; break;
case SDLK_RIGHT: xVel+= dotW/2; break;
}
}
else
if (event.type==SDL_KEYUP)
{
switch(event.key.keysym.sym)
{
case SDLK_UP: yVel-= dotH/2; break;
case SDLK_DOWN: yVel+= dotH/2; break;
case SDLK_LEFT: xVel-= dotW/2; break;
case SDLK_RIGHT: xVel+= dotW/2; break;
}
}
}
//.
//Objects:
//Constructor
objects::objects()
{
wall.x= 400;
wall.y= 300;
wall.w= 200;
wall.h= 250;
}
//Wall Show
void objects::wallShow()
{
SDL_FillRect(screen,&wall,SDL_MapRGB(screen->format,0,0,0));
}
//.
//Frame Manager
//---------------------------------------
//Constructor
fManager::fManager()
{
CAP= 10;
cFrame= 0;
}
//Cap Start
void fManager::capStart()
{
o.start();
}
//Cap
void fManager::cap()
{
if (o.getT()<1000/CAP)
{
SDL_Delay(1000/CAP-o.getT());
}
}
//---------------------------------------
//---------------------------------------
//Show Cap Start
void fManager::showCapStart()
{
M.start();
S.start();
}
//Current Frame Increase
void fManager::cFrameI()
{
cFrame++;
}
//Show Cap
void fManager::showCap()
{
if (M.getT()>1000)
{
stringstream o;
o<< "Test "<< cFrame/(S.getT()/1000);
SDL_WM_SetCaption(o.str().c_str(),0);
M.start();
}
}
//---------------------------------------
//.
//Timer:
//Constructor
timer::timer()
{
startT= 0;
}
//Timer start
void timer::start()
{
startT= SDL_GetTicks();
}
//Get Ticks
int timer::getT()
{
return SDL_GetTicks()-startT;
}
//.
//Main:
int main(int argc,char** argv)
{
init();
eve();
clean();
return 0;
}
//Init
bool init()
{
if (SDL_Init(SDL_INIT_EVERYTHING)== -1)
{
return false;
}
screen= SDL_SetVideoMode(screenW,screenH,32,SDL_SWSURFACE);
background= optimize("background.png");
dot= optimize("player.png");
SDL_WM_SetCaption("Test",0);
SDL_WM_SetIcon(background,0);
return true;
}
//Optimize
SDL_Surface *optimize(string filename)
{
SDL_Surface *loaded= IMG_Load(filename.c_str());
SDL_Surface *optimized= SDL_DisplayFormat(loaded);
SDL_FreeSurface(loaded);
SDL_SetColorKey(optimized,SDL_SRCCOLORKEY,SDL_MapRGB(optimized->format,255,255,255));
return optimized;
}
//Blitting
void blit(SDL_Surface *source,SDL_Surface *destination,int x,int y,SDL_Rect *clip)
{
SDL_Rect offset;
offset.x= x;
offset.y= y;
SDL_BlitSurface(source,clip,destination,&offset);
}
//Event ***
void eve()
{
//Cap:
fManager C;
//Show Cap:
fManager S;
S.showCapStart();
//Player:
Dot D;
while(quit== false)
{
C.capStart();//Cap
while(SDL_PollEvent(&event))
{
D.dotEvent();
if (event.type== SDL_QUIT) { quit= true; }
}
D.dotMove();
D.setCamera();
blit(background,screen,0,0);
D.dotShow();
SDL_Flip(screen);
S.cFrameI();//Show Cap
S.showCap();//Show Cap
C.cap();//Cap
}
}
//Clean
void clean()
{
SDL_FreeSurface(background);
SDL_FreeSurface(dot);
SDL_Quit();
}
//.
Pasting the whole code since i cant find any mystake only by looing in the dot class so im not sure where to look.
P.S maybe my code is not exacly the same like Foo's, but everything works perfectly, except for the Camera thing.
Edited by nuclear because: n/a
nuclear -9 Junior Poster in Training
Whoops! It seems that i actually missed one line, the one line that I was looking for more than a couple of hours :D . Everything is fine now.
raptr_dflo 48 Posting Pro
Cool! :)
nuclear -9 Junior Poster in Training
http://lazyfoo.net/SDL_tutorials/lesson21/index.php
Now theres this line i dont fully understand :
void Dot::show()
{
//Show the dot
apply_surface( x - camera.x, y - camera.y, dot, screen );
}
When i do simply like that :
//Show the dot
apply_surface( x, y , dot, screen );
Then the dot eventually gets out of range of the camera. I'm trying to do the math but i'm not able to find the correct answer since i get that everything should be fine using the second line too, im pretty sure i'm missing something yet again, common thing for me :)
Edited by nuclear because: n/a
raptr_dflo 48 Posting Pro
No worries. Looks like what's going on is: you're moving a dot around on a "large" level (1280 x 960, but can be arbitrarily large), then you're also moving the smaller "camera" window (640 x 480) around to view just a piece of the level at a time. Since both camera coordinates and dot coordinates are both offsets into the level coordinate system, in order to draw the dot onto the piece of the level you can see through the camera, you need to know it's position relative to the camera, which is (x-camera.x, y-camera.y).
If you're background.png is 1280x960, or if you can make one that's bigger, make sure you blit the correct portion of that into your output SDL window. Without looking up the references, maybe your line 354 above needs to be:
blit(background,screen,0,0,camera);
to clip the portion of the background visible through the camera (and paint it to the screen at postion (0,0)).
nuclear -9 Junior Poster in Training
No worries. Looks like what's going on is: you're moving a dot around on a "large" level (1280 x 960, but can be arbitrarily large), then you're also moving the smaller "camera" window (640 x 480) around to view just a piece of the level at a time. Since both camera coordinates and dot coordinates are both offsets into the level coordinate system, in order to draw the dot onto the piece of the level you can see through the camera, you need to know it's position relative to the camera, which is (x-camera.x, y-camera.y).
If you're background.png is 1280x960, or if you can make one that's bigger, make sure you blit the correct portion of that into your output SDL window. Without looking up the references, maybe your line 354 above needs to be:
blit(background,screen,0,0,camera);
to clip the portion of the background visible through the camera (and paint it to the screen at postion (0,0)).
The line 354 was the problem i had earlier, I have changed it to the line you posted and it worked fine :) . And a big thanks yet again, i get it now.
P.S Can i ask for some information about you, since you seem to be really good at SDL, guessing thats not it :) . I understand if you dont want to answer this kind of stuff :D .
Edited by nuclear because: n/a
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.