#include "bufferfish.h" #include "gravityball.h" #include "game.h" #include #include using namespace std; BufferFish::BufferFish(FMOD::System* sound_sys, const char* fname, DeathBall* death_ball) : _accel(0,0,0) , _gravity_ball(NULL) , _tail_spawn_time(0) , _is_dead(false) , _is_dying(false) , _death_ball(death_ball) { _pos.z = 10 + 3 * float(rand()) / RAND_MAX; _pos.x = 2 - 4 * float(rand()) / RAND_MAX; _vel.x = .5 - float(rand()) / RAND_MAX; _vel.y = .5 - float(rand()) / RAND_MAX; _vel.z = .5 - float(rand()) / RAND_MAX; _vel *= 4; _type = Actor::bufferfish; _audio_loop = new AudioLoop(sound_sys); _audio_loop->load_file(fname); _audio_loop->play(); update(0); } BufferFish::~BufferFish() { delete _audio_loop; } void BufferFish::update(double tick_time) { if (_gravity_ball && !_gravity_ball->_is_exploding) { _accel = 2*(_gravity_ball->_pos - _pos); } else { STVector3 dir = _death_ball->_pos - _pos; if (dir.LengthSq() < .4) { _is_dying = true; } dir.Normalize(); _accel = 100*dir; _vel *= .99; } if (_is_dying) { _audio_loop->_volume = max(0.0, _audio_loop->_volume - tick_time); if (_is_dead == false && _audio_loop->_volume == 0) { _is_dead = true; _death_ball->increment_fish(); } } else { double d = (_pos - _death_ball->_pos).Length(); double vol = min(1.0, 20 * 1/d); _audio_loop->_volume = vol; } _vel += _accel * tick_time; //if (_vel.Length() > 10) _vel *= .9; _pos += _vel * tick_time; //_audio_loop->_volume = .7;//_vel.Length() / 10; _audio_loop->set_3D(_pos, _vel); _tail_spawn_time += tick_time; while (_tail_spawn_time > .01) { _tail_spawn_time -= .01; tail_cell_t cell; cell.pos = _pos; SAMPLE min, max; min = max = _audio_loop->get_sample(0); for (unsigned k = 0; k < SAMPLE_RATE * .01; k++) { SAMPLE samp = _audio_loop->get_sample(-k); if (samp < min) min = samp; if (samp > max) max = samp; } cell.max = max / double(MAX_SAMPLE_VALUE); cell.min = min / double(MAX_SAMPLE_VALUE); //cell.max *= cell.max; //cell.min *= cell.min*-1; _tail.push_front(cell); if (_tail.size() > 50) { _tail.pop_back(); } } } static void set_material() { GLfloat material_Ka[] = {0.2f, 0.9f, 0.9f, 1.0f}; GLfloat material_Kd[] = {0.0f, 0.6f, 0.6f, 1.0f}; GLfloat material_Ks[] = {0.0f, 1.0f, 1.0f, 1.0f}; ALPHA_HACK(1); GLfloat material_Se = 2.0f; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material_Ka); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material_Kd); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_Ks); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material_Se); } void BufferFish::render(double tick_time) { //glEnable(GL_POINT_SMOOTH); //glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); //glPointSize(10); set_material(); glBegin(GL_QUAD_STRIP); { // glVertex3f(_pos.x, _pos.y + .2, _pos.z); // glVertex3f(_pos.x, _pos.y - .2, _pos.z); for (unsigned i = 0; i < _tail.size(); i++) { float alpha = .8 * (_tail.size() - i) / _tail.size(); alpha*=alpha; glColor4f(alpha, .7, 1, alpha); STVector3 pos = _tail[i].pos; if (i + 1 < _tail.size() && !(_tail[i].pos == _tail[i+1].pos)) { STVector3 normal = STVector3::Cross(_tail[i].pos - _tail[i +1].pos, STVector3::eY); normal.Normalize(); glNormal3f(normal.x, normal.y, normal.z); } glVertex3f(pos.x, pos.y + _tail[i].min, pos.z); glVertex3f(pos.x, pos.y + _tail[i].max, pos.z); } } glEnd(); /* glColor4f(0, .8, 1, .8); glBegin(GL_LINES); { for (unsigned i = 0; i < 10; i++) { SAMPLE min = 0, max = 0; for (unsigned k = 0; k < 500; k++) { SAMPLE samp = _audio_loop->get_sample(i*500 + k); if (samp < min) min = samp; if (samp > max) max = samp; } glVertex3f(_pos.x + i/10.0, _pos.y + min / double(MAX_SAMPLE_VALUE), _pos.z); glVertex3f(_pos.x + i/10.0, _pos.y + max / double(MAX_SAMPLE_VALUE), _pos.z); } } glEnd(); */ }