Witam, patrzac po dacie zalozenia tematu moja odpowiedz moze byc troche nieaktualna.
Jakis czas temu zrobilem taka mapke w ramach nauki(miala jeszcze opcje sprawdzania z ktorej strony heksa jest myszka) i wygladalo to mniej wiecej tak:
(zakladam ze mowa o figurze foremnej)
siec takich figur to zbior trzech rodzajow lini; dwie ukosne i jedna rownolegla do jakiejs osi...(w najprostszym przypadku)
stworzylem wiec klase line, z ktorej obiektow z kolei zbudowana byla klasa triangle, z kolej z jej obiektow byla zbudowana klasa hexagon
W zaleznosci od ustawienia tych szesciokatow obliczenie lini moze sie troche roznic, np w moim przypadku odleglosc pomiedzy najwyzszym a najnizszym wierzcholkiem w hex'ie byla rowna 2a, gdzie a to oczywiscie bok trojkata rownobocznego dlatego tez linie skosne byly ustawione pod katem 30 badz 150 stopni do osi x. Zeby sprawdzic czy mysz znajduje sie nad danym hexagonem musisz sprawdzic czy znajduje sie nad ktoryms z jej trojkatow,
dla kazdego bedzie sie to odbywalo troche inaczej bo sa ustawione pod roznym katem, ale sprawa wyglada tak ze x musi byc raz albo wiekszy od hex_center_x - a*sqrt(3)/2 i mniejszy od hex_center_x albo wiekszy od
hex_center_x i mniejszy od hex_center_x + a*sqrt(3)/2, natomiast y musi byc mniejsze albo wieksze(zalezy od lini i samego trojkata) od Ax+B(ze wzoru na prosta y=ax+b) gdzie A to tg 30(badz 150 tu pamietamy ze uklad wspolrzednych jest odbity wzgledem osi x ;) ) stopni a B to 0(linia przecinajaca srodek hexagonu) albo +- a(dlugosc boku trojkata).
Podsumowujac, ten problem nalezy rozwiazac bardziej matematycznie niz informatycznie bo z tego co pamietam to jak juz wszystko obliczylem na kartce to calosc napisalem w godzinke
(+ druga na naprawe kilku bledow z wyswietlaniem ;/ )
Wstawiam tez wszystko w postaci kodu(mam nadzieje ze wstawi sie caly)
Pozdrawiam
Mr.J
float count_y( float arg_a, int arg_x, int arg_b )
{
float y = 0;
y = arg_a * arg_x + arg_b;
return y;
}
class Line
{
private:
float arg_a;
int arg_b;
public:
Line() { };
void set_arguments( float a, int b );
float get_y( int x, int b_offset );
};
void Line::set_arguments( float a, int b )
{
arg_a = a;
arg_b = b;
}
float Line::get_y( int x, int b_offset )
{
float y = arg_a * static_cast < float >( x ) + static_cast < float >( arg_b ) + static_cast < float >( b_offset );
return y;
}
class Equilateral
{
private:
Line line1;
Line line2;
float A_side;
int height;
int Enumber;
public:
Equilateral();
void set_triangle( int number );
bool check_range( int x_offset, int b );
int get_Aside();
int get_H();
};
Equilateral::Equilateral()
{
height = 40;
A_side = 2 * height / sqrt( 3 );
Enumber = 0;
}
int Equilateral::get_Aside()
{
int tempA = static_cast < int >( A_side );
return tempA;
}
int Equilateral::get_H()
{
int tempH = static_cast < int >( height );
return tempH;
}
void Equilateral::set_triangle( int number )
{
Enumber = number;
switch( number )
{
case 1:
line1.set_arguments( sqrt( 3 ) / 3, - A_side );
line2.set_arguments( - sqrt( 3 ) / 3, 0 );
break;
case 2:
line1.set_arguments( - sqrt( 3 ) / 3, 0 );
line2.set_arguments( sqrt( 3 ) / 3, 0 );
break;
case 3:
line1.set_arguments( sqrt( 3 ) / 3, 0 );
line2.set_arguments( - sqrt( 3 ) / 3, A_side );
break;
case 4:
line1.set_arguments( - sqrt( 3 ) / 3, 0 );
line2.set_arguments( sqrt( 3 ) / 3, A_side );
break;
case 5:
line1.set_arguments( sqrt( 3 ) / 3, 0 );
line2.set_arguments( - sqrt( 3 ) / 3, 0 );
break;
case 6:
line1.set_arguments( - sqrt( 3 ) / 3, - A_side );
line2.set_arguments( sqrt( 3 ) / 3, 0 );
break;
default:
break;
}
}
bool Equilateral::check_range( int x_offset, int b )
{
int x = 0;
int y = 0;
SDL_GetMouseState( & x, & y );
if( Enumber == 1 )
{
if( y >= line1.get_y( x - x_offset, b ) && y < line2.get_y( x - x_offset, b ) && x >= x_offset && x <= x_offset + height )
{
return true;
}
}
if( Enumber == 2 )
{
if( y >= line1.get_y( x - x_offset, b ) && y < line2.get_y( x - x_offset, b ) && x >= x_offset && x <= x_offset + height )
{
return true;
}
}
if( Enumber == 3 )
{
if( y >= line1.get_y( x - x_offset, b ) && y < line2.get_y( x - x_offset, b ) && x >= x_offset && x <= x_offset + height )
{
return true;
}
}
if( Enumber == 4 )
{
if( y >= line1.get_y( x - x_offset, b ) && y < line2.get_y( x - x_offset, b ) && x > x_offset - height && x < x_offset )
{
return true;
}
}
if( Enumber == 5 )
{
if( y >= line1.get_y( x - x_offset, b ) && y < line2.get_y( x - x_offset, b ) && x > x_offset - height && x < x_offset )
{
return true;
}
}
if( Enumber == 6 )
{
if( y >= line1.get_y( x - x_offset, b ) && y < line2.get_y( x - x_offset, b ) && x > x_offset - height && x < x_offset )
{
return true;
}
}
return false;
}
class WarTile
{
private:
Equilateral triangle[ 6 ];
int x_coordinates;
int y_coordinates;
bool occupied;
public:
WarTile();
void set_position( int x, int y );
int get_x();
int get_y();
void show( int row_number, int x_offset, int y_offset, int spaceing, SDL_Surface * thisSurface );
int check_mouse( int row_number, int x_offset, int y_offset, int spaceing );
};
WarTile::WarTile()
{
triangle[ 0 ].set_triangle( 1 );
triangle[ 1 ].set_triangle( 2 );
triangle[ 2 ].set_triangle( 3 );
triangle[ 3 ].set_triangle( 4 );
triangle[ 4 ].set_triangle( 5 );
triangle[ 5 ].set_triangle( 6 );
occupied = false;
}
void WarTile::set_position( int x, int y )
{
x_coordinates = x;
y_coordinates = y;
}
int WarTile::get_x()
{
return x_coordinates;
}
int WarTile::get_y()
{
return y_coordinates;
}
void WarTile::show( int row_number, int x_offset, int y_offset, int spaceing, SDL_Surface * thisSurface )
{
if( occupied == false )
{
int H = triangle[ 0 ].get_H();
int A = triangle[ 0 ].get_Aside();
if( row_number == 0 || row_number % 2 == 0 )
{
apply_surface( x_offset + spaceing + H - 40 , y_offset + row_number *( 3 * A ) / 2 - 46 , thisSurface, screen );
}
if( row_number % 2 == 1 )
{
apply_surface( x_offset + spaceing - 40 , y_offset + row_number *( 3 * A ) / 2 - 46 , thisSurface, screen );
}
}
}
int WarTile::check_mouse( int row_number, int x_offset, int y_offset, int spaceing )
{
int A = triangle[ 0 ].get_Aside();
int H = triangle[ 0 ].get_H();
if( row_number == 0 || row_number % 2 == 0 )
{
for( int i = 0; i < 6; i++ )
{
if( triangle[ i ].check_range( x_offset + spaceing + H, y_offset + y_coordinates *( 3 * A ) / 2 ) == true )
{
return i + 1;
}
}
}
if( row_number % 2 == 1 )
{
for( int i = 0; i < 6; i++ )
{
if( triangle[ i ].check_range( x_offset + spaceing, y_offset + y_coordinates *( 3 * A ) / 2 ) == true )
{
return i + 1;
}
}
}
return 0;
}