2012-03-02 51 views
0

當我嘗試編譯以下教訓 http://lazyfoo.net/downloads/index.php?file=SDLTut_lesson19不能編譯這個SDL課...:/

我在Visual Studio 2010中的輸出:

1>------ Build started: Project: 19-circularcollisiondetect, Configuration: Debug Win32 ------ 
1>Build started 02/03/2012 03:47:51. 
1>InitializeBuildStatus: 
1> Touching "Debug\19-circularcollisiondetect.unsuccessfulbuild". 
1>ClCompile: 
1> main.cpp 
1>c:\users\fab\desktop\c++\sdl 1.2.15\19-circularcollisiondetect\19-circularcollisiondetect\main.cpp(140): error C2668: 'pow' : ambiguous call to overloaded function 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(583): could be 'long double pow(long double,int)' 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(535): or  'float pow(float,int)' 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(497): or  'double pow(double,int)' 
1>   while trying to match the argument list '(int, int)' 
1>c:\users\fab\desktop\c++\sdl 1.2.15\19-circularcollisiondetect\19-circularcollisiondetect\main.cpp(140): error C2668: 'pow' : ambiguous call to overloaded function 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(583): could be 'long double pow(long double,int)' 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(535): or  'float pow(float,int)' 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(497): or  'double pow(double,int)' 
1>   while trying to match the argument list '(int, int)' 
1>c:\users\fab\desktop\c++\sdl 1.2.15\19-circularcollisiondetect\19-circularcollisiondetect\main.cpp(162): warning C4018: '<' : signed/unsigned mismatch 
1> 
1>Build FAILED. 
1> 
1>Time Elapsed 00:00:00.80 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

我該如何解決? 我正在使用Visual Studio 2010和SDL 1.2.15。我沒有修改原始代碼。 你能否驗證你是否可以編譯它?

/*This source code copyrighted by Lazy Foo' Productions (2004-2012) 
and may not be redestributed without written permission.*/ 

//The headers 
#include "SDL.h" 
#include "SDL_image.h" 
#include <string> 
#include <vector> 
#include <cmath> 

//Screen attributes 
const int SCREEN_WIDTH = 640; 
const int SCREEN_HEIGHT = 480; 
const int SCREEN_BPP = 32; 

//The frame rate 
const int FRAMES_PER_SECOND = 20; 

//The dot attributes 
const int DOT_WIDTH = 20; 

//The surfaces 
SDL_Surface *dot = NULL; 
SDL_Surface *screen = NULL; 

//The event structure 
SDL_Event event; 

//A circle structure 
struct Circle 
{ 
    int x, y; 
    int r; 
}; 

//The dot 
class Dot 
{ 
private: 
    //The area of the dot 
    Circle c; 

    //The velocity of the dot 
    int xVel, yVel; 

public: 
    //Initializes the variables 
    Dot(); 

    //Takes key presses and adjusts the dot's velocity 
    void handle_input(); 

    //Moves the dot 
    void move(std::vector<SDL_Rect> &rects, Circle &circle); 

    //Shows the dot on the screen 
    void show(); 
}; 

//The timer class 
class Timer 
{ 
private: 
    //The clock time when the timer started 
    int startTicks; 

    //The ticks stored when the timer was paused 
    int pausedTicks; 

    //The timer status 
    bool paused; 
    bool started; 

public: 
    //Initializes variables 
    Timer(); 

    //The various clock actions 
    void start(); 
    void stop(); 
    void pause(); 
    void unpause(); 

    //Gets the timer's time 
    int get_ticks(); 

    //Checks the status of the timer 
    bool is_started(); 
    bool is_paused(); 
}; 

SDL_Surface *load_image(std::string filename) 
{ 
    //The image that's loaded 
    SDL_Surface* loadedImage = NULL; 

    //The optimized surface that will be used 
    SDL_Surface* optimizedImage = NULL; 

    //Load the image 
    loadedImage = IMG_Load(filename.c_str()); 

    //If the image loaded 
    if(loadedImage != NULL) 
    { 
     //Create an optimized surface 
     optimizedImage = SDL_DisplayFormat(loadedImage); 

     //Free the old surface 
     SDL_FreeSurface(loadedImage); 

     //If the surface was optimized 
     if(optimizedImage != NULL) 
     { 
      //Color key surface 
      SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB(optimizedImage->format, 0, 0xFF, 0xFF)); 
     } 
    } 

    //Return the optimized surface 
    return optimizedImage; 
} 

void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL) 
{ 
    //Holds offsets 
    SDL_Rect offset; 

    //Get offsets 
    offset.x = x; 
    offset.y = y; 

    //Blit 
    SDL_BlitSurface(source, clip, destination, &offset); 
} 

double distance(int x1, int y1, int x2, int y2) 
{ 
    //Return the distance between the two points 
    return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2)); 
} 

bool check_collision(Circle &A, Circle &B) 
{ 
    //If the distance between the centers of the circles is less than the sum of their radii 
    if(distance(A.x, A.y, B.x, B.y) < (A.r + B.r)) 
    { 
     //The circles have collided 
     return true; 
    } 

    //If not 
    return false; 
} 

