Przesuwanie wybranego obiektu

0

Witam, robię właśnie takie zadanie
"Zmodyfikuj program, aby po wciśnięciu ‘o’ używanie klawiszy (a,w,s,d) umożliwiało przesuwanie okręgu, zaś po wciśnięciu ‘k’ przesuwanie kwadratu." I na razie wygląda to u mnie tak:

 
// opengl.cpp : Defines the entry point for the console application.
//

#include "glut.h"
#include "math.h"

float x = 0, y = 0;
int kolor = 0;

void drawCircle(float xc, float yc, float rad)
{
	//
	// draw a circle centered at (xc,yc) with radius rad
	//
	glPushMatrix(); //zachowuje aktualna macierz transformacji 
	glTranslatef(xc, yc, 0); //przesuwa uklad o dany wektor
	glBegin(GL_LINE_LOOP);
	//
	for (int angle = 0; angle < 365; angle = angle + 5)
	{
		float angle_radians = angle * (float)3.14159 / (float)180;
		float x = rad * (float)cos(angle_radians);
		float y = rad * (float)sin(angle_radians);
		glVertex3f(x, y, 0);
	}
	//
	glEnd();
	glPopMatrix(); //przywracan poprzednia macierz transformacji 
}

void display(void)
{
	/* clear window */

	glClear(GL_COLOR_BUFFER_BIT);
	glPushMatrix();
	glTranslatef(x, y, 0);
	//glRotatef(kat,0,0,1); rotacja w okolo osi z

	if (kolor > 3) kolor = 1;
	if (kolor == 1) glColor3f(1.0, 0.0, 0.0);//pokoloruj red
	if (kolor == 2) glColor3f(0.0, 1.0, 0.0);//pokoloruj green
	if (kolor == 3) glColor3f(0.0, 0.0, 1.0);//pokoloruj blue 

	/* draw unit square polygon */
	glBegin(GL_POLYGON);
	glVertex2f(-0.5, -0.5);
	glVertex2f(-0.5, 0.5);
	glVertex2f(0.5, 0.5);
	glVertex2f(0.5, -0.5);
	glEnd();
	/* flush GL buffers */
	glPopMatrix();

	//rysowanie okregu
	drawCircle(0, 0, 1);
	glEnd();
	//

	glFlush();//natychmiastowe wykonanie wszystkich poprzednich polecen
}

static void Przesuniecie(unsigned char przycisk)
{
	switch (przycisk)
	{
	case 'o':
		Key()

		break;
	case 'k':

		break;
	case ' ':
		kolor++;
		glutPostRedisplay();
		break;
	case 27:
		exit(0);

	}
}

static void Key(unsigned char key, int x_d, int y_d)
{

	switch (key)
	{
	case 'w':
		y += .1;
		glutPostRedisplay();
		break;
	case 's':
		y -= .1;
		glutPostRedisplay();
		break;
	case 'a':
		x -= .1;
		glutPostRedisplay();
		break;
	case 'd':
		x += .1;
		glutPostRedisplay();
		break;
	}
}

