/****************/ /* show_man.cpp */ /****************/ // Ohjelma, joka aukaisee yhden ikkunan ja piirtää siihen tikku-ukon // Esimerkki hiiren viesteistä ja animaatiosta /vl-96 // Projektiin vain tämä tiedosto. mfc 4.0 // Tehtäviä: // 1. Lisää kuvaan toinen ukko, joka myös näyttää missä hiiri on menossa // 2. Muuta ruumiinosat taulukoksi // 3. Lisää ukolle silmät, jotka "katsovat" hiiren suuntaan. // 4. Mieti miten voisit tehdä raajoihin ja "mahaan" niveliä, joiden // avulla ukkoon saadaan "luonnollisempaa" liikettä // #include #include #define TDC CDC #define TPoint CPoint double angle(const TPoint &p1,const TPoint &p2) { // Lasketaan suuntakulma pisteestä p1 pisteeseen p2 radiaaneissa double dx,dy; dx = p2.x - p1.x; dy = p2.y - p1.y; if ( dx || dy ) return atan2(-dy,dx); return 0; } double distance(const TPoint &p1,const TPoint &p2) { // Lasketaan pisteiden p1 ja p2 välinen etäisyys double dx,dy; dx = p2.x - p1.x; dy = p2.y - p1.y; return sqrt(dx*dx + dy*dy); } //------------------------------------------------------------------------------ class caBodyPart { // Ihmisen ruumiin osan abstrakti luokka protected: TPoint beg; // Ruumiinosan alkupiste int r; // Ruumiinosan "pituus" public: caBodyPart(const TPoint &org, int x, int y,int ir): beg(TPoint(org.x+x,org.y+y)), r(ir) {}; virtual void Draw(TDC &dc) const = 0; void DrawNot(TDC &dc) const { // Piirtää ruumiinosan siten, että joka dc.SaveDC(); // toinen kerta piirtää ja joka toinen dc.SetROP2(R2_NOT); // kerta pyyhkii pois Draw(dc); dc.RestoreDC(-1); // Huom! MFC:ssä Täytyy olla param. } }; //------------------------------------------------------------------------------ class cHead : public caBodyPart { // Luokka ihmisen päälle public: cHead(const TPoint &org, int x, int y,int ir): caBodyPart(org,x,y,ir) {} void Draw(TDC &dc) const { dc.Ellipse(beg.x-r,beg.y-2*r,beg.x+r,beg.y+0); } }; //------------------------------------------------------------------------------ class cLimb : public caBodyPart { // Raajan luokka double a; // Raajan suuntakulma radiaaneina TPoint End() const // Raajan päätepiste pisteenä { return TPoint(int(beg.x+r*cos(a)+0.5),int(beg.y-r*sin(a)+0.5));} public: cLimb(const TPoint &org, int x, int y,int ix2, int iy2): caBodyPart(org,x,y,distance(TPoint(x,y),TPoint(ix2,iy2))), a(angle(TPoint(x,y),TPoint(ix2,iy2))) {}; void Draw(TDC &dc) const { dc.MoveTo(beg); dc.LineTo(End()); } void ChangeDir(TDC &dc,const TPoint &pt) { DrawNot(dc); a = angle(beg,pt); DrawNot(dc); } }; //------------------------------------------------------------------------------ class cMan { // Ihminen kaula "keskipisteenä" TPoint origo; // Kaulan paikka cHead Head; cLimb Body; cLimb LeftHand; cLimb RightHand; cLimb LeftLeg; cLimb RightLeg; public: cMan(const TPoint &pt) : origo(pt), Head (pt, 0, 0, 20), Body (pt, 0, 0, 0,100), LeftHand (pt, 0, 10,-40, 80), RightHand(pt, 0, 10, 60,-40), LeftLeg (pt, 0,100,-40,180), RightLeg (pt, 0,100, 40,180) {} void Draw(TDC &dc) const { Head.Draw(dc); Body.Draw(dc); LeftHand.Draw(dc); RightHand.Draw(dc); LeftLeg.Draw(dc); RightLeg.Draw(dc); } void PointByHand(TDC &dc,const TPoint pt) { RightHand.ChangeDir(dc,pt); } }; //------------------------------------------------------------------------------ class CMainWindow : public CFrameWnd { TDC *pHoldDC; // Siirron aikana käytössä oleva laiteyhteys cMan Man; // Piirrettävä ukko public: CMainWindow() : Man(TPoint(60,80)) { pHoldDC = NULL; Create(NULL,"Show Man"); } afx_msg void OnPaint() { CPaintDC dc(this); Man.Draw(dc); } afx_msg void OnLButtonDown(UINT modKeys, TPoint point) { // Huom! EI &point if ( pHoldDC != NULL ) return; SetCapture(); // Direct all subsequent mouse input to this window pHoldDC = new CClientDC(this); Man.PointByHand(*pHoldDC,point); } afx_msg void OnLButtonUp(UINT modKeys, TPoint point) { if ( pHoldDC == NULL ) return; ReleaseCapture(); delete pHoldDC; pHoldDC = NULL; } afx_msg void OnMouseMove(UINT modKeys, TPoint point) { if ( pHoldDC == NULL ) return; Man.PointByHand(*pHoldDC,point); } DECLARE_MESSAGE_MAP() }; BEGIN_MESSAGE_MAP( CMainWindow, CFrameWnd ) ON_WM_PAINT() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_MOUSEMOVE() END_MESSAGE_MAP() //------------------------------------------------------------------------------ class CShowManApp : public CWinApp { public: virtual BOOL InitInstance() { m_pMainWnd = new CMainWindow(); m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } }; //------------------------------------------------------------------------------ CShowManApp ShowManApp; // constructor initializes and runs the app