bool check_collision(Circle &A, std::vector<SDL_Rect> &B) 
{ 
    //Closest point on collision box 
    int cX, cY; 

    //Go through the B boxes 
    for(int Bbox = 0; Bbox < B.size(); Bbox++) 
    { 
     //Find closest x offset 
     if(A.x < B[ Bbox ].x) 
     { 
      cX = B[ Bbox ].x; 
     } 
     else if(A.x > B[ Bbox ].x + B[ Bbox ].w) 
     { 
      cX = B[ Bbox ].x + B[ Bbox ].w; 
     } 
     else 
     { 
      cX = A.x; 
     } 

     //Find closest y offset 
     if(A.y < B[ Bbox ].y) 
     { 
      cY = B[ Bbox ].y; 
     } 
     else if(A.y > B[ Bbox ].y + B[ Bbox ].h) 
     { 
      cY = B[ Bbox ].y + B[ Bbox ].h; 
     } 
     else 
     { 
      cY = A.y; 
     } 

     //If the closest point is inside the circle 
     if(distance(A.x, A.y, cX, cY) < A.r) 
     { 
      //This box and the circle have collided 
      return true; 
     } 
    } 

    //If the shapes have not collided 
    return false; 
} 

bool init() 
{ 
    //Initialize all SDL subsystems 
    if(SDL_Init(SDL_INIT_EVERYTHING) == -1) 
    { 
     return false; 
    } 

    //Set up the screen 
    screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE); 

    //If there was an error in setting up the screen 
    if(screen == NULL) 
    { 
     return false; 
    } 

    //Set the window caption 
    SDL_WM_SetCaption("Move the Dot", NULL); 

    //If everything initialized fine 
    return true; 
} 

bool load_files() 
{ 
    //Load the dot image 
    dot = load_image("dot.bmp"); 

    //If there was a problem in loading the dot 
    if(dot == NULL) 
    { 
     return false; 
    } 

    //If everything loaded fine 
    return true; 
} 

void clean_up() 
{ 
    //Free the surface 
    SDL_FreeSurface(dot); 

    //Quit SDL 
    SDL_Quit(); 
} 

Dot::Dot() 
{ 
    //Initialize the offsets and dimentions 
    c.x = DOT_WIDTH/2; 
    c.y = DOT_WIDTH/2; 
    c.r = DOT_WIDTH/2; 

    //Initialize the velocity 
    xVel = 0; 
    yVel = 0; 
} 

void Dot::handle_input() 
{ 
    //If a key was pressed 
    if(event.type == SDL_KEYDOWN) 
    { 
     //Adjust the velocity 
     switch(event.key.keysym.sym) 
     { 
     case SDLK_UP: yVel -= 1; break; 
     case SDLK_DOWN: yVel += 1; break; 
     case SDLK_LEFT: xVel -= 1; break; 
     case SDLK_RIGHT: xVel += 1; break; 
     } 
    } 
    //If a key was released 
    else if(event.type == SDL_KEYUP) 
    { 
     //Adjust the velocity 
     switch(event.key.keysym.sym) 
     { 
     case SDLK_UP: yVel += 1; break; 
     case SDLK_DOWN: yVel -= 1; break; 
     case SDLK_LEFT: xVel += 1; break; 
     case SDLK_RIGHT: xVel -= 1; break; 
     } 
    } 
} 

void Dot::move(std::vector<SDL_Rect> &rects, Circle &circle) 
{ 
    //Move the dot left or right 
    c.x += xVel; 

    //If the dot went too far to the left or right or has collided with the other shapes 
    if((c.x - DOT_WIDTH/2 < 0) || (c.x + DOT_WIDTH/2 > SCREEN_WIDTH) || (check_collision(c, rects)) || (check_collision(c, circle))) 
    { 
     //Move back 
     c.x -= xVel; 
    } 

    //Move the dot up or down 
    c.y += yVel; 

    //If the dot went too far up or down or has collided with the other shapes 
    if((c.y - DOT_WIDTH/2 < 0) || (c.y + DOT_WIDTH/2 > SCREEN_HEIGHT) || (check_collision(c, rects)) || (check_collision(c, circle))) 
    { 
     //Move back 
     c.y -= yVel; 
    } 
} 

void Dot::show() 
{ 
    //Show the dot 
    apply_surface(c.x - c.r, c.y - c.r, dot, screen); 
} 

Timer::Timer() 
{ 
    //Initialize the variables 
    startTicks = 0; 
    pausedTicks = 0; 
    paused = false; 
    started = false; 
} 

void Timer::start() 
{ 
    //Start the timer 
    started = true; 

    //Unpause the timer 
    paused = false; 

    //Get the current clock time 
    startTicks = SDL_GetTicks(); 
} 

void Timer::stop() 
{ 
    //Stop the timer 
    started = false; 

    //Unpause the timer 
    paused = false; 
} 

