H
Hallo!
erm..ich hab mal einige Tutorials und Docus durchforstet und hab mir daraus folgendes Programm gebastelt:
#include <SDL/SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL_framerate.h>
#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)
{ /* x dominant */
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
{ /* y dominant */
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(x1), y1(y1),
dx1(dx1), dy1(dy1),
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,
red,
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_Delay(10);
}
SDL_framerateDelay(&fpsm);
}
return 0;
}
Nur bekomme ich es nicht hin, dass die gezeichnete Linie "Pendelcharakter" bzw. "Pendeloptik" hat. Wie krieg ich also den "Drehpunkt" zentiriert an den oberen Bildschirmrand? Wie simuliere ich eine echte Pendelbewegung?