#include "deathball.h" #include #include "types.h" #include "game.h" using namespace std; #define MOVE_SPEED 20 #define TURN_SPEED 30 double volume; DeathBall::DeathBall(FMOD::System* sound_sys) : _pos(0,0,0) , _dir(0,0,1) , _moving_forward(false) , _moving_backward(false) , _moving_left(false) , _moving_right(false) , _selected(NULL) , _pitch(0) , _yaw(-PI/2) , _sig_vol(0) , _fish_count(0) , _fish_clock(0) { _ball = new STShape("content/models/deathball_model.obj"); _wahwah_loop = new AudioLoop(sound_sys); _wahwah_loop->load_file("content/audio/bass_wahwah.wav"); _wahwah_loop->_volume = .1; _wahwah_loop->play(); _wahwah_loop->set_death_handle(this); } static void set_material() { GLfloat material_Ka[] = {0.5f, 0.0f, 0.0f, 1.0f}; GLfloat material_Kd[] = {0.4f, 0.4f, 0.5f, 1.0f}; GLfloat material_Ks[] = {0.8f, 0.8f, 0.0f, 1.0f}; ALPHA_HACK(.5); GLfloat material_Se = 20.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 DeathBall::render(double tick_time) { set_material(); if (_selected != NULL) { glDisable(GL_LIGHTING); Game::get_singleton()._shader->UnBind(); /* draw the selection box */ STVector3 sel_pos = _selected->_pos; STVector3 d = sel_pos - _pos; STVector3 left = STVector3::Cross(d, STVector3(0,1,0)); left.y = 0; left.Normalize(); glColor4f(0,1,0,1); glBegin(GL_LINE_STRIP); { glVertex3f(sel_pos.x+left.x, sel_pos.y-1, sel_pos.z+left.z); glVertex3f(sel_pos.x+left.x, sel_pos.y+1, sel_pos.z+left.z); glVertex3f(sel_pos.x-left.x, sel_pos.y+1, sel_pos.z-left.z); glVertex3f(sel_pos.x-left.x, sel_pos.y-1, sel_pos.z-left.z); glVertex3f(sel_pos.x+left.x, sel_pos.y-1, sel_pos.z+left.z); } glEnd(); Game::get_singleton()._shader->Bind(); glEnable(GL_LIGHTING); } glPushMatrix(); glTranslatef(_pos.x, _pos.y, _pos.z); glScalef(.5 + 2*_sig_vol, .5 + 2*_sig_vol, .5 + 2*_sig_vol); _ball->Draw(); glPopMatrix(); } void DeathBall::change_yaw(double dyaw) { dyaw *= TURN_SPEED * .01 * PI / 180; _yaw += dyaw; // cout << dir.x << ", " << dir.z << endl; } void DeathBall::change_pitch(double dpitch) { dpitch *= TURN_SPEED * .01 * PI / 180; _pitch += dpitch; if (_pitch < -PI/4) _pitch = -PI/4; if (_pitch > PI/3) _pitch = PI/3; // cout << dir.x << ", " << dir.z << endl; } void DeathBall::update_dir() { double r = cos(_pitch); double y = -sin(_pitch); double x = r * cos(_yaw); double z = r * -sin(_yaw); _dir.x = x; _dir.y = y; _dir.z = z; // double r = sqrt(_dir.x * _dir.x + _dir.z * _dir.z); // double theta = atan2(_dir.z, _dir.x); // // double newr = cos(dpitch) * r + sin(dpitch) * _dir.y; // double newy = cos(dpitch) * _dir.y - sin(dpitch) * r; // // _dir.x = newr * sin(theta); // _dir.y = newy; // _dir.z = newr * cos(theta); } void DeathBall::update(double tick_time) { _fish_clock += tick_time; if (_fish_clock > 1) { _fish_clock = 0; decrement_fish(); } for (int i = -tick_time * SAMPLE_RATE; i < 0; i++) { _sig_vol = _sig_vol * .9999 + abs(_wahwah_loop->get_sample(i))/double(MAX_SAMPLE_VALUE) * .0001; } update_dir(); STVector3 d = _dir; d.y = 0; d.Normalize(); STVector3 left = STVector3::Cross(d, STVector3(0,1,0)); // back and forth motion bool positive = STVector3::Dot(_vel, d) > 0; if (_moving_forward) { if (positive) { _vel += MOVE_SPEED * d * tick_time; } else { _vel += 3 * MOVE_SPEED * d * tick_time; } } else if (_moving_backward) { if (positive) { _vel -= 3 * MOVE_SPEED * d * tick_time; } else { _vel -= MOVE_SPEED * d * tick_time; } } else { if (positive) { _vel -= 2 * MOVE_SPEED * d * tick_time; if (STVector3::Dot(_vel, d) < 0) _vel = left * STVector3::Dot(_vel, left); } else { _vel += 2 * MOVE_SPEED * d * tick_time; if (STVector3::Dot(_vel, d) > 0) _vel = left * STVector3::Dot(_vel, left); } } // side-to-side motion positive = STVector3::Dot(_vel, left) > 0; if (_moving_left) { if (positive) { _vel += MOVE_SPEED * left * tick_time; } else { _vel += 3 * MOVE_SPEED * left * tick_time; } } else if (_moving_right) { if (positive) { _vel -= 3 * MOVE_SPEED * left * tick_time; } else { _vel -= MOVE_SPEED * left * tick_time; } } else { if (positive) { _vel -= 2 * MOVE_SPEED * left * tick_time; if (STVector3::Dot(_vel, left) < 0) _vel = d * STVector3::Dot(_vel, d); } else { _vel += 2 * MOVE_SPEED * left * tick_time; if (STVector3::Dot(_vel, left) > 0) _vel = d * STVector3::Dot(_vel, d); } } if (_vel.Length() > MOVE_SPEED) { _vel = _vel / _vel.Length() * MOVE_SPEED; } _pos += _vel * tick_time; _wahwah_loop->set_3D(_pos, _vel); // GLfloat material_Ka[] = {0.5f*volume, 0.0f, 0.0f, 1.0f}; // GLfloat material_Kd[] = {0.4f*volume, 0.4f*volume, 0.5f*volume, 1.0f}; // GLfloat material_Ks[] = {0.8f*volume, 0.8f*volume, 0.0f, 1.0f}; // GLfloat material_Ke[] = {0.1f*volume, 0.0f*volume, 0.0f, 0.0f}; // GLfloat material_Se = 20.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); // glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, material_Ke); // glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material_Se); } void DeathBall::select(GravityBall* g_ball) { _selected = g_ball; } void DeathBall::distort_handle(SAMPLE* mono16bitbuffer, unsigned int n_samples) { // double result = 0; // if (_selected != NULL) { // for (unsigned k = 0; k < n_samples; k++) { // mono16bitbuffer[k] = mono16bitbuffer[k] / double(MAX_SAMPLE_VALUE) * (_selected->_audio_loop->get_sample(k)); // result += mono16bitbuffer[k] / double(MAX_SAMPLE_VALUE); // //mono16bitbuffer[k] = pow(mono16bitbuffer[k] / double(MAX_SAMPLE_VALUE), 2) * MAX_SAMPLE_VALUE; // } // } // for (unsigned k = 0; k < n_samples; k++) { // result += abs(mono16bitbuffer[k]) / double(MAX_SAMPLE_VALUE); // } // result /= n_samples; // volume = result; // volume *= 10; // volume = pow(volume, .5); //cout << mono16bitbuffer[0] << endl; //mono16bitbuffer[0] = MAX_SAMPLE_VALUE; //mono16bitbuffer[1] = -MAX_SAMPLE_VALUE; } void DeathBall::kill() { if ( _selected != NULL) { _selected->explode(); } } void DeathBall::hurt() { if ( _selected != NULL) { _selected->corrupt(); } } void DeathBall::increment_fish() { _fish_count++; cout << _fish_count << endl; _wahwah_loop->_volume = .1 * log(_fish_count+2); } void DeathBall::decrement_fish() { _fish_count--; if (_fish_count < 0) _fish_count = 0; cout << _fish_count << endl; _wahwah_loop->_volume = .1 * log(_fish_count+2); }