void Timer::pause() 
{ 
    //If the timer is running and isn't already paused 
    if((started == true) && (paused == false)) 
    { 
     //Pause the timer 
     paused = true; 

     //Calculate the paused ticks 
     pausedTicks = SDL_GetTicks() - startTicks; 
    } 
} 

void Timer::unpause() 
{ 
    //If the timer is paused 
    if(paused == true) 
    { 
     //Unpause the timer 
     paused = false; 

     //Reset the starting ticks 
     startTicks = SDL_GetTicks() - pausedTicks; 

     //Reset the paused ticks 
     pausedTicks = 0; 
    } 
} 

int Timer::get_ticks() 
{ 
    //If the timer is running 
    if(started == true) 
    { 
     //If the timer is paused 
     if(paused == true) 
     { 
      //Return the number of ticks when the timer was paused 
      return pausedTicks; 
     } 
     else 
     { 
      //Return the current time minus the start time 
      return SDL_GetTicks() - startTicks; 
     } 
    } 

    //If the timer isn't running 
    return 0; 
} 

bool Timer::is_started() 
{ 
    return started; 
} 

bool Timer::is_paused() 
{ 
    return paused; 
} 

int main(int argc, char* args[]) 
{ 
    //Quit flag 
    bool quit = false; 

    //Make the dot 
    Dot myDot; 

    //Make the shapes 
    std::vector<SDL_Rect> box(1); 
    Circle otherDot; 

    //Set the shapes' attributes 
    box[ 0 ].x = 60; 
    box[ 0 ].y = 60; 
    box[ 0 ].w = 40; 
    box[ 0 ].h = 40; 

    otherDot.x = 30; 
    otherDot.y = 30; 
    otherDot.r = DOT_WIDTH/2; 

    //The frame rate regulator 
    Timer fps; 

    //Initialize 
    if(init() == false) 
    { 
     return 1; 
    } 

    //Load the files 
    if(load_files() == false) 
    { 
     return 1; 
    } 

    //While the user hasn't quit 
    while(quit == false) 
    { 
     //Start the frame timer 
     fps.start(); 

     //While there's events to handle 
     while(SDL_PollEvent(&event)) 
     { 
      //Handle events for the dot 
      myDot.handle_input(); 

      //If the user has Xed out the window 
      if(event.type == SDL_QUIT) 
      { 
       //Quit the program 
       quit = true; 
      } 
     } 

     //Move the dot 
     myDot.move(box, otherDot); 

     //Fill the screen white 
     SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF)); 

     //Show the box 
     SDL_FillRect(screen, &box[ 0 ], SDL_MapRGB(screen->format, 0x00, 0x00, 0x00)); 

     //Show the other dot 
     apply_surface(otherDot.x - otherDot.r, otherDot.y - otherDot.r, dot, screen); 

     //Show our dot 
     myDot.show(); 

     //Update the screen 
     if(SDL_Flip(screen) == -1) 
     { 
      return 1; 
     } 

     //Cap the frame rate 
     if(fps.get_ticks() < 1000/FRAMES_PER_SECOND) 
     { 
      SDL_Delay((1000/FRAMES_PER_SECOND) - fps.get_ticks()); 
     } 
    } 

    //Clean up 
    clean_up(); 

    return 0; 
} 
+0

很簡單,因爲你無法通過'int's作爲參數到'pow'。請參閱[本文](http://stackoverflow.com/questions/2398442/why-isnt-int-powint-base-int-exponent-in-the-standard-c-libraries)瞭解它背後的基本原理。您可以根據您在函數中需要的精度選擇提供的任一解決方案 – 2012-03-02 04:26:00

+0

對於將來的問題,您可以儘量保持代碼示例儘可能小。換句話說,[簡短,獨立,正確(可編譯),示例](http://sscce.org/)。 – 2012-03-02 06:31:19

回答

1

由於錯誤顯示:

1>c:\users\fab\desktop\c++\sdl 1.2.15\19-circularcollisiondetect\19-circularcollisiondetect\main.cpp(140): error C2668: 'pow' : ambiguous call to overloaded function 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(583): could be 'long double pow(long double,int)' 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(535): or  'float pow(float,int)' 
1>   c:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(497): or  'double pow(double,int)' 

你傳遞兩個整數到POW(),但它要麼需要很長的雙和整數,浮點和int或double和int類型。鑄造他們中的一個應該解決這個問題對你來說,如:

return sqrt(pow((double)(x2 - x1), 2) + pow((double)(y2 - y1), 2)); 

我使用雙在這裏,因爲它會更準確地代表了全範圍不是浮點整數而不被矯枉過正,但如果你正在處理小數字(在100和1000年),你可能只是使用浮動。

0

該錯誤基本上是說數學函數pow有多個定義,編譯器不知道在這種情況下自動選擇哪一個。嘗試明確鑄造整數(X1,X2,Y1,Y2)在該行:

return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2)); 

...到花車,像這樣:

return sqrt(pow((float)(x2 - x1), 2) + pow((float)(y2 - y1), 2));