Pendel mit SDL



  • Hallo! Ich versuche derzeit eine Pendelsimulation zu programmieren, aber ich schaffe es nicht, dass das Pendel bzw. der Endpunkt der "pendelnden" Linie sich auf einer Kreisbahn bewegt. In meinem Programm "klebt" er immer am unteren Fensterrand :-(. Bitte helft mir 😕

    Hier der Code :

    #include <SDL/SDL.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <SDL/SDL_framerate.h>		// SDL_gfx Framerate Manager
    
    //----------------------------------------------------------
    
    // A set of very useful macros that you will find in most
    // code that I write whether I use them in a program or
    // not.
    
    #define max(a,b) (((a) > (b)) ? (a) : (b))
    #define min(a,b) (((a) < (b)) ? (a) : (b))
    #define abs(a) (((a)<0) ? -(a) : (a))
    #define sign(a) (((a)<0) ? -1 : (a)>0 ? 1 : 0)
    
    //----------------------------------------------------------
    
    // Draw lines in 32 bit surfaces. Note that this routine
    // ignores alpha values. It writes them into the surface
    // if they are included in the pixel, but does nothing
    // else with them.
    
    static void line32(SDL_Surface *s, 
                       int x1, int y1, 
                       int x2, int y2, 
                       Uint32 color)
    {
      int d;
      int x;
      int y;
      int ax;
      int ay;
      int sx;
      int sy;
      int dx;
      int dy;
    
      Uint8 *lineAddr;
      Sint32 yOffset;
    
      dx = x2 - x1;  
      ax = abs(dx) << 1;  
      sx = sign(dx);
    
      dy = y2 - y1;  
      ay = abs(dy) << 1;  
      sy = sign(dy);
      yOffset = sy * s->pitch;
    
      x = x1;
      y = y1;
    
      lineAddr = ((Uint8 *)(s->pixels)) + (y * s->pitch);
      if (ax>ay)
      {                      
        d = ay - (ax >> 1);
        for (;;)
        {
          *((Uint32 *)(lineAddr + (x << 2))) = (Uint32)color;
    
          if (x == x2)
          {
            return;
          }
          if (d>=0)
          {
            y += sy;
            lineAddr += yOffset;
            d -= ax;
          }
          x += sx;
          d += ay;
        }
      }
      else
      {                    
        d = ax - (ay >> 1);
        for (;;)
        {
          *((Uint32 *)(lineAddr + (x << 2))) = (Uint32)color;
    
          if (y == y2)
          {
            return;
          }
          if (d>=0) 
          {
            x += sx;
            d -= ay;
          }
          y += sy;
          lineAddr += yOffset;
          d += ax;
        }
      }
    }
    
    //----------------------------------------------------------
    
    // Examine the depth of a surface and select a line
    // drawing routine optimized for the bytes/pixel of the
    // surface.
    
    static void line(SDL_Surface *s, int x1, int y1, int x2, int y2, Uint32 color)
    {
      switch (s->format->BytesPerPixel)
      {
      case 4:
        line32(s, x1, y1, x2, y2, color);
        break;
      }
    }
    
    //----------------------------------------------------------
    
    // sweepLine animates a line on a surface based on the
    // elapsed time.
    
    class sweepLine
    {
    private:
      SDL_Surface *s;             // The surface to draw on.
      Uint32 color;               // The color of the line.
      int last;                   // last time update() was
                                  // called.
      int maxx;                   // Maximum valid X value.
      int maxy;                   // Maximum valid Y value.
      float x1, y1;               // The current location
      float dx1, dy1;             // and velocity of the line
      float x2, y2;               // end points.
      float dx2, dy2;
    
      // movePoint computes the new location of a point based
      // on its initial location, its velocity, and the
      // elapsed time.
    
      void movePoint(float &x, float &y, 
                     float &dx, float &dy,
                     int dt)
      {
        // Compute the new X location.
    
        x += (dx * dt);
    
        // if the X value is off of the screen, move it back
        // on and reverse the velocity in the X direction.
    
        if (x >= maxx)
        {
          x = maxx;
          dx = -dx;
        }
        else if (x <= 0)
        {
          x = 0;
          dx = -dx;
        }
    
        // Same thing for Y.
        y += (dy * dt);
        if (y >= maxy)
        {
          y = maxy;
          dy = -dy;
        }
        else if (y <= 0)
        {
          y = 0;
          dy = -dy;
        }
      }
    
    public:
    
      // sweepLine animates a line on a surface. It is
      // initialized with a pointer to the surface to draw the
      // line on, a pixel value that specifies the color of
      // the line, the current time, and the initial locations
      // of the line end points and their
      // velocities. Velocities are specified in
      // pixels/millisecond.
    
      // This method initializes the class and forces the end
      // points of the lines to be inside the boundaries of
      // the surface. If it didn't do that the line drawing
      // code would try to write outside of the surface and
      // crash the program.
    
      sweepLine(SDL_Surface *s, 
                Uint32 color,
                int time,
                float x1,  float y1,
                float dx1, float dy1,
                float x2,  float y2,
                float dx2, float dy2): 
        s(s),
        color(color),
        last(time),
        x1(320), y1(0),
        dx1(0), dy1(0),
        x2(x2), y2(y2),
        dx2(dx2), dy2(dy2)
      {
    
        // Set the values of maxx and maxy to one less than
        // the width and height. Do this makes clipping easier
        // to code.
    
        maxx = 0;
        maxy = 0;
    
        if (NULL != s)
        {
          maxx = s->w - 1;
          maxy = s->h - 1;
        }
    
        // Force the line end points onto the screen.
    
        x1 = max(x1, 0);
        y1 = max(y1, 0);
    
        x2 = max(x2, 0);
        y2 = max(y2, 0);
    
        x1 = min(x1, maxx);
        y1 = min(y1, maxy);
    
        x2 = min(x2, maxx);
        y2 = min(y2, maxy);
      }
    
      void update(long now)
      {
        int dt = now - last;
        last = now;
    
        // Update the locations of the line end points.
    
        movePoint(x1, y1, dx1, dy1, dt);
        movePoint(x2, y2, dx2, dy2, dt);
    
        // Draw the line at its new location.
    
        line(s,(int)x1, (int)y1, (int)x2, (int)y2, color);
      }
    
    };
    
    //----------------------------------------------------------
    
    // gameTime keeps track of game time as opposed to real
    // time. Game time can start and stop and even change its
    // speed while real time just keeps ticking along.
    
    class gameTime
    {
    private:
      int startTime;              // Last time the clock was
                                  // started.
      int baseTime;               // How much game time passed
                                  // before the last time the
                                  // clock was started.
      bool running;               // Is the clock running or
                                  // not?
    
    public:
    
      // Initialize the class variables. At this point no game
      // time has elapsed and the clock is not running.
    
      gameTime()
      {
        startTime = 0;
        baseTime = 0;
        running = false;
      }
    
      // Start the clock.
    
      void start()
      {
        if (!running)
        {
          startTime = SDL_GetTicks();
          running = true;
        }
      }
    
      // stop the clock
    
      void stop()
      {
        if (running)
        {
          baseTime = baseTime + (SDL_GetTicks() - startTime);
          running = false;
        }
      }
    
      // True if the clock is paused.
    
      bool stopped()
      {
        return !running;
      }
    
      // Get this clocks current time in milliseconds.
    
      int time()
      {
        if (running)
        {
          return baseTime + (SDL_GetTicks() - startTime);
        }
        else
        {
          return baseTime;
        }
      }
    };
    
    //----------------------------------------------------------
    
    int main(int argc, char *argv[]){
    
    	SDL_Init(SDL_INIT_EVERYTHING);
    
    	SDL_Surface *screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
    
      gameTime gt;
      char *name = argv[0];
    
      SDL_Event event;
      SDL_PixelFormat *pf = NULL;
      Uint32 black;
      Uint32 red;
      Uint32 green;
      Uint32 blue;
    
      int screenWidth = 640;
      int screenHeight = 480;
    
      bool done = false;
    
      sweepLine *rl = NULL;
    
      screen = SDL_SetVideoMode(screenWidth, 
                                screenHeight, 
                                0, 
                                SDL_ANYFORMAT |
                                //SDL_FULLSCREEN |
                                SDL_SWSURFACE
                                );
    
      // Grab the pixel format for the screen. SDL_MapRGB()
      // needs the pixel format to create pixels that are laid
      // out correctly for the screen.
    
      pf = screen->format;
    
      //Create the pixel values used in the program. Black is
      //for clearing the background and the other three are
      //for line colors. Note that in SDL you specify color
      //intensities in the rang 0 to 255 (hex ff). That
      //doesn't mean that you always get 24 or 32 bits of
      //color. If the format doesn't support the full color
      //range, SDL scales it to the range that is correct for
      //the pixel format.
    
      black = SDL_MapRGB(pf, 0x00, 0x00, 0x00);
      red = SDL_MapRGB(pf, 0xff, 0x00, 0x00);
      green = SDL_MapRGB(pf, 0x00, 0xff, 0x00);
      blue = SDL_MapRGB(pf, 0x00, 0x00, 0xff);
    
      SDL_WM_SetCaption(name, name);
    
      // Create the three animating lines. It is amazing to
      // see the different kinds of behavior you can get from
      // such a simple animation object.
    
      rl = new sweepLine(screen, 
                         black, 
                         gt.time(),
                         screen->w - 1, 0,
                         -0.3, 0,
                         0, screen->h - 1,
                         0.3, 0);
    
      // Start the game clock.
    
      gt.start();
    
      while (!done)
      {
    
    	FPSmanager fpsm;
    	SDL_initFramerate(&fpsm);
    	SDL_setFramerate(&fpsm, 60); // 60 Frames Per Second
    
    	bool isRunning = true;
    	while(isRunning){
    
    		// Clear the screen
    		SDL_FillRect(screen, NULL, 0);
    
    		// ROTOZOOM EXAMPLE
    		// Make the new rotated image
    		static double rotationAngle = 0;
    		rotationAngle = 0.0;
    		SDL_Surface* image = SDL_LoadBMP("white.bmp");
    
    		// Draw the rotated image
    		SDL_Rect rect;
    		SDL_BlitSurface(image, NULL, screen, &rect);
    
    		// Clear memory when finished with the rotated image
    		SDL_FreeSurface(image);
    
        int t = gt.time();
    
        rl->update(t);
    
        SDL_Flip(screen);
    
      }
    
    		SDL_framerateDelay(&fpsm);	
    	}
    
    	return 0;
    }
    

Log in to reply