void DragSprite::Update(float deltaTime) { if(mVisible) { float x = Input_GetMouseScreenX(); float y = Input_GetMouseScreenY(); if(Input_IsMouseDown(Mouse::LBUTTON) && x - mPosition.x > 176 && y - mPosition.y < 16) { mVisible = false; } // Draggable Inventory else if(Input_IsMouseDown(Mouse::LBUTTON) && (x > mPosition.x && x < mPosition.x + mSprite.GetWidth() - 20) && (y > mPosition.y && y < mPosition.y + 30)) { mDragDown = true; } if(!Input_IsMouseDown(Mouse::LBUTTON) && mDragDown) { mDragDown = false; } if(mDragDown) { mPosition = SVector2(x - 75, y - 20); mSprite.Update(deltaTime); } } }
for_each( TGUINode, node, gGUINodeList ) { if( GUI_IsNodeVisible( node ) ) { TVector2 absPos = GUI_GetNodeAbsolutePosition( node ); // render and update rectangles if( node->rect ) { TGUIRect * pRect = node->rect; Renderer_BindTexture( pRect->tex, 0 ); Renderer_RenderRect( absPos.x, absPos.y, absPos.x + pRect->w, absPos.y + pRect->h, node->color ); // render and update texts } else if( node->text ) { TGUIText * pText = node->text; Renderer_BindTexture( pText->font->atlas, 0 ); int caretX = absPos.x; int caretY = absPos.y; int length = strlen( pText->text ); if( pText->textAlign == GUITA_MIDDLE ) { caretX += (pText->fieldWidth - pText->width) / 2; caretY += (pText->fieldHeight - pText->font->size ) / 4; } int nextWordPosition = -1; // for wordbreak for( int i = 0; i < length; i++ ) { unsigned char symbol = pText->text[i]; TCharMetrics * symbolMetrics = &pText->font->charMetrics[symbol]; // handle wordbreak int wordWidth = 0; if( pText->wordBreak ) { if( i >= nextWordPosition ) { int wordBegin = -1; int wordEnd = -1; bool wordFound = false; int j = i; for( ; j < length; j++ ) { if( isalpha( (unsigned int)pText->text[j] )) { if( wordBegin < 0 ) { wordBegin = j; wordFound = true; } } else { if( wordFound ) { wordEnd = j; break; } } } if( wordFound ) { if( wordEnd < 0 ) { wordEnd = j; } nextWordPosition = wordEnd; } if( wordFound && (wordBegin >= 0) && (wordEnd > 0)) { for( int k = wordBegin; k < wordEnd; k++ ){ wordWidth += pText->font->charMetrics[(unsigned int)pText->text[k]].advanceX; } wordFound = -1; wordEnd = -1; wordFound = false; if( caretX + wordWidth > absPos.x + pText->fieldWidth ) { caretX = absPos.x; caretY += pText->font->size; } } } } if( symbol != '\n' && symbol != '\t' ) { TGlyphRenderInfo ri; ri.x = caretX + symbolMetrics->bitmapLeft; ri.y = caretY - symbolMetrics->bitmapTop + pText->font->size; ri.w = pText->font->size; ri.h = pText->font->size; memcpy( ri.texCoords, symbolMetrics->texCoords, sizeof( TTexCoord ) * 4 ); ri.color = node->color; Renderer_RenderGlyph( &ri ); caretX += symbolMetrics->advanceX; } else if( symbol == '\t' ) { // four space indentation caretX += pText->font->charMetrics[(unsigned int)' '].advanceX * 4; } if( (caretX > absPos.x + pText->fieldWidth) || symbol == '\n' ) { caretX = absPos.x; caretY += pText->font->size; } } // render and update buttons } else if( node->button ) { TGUIButton * button = node->button; TGUIRect * background = button->background->rect; button->background->color = button->normalColor; if( GUI_MouseInsideRectangle( absPos.x, absPos.y, background->w, background->h )) { button->background->color = button->pickedColor; if( Input_IsMouseDown( MB_Left )) { button->background->color = button->pressedColor; // execute events if( button->OnClick ){ button->OnClick(); } } } // update slider } else if( node->slider ) { TGUISlider * slider = node->slider; TGUIRect * sliderRect = slider->slider->rect; TVector2 sliderRectAbsPos = GUI_GetNodeAbsolutePosition( slider->slider ); if( GUI_MouseInsideRectangle( sliderRectAbsPos.x , sliderRectAbsPos.y, sliderRect->w, sliderRect->h )) { if( Input_IsMouseDown( MB_Left )) { sliderRect->x = Input_GetMouseX() - absPos.x - sliderRect->w / 2; if( sliderRect->x < 0 ){ sliderRect->x = 0; } if( sliderRect->x > slider->background->rect->w - sliderRect->w ) { sliderRect->x = slider->background->rect->w - sliderRect->w; } slider->value = ((float)sliderRect->x / (float)slider->background->rect->w) * ( slider->maxValue - slider->minValue ); if( slider->OnValueChanged ) { slider->OnValueChanged( slider->value ); } } } } } }
void Player_Update( float timeStep ) { if( player ) { TVec3 vAxis = Vec3_Set( 0.0f, 1.0f, 0.0f ); // get correct vectors for moving TVec3 look = Entity_GetLookVector( player->pivot ); TVec3 right = Entity_GetRightVector( player->pivot ); TVec3 listenerPosition = Entity_GetGlobalPosition( player->cameraPivot ); Lightprobe_LightEntity( player->weapon->model ); player->onGround = false; for( int i = 0; i < player->body.contactCount; i++ ) { TContact * contact = &player->body.contacts[i]; // check angle between contact normal and vertical axis, it must be less than 60 degrees if( Vec3_Angle( vAxis, contact->normal ) < M_PI / 3.0 ) { player->onGround = true; } } // ==================== // moving player->destVelocity = Vec3_Zero(); player->move = false; if( Input_IsKeyDown( KEY_W )) { player->destVelocity = Vec3_Add( player->destVelocity, look ); player->move = true; } if( Input_IsKeyDown( KEY_S )) { player->destVelocity = Vec3_Sub( player->destVelocity, look ); player->move = true; } if( Input_IsKeyDown( KEY_A )) { player->destVelocity = Vec3_Add( player->destVelocity, right ); player->move = true; } if( Input_IsKeyDown( KEY_D )) { player->destVelocity = Vec3_Sub( player->destVelocity, right ); player->move = true; } if( Input_IsKeyDown( KEY_C ) ) { player->crouch = true; if( player->body.shape->sphereRadius > player->crouchRadius ) { player->body.shape->sphereRadius -= 0.05f; } else { player->body.shape->sphereRadius = player->crouchRadius; } } else { player->crouch = false; char standUp = 1; // before stand up, we must trace ray up on player's head, to ensure, that // there enough space to stand up. TVec3 end = Vec3_Set( player->body.position.x, player->body.position.y + 1.0f, player->body.position.z ); TRay headRay = Ray_Set( player->body.position, end ); TRayTraceResult out; Ray_TraceWorldStatic( &headRay, &out ); if( out.body ) { float maxRadius = player->shape.sphereRadius + 0.4f; if( Vec3_SqrDistance( out.position, player->body.position ) < maxRadius * maxRadius ) { standUp = 0; player->crouch = true; } } if( standUp ) { if( player->body.shape->sphereRadius < player->standRadius ) { player->body.shape->sphereRadius += 0.04f; } else { player->body.shape->sphereRadius = player->standRadius; } } } // sync step sound position with player position for( int i = 0; i < player->stepSoundGroup->count; i++ ) { SoundSource_SetPosition( &player->stepSoundGroup->sounds[i], &listenerPosition ); if( player->crouch ) { SoundSource_SetVolume( &player->stepSoundGroup->sounds[i], 0.5f ); } else { SoundSource_SetVolume( &player->stepSoundGroup->sounds[i], 1.0f ); } } // emit step sound only if got contact with the ground if( player->body.contactCount > 0 ) { TContact * lowestContact = &player->body.contacts[0]; for( int i = 0; i < player->body.contactCount; i++ ) { if( player->body.contacts[i].position.y < lowestContact->position.y ) { lowestContact = &player->body.contacts[i]; } } // select emittable sounds if( lowestContact->triangle ) { // iterate over all possible step sound groups for( int i = 0; i < STEP_GROUP_COUNT; i++ ) { // iterate over each material in group for( int j = 0; j < player->stepSounds[i].materialCount; j++ ) { if( lowestContact->triangle->material == player->stepSounds[i].material[j] ) { player->stepSoundGroup = &player->stepSounds[i]; } } } } if( player->pathLength > 15 * player->speed ) { int randomSound = rand() % player->stepSoundGroup->count; if( randomSound >= 4 ) { randomSound = 3; } SoundSource_Play( &player->stepSoundGroup->sounds[ randomSound ] ); player->pathLength = 0.0f; } } float realSpeed = player->speed; player->run = false; if( Input_IsKeyDown( KEY_LeftShift ) && !player->crouch ) { realSpeed *= player->speedMultiplier; player->run = true; } if( player->crouch ) { realSpeed *= 0.65f; } if( player->move ) { // prevent divide by zero player->destVelocity = Vec3_Normalize( player->destVelocity ); player->pathLength += realSpeed * 0.5f; } float interpCoeff = 0.25f; if( !player->onGround ) { interpCoeff = 0.0035f; } player->destVelocity.x *= realSpeed; player->destVelocity.z *= realSpeed; player->velocity.x += ( player->destVelocity.x - player->velocity.x ) * interpCoeff; player->velocity.z += ( player->destVelocity.z - player->velocity.z ) * interpCoeff; // do not overwrite gravity component (y), apply only x and z player->body.linearVelocity.x = player->velocity.x * timeStep; player->body.linearVelocity.z = player->velocity.z * timeStep; // ==================== // jump if( Input_IsKeyHit( KEY_Space ) ) { if( player->onGround ) { player->body.linearVelocity.y += player->jumpStrength; } } // sync pivot's position with physical body player->pivot->localPosition = player->body.position; // ==================== // mouse look player->yaw -= Input_GetMouseXSpeed() * player->mouseSensivity * timeStep; player->pitch += Input_GetMouseYSpeed() * player->mouseSensivity * timeStep; // clamp pitch if( player->pitch > player->maxPitch ) { player->pitch = player->maxPitch; } if( player->pitch < -player->maxPitch ) { player->pitch = -player->maxPitch; } right = Vec3_Set( 1, 0, 0 ); vAxis = Vec3_Set( 0, 1, 0 ); player->pivot->localRotation = Quaternion_SetAxisAngle( vAxis, player->yaw ); player->cameraPivot->localRotation = Quaternion_SetAxisAngle( right, player->pitch ); // sound TVec3 up = Entity_GetUpVector( player->cameraPivot ); SoundListener_SetPosition( &listenerPosition ); SoundListener_SetOrientation( &look, &up ); // weapon Weapon_Update( player->weapon ); if( Input_IsMouseDown( MB_Left )) { Weapon_Shoot( player->weapon ); } player->weapon->moveSpeed = player->body.linearVelocity; Player_CameraShake( ); } }