@@ -156,6 +156,131 @@ void Model::sendToShader(ShaderProgram *sp) {
156156 glVertexAttribPointer (sp->a (" normal" ), 4 , GL_FLOAT , false , 0 , this ->getNormal ());
157157}
158158
159+ // -----------------------------------------------------------------------------------------------------------------------------------
160+
161+ // -----------------------------------------------------------------------------------------------------------------------------------
162+ // SNAKE CLASS
163+
164+ Snake::Snake (Model* snakeHead, Model* snake, int baseLength) {
165+ this ->length = 1 ;
166+ this ->baseLength = baseLength + 1 ;
167+
168+ this ->snakeHead = snakeHead;
169+ this ->snakeBody = snake;
170+
171+ this ->snake .push_back (new Model (*this ->snakeHead ));
172+
173+ this ->extendSnake (baseLength);
174+ }
175+
176+ Snake::~Snake () {
177+
178+ }
179+
180+ void Snake::extendSnake (int amount) {
181+ if (length <= 1 ) {
182+ this ->snake .push_back (new Model (*this ->snakeBody ));
183+ amount--;
184+ length++;
185+ }
186+ for (int i = 0 ; i < amount; i++) {
187+ this ->snake .push_back (new Model (*this ->snake .at (length - 1 )));
188+ }
189+ length += amount;
190+ }
191+
192+ void Snake::renderSnake (ShaderProgram *sp) {
193+ for (int i = 0 ; i < this ->snake .size (); i++) {
194+ this ->snake .at (i)->sendToShader (sp);
195+ this ->snake .at (i)->activateTexture (sp);
196+
197+ if (this ->snake .at (i)->getIndexCount () == 0 ) glDrawArrays (GL_TRIANGLES , 0 , this ->snake .at (i)->getVertexCount ());
198+ else glDrawElements (GL_TRIANGLES , this ->snake .at (i)->getIndexCount (), GL_UNSIGNED_INT , 0 );
199+ }
200+ }
201+
202+ void Snake::move (int direction, int pos) {
203+ if (checkCollision ()) {
204+ std::cout << " Snake collided with wall or himself, you died!" << std::endl;
205+ exit (EXIT_SUCCESS );
206+ }
207+ if (pos == 0 ) {
208+ this ->snake .at (pos)->translate (glm::vec3 (0 .0f , this ->velocity , 0 .0f ));
209+ if (direction == 2 )
210+ this ->snake .at (pos)->rotate (glm::vec3 (this ->angle , 0 .0f , 0 .0f ));
211+ if (direction == 3 )
212+ this ->snake .at (pos)->rotate (glm::vec3 (-this ->angle , 0 .0f , 0 .0f ));
213+ if (appleCollision ()) {
214+ this ->randomizeApple ();
215+ this ->animationIndex = 0 ;
216+ }
217+ return ;
218+ }
219+ this ->snake .at (pos)->setModelMatrix (this ->snake .at (pos-1 )->getModelMatrix ());
220+ this ->move (direction, pos-1 );
221+ }
222+
223+ void Snake::animation () {
224+ if (animationInbound) {
225+ this ->snake .at (animationIndex)->scale (glm::vec3 (0 .8f , 0 .8f , 0 .8f ));
226+ animationInbound = false ;
227+ animationIndex++;
228+ }
229+
230+ if (!animationInbound && animationIndex <= this ->snake .size () - 1 && animationIndex >= 0 ) {
231+ this ->snake .at (animationIndex)->scale (glm::vec3 (1 .25f , 1 .25f , 1 .25f ));
232+ this ->animationInbound = true ;
233+ }
234+
235+ if (animationIndex == this ->snake .size () && !animationInbound) {
236+ this ->extendSnake (1 );
237+ this ->snake .at (length - 1 )->translate (glm::vec3 (0 .0f , -this ->velocity , 0 .0f ));
238+ animationIndex = -1 ;
239+ }
240+ }
241+
242+ bool Snake::checkCollision () {
243+ glm::mat4 head = this ->snake .at (0 )->getModelMatrix ();
244+ head = glm::translate (head, glm::vec3 (0 .0f , this ->velocity , 0 .0f ));
245+ bool wallCollision = (abs (head[3 ][0 ]) > 5.5 || abs (head[3 ][2 ]) > 5.5 );
246+ bool snakeCollision = false ;
247+ for (int i = this ->baseLength ; i < this ->snake .size (); i++)
248+ if (abs (head[3 ][0 ] - this ->snake .at (i)->getModelMatrix ()[3 ][0 ]) < 0.3 && abs (head[3 ][2 ] - this ->snake .at (i)->getModelMatrix ()[3 ][2 ]) < 0.3 )
249+ snakeCollision = true ;
250+ return wallCollision || snakeCollision;
251+ }
252+
253+ bool Snake::appleCollision () {
254+ glm::mat4 modelApple = this ->apple ->getModelMatrix ();
255+ glm::mat4 modelSnake = this ->snake .at (0 )->getModelMatrix ();
256+ return abs (modelApple[3 ][0 ] - modelSnake[3 ][0 ]) < 0.35 && abs (modelApple[3 ][2 ] - modelSnake[3 ][2 ]) < 0.45 ;
257+ }
258+
259+ void Snake::randomizeApple () {
260+ glm::mat4 apple = this ->apple ->getModelMatrix ();
261+ apple[3 ][0 ] = rand ()%7 -3.5 ;
262+ apple[3 ][2 ] = rand ()%7 -3.5 ;
263+ this ->apple ->setModelMatrix (apple);
264+ }
265+
266+ void Snake::appleAnimation () {
267+ glm::mat4 appleMatrix = apple->getModelMatrix ();
268+
269+ this ->apple ->rotate (glm::vec3 (0 .0f , 2 .0f , 0 .0f ));
270+
271+ if (appleMatrix[3 ][1 ] > 1.5 ) {
272+ appleMatrix[3 ][1 ] = 1.5 ;
273+ apple->setModelMatrix (appleMatrix);
274+ appleTranslation = -appleTranslation;
275+
276+ } else if (appleMatrix[3 ][1 ] < 1 ) {
277+ appleMatrix[3 ][1 ] = 1 ;
278+ apple->setModelMatrix (appleMatrix);
279+ appleTranslation = -appleTranslation;
280+ }
281+
282+ this ->apple ->translate (glm::vec3 (0 .0f , appleTranslation, 0 .0f ));
283+ }
159284
160285// -----------------------------------------------------------------------------------------------------------------------------------
161286
@@ -188,7 +313,7 @@ App::App(int width, int height, const char *title) {
188313
189314 // Start GLEW
190315 GLenum err;
191- if ((err= glewInit ()) != GLEW_OK ) {
316+ if ((err = glewInit ()) != GLEW_OK ) {
192317 fprintf (stderr, " Can't initialize GLEW: %s\n " , glewGetErrorString (err));
193318 exit (EXIT_FAILURE );
194319 }
@@ -215,22 +340,9 @@ void App::renderLambertObjects() {
215340 // Enable attributes for Lambert shading
216341 this ->setAttribArrays (this ->lambert );
217342
218- if (arbitralAnimationValue == this ->models .size () && !scaled) {
219- this ->addModel (new Model (*this ->getModel (this ->models .size () - 1 )));
220- arbitralAnimationValue = 0 ;
221- move (UP , this ->models .size () - 1 );
222- }
223-
224- if (scaled) {
225- this ->models .at (arbitralAnimationValue)->scale (glm::vec3 (0 .8f , 0 .8f , 0 .8f ));
226- scaled = false ;
227- arbitralAnimationValue++;
228- }
343+ this ->snake ->animation ();
229344
230- if (!scaled && arbitralAnimationValue <= this ->models .size () - 1 && arbitralAnimationValue >= 2 ) {
231- this ->models .at (arbitralAnimationValue)->scale (glm::vec3 (1 .25f , 1 .25f , 1 .25f ));
232- this ->scaled = true ;
233- }
345+ this ->snake ->renderSnake (this ->lambert );
234346
235347 // Draw models
236348 for (int i = 1 ; i < this ->models .size (); i++) {
@@ -255,6 +367,8 @@ void App::renderInvertedLambertObjects() {
255367 // Enable attributes for inverted Lambert shading
256368 this ->setAttribArrays (this ->invLambert );
257369
370+ this ->snake ->appleAnimation ();
371+
258372 // Draw models
259373 this ->models .at (0 )->sendToShader (this ->invLambert );
260374 this ->models .at (0 )->activateTexture (this ->invLambert );
@@ -283,14 +397,16 @@ void App::renderPhongObjects() {
283397// Update camera matrices
284398void App::updateUniforms (ShaderProgram *sp) {
285399 // Calculate View Matrix based on camera position
286- this ->V = glm::lookAt (glm::vec3 (0 .0f , 8 .5f , 0 .0f ), glm::vec3 (0 .0f , 0 .0f , 0 .25f ), glm::vec3 (0 .0f , 1 .0f , 0 .0f ));
400+ if (cameraToggle) this ->V = this ->camera .getViewMatrix ();
401+ else this ->V = glm::lookAt (glm::vec3 (0 .0f , 8 .5f , 0 .0f ), glm::vec3 (0 .0f , 0 .0f , 0 .25f ), glm::vec3 (0 .0f , 1 .0f , 0 .0f ));
287402
288403 // Send camera to GPU
289404 glUniformMatrix4fv (sp->u (" P" ),1 ,false ,glm::value_ptr (this ->P ));
290405 glUniformMatrix4fv (sp->u (" V" ),1 ,false ,glm::value_ptr (this ->V ));
291406
292407 // Change light based on camera position
293- glUniform4fv (sp->u (" lightDir" ),1 ,glm::value_ptr (this ->camera .getPosition ()));
408+ if (cameraToggle) glUniform4fv (sp->u (" lightDir" ), 1 , glm::value_ptr (this ->camera .getPosition ()));
409+ else glUniform4fv (sp->u (" lightDir" ),1 ,glm::value_ptr (glm::vec3 (0 .0f , 0 .0f , 1 .0f )));
294410}
295411
296412
@@ -365,11 +481,12 @@ void App::disableAttribArrays(ShaderProgram *sp) {
365481void App::updateInput () {
366482 // Poll input
367483 glfwPollEvents ();
368- if (glfwGetKey (this ->window , GLFW_KEY_W ) == GLFW_PRESS ) move (UP , this ->models . size () - 1 );
369- else if (glfwGetKey (this ->window , GLFW_KEY_S ) == GLFW_PRESS ) move (DOWN , this ->models . size () - 1 );
370- else if (glfwGetKey (this ->window , GLFW_KEY_A ) == GLFW_PRESS ) move (LEFT , this ->models . size () - 1 );
371- else if (glfwGetKey (this ->window , GLFW_KEY_D ) == GLFW_PRESS ) move (RIGHT , this ->models . size () - 1 );
484+ if (glfwGetKey (this ->window , GLFW_KEY_W ) == GLFW_PRESS ) this -> snake -> move (UP , this ->snake -> getLength () - 1 );
485+ else if (glfwGetKey (this ->window , GLFW_KEY_S ) == GLFW_PRESS ) this -> snake -> move (DOWN , this ->snake -> getLength () - 1 );
486+ else if (glfwGetKey (this ->window , GLFW_KEY_A ) == GLFW_PRESS ) this -> snake -> move (LEFT , this ->snake -> getLength () - 1 );
487+ else if (glfwGetKey (this ->window , GLFW_KEY_D ) == GLFW_PRESS ) this -> snake -> move (RIGHT , this ->snake -> getLength () - 1 );
372488 else if (glfwGetKey (this ->window , GLFW_KEY_ESCAPE ) == GLFW_PRESS ) glfwSetWindowShouldClose (this ->window , GL_TRUE );
489+ else if (glfwGetKey (this ->window , GLFW_KEY_V ) == GLFW_PRESS ) this ->toggleCamera ();
373490
374491 // Move camera
375492 else if (glfwGetKey (this ->window , GLFW_KEY_UP ) == GLFW_PRESS ) this ->camera .moveCamera (this ->dt , UP );
@@ -411,60 +528,6 @@ void App::updateDt() {
411528 this ->lastTime = this ->curTime ;
412529}
413530
414-
415- // Snake movement
416- void App::move (int direction, int pos) {
417- if (checkCollision ()) {
418- std::cout << " Snake collided with wall or himself, you died!" << std::endl;
419- exit (EXIT_SUCCESS );
420- }
421- if (pos == 2 ) {
422- this ->models .at (pos)->translate (glm::vec3 (0 .0f , this ->velocity , 0 .0f ));
423- if (direction == 2 )
424- this ->models .at (pos)->rotate (glm::vec3 (this ->angle , 0 .0f , 0 .0f ));
425- if (direction == 3 )
426- this ->models .at (pos)->rotate (glm::vec3 (-this ->angle , 0 .0f , 0 .0f ));
427- glm::mat4 modelApple = this ->models .at (0 )->getModelMatrix (), modelSnake = this ->models .at (2 )->getModelMatrix ();
428- if (abs (modelApple[3 ][0 ] - modelSnake[3 ][0 ]) < 0.35 && abs (modelApple[3 ][2 ] - modelSnake[3 ][2 ]) < 0.45 ) {
429- this ->randomizeApple ();
430- this ->arbitralAnimationValue = 2 ;
431- }
432- return ;
433- }
434- this ->models .at (pos)->setModelMatrix (this ->models .at (pos-1 )->getModelMatrix ());
435- this ->move (direction, pos-1 );
436- }
437-
438-
439- // Trigger eating animation and change position of apple
440- void App::eat (int direction, int pos) {
441- this ->randomizeApple ();
442- this ->arbitralAnimationValue = 2 ;
443- }
444-
445-
446- // Place apple at other random position
447- void App::randomizeApple () {
448- glm::mat4 apple = this ->models .at (0 )->getModelMatrix ();
449- apple[3 ][0 ] = rand ()%7 -3.5 ;
450- apple[3 ][2 ] = rand ()%7 -3.5 ;
451- this ->models .at (0 )->setModelMatrix (apple);
452- }
453-
454-
455- // Check for snake collisions
456- bool App::checkCollision () {
457- glm::mat4 head = this ->models .at (2 )->getModelMatrix ();
458- head = glm::translate (head, glm::vec3 (0 .0f , this ->velocity , 0 .0f ));
459- bool wallCollision = (abs (head[3 ][0 ]) > 5.5 || abs (head[3 ][2 ]) > 5.5 );
460- bool snakeCollision = false ;
461- for (int i = 6 ; i < this ->models .size (); i++)
462- if (abs (head[3 ][0 ] - this ->models .at (i)->getModelMatrix ()[3 ][0 ]) < 0.3 && abs (head[3 ][2 ] - this ->models .at (i)->getModelMatrix ()[3 ][2 ]) < 0.3 )
463- snakeCollision = true ;
464- return wallCollision || snakeCollision;
465- }
466-
467-
468531// -----------------------------------------------------------------------------------------------------------------------------------
469532
470533// -----------------------------------------------------------------------------------------------------------------------------------
@@ -528,5 +591,4 @@ void Camera::moveCamera(const float &dt, const int direction) {
528591 }
529592}
530593
531-
532- // -----------------------------------------------------------------------------------------------------------------------------------
594+ // -----------------------------------------------------------------------------------------------------------------------------------
0 commit comments