I'm trying to animate a model about a center point, and I want it to swing back and forth (it's a leg). I'm unsure about my if conditions. Particularly when it's trying to reduce the angle. What I've got now, it seems to:
Increase angle until > 46
Go in the last if statement, minus 0.1 from angle, (makes it < 46)
Now instead of continuing to go in the last if statement until angle = 0, it goes back to second if function.
I want it keep on decreasing until 0, then increase again. (Please note that this whole block of code is in a for loop when it's called).
P/s: CenterPointVec[] is a vector containing x, y and z axis values.
void vertex::AnimatePart()
{
static float angle = 0;
bool goback = false;
if(angle == 0)
{
glTranslatef(CenterPointVec[0], CenterPointVec[1], CenterPointVec[2]);
glRotatef(angle, 1,0,0);
glTranslatef(-CenterPointVec[0], -CenterPointVec[1], -CenterPointVec[2]);
angle += 0.1;
goback = false;
}
if(angle < 46 && goback == false)
{
glTranslatef(CenterPointVec[0], CenterPointVec[1], CenterPointVec[2]);
glRotatef(angle, 1,0,0);
glTranslatef(-CenterPointVec[0], -CenterPointVec[1], -CenterPointVec[2]);
angle += 0.1;
if(angle > 46)
{
goback = true;
cout << "Angle : " << angle << endl;
cout << "Go back? " << goback << endl;
}
}
if(angle > 0 && goback == true)
{
glTranslatef(CenterPointVec[0], CenterPointVec[1], CenterPointVec[2]);
glRotatef(angle, 1,0,0);
glTranslatef(-CenterPointVec[0], -CenterPointVec[1], -CenterPointVec[2]);
angle -= 0.1;
if(angle <= 0)
{
goback = false;
cout << "Angle : " << angle << endl;
}
}
}
Related
I'm new to SFML currently I'm trying to make a simple 2D golf ball physics. Right now, I have a class called Ball that contain the attributes of the ball sprite, position, velocity etc. I would call the call class it in main and it working as expected, but the one thing that didn't work is it would just move/teleport the ball to the next position rather than moving the ball like expected.
void Ball::move(sf::Vector2f& velocity)
{
// boundaries
if (ballSprite.getPosition().x < 0 - 49 || ballSprite.getPosition().x > 700 - 70)
{
velocity.x *= (float) -1;
}
if (ballSprite.getPosition().y < 0 - 30 || ballSprite.getPosition().y > 1200 - 70)
{
velocity.y *= (float) -1;
}
if (ballSprite.getPosition().x + 1 == 700 || ballSprite.getPosition().x - 1 == 0)
{
velocity.x *= -1;
}
if (ballSprite.getPosition().y + 1 == 1200 || ballSprite.getPosition().y - 1 == 0)
{
velocity.y *= -1;
}
ballSprite.move(velocity.x, velocity.y);
sf::Texture ballTex;
ballTex.loadFromFile("ball2.png");
Ball gameBall(1, ballTex);
while (window.isOpen())
{
sf::Event event;
bool mouseReleased = false;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
}
if (event.type == sf::Event::MouseButtonPressed)
{
cout << "Mouse Button Pressed\n";
}
mouseReleased = false;
if (event.mouseButton.button == sf::Mouse::Left && event.type == sf::Event::MouseButtonReleased)
{
mouseReleased = true;
cout << "Mouse Button Released\n";
cout << "Ball Position: " << gameBall.getSprite().getPosition().x << "," << gameBall.getSprite().getPosition().y << endl;
sf::Vector2i velo = sf::Mouse::getPosition(window);
cout << "Velocity: " << velo.x - gameBall.getSprite().getPosition().x << ", " << -1 * (velo.y - gameBall.getSprite().getPosition().y) << endl;
sf::Vector2f velocity(-1 *(velo.x - gameBall.getSprite().getPosition().x) , (-1 * (velo.y - gameBall.getSprite().getPosition().y)));
gameBall.move(velocity);
cout << "Ball Position After: " << gameBall.getSprite().getPosition().x << "," << gameBall.getSprite().getPosition().y << endl;
}
}
I'm not sure how to update the ball so it would show the ball move on the screen rather than teleporting to a new position on the screen.
The way you are calculating the change in position is simply a delta of position i.e. movining your ball by the delta will result in teleporting to the destination. The delta itself is really useful.
One way to make it work is to devide the delta into smaller parts (ball speed) and move by these parts.
However, it seems to me that it is easier to calculate the normalized vector (unit vector) and multiply by the ball speed, then fix it (if needed) by multiplying by sqrt of 2 (to prevent faster movement on diagonal).
This method is not very accurate, the ball would only move in 8 directions (it doesn't keep the vector ratio) so if you need it to be more realistic i.e. keep the ratio of x and y delta you can calculate it like that:
sf::Vector2f stretchVector(const sf::Vector2f& vector, const float& radius)
{
sf::Vector2i xySymb(1, 1);//calculation of the symbol(-/+)
xySymb.x = isPositive(vector.x);//isPositive should return -1 or (1 when>=0)
xySymb.y = isPositive(vector.y);
//dealing with [0,...] or [0,0] vectors and the 0 radius.
if (radius == 0.f)
return sf::Vector2f(0.f, 0.f);
if (vector.y == 0.f or vector.x == 0.f) {
if (vector.x == vector.y) {
return sf::Vector2f(0.f, 0.f);
}
if (vector.x != 0.f) {
return sf::Vector2f(radius*xySymb.x, 0.f);
}
return sf::Vector2f(0.f, radius*xySymb.y);
}
//<------------------------------------------------>
else {
float ratio = abs(vector.x / vector.y);
float x, y;
x = sqrt((radius * radius * ratio * ratio) / (1 + ratio * ratio));
y = sqrt(abs(radius * radius - x * x));
return sf::Vector2f(float(x * xySymb.x), float(y * xySymb.y));
}
}
I didn't know how to name the function but it can stretch and shrink to provided radius.
The example stretchVector call:
sf::Vector2f deltaPosition(mousePos.x-ballPos.x,mousePos.y-ballPos.y);
sf::Vector2f desiredMove = stretchVector(deltaPositon, ballSpeed);
ball.move(desiredMove);
i wrote a program to arrange points on a graph in clockwise manner from 12 o'clock such that, a vector containing these points is sorted in that order. I am using atan2 to get the angle from 12 o'clock and then making adjustments based on the quadrant. i am trying to figure out where the bug is coming from as it is not ordering them correctly. So given 4 random points like those in the photo, it should order then in the containing vector as P1,P2,P3,P4
Here is my code:
//sort_points.cpp
#include <iostream>
#include <math.h>
#include <algorithm>
#include <vector>
using namespace std;
class Point
{
public:
double x;
double y;
Point(double xx, double yy) : x(xx), y(yy) {}
~Point();
inline friend ostream& operator<<(ostream& output, const Point& point)
{
output << "[" << point.x << ", " << point.y <<"]";
return output;
}
};
Point::~Point() {;}
/* get quadrant from 12 o'clock*/
int get_quadrant (const Point& p)
{
int result = 4; //origin
if (p.x > 0 && p.y > 0)
return 1;
else if(p.x < 0 && p.y > 0)
return 2;
else if(p.x < 0 && p.y < 0)
return 3;
//else 4th quadrant
return result;
}
double get_clockwise_angle(const Point& p)
{
double angle = 0.0;
int quadrant = get_quadrant(p);
/*making sure the quadrants are correct*/
cout << "Point: " << p << " is on the " << quadrant << " quadrant" << endl;
/*add the appropriate pi/2 value based on the quadrant. (one of 0, pi/2, pi, 3pi/2)*/
switch(quadrant)
{
case 1:
angle = atan2(p.x,p.y) * 180/M_PI;
break;
case 2:
angle = atan2(p.y, p.x)* 180/M_PI;
angle += M_PI/2;
break;
case 3:
angle = atan2(p.x,p.y)* 180/M_PI;
angle += M_PI;
break;
case 4:
angle = atan2(p.y, p.x)* 180/M_PI;
angle += 3*M_PI/2;
break;
}
return angle;
}
bool compare_points(const Point& a, const Point& b)
{
return (get_clockwise_angle(a) < get_clockwise_angle(b));
}
int main(int argc, char const *argv[])
{
std::vector <Point> points;
points.push_back( Point( 1, 3 ) );
points.push_back( Point( 2, 1 ) );
points.push_back( Point( -3, 2 ) );
points.push_back( Point( -1, -1 ) );
cout << "\nBefore sorting" << endl;
for (int i = 0; i < points.size(); ++i)
{
cout << points.at(i) << endl;
}
std::sort(points.begin(), points.end(),compare_points);
cout << "\nAfter sorting" << endl;
for (int i = 0; i < points.size(); ++i)
{
cout << points.at(i) << endl;
}
return 0;
}
You don't need the adjustment. atan2 will give you the angle from positive direction of x axis, counterclockwise in range of -PI to PI.
Firstly, to make the starting point positive direction of y axis, let me give parameter to atan2 as if negative direction of y axis is positive direction of x axis and positive direction of x axis is positive direction is y axis.
Then, this will make the angle counterclockwise, so negate the angle in order to reverse the order.
double get_clockwise_angle(const Point& p)
{
double angle = 0.0;
int quadrant = get_quadrant(p);
/*making sure the quadrants are correct*/
cout << "Point: " << p << " is on the " << quadrant << " quadrant" << endl;
/*calculate angle and return it*/
angle = -atan2(p.x,-p.y);
return angle;
}
I don't work with tiles but cubes drawn with sf::Vertex. Each cubes have 6 sides with 4 points each.
So i just have to cubes[numCube].sides()[numSide].... to select a side.
I create cubes layer.cpp :
for(int J = 0; J < mapSize; J++)
{
for(int I = 0; I < mapSize; I++)
{
x = (J - I) * (cubeSize/2);
y = (J + I) * (cubeSize/4);
c = new cube(cubeSize, x, y, z, I, J);
cs.push_back(*c);
}
}
In cube.cpp i create sides, then, in sides.cpp, i calcul each points' coordinates like this :
switch(typeSide)
{
case 0://DOWN_SIDE
light = 1;
tmp_x = x + (size/2);
tmp_y = y + (size/2);
p0 = new point(tmp_x, tmp_y, tmp_z);
tmp_x = x + size;
tmp_y = y + (3 * (size/4));
p1 = new point(tmp_x, tmp_y, tmp_z);
tmp_x = x + (size/2);
tmp_y = y + size;
p2 = new point(tmp_x, tmp_y, tmp_z);
tmp_x = x;
tmp_y = y + (3 * (size/4));
p3 = new point(tmp_x, tmp_y, tmp_z);
break;
case 1://BACK_LEFT_SIDE
//ETC. ....
Point.cpp :
/*
* point.cpp
*
* Created on: 21 nov. 2015
* Author: user
*/
#include "point.h"
point::point(float tx, float ty, float tz)
{
coords* dummyVar = new coords(tx, ty, tz);
coordinates = dummyVar;
}
std::vector<float> point::position()//Use : myPoint.getPosition[0] //get the x
{
std::vector<float> dummyVar;
dummyVar.push_back(coordinates->getX());
dummyVar.push_back(coordinates->getY() - coordinates->getZ());
return dummyVar;
}
void point::move(float tx, float ty, float tz)
{
coordinates->setX(tx);
coordinates->setY(ty);
coordinates->setZ(tz);
}
My problem come from the function i use to detect click :
if (event.type == sf::Event::MouseMoved)
{
currentSelectedCube = maps[currentMapID].getCubeIDAt(event.mouseMove.x, event.mouseMove.y, offsetLeft, offsetTop, enableOffset);
}
The function(don't bother with the comments) :
I try to get a cube's entry in my cube vector without 'for loop'.
Why ? to use less CPU when i click.
int map::getCubeIDAt(float x, float y, int offsetLeft, int offsetTop, bool enableOffset)//WIP ! //USED FOR CLICK DETECTION ON CUBES
{
//----------------------------------------------------------------//
int unsigned entry = -1;
int I = 0;
int J = 0;
//----------------------------------------------------------------//
if(currentLayerId() > -1)//If there is any layers
{
//IF CHECK IN MAP BOUDING BOX + ROTATION TO GOT DIAMOND SHAPE AREA(LAYER + OFFSETS)----------------------------------
//{
if(!enableOffset)//With offsets disabled
{
I = (y * 2 - x) / cubeSize;
J = (y * 2 + x) / cubeSize;
}
else //With offsets enabled
{
I = (((y-offsetTop)+(currentLayerId()*(cubeSize/2))) * 2 - (x-offsetLeft)) / cubeSize;
J = (((y-offsetTop)+(currentLayerId()*(cubeSize/2))) * 2 + (x-offsetLeft)) / cubeSize;
}
entry = I + J * size;
if (entry < 0 || entry >= layers()[currentLayerId()].cubes().size())
{
entry = -1;
}
else//DEBUG - DISPLAYING VALUES FOR TEST
{
std::cout << "Entry n°" << entry << " - ";
std::cout << "[" << I << "; " << J << "]" << std::endl;
}
//}
//END IF CHECK IN MAP BOUDING BOX + ROTATION TO GOT DIAMOND SHAPE AREA(LAYER + OFFSETS)----------------------------------
}
return entry;
}
The I-J and entryNumber are OK. i mean, for example, for the cube 0, i have I = 0; J = 0; etc ... This is working.
I don't understand why the coordinate range is like the red part(not accurate at 100%, i'm not a paint genius ha ha) in this picture :
But i should get that(2nd picture - the red part is where i click) :
But after few checks, the I-J and the entry i got are corresponding. This is so weird.
EDIT2:
Offsets and layer number implemented.
Problem left: wrong coordinates range.
Just in case, this is the 'function' handling events :
void GRAPHICS_HANDLER::listenEvents()
{
while (window->pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window->close();
}
if(event.type == sf::Event::KeyPressed)
{
//DISPLAY/UNDISPLAY GRID -- DEBUG FUNCTION
if(event.key.code == sf::Keyboard::Escape)
{
if(grid)
grid = false;
else
grid = true;
}
//-----------------------------------------------------------------------------------DEBUG---------------------------------------------------------------//
if(event.key.code == sf::Keyboard::B)//ACTIVE BRUSHMODE -- NEED TO BLOCK IT WHEN ACCESS VIOLATION OF CUBES ARRAY(CRASH)
{
if(!brushMode)
{
brushMode = true;
std::cout << "Brush mode enabled" << std::endl;
}
else
{
brushMode = false;
std::cout << "Brush mode disabled" << std::endl;
}
}
if(event.key.code == sf::Keyboard::L)//ADD_LAYER
{
addLayer(getCurrentMapID());
}
if(event.key.code == sf::Keyboard::M)//DELETE_LAYER
{
deleteLayer(currentMapID, maps[currentMapID].currentLayerId());
}
if(event.key.code == sf::Keyboard::S)//ADD_LAYER
{
std::cout << "Select a texture: ";
std::cin >> currentSelectedTexture; std::cout << std::endl;
}
if(event.key.code == sf::Keyboard::Left)//Move in Layer
{
if(maps[currentMapID].currentLayerId() > 0)
{
maps[currentMapID].setCurrentLayerID(maps[currentMapID].currentLayerId()-1);
}
}
if(event.key.code == sf::Keyboard::Right)//Move in Layer
{
if(maps[currentMapID].currentLayerId() < maps[currentMapID].layers().size()-1)
{
maps[currentMapID].setCurrentLayerID(maps[currentMapID].currentLayerId()+1);
}
}
//-----------------------------------------------------------------------------------DEBUG---------------------------------------------------------------//
}
if (event.type == sf::Event::MouseMoved)
{
//--------------------------------------------------------------------------CURSOR-----------------------------------------------------------------------//
currentSelectedCube = maps[currentMapID].getCubeIDAt(event.mouseMove.x, event.mouseMove.y, offsetLeft, offsetTop, enableOffset);
//--------------------------------------------------------------------------CURSOR-----------------------------------------------------------------------//
}
if (event.type == sf::Event::MouseButtonPressed)
{
//--------------------------------------------------------------------------CURSOR-----------------------------------------------------------------------//
currentSelectedCube = maps[currentMapID].getCubeIDAt(event.mouseButton.x, event.mouseButton.y, offsetLeft, offsetTop, enableOffset);
//--------------------------------------------------------------------------CURSOR-----------------------------------------------------------------------//
if (event.mouseButton.button == sf::Mouse::Left)
{
//--------------------------------------------------------------------------CUBE CLICK DETECTION--------------------------------------------------//
if(maps.size() > 0 && maps[currentMapID].layers().size() > 0 && currentSelectedCube > -1)
{
cubeClicked = true;
}
}
if (event.mouseButton.button == sf::Mouse::Right)
{
if(maps.size() > 0 && maps[currentMapID].layers().size() > 0 && currentSelectedCube > -1)
{
maps[currentMapID].layers()[maps[currentMapID].currentLayerId()].cubes()[currentSelectedCube].setTexture(1);
}
}
//--------------------------------------------------------------------------CUBE CLICK DETECTION--------------------------------------------------//
}
}
}
EDIT3: I updated my code to allow me to draw only the down side of the cube, so i can do this(the grass) :
The coordinate range(the red isometric square shown before in the screenshots) change a little when i put flat square(green).
I don't know why, i prefer to precise it, just in case.
You need to store the "heigth" of each element from the tiles plane in order to distinguish which cube are you actually selecting (the closer to the observer):
Same screen coordinates, but different tiles.
It's not clear to me how you modeled your world, so I'll give you a partial algorithm to check what face of what cube is the one clicked. Please, adapt it to your actual code and to the classes you have written to make it work.
// I'll let you to add the offsets for the screen coordinates
I = (y * 2 - x) / cubeSize;
J = (y * 2 + x) / cubeSize;
// find out if it is a left or right triangle
if ( x < (J - I) * (cubeSize/2) ) {
// left triangle
for ( k = max_n_layer; k > -1; --k ) {
// you create the cubes nesting the I loop in the J loop, so to get the index of a cube,
// assuming that you have created all the cubes (even the invisible ones, like it seems from your code)
index = (J+1+k)*mapsize + I+1+k;
// I don't really get how you define the existence or not of a face, but I guess something like this:
if ( index < map.layer[k].cubes.size()
&& map.layer[k].cubes[index].sides[top_side] != 0 ) {
// the face selected is the top side of cube[index] of layer k
// you have to return index and k to select the right face, or simply a pointer to that face
// if this makes any sense with how you have designed your model
return &map.layer[k].cubes[index].sides[top_side];
}
// now check for the side
index = (J+k)*mapsize + I+1+k;
if ( index < map.layer[k].cubes.size()
&& map.layer[k].cubes[index].sides[right_side] != 0 ) {
return &map.layer[k].cubes[index].sides[right_side];
}
index = (J+k)*mapsize + I+k;
if ( index < map.layer[k].cubes.size()
&& map.layer[k].cubes[index].sides[left_side] != 0 ) {
return &map.layer[k].cubes[index].sides[left_side];
}
}
} else {
// right triangle
for ( k = max_n_layer; k > -1; --k ) {
index = (J+1+k)*mapsize + I+1+k;
if ( index < map.layer[k].cubes.size()
&& map.layer[k].cubes[index].sides[top_side] != 0 ) {
return &map.layer[k].cubes[index].sides[top_side];
}
index = (J+1+k)*mapsize + I+k;
if ( index < map.layer[k].cubes.size()
&& map.layer[k].cubes[index].sides[left_side] != 0 ) {
return &map.layer[k].cubes[index].sides[left_side];
}
index = (J+k)*mapsize + I+k;
if ( index < map.layer[k].cubes.size()
&& map.layer[k].cubes[index].sides[right_side] != 0 ) {
return &map.layer[k].cubes[index].sides[right_side];
}
}
}
// well, no match found. As I said is up to you to decide how to do in this case
return nullptr;
Edit
I suggest you to try another way.
Consider the screen as divided not by quadrangular tiles but by the triangles you already depicted. Every 2D tile of your model will be formed by two of those triangles and so all the sides of the cubes you want to draw. For every cube don't draw nor even create the back sides, those will never be drawn.
You can try to implement a sort of specialized z-buffer algorithm by storing for each one of the triangles you have to draw on the screen the index of the side which is closer to the observer.
The coordinates of the vertex of all the triangles are calculated (once) with the code you already have.
(I,J) //For every node (I,J) you have a left and a right triangle
. * .
(I+1,J) * . | . * (I,J+1)
*
(I+1,J+1)
You are creating your cubes layer by layer, I guess, each layer having a different heigth over the base plane. Create every side of the cube using the coordinates calculated earlier. For every face (only the 3 pointing to the observer) consider each one of its 2 triangles. You can easily determine if it is visible or not if you proceed in order, then you only have to update the ID stored in the corresponding triangle.
Once finished this fase, you'll have to draw each triangle once as you already have dropped the hidden ones.
To determine the inverse transformation from screen coordinates to cell indexes, you only have to calculate which triangle is hitted and then look up which ID correspond to that. So transform back x,y to I,J (you already have those equations) and choose the left triangle if x < (J-I)/cubesize the right one otherwise.
So I am working on a GUI for a Hex Board game. Hex game has 121 Hex Shapes in an 11 by 11 Rhombus. I have drawn an 11 by 11 board that is shaped like a Quad or a square. How would I go about translating the coordinates to draw the Hex shapes like a rhombus? Here is the piece of my code that draws the board every frame.
void draw_Board(HexBoard* h) {
glPushMatrix();
glTranslatef(1.5f, 1.5f, 0.0f);
for (auto iter = h->drawList.begin(); iter != h->drawList.end(); ++iter) {
pointRef t = *iter;
colorRef c;
float scale_factor = h->get_scale_factor();
if (t.player == 0) {
c.red = 1;
c.green = 1;
c.blue = 1;
}
else if (t.player == 1) {
c.red = 1;
c.green = 0;
c.blue = 0;
}
else if (t.player == 2) {
c.red = 0;
c.green = 0;
c.blue = 1;
}
int x_increment = 2;
int y_increment = 2;
glPushMatrix();
//cout << t.x_pos << " " << t.y_pos << endl;
//cout << c.red << " " << c.green << " " << c.blue << endl;
glTranslatef(t.x_pos * 2 , t.y_pos * 2, 0);
draw_Hex(c, scale_factor);
glPopMatrix();
}
glPopMatrix();
}
Here is how my board looks like
http://imgur.com/criFeDM
Goal shape is this
http://upload.wikimedia.org/wikipedia/commons/3/38/Hex-board-11x11-%282%29.jpg
You need to grasp the basic trigonometry behind hexagons
as you can see there are two valid angles 30 and 60 degrees. I assume you have no problem of obtaining the hexagon points itself so focus on the i,j step in the grid then:
i-step is 2*dx which is 2.0*r*cos(30deg) in x-axis
j-step changes booth x and y and it is
dx in x-axis and 2.0*dx*sin(60deg) in y-axis
now just create loop through your grid and compute each hexagon start point ...
This is the result for 10x10 grid:
Here the source in C++:
//---------------------------------------------------------------------------
#include <math.h>
const float hexagon_r=0.2;
const float hexagon_dx=hexagon_r*cos(30.0*M_PI/180.0);
const float hexagon_dy=hexagon_r*sin(30.0*M_PI/180.0);
const float hexagon_gx=2.0*hexagon_dx;
const float hexagon_gy=2.0*hexagon_dx*sin(60.0*M_PI/180.0);
void draw_hexagon(float x,float y,float z)
{
glBegin(GL_LINE_LOOP);
glVertex3f(x-hexagon_dx,y-hexagon_dy,z);
glVertex3f(x-hexagon_dx,y+hexagon_dy,z);
glVertex3f(x ,y+hexagon_r ,z);
glVertex3f(x+hexagon_dx,y+hexagon_dy,z);
glVertex3f(x+hexagon_dx,y-hexagon_dy,z);
glVertex3f(x ,y-hexagon_r ,z);
glEnd();
}
//---------------------------------------------------------------------------
void draw_hexagon_grid(float x,float y,float z,int ni,int nj)
{
int i,j; float x0;
x-=float(ni-1)*hexagon_gx*0.5; // just shift x,y to start position (i=0,j=0)
x-=float(nj-1)*hexagon_dx*0.5;
y-=float(nj-1)*hexagon_gy*0.5;
for (x0=x,j=0;j<nj;j++,x0+=hexagon_dx,x=x0,y+=hexagon_gy)
for (i=0;i<ni;i++,x+=hexagon_gx)
draw_hexagon(x,y,z);
}
//---------------------------------------------------------------------------
Usage is simple: draw_hexagon_grid(0.0,0.0,-7.0,10,10);
x,y,z is the center point of grid (I have 3D view therefore I got z=-7 just to get the grid before camera)
ni,nj is the grid size in x and y axis
you can ignore the z axis ...
Ok So I have a few images I am putting on a screen, Really all you would need to know is each glvertex2f() is a point, thus 4 points connected is an area. Each glVertex2f is created by and X,Y . I would like to save this area range so when i do a mouse click and get the x,y result, I can test to see if the mouseclick x,y is inside this area.
So here is where i create the area
for( int z = 0; z < 6; z++ )
{
if( game->player1.Blockbestand[z] > 0 )
{
glLoadIdentity();
xoff = (z/4.0f);
yoff = (floor(xoff))/4.0f;
glBegin(GL_QUADS);
glTexCoord2f(0/4 + xoff,0/4 + yoff); glVertex2f( x1,game->camera.height-y1);
glTexCoord2f(0/4 + xoff,1.0/4 + yoff); glVertex2f( x2,game->camera.height-y1 );
glTexCoord2f(1.0/4 + xoff,1.0/4 + yoff); glVertex2f( x2,game->camera.height-y2 );
glTexCoord2f(1.0/4 + xoff,0/4 + yoff); glVertex2f( x1,game->camera.height-y2 );
glEnd();
x1= x2+10;
x2 = x1+30;
xoff = (z/4.0f);
yoff = (floor(xoff))/4.0f;
}
}
and here is where i get the mouse click
for (std::list<MouseState>::iterator it = clicks->begin(); it != clicks->end(); it++) {
if (it->leftButton == true){
std::cout << "Left click!\n";
std::cout << "x: " << it->x << "\n";
std::cout << "y: " << it->y << "\n";
}
}
So i assume i can save the area in an array somehow. and then when ever a leftbutton click is true , i get the x, y and look in the array to see if its in the area.. but no clue how to do this..
First save the 4 points in an array
locationCheck[m][n] = x1;
locationCheck[m][n+1] = x2;
locationCheck[m][n+2] = game->camera.height-y1;
locationCheck[m][n+3] = game->camera.height-y2;
m++;
then check if the x/y of mouse is between the 4 points like so.
void GameScreen::menuClickCheck(int x,int y){
int m = 0;
int n=0;
while (m < 32){
if (locationCheck[m][n] < x && locationCheck[m][n+1] > x)
if (locationCheck[m][n+2] > y && locationCheck[m][n+3] < y)
{
switch (m)
{
case 0 : cout << "Type=DefaultLand \n";
break;
case 1 : cout << "Type=Lava \n";
break;
case 2 : cout << "Type=Stone \n";
break;
}//end switch
m=32;
}//endif
m++;
}//whileloop
}