// // Game.h // SkyRoads // // Created by Joshua Moerman on 12/22/12. // Copyright (c) 2012 Vadovas. All rights reserved. // #ifndef SkyRoads_Game_h #define SkyRoads_Game_h #import #include "statics.h" #include "myGL.h" static const float accel = 4.0; static const float max_speed = 9.0; struct Game{ std::vector quads; std::vector spaceship; struct Position { float x, y, z; } position; struct Speed { float x, y, z; } speed; struct Box { Position min, max; } boundingbox; Game() : position({0.0, -1.0, 0.0}) , speed({0.0, 0.0, 0.0}) , boundingbox({-0.2, 0.0, -0.3, 0.2, 0.0, 0.3}) { make_spaceship(); make_quads(); } void make_spaceship(){ spaceship.resize(5); spaceship[0] = {-1.0, 0.0, 2.0, 0.5, 0.0, 0.0, 0.0}; spaceship[1] = { 1.0, 0.0, 2.0, 0.5, 0.0, 0.0, 0.0}; spaceship[2] = { 0.0, 1.0, 1.5, 1.0, 0.2, 0.0, 0.0}; spaceship[3] = { 0.0, 0.0, -2.0, 1.0, 0.0, 1.5, 0.0}; spaceship[4] = {-1.0, 0.0, 2.0, 0.5, 0.0, 0.0, 0.0}; float scale = 0.7; for(auto& v : spaceship){ v = gl::scale(v, scale*0.3, scale*0.2, scale*0.4); } } void make_quads(){ quads.reserve(number_of_quads); for(int zz = 0; zz < level_length; ++zz){ for(int xx = 0; xx < level_width; ++xx){ if(level[xx + level_width*zz] == 0) continue; const double size = 1.0; // DONT CHANGE double x = xx - (int)level_width/2; double z = zz; double y = -1.0; Quad q; // deg. q[0][0] = x - size*0.5; q[0][1] = y; q[0][2] = z - size*0.5; q[1][0] = x - size*0.5; q[1][1] = y; q[1][2] = z - size*0.5; // real quad q[2][0] = x - size*0.5; q[2][1] = y; q[2][2] = z - size*0.5; q[3][0] = x - size*0.5; q[3][1] = y; q[3][2] = z + size*0.5; q[4][0] = x + size*0.5; q[4][1] = y; q[4][2] = z - size*0.5; q[5][0] = x + size*0.5; q[5][1] = y; q[5][2] = z + size*0.5; // deg. q[6][0] = x + size*0.5; q[6][1] = y; q[6][2] = z + size*0.5; q[7][0] = x + size*0.5; q[7][1] = y; q[7][2] = z + size*0.5; //double r = rand() / (double) RAND_MAX; //double g = rand() / (double) RAND_MAX; //double b = rand() / (double) RAND_MAX; for(auto& v : q){ v[3] = 0.2*std::abs(x); v[4] = 1.0 - 0.2*std::abs(x); v[5] = (level[xx + level_width*zz] > 1)? 1.0 : 0.0; v[6] = 1.0; } quads.push_back(q); } } } void update(float dt){ speed.z -= dt * accel; if(speed.z < -max_speed) speed.z = -max_speed; position.z += dt * speed.z; for(auto& q : quads){ if(q[0][2] > position.z + 4.0) { for(auto& v : q){ v[2] -= level_length; } } } if(check() && position.y > -1.1){ // alive position.y = -1.0; speed.y = 0.0; } else { speed.y -= dt * 4.0; position.y += dt * speed.y; } } int clamp(int x, int min, int max){ return (x < min) ? min : ((x > max) ? max : x); } int position_to_index(Position p){ int amp = level_width/2; int x = clamp(std::round(p.x), -amp, amp) + amp; int z = int(std::round(p.z)) % int(level_length); if(z < 0) z += level_length; return x + level_width*z; } bool check(){ for(auto x : {boundingbox.min.x, boundingbox.max.y}){ for(auto z : {boundingbox.min.z, boundingbox.max.z}){ int index = position_to_index({position.x + x, 0.0, position.z + z}); if(level[index] > 0) return true; } } return false; } void draw(GLKMatrix4 projectionMatrix, J::shader& shader){ draw_spaceship(projectionMatrix, shader); draw_quads(projectionMatrix, shader); } void draw_spaceship(GLKMatrix4 projectionMatrix, J::shader& shader){ GLKMatrix4 modelViewMatrix = GLKMatrix4Identity; GLKMatrix4 modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); GLKMatrix3 normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); shader.set_uniform("modelViewProjectionMatrix", modelViewProjectionMatrix.m, 0); shader.set_uniform("normalMatrix", normalMatrix.m, 0); shader.set_attribute("position", 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &quads[0][0][0]); shader.set_attribute("color", 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), &quads[0][0][3]); glDrawArrays(GL_TRIANGLE_STRIP, 0, quads.size()*8); } void draw_quads(GLKMatrix4 projectionMatrix, J::shader& shader){ GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(position.x, position.y, position.z); GLKMatrix4 modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix); GLKMatrix3 normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); shader.set_uniform("modelViewProjectionMatrix", modelViewProjectionMatrix.m, 0); shader.set_uniform("normalMatrix", normalMatrix.m, 0); shader.set_attribute("position", 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &spaceship[0][0]); shader.set_attribute("color", 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), &spaceship[0][3]); glDrawArrays(GL_TRIANGLE_STRIP, 0, spaceship.size()); } }; #endif