//Handle mouse input void mouse(int mouseButton, int buttonState, int x, int y) { GLfloat mouseX,mouseY; screenToWorld(x,y,mouseX,mouseY); Point mousePt(mouseX,mouseY,0); if(sb->getResetButton().pointInButton(mousePt) && buttonState == GLUT_DOWN) //did user click on reset button { sb->getResetButton().setButtonIsPressed(true); return; } if(sb->getResetButton().pointInButton(mousePt) && sb->getResetButton().isButtonPressed() && buttonState == GLUT_UP) //did user click on reset button { initGame(); initStartupScript(); return; } sb->getResetButton().setButtonIsPressed(false); if (gameStatus!= IN_PLAY) return; if( mouseButton == GLUT_LEFT_BUTTON && buttonState == GLUT_DOWN) { gamePiece tmp = player1Turn?player1GamePiece:player2GamePiece; Move m= getSlotFromPoint(mousePt); makeMove(m ,tmp); } glutPostRedisplay(); }
//-------------------------------------------------------------- void testApp::keyPressed(int key) { if(key == ' ') { if(bullets.size() < maxBullets) { bFire = true; Bullet b; // the two points for the mouse and gun ofVec2f gunPt(ofGetWidth()/2, ofGetHeight()-20); ofVec2f mousePt(ofGetMouseX(), ofGetMouseY()); // the vector between the two ofVec2f vec = mousePt - gunPt; // normalize = 0.0 - 1.0 vec.normalize(); // bullet position = the start pos of the gun // and the vec scaled by 100 ofVec2f bulletPos = gunPt + (vec * 100); b.pos = bulletPos; b.vel = vec * ofRandom(9, 12); // randomly make it faster b.bRemove = false; // add the bullets to the array bullets.push_back(b); } } }
//-------------------------------------------------------------- void testApp::update(){ if(recording){ //we are going to be smart! //we don't want to record a point unless it is at least 2 pixels away from our previous point! ofxVec2f mousePt(mouseX, mouseY); //find the distance between our mouse and our previous point ofxVec2f dist = mousePt - prevPoint; if( dist.length() > 2 ){ //add the point in. ptsList.push_back( mousePt ); //lets store the current position prevPoint.set(mousePt); } }else{ //if we are not recording we are playing back //playPos goes from 0.0 - 1.0 //when we draw we scale up that number by the number of pts in the list //so it will draw from point 0 up to a certain percentage of the total points. playPos += 0.01; if(playPos > 2.0){ playPos = 0; } } }
bool TwWindow::onWinMessage( UINT msg, WPARAM w, LPARAM l, LRESULT& r ) { TW_UNUSED(msg); TW_UNUSED(w); TW_UNUSED(l); TW_UNUSED(r); switch (msg) { case WM_GETMINMAXINFO: { TwSize<int> preferredSize = this->preferredSize(); if (preferredSize.width() > m_maxSize.width()) { preferredSize.setWidth(m_maxSize.width()); } if (preferredSize.height() > m_maxSize.height()) { preferredSize.setHeight(m_maxSize.height()); } MINMAXINFO* minmaxInfo = (MINMAXINFO*)l; minmaxInfo->ptMinTrackSize.x = preferredSize.width(); minmaxInfo->ptMinTrackSize.y = preferredSize.height(); minmaxInfo->ptMaxTrackSize.x = m_maxSize.width(); minmaxInfo->ptMaxTrackSize.y = m_maxSize.height(); r = 0; return true; } case WM_SETCURSOR: { if (LOWORD(l) == HTCLIENT) { POINT pt; GetCursorPos(&pt); TwPoint<int> mousePt(pt.x, pt.y); TwWidget* w = m_rootWidget->eventHandlerFromPoint(mapFromScreenToClient(mousePt)); if (w && w->isEnabled()) { HCURSOR cursorHandle = WindowsCursorS::windowsCursors()->getWindowsCursor(w->cursor().cursorType())->cursorHandle(); ::SetCursor(cursorHandle); r = 1; return true; } } } break; default: break; } return false; }
LRESULT JHCEdit::OnContextMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) { UINT cmd; CPoint mousePt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); DWORD sel = GetSel(); this->SetFocus(); SetCCMenuGutter(FALSE); conMenu.CreatePopupMenu(); if (this->GetStyle() & ES_READONLY) { conMenu.AppendMenu(((LOWORD(sel) == HIWORD(sel))? MF_GRAYED : MF_ENABLED), WM_COPY, _T("Copy")); } else { conMenu.AppendMenu(((LOWORD(sel) == HIWORD(sel))? MF_GRAYED : MF_ENABLED), WM_CUT, _T("Cut")); conMenu.AppendMenu(((LOWORD(sel) == HIWORD(sel))? MF_GRAYED : MF_ENABLED), WM_COPY, _T("Copy")); conMenu.AppendMenu(((::IsClipboardFormatAvailable(CF_TEXT) || ::IsClipboardFormatAvailable(CF_UNICODETEXT))? MF_ENABLED : MF_GRAYED), WM_PASTE, _T("Paste")); conMenu.AppendMenu(((LOWORD(sel) == HIWORD(sel))? MF_GRAYED : MF_ENABLED), WM_CLEAR, _T("Delete")); } this->SendMessage((HWND)this->GetTopLevelParent(), WM_CONTEXTMENU, (WPARAM)conMenu.m_hMenu, (LPARAM)sel); cmd = conMenu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD, mousePt.x, mousePt.y, m_hWnd); conMenu.DestroyMenu(); switch (cmd) { case WM_CUT: case WM_COPY: case WM_PASTE: case WM_CLEAR: this->SendMessage(cmd, 0, -1); break; default: this->SendMessage((HWND)this->GetTopLevelParent(), WM_COMMAND, (WPARAM)cmd, 0); break; } return 0; }
//-------------------------------------------------------------- void oilWaterNode::updateActive(){ //TODO: Figure put when particles are not on screen //IF NONE OUR - PAUSE THE UPDATING OF PARTICLES //TODO: AVOID [] operator - for each create a reference and work with that //8% CPU!!! //TODO: fabs using 2% CPU //for particle vs particle each particle needs to check itself against every other particle //this is very slow as for 10 particles you have 100 calculations for 100 particles you have 10,000 calculations //it is called an n-squared problem //so we try to be smart - we sort our vector of particles by X //so they go in order from smallest x pos to largest pos. //we then will check the difference in x pos between our particle and the one to be checked if it is greater than a certain amount we can stop checking all other particles //as we know that they will be getting further and further away from us sort(balls.begin(), balls.end(), xSort); //lets create some vars here which we will use a lot in the loop float ppDist; float frcPct; ofVec2f repulsionAmnt; ofVec2f deltaVec; bool soundFired = false; //we will work with squared values as much as possible - as the sqrt in ofVec2f::length() is slow float repulsionDistTmp = repulsionDist; float repulsionDistSquared = repulsionDist*repulsionDist; float ppDistSquared; float maxVel = 8.0; //OUR REPEL POINT ofVec2f mousePt(myPerson.pos.x, myPerson.pos.y); if( bRise ){ mousePt.y += 100.0; }else{ mousePt.y -= 100.0; } //NOTE: this is a performance hack - don't update particles that are far from the person float vDistToPerson; int frameNo = ofGetFrameNum(); for(int i = 0; i < balls.size(); i++){ oilParticle & pI = balls[i]; //NOTE: this is a performance hack - don't update particles that are far from the person vDistToPerson = fabs(pI.pos.y - myPerson.pos.y); if( vDistToPerson > ofGetHeight() && frameNo % 4 != 0 )continue; // if( pI.type ){ ofVec2f delta = pos - pI.pos; pI.vel += delta.normalized() * 0.35; // }else{ // ofVec2f delta = ofPoint(ofGetWidth()/2, 50 + ofGetHeight()/2) - pI.pos; // pI.vel += delta.normalized() * 0.05; // } for(int j = i; j >= 0; j--){ //check 1 -- we shouldn't check against ourself if( j == i )continue; oilParticle & pJ = balls[j]; repulsionDistTmp = MAX(repulsionDist, 1.6 * (pI.radius + pJ.radius)); repulsionDistSquared = repulsionDistTmp*repulsionDistTmp; //check 2 -- once the x distance between us and the particle we are checking is greater than our repel distance we can stop checking all other particles //we can do this because the particles are sorted by x - so the next particle will be even further away. if( fabs( pJ.pos.x - pI.pos.x ) > repulsionDistTmp ){ break; //this means stop the current loop we are in } //check 3 -- we can also see if the difference in y is greater than our repulsion dist and if so skip the check if( fabs( pJ.pos.y - pI.pos.y ) > repulsionDistTmp ){ continue; } deltaVec = pJ.pos - pI.pos; ppDistSquared = deltaVec.lengthSquared(); if( pI.type != (int)bRise && pJ.type != (int)bRise ){ ppDistSquared *= 3.5; } //check 3 -- we check the squared distances as this is much faster than calling square root if( ppDistSquared <= repulsionDistSquared ){ //now we sqrt it as we know it will be needed ppDist = sqrt(ppDistSquared); //make the repulsion force get stronger as the particles get closer frcPct = 1.0 - (ppDist/repulsionDistTmp); if( pI.type && !pJ.type ){ repulsionAmnt = deltaVec.normalized() * frcPct * repulsionForce; ofPoint force; ofVec2f angVec; angVec = repulsionAmnt; float angle = angVec.angle(pI.vel); if( angle < 0 ){ force.set(repulsionAmnt.y * 0.5 + repulsionAmnt.x* 0.5, -repulsionAmnt.x * 0.5 + repulsionAmnt.y * 0.5); }else{ force.set(-repulsionAmnt.y * 0.5 + repulsionAmnt.x* 0.5, repulsionAmnt.x * 0.5 + repulsionAmnt.y * 0.5); } if( fabs(myPerson.pos.y - pI.pos.y) < 500 && ofGetElapsedTimef() - lastTimeTriggered > ofRandom(0.06, 0.23) ){ // if( ofRandom(0, 200) > 100 ){ // globalSnd.play("OIL_1", ofRandom(0.2, 0.7), 1.0, ofRandom(-0.6, 0.6)); // }else{ float volPct = ofMap(fabs(myPerson.pos.y - pI.pos.y), 200, ofGetHeight(), 1.0, 0.0, true); globalSnd.play("OIL_WATER_COLLISION", ofRandom(0.2, 0.7) * volPct, ofRandom(0.4, 1.8), ofRandom(-0.6, 0.6)); // } lastTimeTriggered = ofGetElapsedTimef(); } //no we apply the force to the two particles being checked - they will have opposite forces so one will be positive and one will be negative. pI.vel -= force * 1.2; pJ.vel += repulsionAmnt*1.2; }else{ repulsionAmnt = deltaVec.normalized() * frcPct * repulsionForce; //no we apply the force to the two particles being checked - they will have opposite forces so one will be positive and one will be negative. pI.vel -= repulsionAmnt; pJ.vel += repulsionAmnt; } } } //POINT REPULSION //for each particle lets look at the distance between it and the mouse //if the distance is less than a certain amount lets add a repulsive force that gets stronger with proximity ofVec2f distVec = mousePt - pI.pos; //to know how close we are to the particle we need the straight line distance - or the length of the distVec vector float straightDist = distVec.length(); float repelDist = 240.0; int curType = 0; if( myPerson.vel.y < 0 ){ curType = 1; } if( straightDist < repelDist && pI.type == curType){ //get the dist as a 0-1 value float pct = straightDist/repelDist; // //so we make a value for the amount of force to apply // //we make this inverse to the distance between the mouse and the ball // //ie: smaller the distance = greater the force float repulsionStrength = (1.0 - pct) * 2.6; // // if( straightDist < 16.0 ){ // globalSnd.play("OIL_WATER_COLLISION_WITH_PERSON", ofRandom(0.1, 0.6), ofRandom(0.4, 1.8), ofRandom(-0.4, 0.4)); // } //we now need a vector that describes the direction to move in. //because we want to move AWAY from the mouse we can just take the distVec and make it negative //we want it normalized so we can apply strength to it ofVec2f repulVec = -distVec.normalized(); float repelX = repulVec.x * repulsionStrength * 0.35; float repelY = repulVec.y * repulsionStrength; //finaly add the force to our balls velocity; pI.vel.x += repelX; pI.vel.y += repelY; } if( pI.vel.lengthSquared() > maxVel*maxVel ){ pI.vel.normalize(); pI.vel *= maxVel; } if( pI.type == 1 && bRise ){ pI.extraScale = 1.2; }else{ pI.extraScale = 1.0; } if( pI.type == 0 && !bRise ){ pI.extraScale = 1.2; }else{ pI.extraScale = 1.0; } pI.update(); } }