void init()
{
	/* set clear color to black */
	glClearColor(0.0, 0.0, 0.0, 0.0);
	/* set fill  color to white */
	glColor3f(1.0, 1.0, 1.0);

	/* set up standard orthogonal view with clipping */
	/* box as cube of side 2 centered at origin */
	/* This is default view and these statement could be removed */
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

int main(int argc, char* argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(500, 500);
	glutInitWindowPosition(0, 0);
	glutCreateWindow("simple");
	glutDisplayFunc(display);
	glutKeyboardFunc(Key);
	init();
	glutMainLoop();

	return 0;
}

No i właśnie nie wiem jak zrobić, żeby jak ktoś wciśnie "o" lub "k" to, żeby przechodziło do drugiej funkcji, bo ta zmienna "key" cały czas się będzie zmieniać. Chyba, że to należy jakoś inaczej ugryźć.
Bo na początku to wyglądało ogółem u mnie tak o:

// opengl.cpp : Defines the entry point for the console application.
//

#include "glut.h"
#include "math.h"

float x = 0, y = 0;
int kolor = 0;

void drawCircle(float xc, float yc, float rad)
{
	//
	// draw a circle centered at (xc,yc) with radius rad
	//
	glPushMatrix(); //zachowuje aktualna macierz transformacji 
	glTranslatef(xc, yc, 0); //przesuwa uklad o dany wektor
	glBegin(GL_LINE_LOOP);
	//
	for (int angle = 0; angle < 365; angle = angle + 5)
	{
		float angle_radians = angle * (float)3.14159 / (float)180;
		float x = rad * (float)cos(angle_radians);
		float y = rad * (float)sin(angle_radians);
		glVertex3f(x, y, 0);
	}
	//
	glEnd();
	glPopMatrix();
}

void display(void)
{
	/* clear window */

	glClear(GL_COLOR_BUFFER_BIT);
	glPushMatrix();
	glTranslatef(x, y, 0);
	//glRotatef(kat,0,0,1); rotacja w okolo osi z

	if (kolor > 3) kolor = 1;
	if (kolor == 1) glColor3f(1.0, 0.0, 0.0);//pokoloruj red
	if (kolor == 2) glColor3f(0.0, 1.0, 0.0);//pokoloruj green
	if (kolor == 3) glColor3f(0.0, 0.0, 1.0);//pokoloruj blue 

	/* draw unit square polygon */
	glBegin(GL_POLYGON);
	glVertex2f(-0.5, -0.5);
	glVertex2f(-0.5, 0.5);
	glVertex2f(0.5, 0.5);
	glVertex2f(0.5, -0.5);
	glEnd();
	/* flush GL buffers */
	glPopMatrix();

	//rysowanie okregu
	drawCircle(0, 0, 1);
	glEnd();
	//

	glFlush();//natychmiastowe wykonanie wszystkich poprzednich polecen
}

static void Key(unsigned char key, int x_d, int y_d)
{

	switch (key)
	{
	case 'w':
		y += .1;
		glutPostRedisplay();
		break;
	case 's':
		y -= .1;
		glutPostRedisplay();
		break;
	case 'a':
		x -= .1;
		glutPostRedisplay();
		break;
	case 'd':
		x += .1;
		glutPostRedisplay();
		break;
	case ' ':
		kolor++;
		glutPostRedisplay();
		break;
	case 27:
		exit(0);
	}
}

void init()
{
	/* set clear color to black */
	glClearColor(0.0, 0.0, 0.0, 0.0);
	/* set fill  color to white */
	glColor3f(1.0, 1.0, 1.0);

	/* set up standard orthogonal view with clipping */
	/* box as cube of side 2 centered at origin */
	/* This is default view and these statement could be removed */
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

int main(int argc, char* argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(500, 500);
	glutInitWindowPosition(0, 0);
	glutCreateWindow("simple");
	glutDisplayFunc(display);
	glutKeyboardFunc(Key);
	init();
	glutMainLoop();

	return 0;
}
0

Zrób sobie bool squareSelected przykładowo, jeśli będzie wcisnięte k to ustaw na true, jeśli 'o' to na false, potem odpowiednio x,y,z dla koła i kwadratu, i według zmiennej squareSelected zmieniaj wartości współrzędnych w funkcji gdzie tam sobie przestawiasz te coordy.
To takie najprostsze rozwiązanie, niekoniecznie ładne.

0
// opengl.cpp : Defines the entry point for the console application.
//

#include "glut.h"
#include "math.h"

float x = 0, y = 0;
int kolor = 0;

void drawCircle(float xc, float yc, float rad)
{
	//
	// draw a circle centered at (xc,yc) with radius rad
	//
	glPushMatrix(); //zachowuje aktualna macierz transformacji 
	glTranslatef(xc, yc, 0); //przesuwa uklad o dany wektor
	glBegin(GL_LINE_LOOP);
	//
	for (int angle = 0; angle < 365; angle = angle + 5)
	{
		float angle_radians = angle * (float)3.14159 / (float)180;
		float x = rad * (float)cos(angle_radians);
		float y = rad * (float)sin(angle_radians);
		glVertex3f(x, y, 0);
	}
	//
	glEnd();
	glPopMatrix();
}

void display(void)
{
	/* clear window */

	glClear(GL_COLOR_BUFFER_BIT);
	glPushMatrix();
	glTranslatef(x, y, 0);
	//glRotatef(kat,0,0,1); rotacja w okolo osi z

	if (kolor > 3) kolor = 1;
	if (kolor == 1) glColor3f(1.0, 0.0, 0.0);//pokoloruj red
	if (kolor == 2) glColor3f(0.0, 1.0, 0.0);//pokoloruj green
	if (kolor == 3) glColor3f(0.0, 0.0, 1.0);//pokoloruj blue 

	/* draw unit square polygon */
	glBegin(GL_POLYGON);
	glVertex2f(-0.5, -0.5);
	glVertex2f(-0.5, 0.5);
	glVertex2f(0.5, 0.5);
	glVertex2f(0.5, -0.5);
	glEnd();
	/* flush GL buffers */
	glPopMatrix();

	//rysowanie okregu
	drawCircle(0, 0, 1);
	glEnd();
	//

	glFlush();//natychmiastowe wykonanie wszystkich poprzednich polecen
}


bool squareSelected(unsigned char przycisk)
{
	if (przycisk == 'k') return true;
	if (przycisk == 'o') return false;
}


static void Key(unsigned char key, int x_d, int y_d)
{
	squareSelected(key);

	switch (key)
	{
	case 'w':
		y += .1;
		glutPostRedisplay();
		break;
	case 's':
		y -= .1;
		glutPostRedisplay();
		break;
	case 'a':
		x -= .1;
		glutPostRedisplay();
		break;
	case 'd':
		x += .1;
		glutPostRedisplay();
		break;
	case ' ':
		kolor++;
		glutPostRedisplay();
		break;
	case 27:
		exit(0);
	}
}

void init()
{
	/* set clear color to black */
	glClearColor(0.0, 0.0, 0.0, 0.0);
	/* set fill  color to white */
	glColor3f(1.0, 1.0, 1.0);

	/* set up standard orthogonal view with clipping */
	/* box as cube of side 2 centered at origin */
	/* This is default view and these statement could be removed */
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

int main(int argc, char* argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(500, 500);
	glutInitWindowPosition(0, 0);
	glutCreateWindow("simple");
	glutDisplayFunc(display);
	glutKeyboardFunc(Key);
	init();
	glutMainLoop();

	return 0;
}

O takim czymś mówisz z tym boolem? I potem w funkcji display mam ustawić to x,y,z, tak? Tylko umm

if (squareSelected() == true)
	{
		glTranslatef(x, y, 0);
	}
 

No w ten sposób coś źle robię.

0

... tam, gdzie zwiększasz x i y tego co tam aktualnie masz, to sprawdzaj który masz obiekt zaznaczony i zmieniaj jego współrzędne

0

Ach, racja. Okej, dzięki wielkie ;)

0

Podbijam raz jeszcze, bo teraz chcę, żeby po wciśnięciu klawiszu ‘p’ kwadrat przesunął się w miejsce okręgu w czasie 2s. I mam do tego zastosować funkcję glutTimerFunc.

float x = 0, y = 0;
float x_c = 0, y_c = 0;
float m_x = 0, m_y = 0;
int kolor = 0;
bool isSquare = true;


void drawCircle(float xc, float yc, float rad)
{
	//
	// draw a circle centered at (xc,yc) with radius rad
	//
	glPushMatrix(); //zachowuje aktualna macierz transformacji 
	if (isSquare == false)
	{
		x_c += m_x;
		y_c += m_y;
		glTranslatef(x_c, y_c, 0);
	}
	//przesuwa uklad o dany wektor
	glBegin(GL_LINE_LOOP);
	//
	for (int angle = 0; angle < 365; angle = angle + 5)
	{
		float angle_radians = angle * (float)3.14159 / (float)180;
		float x = rad * (float)cos(angle_radians);
		float y = rad * (float)sin(angle_radians);
		glVertex3f(x, y, 0);
	}
	//
	glEnd();
	glPopMatrix();
}

void display(void)
{
	/* clear window */

	glClear(GL_COLOR_BUFFER_BIT);
	glPushMatrix();
	if (isSquare)
	{
		x += m_x;
		y += m_y;
		glTranslatef(x, y, 0);
	}

	//glRotatef(kat,0,0,1); rotacja w okolo osi z


	if (kolor == 1) glColor3f(1.0, 0.0, 0.0);//pokoloruj red
	else  if (kolor == 2) glColor3f(0.0, 1.0, 0.0);//pokoloruj green
	else if (kolor == 3) glColor3f(0.0, 0.0, 1.0);//pokoloruj blue 
	else  if (kolor > 3) kolor = 1;
	/* draw unit square polygon */
	glBegin(GL_POLYGON);
	glVertex2f(-0.5, -0.5);
	glVertex2f(-0.5, 0.5);
	glVertex2f(0.5, 0.5);
	glVertex2f(0.5, -0.5);
	glEnd();
	/* flush GL buffers */
	glPopMatrix();

	//rysowanie okregu
	drawCircle(0, 0, 1);
	//

	glFlush();//natychmiastowe wykonanie wszystkich poprzednich polecen
}

int licznik;
static void timerCallback(int value)
{
	if (licznik < 50)
	{
		licznik++; //odliczanie kolejnych klatek
		glutTimerFunc(100, timerCallback, value); //ustawienie ponownego wywolania naszej funkcji 'timerCallback' po 100ms
	}
}

static void Key(unsigned char key, int x_d, int y_d)
{
	m_x = 0, m_y = 0;
	switch (key)
	{
	case 'k':
		isSquare = true;
		break;
	case 'o':
		isSquare = false;
		break;
	case 'w':
		m_y += .1;
		glutPostRedisplay();
		break;
	case 's':
		m_y -= .1;
		glutPostRedisplay();
		break;
	case 'a':
		m_x -= .1;
		glutPostRedisplay();
		break;
	case 'd':
		m_x += .1;
		glutPostRedisplay();
		break;
	case ' ':
		kolor++;
		glutPostRedisplay();
		break;
	case 'p':

		break;
	case 27:
		exit(0);
	default:

		break;

	}

}
 

Ale skoro mają na początku te same współrzedne środka to jeśli się zamienią miejscami to będzie tak samo wyglądało, prawda?
Czy mam dodać sobie zmienne, które przechowają mi współrzedne środka kwadrata, okręgu po przesunięciu?

1 użytkowników online, w tym zalogowanych: 0, gości: 1