Hello,
once again I need your help. I have a checkerboard and I’d like to draw a semi-transparent green arrow from one square to another using a click on the source square and a drop on the destination square. Here is what I did so far :
My squares can be accessed with (i,j) their coordinates, and my pixels can be accessed with their (x,y) coordinates as well :
Code:
typedef struct {int x; int y;} Coord;
typedef struct {int i; int j;} Square;
I have a global variable
Code:
int square_size;
which stores the current size of every square.
I created 2 functions to switch between square coordinates and pixel coordinates (only multiplies or divides by the square size, basically) :
Code:
Square CoordToSquare (Coord MousePosition);
Coord SquareToCoord (Square square);
I have also included the following librairies to make it easier to implement :
Code:
#include <SDL_rotozoom.h>
#include <math.h>
In order not to try everything at once, to begin with I’m just trying to draw a simple segment from the center of the source square to the center of the destination square. Here is my function :
Code:
int draw_arrow(Square sq1, Square sq2)
{
int i1 = sq1.i, i2 = sq2.i, j1 = sq1.j, j2 = sq2.j;
if ( i1 < 0 || i1 > 7 || j1 < 0 || j1 > 7 || i2 < 0 || i2 > 7 || j2 < 0 || j2 > 7) //not chessboard squares.
return 1;
//start calculating the distance between the 2 squares and their angle with the x-axis.
Coord square_coord1 = SquareToCoord (sq1);
int x1 = square_coord1.x;
int y1 = square_coord1.y;
Coord square_coord2 = SquareToCoord (sq2);
int x2 = square_coord2.x;
int y2 = square_coord2.y;
double x = x2 - x1, y = y2 - y1;
double distance = sqrt ( x * x + y * y);
double theta = 180 / PI;
if ( x > 0 && y >= 0 )
theta *= atan (y / x);
else if (x > 0 && y < 0)
theta *= atan (y / x) + 2 * PI;
else if (x < 0)
theta *= atan (y / x) + PI;
else if (x == 0 && y > 0)
theta *= PI / 2;
else if (x == 0 && y < 0)
theta *= 3 * PI / 2;
else //undef angle : (x,y)=(0,0).
return 1;
//end calculating.
SDL_Surface * screen = SDL_GetVideoSurface();
SDL_Surface* layer = SDL_CreateRGBSurface (SDL_HWSURFACE, distance, square_size/4, 32, 0, 0, 0, 0);
SDL_FillRect (layer, NULL, SDL_MapRGB (layer->format, 0, 255, 0));
SDL_Rect position;
position.x = x1 + square_size / 2;
position.y = y1 + square_size / 2 - layer->h / 2;
layer = rotozoomSurface(layer,-theta,1,SMOOTH);
SDL_SetColorKey (layer, SDL_SRCCOLORKEY, SDL_MapRGB (layer->format, 0, 0, 0));
SDL_SetAlpha(layer, SDL_SRCALPHA, 64);
SDL_BlitSurface(layer,NULL,screen,&position);
SDL_FreeSurface(layer);
return 0;
}
In order to try it, I wrote
Code:
Square sq1 = {4,4};
Square sq2 = {5,6};
draw_arrow(sq1,sq2);
in my function “draw_everything”, and I was careful to insert this portion of code after the squares have been drawn.
Here are my questions (finally !) :
- I tried to do it on my own, but maybe there’s a better/faster way to draw an arrow. Do you have any ideas ?
- I have a memory leak with that function, though I don’t see why because I used SDL_FreeSurface. Do you see where it is ?
- How can I locate memory leaks with codeblocks (and wingw) ?
- I need to rotate with -theta to make it work, but I don’t understand why it’s not just +theta.
- Is there any other way to draw a line than to create a rectangle of tickness 1 ?
- The only way to draw a slanted line is to create a SDL_surface * and to rotate it as I did, right ? (it’s not possible to use a SDL_rect, or is it?).
- I’d like to add a black frame to the “arrow” (which is currently only a rectangle), but how can I do it since the rotation adds many black pixels that I then need to remove with SDL_SetColorKey (and since it would be difficult to draw a frame after the rotation) ?
- Finally, I will need to draw a black triangle and fill it with semi-transparent green. How can I do that ?
(I might edit these questions to find answers to my lattest problems so please keep checking for updates).
If you would be kind enough to answer at least some of them, I’d be really greatful.
Thanks.