CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Nov 2016
    Posts
    12

    (OpenGL) Trying to get object to chase the camera, but unsure how

    Hey there! So, I'm trying to get my "Ogro" object to chase the camera, but I am currently unsure as to how to accomplish this. Could someone please help me out with this? I don't need AI that can navigate around objects or anything, just so the "Ogro" kind of makes a beeline for the camera. I am pretty certain that I would be able to accomplish this in my main.cpp:

    Code:
    /*
    TODO (Necessary):
    	
    TODO (After base game has been completed):
    	Make Ogro that chases player throughout collection time, one hit kill
    COMPLETED:
    	Check to see if there has already been a collision between camera and tree. If so, points and tapped trees don't increment (Complete)
    	Set up countdown to "season end" (Complete)
    	Change point values/textures individually (Complete)
    	Make it so that only the tree trunk changes textures, not the leaves (Complete)	
    	When the player presses 'r', restart the game, only after timer has run out (Complete)
    	Make 60 trees (Complete)
    */
    
    #include "Font.h"
    #include "ogro.h"
    #include "Box.h"
    #include "md2model.h"
    #include "sstream"
    #include "Camera.h"
    #include "Time.h"
    #include <vector>
    using namespace std;
    
    #include "vgl.h"
    #include <glm/glm.hpp>
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtx/norm.hpp>
    using namespace glm;
    #define SPACEBAR_KEY 32
    #define ESCAPE_KEY 033
    #define e 101
    
    Camera* camera;
    Ogro* ogro;
    //Box* boxes;
    Font* font;
    string fontText;
    vector<GameObject*> gameObjects;
    vector<Box * > boxes;
    //vector<Box * > boxes;
    
    int treesTapped = 0, points = 0;
    
    
    float lastTime;
    bool keyDown[255];
    bool collided = false, alreadyCollided;
    int counter = 0, minute = 60, tapsInInventory = 10, playerHealth = 1;
    bool gameOver = false, kill = false, playerDead;
    
    void timer(int value)
    {
    	glutPostRedisplay();
    	glutTimerFunc(25, timer, 0);
    
    	if (counter == 40)
    	{
    		counter = 0;
    		minute--;
    	}
    	counter++;
    	if (minute <= 0)
    	{
    		gameOver = true;
    		minute = 0;
    	}
    }
    
    void newGame()
    {
    	camera->setPosition(vec3(20.0f, .5f, 0.0f));
    	minute = 60;
    	counter = 0;
    	treesTapped = 0;
    	points = 0;
    	gameOver = false;
    	kill = false;
    	playerDead = false;
    	playerHealth = 1;
    	((Ogro*)gameObjects[163])->setPosition(vec3(55, 0, 55));
    	
    	for (auto i = gameObjects.begin(); i != gameObjects.end(); ++i)
    	{
    		if ((*i)->getType() == ObjectType::BOX)
    		{
    			auto b = (Box*)*i;
    			if (b->collided1 != false && b->trunk == true)
    			{
    				b->ChangeTextureBack();
    				b->alreadyCollided = false;
    			}
    		}
    	}
    }
    
    void closeApp()
    {
    	delete camera;
    	delete font;
    	for (auto it = gameObjects.begin(); it != gameObjects.end(); ++it)
    	{
    		delete (*it);
    	}	
    }
    
    void CheckKeyboard()
    {
    
    	if (gameOver == false && playerDead == false)
    	{
    		if (keyDown['a'])
    			camera->RotateLeft();
    		if (keyDown['d'])
    			camera->RotateRight();
    		if (keyDown['w'])
    			camera->MoveForward();
    		if (keyDown['s'])
    			camera->MoveBackWard();
    		/*if (keyDown['e'])
    		camera->StrafeRight();
    		if (keyDown['q'])
    		camera->StrafeLeft();*/
    	}
    
    	vec3 p = camera->getPosition();
    	camera->Update();
    
    
    	for (auto i = gameObjects.begin(); i != gameObjects.end(); ++i)
    	{
    		if ((*i)->getType() == ObjectType::BOX)
    		{
    			auto b = (Box*)*i;
    			if (camera->getPosition().x >= (b->Position.x - b->getXBuffer()) && camera->getPosition().x <= (b->Position.x + b->getXBuffer()))
    			{
    				if (camera->getPosition().z >= (b->Position.z - b->getZBuffer()) && camera->getPosition().z <= (b->Position.z + b->getZBuffer()))		//change to Z axis and get camera position instead of radius
    				{
    					if (b->collided1 == false)		//Makes it so that boxes[0] does not have collision
    					{
    						collided = false;
    					}
    					else if (b->collided1 == true && b->trunk == true)
    					{
    						collided = true;
    						if (b->alreadyCollided == false && keyDown['e'])
    						{
    							if (b->mapleLeaves == true)
    							{
    								treesTapped++;
    								points += 500;
    								b->ChangeTexture();
    								b->alreadyCollided = true;
    							}
    							else
    							{
    								treesTapped++;
    								points += 100;
    								b->ChangeTexture();
    								b->alreadyCollided = true;
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    	for (int j = 0; j <= gameObjects.size() - 1; j++)
    	{
    		if (gameObjects[j]->getType() == ObjectType::OGRO)		//If object is equal to Orgro, check to see if colliding
    		{
    			float distance = glm::distance(((Ogro*)gameObjects[j])->getPosition(), camera->getPosition());
    			float cr = camera->getRadius();
    			float mr = ((Ogro*)gameObjects[j])->getRadius();
    			float sum = mr + cr;
    			if (distance <= sum)			//Camera and orgro have collided if distance is less than or equal to radius of 
    			{								//camera plus radius of monster
    				kill = true;
    			}
    		}
    	}
    	
    	if (collided)
    	{
    		camera->position = p;
    		camera->Update();
    	}
    	if (!kill)
    	{
    		((Ogro*)gameObjects[163])->model->setAnimation(Ogro::Animations[Ogro::RUN].AnimationFrame);
    	}
    	if (kill)
    	{
    		playerHealth--;
    		((Ogro*)gameObjects[163])->model->setAnimation(Ogro::Animations[Ogro::JUMP].AnimationFrame);
    		playerDead = true;
    	}
    
    	if (camera->position.x >= 60.0f)
    	{
    		camera->position.x = 60.0f;
    	}
    	if (camera->position.x <= -60.0f)
    	{
    		camera->position.x = -60.0f;
    	}
    	if (camera->position.z >= 60.0f)
    	{
    		camera->position.z = 60.0f;
    	}
    	if (camera->position.z <= -60.0f)
    	{
    		camera->position.z = -60.0f;
    	}
    
    	srand(time(NULL));
    
    }
    
    float getElapsedSeconds()
    {
    	float currentTime = float(GetTickCount()) / 1000.0f;
    	float seconds = float(currentTime - lastTime);
    	lastTime = currentTime;
    	return seconds;
    }
    
    void keyboardUp(unsigned char key, int x, int y)
    {
    	keyDown[key] = false;
    }
    
    void mouseMovement(int x, int y)
    {
    	static bool warp = true;
    
    	if (warp)
    	{
    		if (x>glutGet(GLUT_WINDOW_WIDTH) / 2)
    			camera->RotateRight();
    		else if (x<glutGet(GLUT_WINDOW_WIDTH) / 2)
    			camera->RotateLeft();
    
    		if (y>glutGet(GLUT_WINDOW_HEIGHT) / 2)
    			camera->RotateUp();
    		else if (y<glutGet(GLUT_WINDOW_HEIGHT) / 2)
    			camera->RotateDown();
    
    		glutWarpPointer(glutGet(GLUT_WINDOW_WIDTH) / 2, glutGet(GLUT_WINDOW_HEIGHT) / 2);
    		warp = false;
    	}
    	else
    		warp = true;
    }
    
    void mouseWheel(int button, int direction, int x, int y)
    {
    
    	if (button == 16)
    		camera->ResetFOV();
    	else if (direction > 0)
    		camera->ZoomIn();
    	else
    		camera->ZoomOut();
    }
    
    void keyboardSpecialKeys(int key, int x, int y)
    {
    	float yaw;
    	switch (key)
    	{
    	case GLUT_KEY_LEFT:
    		yaw = ((Ogro*)gameObjects[1])->getYaw();
    		yaw -= 5.0;
    		((Ogro*)gameObjects[1])->setYaw(yaw);
    		break;
    	case GLUT_KEY_RIGHT:
    		yaw = ((Ogro*)gameObjects[1])->getYaw();
    		yaw += 5.0;
    		((Ogro*)gameObjects[1])->setYaw(yaw);
    		break;
    	}
    }
    
    void keyboard(unsigned char key, int x, int y)
    {
    	keyDown[key] = true;
    	switch (key)
    	{
    	case ESCAPE_KEY:
    		exit(EXIT_SUCCESS);
    		break;
    	//case 'e':
    		/*if (collided)			//TODO: differentiate between the trees
    		{
    			((Box*)gameObjects[1])->ChangeTexture();
    			treesTapped++;
    			points += 100;
    		}
    		break;*/
    	case 'r':
    		if (gameOver || playerDead)
    		{
    			newGame();
    		}
    	}
    	
    }
    
    void display()
    {
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	CheckKeyboard();
    
    	if (fontText.length() != 0)
    		font->printText(fontText, 350, 550, 25);
    
    	float dt = getElapsedSeconds();
    	for (int i = 0; i <= gameObjects.size() - 1; i++)
    	{
    		switch (gameObjects[i]->getType())
    		{
    		case ObjectType::BOX:
    			((Box*)gameObjects[i])->setMVPMatrix(camera->ViewMatrix, camera->ProjectionMatrix);
    			gameObjects[i]->Draw(dt);
    			break;
    		case ObjectType::OGRO:
    			((Ogro*)gameObjects[i])->changeInTime = dt;
    			((Ogro*)gameObjects[i])->Draw(camera->ViewMatrix, camera->ProjectionMatrix);
    			break;
    		}
    	}
    
    	/*if (timer == 40)
    	{
    		timer = 0;
    		seconds--;
    	}
    	timer++;*/
    
    	std::stringstream ss1;
    	ss1 << "Trees tapped: " << treesTapped;
    	font->printText(ss1.str().c_str(), 20, 510, 15);
    	std::stringstream ss2;
    	ss2 << "Points: " << points;
    	font->printText(ss2.str().c_str(), 20, 480, 15);
    	std::stringstream ss3;
    	ss3 << "Time until season end: " << minute;
    	font->printText(ss3.str().c_str(), 143, 570, 20);
    	
    	if (gameOver)
    	{
    		std::stringstream ss4;
    		ss4 << "Nice haul!";
    		font->printText(ss4.str().c_str(), 270, 330, 25);
    		std::stringstream ss5;
    		ss5 << "Press 'r' to play again!";
    		font->printText(ss5.str().c_str(), 100, 310, 25);
    	}
    	if (playerDead)
    	{
    		std::stringstream ss4;
    		ss4 << "You got caught!";
    		font->printText(ss4.str().c_str(), 270, 330, 25);
    		std::stringstream ss5;
    		ss5 << "Press 'r' to play again!";
    		font->printText(ss5.str().c_str(), 100, 310, 25);
    	}
    	glutSwapBuffers();
    }
    
    
    void init()
    {
    	glClearColor(0.0f, 0.0f, 0.7f, 0.0f);
    	glEnable(GL_DEPTH_TEST);
    	glDepthFunc(GL_LESS);
    
    	
    	font = new Font();
    	camera = new Camera();
    	camera->setPosition(vec3(20.0f, .5f, 0.0f));
    	glutWarpPointer(glutGet(GLUT_WINDOW_WIDTH) / 2, glutGet(GLUT_WINDOW_HEIGHT) / 2);
    	std::fill(keyDown, keyDown + 255, false);
    							
    																																											//bools: vsibility, collided1, already collided, trunk, mapleLeaves
    	gameObjects.push_back(new Box(vec3(0.0f, -2.0f, 0.0f), "data/images/grass-1.png", "data/shaders/Texture.vertexshader", "data/shaders/Texture.fragmentshader", "Data\\Models\\Floor.xml", true, 0.1f, vec3(70.0f, 0.1f, 70.0f), true, false, true, false, false));
    	//New tree (trunk+leaves)
    	gameObjects.push_back(new Box(vec3(0.0f, -2.0f, 0.0f), "data/images/wood.bmp", "data/shaders/Texture.vertexshader", "data/shaders/Texture.fragmentshader", "Data\\Models\\Floor.xml", true, 0.1f, vec3(1.0f, 10.0f, 1.0f), true, true, false, true, false));
    	gameObjects.push_back(new Box(vec3(0.0f, 6.0f, 0.0f), "data/images/leaves.jpg", "data/shaders/Texture.vertexshader", "data/shaders/Texture.fragmentshader", "Data\\Models\\Floor.xml", true, 0.1f, vec3(2.5f, 2.5f, 2.5f), true, true, false, false, false));
    	//New tree (trunk+leaves)
    
    //JUST IMAGINE 160 OTHER TREE OBJECTS HERE
    //I REMOVED FOR THE SAKE OF READABILITY
    
    	gameObjects.push_back(new Ogro());
    	((Ogro*)gameObjects[163])->Initialize();
    	((Ogro*)gameObjects[163])->setPosition(vec3(-55, 0, -55));
    	((Ogro*)gameObjects[163])->setDirection(vec3(1, 0, 0));
    	((Ogro*)gameObjects[163])->setYaw(90);
    
    	/*gameObjects.push_back(new Ogro());
    	((Ogro*)gameObjects[2])->Initialize();
    	((Ogro*)gameObjects[2])->setYaw(-90);
    	((Ogro*)gameObjects[2])->setPosition(vec3(0, 0, -3));
    	((Ogro*)gameObjects[2])->setDirection(vec3(1, 0, 0));*/
    }
    
    
    
    int main(int argc, char** argv)
    {
    	glutInit(&argc, argv);
    
    	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH);
    	glutInitWindowSize(1024, 768);
    	glutInitContextProfile(GLUT_CORE_PROFILE);
    	glutCreateWindow("Model Example1");
    	
    
    	if (glewInit())
    	{
    		cerr << "Unable to init glew" << endl;
    		exit(EXIT_FAILURE);
    	}
    
    	init();
    	glutDisplayFunc(display);
    	glutKeyboardFunc(keyboard);
    	glutKeyboardUpFunc(keyboardUp);
    	glutSpecialFunc(keyboardSpecialKeys);
    	//glutPassiveMotionFunc(mouseMovement);
    	glutMouseWheelFunc(mouseWheel);
    	glutTimerFunc(25, timer, 0);
    	glutMainLoop();
    	return 0;
    }
    I know how to get both the positions of the camera and the ogro, but what to do after this is confusing me greatly. Thank you so much for all the help!

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: (OpenGL) Trying to get object to chase the camera, but unsure how

    TODO (After base game has been completed):
    Make Ogro that chases player throughout collection time, one hit kill

    but what to do after this is confusing me greatly
    This is the problem with these types of exercises! After some part is working you are expected to then modify it to add further 'features'. Unless the design of the program from the start incorporates these 'features', it is not always easy to do! Although in the real programming world, this is quite common - so the experience is useful.

    Rather than dive head in and start adding code, I would suggest you go back to the program design, change the design and then make the required code changes.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    Join Date
    Nov 2016
    Posts
    12

    Re: (OpenGL) Trying to get object to chase the camera, but unsure how

    Quote Originally Posted by 2kaud View Post
    This is the problem with these types of exercises! After some part is working you are expected to then modify it to add further 'features'. Unless the design of the program from the start incorporates these 'features', it is not always easy to do! Although in the real programming world, this is quite common - so the experience is useful.

    Rather than dive head in and start adding code, I would suggest you go back to the program design, change the design and then make the required code changes.
    I know my program is logically unsound and inefficient, but I really just need help with the math and logic of how I would get the model to chase the camera. I do agree that these exercises could be handled in a much more learning appropriate way, however, but it's due next week and I would much rather get the program working than worry about rewriting the whole thing.

    I do really appreciate all the help you've provided me 2kaud. I really means a lot.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured