📄 q3canvas.cpp
字号:
{ if (y != (bool)ani) { ani = (uint)y; if (y) { cnv->addAnimation(this); } else { cnv->removeAnimation(this); } }}/*! \fn void Q3CanvasItem::setXVelocity(double vx) Sets the horizontal component of the canvas item's velocity to \a vx. \sa setYVelocity() setVelocity()*//*! \fn void Q3CanvasItem::setYVelocity(double vy) Sets the vertical component of the canvas item's velocity to \a vy. \sa setXVelocity() setVelocity()*//*! Sets the canvas item to be in motion, moving by \a vx and \a vy pixels in the horizontal and vertical directions respectively. \sa advance() setXVelocity() setYVelocity()*/void Q3CanvasItem::setVelocity(double vx, double vy){ if (ext || vx!=0.0 || vy!=0.0) { if (!ani) setAnimated(true); extra().vx = vx; extra().vy = vy; }}/*! Returns the horizontal velocity component of the canvas item.*/double Q3CanvasItem::xVelocity() const{ return ext ? ext->vx : 0;}/*! Returns the vertical velocity component of the canvas item.*/double Q3CanvasItem::yVelocity() const{ return ext ? ext->vy : 0;}/*! The default implementation moves the canvas item, if it is animated(), by the preset velocity if \a phase is 1, and does nothing if \a phase is 0. Note that if you reimplement this function, the reimplementation must not change the canvas in any way, for example it must not add or remove items. \sa Q3Canvas::advance() setVelocity()*/void Q3CanvasItem::advance(int phase){ if (ext && phase==1) moveBy(ext->vx,ext->vy);}/*! \fn void Q3CanvasItem::draw(QPainter& painter) This abstract virtual function draws the canvas item using \a painter.*//*! Sets the Q3Canvas upon which the canvas item is to be drawn to \a c. \sa canvas()*/void Q3CanvasItem::setCanvas(Q3Canvas* c){ bool v=isVisible(); setVisible(false); if (cnv) { if (ext) cnv->removeAnimation(this); cnv->removeItem(this); } cnv=c; if (cnv) { cnv->addItem(this); if (ext) cnv->addAnimation(this); } setVisible(v);}/*! \fn Q3Canvas* Q3CanvasItem::canvas() const Returns the canvas containing the canvas item.*//*! Shorthand for setVisible(true). */void Q3CanvasItem::show(){ setVisible(true);}/*! Shorthand for setVisible(false). */void Q3CanvasItem::hide(){ setVisible(false);}/*! Makes the canvas item visible if \a yes is true, or invisible if \a yes is false. The change takes effect when Q3Canvas::update() is next called.*/void Q3CanvasItem::setVisible(bool yes){ if ((bool)vis!=yes) { if (yes) { vis=(uint)yes; addToChunks(); } else { removeFromChunks(); vis=(uint)yes; } }}/*! \obsolete \fn bool Q3CanvasItem::visible() const Use isVisible() instead.*//*! \fn bool Q3CanvasItem::isVisible() const Returns true if the canvas item is visible; otherwise returns false. Note that in this context true does \e not mean that the canvas item is currently in a view, merely that if a view is showing the area where the canvas item is positioned, and the item is not obscured by items with higher z values, and the view is not obscured by overlaying windows, it would be visible. \sa setVisible(), z()*//*! \obsolete \fn bool Q3CanvasItem::selected() const Use isSelected() instead.*//*! \fn bool Q3CanvasItem::isSelected() const Returns true if the canvas item is selected; otherwise returns false.*//*! Sets the selected flag of the item to \a yes. If this changes the item's selected state the item will be redrawn when Q3Canvas::update() is next called. The Q3Canvas, Q3CanvasItem and the Qt-supplied Q3CanvasItem subclasses do not make use of this value. The setSelected() function is supplied because many applications need it, but it is up to you how you use the isSelected() value.*/void Q3CanvasItem::setSelected(bool yes){ if ((bool)sel!=yes) { sel=(uint)yes; changeChunks(); }}/*! \obsolete \fn bool Q3CanvasItem::enabled() const Use isEnabled() instead.*//*! \fn bool Q3CanvasItem::isEnabled() const Returns true if the Q3CanvasItem is enabled; otherwise returns false.*//*! Sets the enabled flag of the item to \a yes. If this changes the item's enabled state the item will be redrawn when Q3Canvas::update() is next called. The Q3Canvas, Q3CanvasItem and the Qt-supplied Q3CanvasItem subclasses do not make use of this value. The setEnabled() function is supplied because many applications need it, but it is up to you how you use the isEnabled() value.*/void Q3CanvasItem::setEnabled(bool yes){ if (ena!=(uint)yes) { ena=(uint)yes; changeChunks(); }}/*! \obsolete \fn bool Q3CanvasItem::active() const Use isActive() instead.*//*! \fn bool Q3CanvasItem::isActive() const Returns true if the Q3CanvasItem is active; otherwise returns false.*//*! Sets the active flag of the item to \a yes. If this changes the item's active state the item will be redrawn when Q3Canvas::update() is next called. The Q3Canvas, Q3CanvasItem and the Qt-supplied Q3CanvasItem subclasses do not make use of this value. The setActive() function is supplied because many applications need it, but it is up to you how you use the isActive() value.*/void Q3CanvasItem::setActive(bool yes){ if (act!=(uint)yes) { act=(uint)yes; changeChunks(); }}bool qt_testCollision(const Q3CanvasSprite* s1, const Q3CanvasSprite* s2){ const QImage* s2image = s2->imageAdvanced()->collision_mask; QRect s2area = s2->boundingRectAdvanced(); QRect cyourarea(s2area.x(),s2area.y(), s2area.width(),s2area.height()); QImage* s1image=s1->imageAdvanced()->collision_mask; QRect s1area = s1->boundingRectAdvanced(); QRect ourarea = s1area.intersected(cyourarea); if (ourarea.isEmpty()) return false; int x2=ourarea.x()-cyourarea.x(); int y2=ourarea.y()-cyourarea.y(); int x1=ourarea.x()-s1area.x(); int y1=ourarea.y()-s1area.y(); int w=ourarea.width(); int h=ourarea.height(); if (!s2image) { if (!s1image) return w>0 && h>0; // swap everything around int t; t=x1; x1=x2; x2=t; t=y1; x1=y2; y2=t; s2image = s1image; s1image = 0; } // s2image != 0 // A non-linear search may be more efficient. // Perhaps spiralling out from the center, or a simpler // vertical expansion from the centreline. // We assume that sprite masks don't have // different bit orders. // // Q_ASSERT(s1image->bitOrder()==s2image->bitOrder()); if (s1image) { if (s1image->bitOrder() == QImage::LittleEndian) { for (int j=0; j<h; j++) { uchar* ml = s1image->scanLine(y1+j); const uchar* yl = s2image->scanLine(y2+j); for (int i=0; i<w; i++) { if (*(yl + ((x2+i) >> 3)) & (1 << ((x2+i) & 7)) && *(ml + ((x1+i) >> 3)) & (1 << ((x1+i) & 7))) { return true; } } } } else { for (int j=0; j<h; j++) { uchar* ml = s1image->scanLine(y1+j); const uchar* yl = s2image->scanLine(y2+j); for (int i=0; i<w; i++) { if (*(yl + ((x2+i) >> 3)) & (1 << (7-((x2+i) & 7))) && *(ml + ((x1+i) >> 3)) & (1 << (7-((x1+i) & 7)))) { return true; } } } } } else { if (s2image->bitOrder() == QImage::LittleEndian) { for (int j=0; j<h; j++) { const uchar* yl = s2image->scanLine(y2+j); for (int i=0; i<w; i++) { if (*(yl + ((x2+i) >> 3)) & (1 << ((x2+i) & 7))) { return true; } } } } else { for (int j=0; j<h; j++) { const uchar* yl = s2image->scanLine(y2+j); for (int i=0; i<w; i++) { if (*(yl + ((x2+i) >> 3)) & (1 << (7-((x2+i) & 7)))) { return true; } } } } } return false;}static bool collision_double_dispatch(const Q3CanvasSprite* s1, const Q3CanvasPolygonalItem* p1, const Q3CanvasRectangle* r1, const Q3CanvasEllipse* e1, const Q3CanvasText* t1, const Q3CanvasSprite* s2, const Q3CanvasPolygonalItem* p2, const Q3CanvasRectangle* r2, const Q3CanvasEllipse* e2, const Q3CanvasText* t2){ const Q3CanvasItem* i1 = s1 ? (const Q3CanvasItem*)s1 : p1 ? (const Q3CanvasItem*)p1 : r1 ? (const Q3CanvasItem*)r1 : e1 ? (const Q3CanvasItem*)e1 : (const Q3CanvasItem*)t1; const Q3CanvasItem* i2 = s2 ? (const Q3CanvasItem*)s2 : p2 ? (const Q3CanvasItem*)p2 : r2 ? (const Q3CanvasItem*)r2 : e2 ? (const Q3CanvasItem*)e2 : (const Q3CanvasItem*)t2; if (s1 && s2) { // a return qt_testCollision(s1,s2); } else if ((r1 || t1 || s1) && (r2 || t2 || s2)) { // b QRect rc1 = i1->boundingRectAdvanced(); QRect rc2 = i2->boundingRectAdvanced(); return rc1.intersects(rc2); } else if (e1 && e2 && e1->angleLength()>=360*16 && e2->angleLength()>=360*16 && e1->width()==e1->height() && e2->width()==e2->height()) { // c double xd = (e1->x()+e1->xVelocity())-(e2->x()+e1->xVelocity()); double yd = (e1->y()+e1->yVelocity())-(e2->y()+e1->yVelocity()); double rd = (e1->width()+e2->width())/2; return xd*xd+yd*yd <= rd*rd; } else if (p1 && (p2 || s2 || t2)) { // d Q3PointArray pa1 = p1->areaPointsAdvanced(); Q3PointArray pa2 = p2 ? p2->areaPointsAdvanced() : Q3PointArray(i2->boundingRectAdvanced()); bool col= !(QRegion(pa1) & QRegion(pa2,true)).isEmpty(); return col; } else { return collision_double_dispatch(s2,p2,r2,e2,t2, s1,p1,r1,e1,t1); }}/*! \fn bool Q3CanvasItem::collidesWith(const Q3CanvasItem* other) const Returns true if the canvas item will collide with the \a other item \e after they have moved by their current velocities; otherwise returns false. \sa collisions()*//*! \class Q3CanvasSprite qcanvas.h \compat \brief The Q3CanvasSprite class provides an animated canvas item on a Q3Canvas. A canvas sprite is an object which can contain any number of images (referred to as frames), only one of which is current, i.e. displayed, at any one time. The images can be passed in the constructor or set or changed later with setSequence(). If you subclass Q3CanvasSprite you can change the frame that is displayed periodically, e.g. whenever Q3CanvasItem::advance(1) is called to create the effect of animation. The current frame can be set with setFrame() or with move(). The number of frames available is given by frameCount(). The bounding rectangle of the current frame is returned by boundingRect(). The current frame's image can be retrieved with image(); use imageAdvanced() to retrieve the image for the frame that will be shown after advance(1) is called. Use the image() overload passing it an integer index to retrieve a particular image from the list of frames. Use width() and height() to retrieve the dimensions of the current frame. Use leftEdge() and rightEdge() to retrieve the current frame's left-hand and right-hand x-coordinates respectively. Use bottomEdge() and topEdge() to retrieve the current frame's bottom and top y-coordinates respectively. These functions have an overload which will accept an integer frame number to retrieve the coordinates of a particular frame. Q3CanvasSprite draws very quickly, at the expense of memory. The current frame's image can be drawn on a painter with draw(). Like any other canvas item, canvas sprites can be moved with move() which sets the x and y coordinates and the frame number, as well as with Q3CanvasItem::move() and Q3CanvasItem::moveBy(), or by setting coordinates with Q3CanvasItem::setX(), Q3CanvasItem::setY() and Q3CanvasItem::setZ(). \sa QtCanvas, {Porting to Graphics View}*//*! \reimp*/bool Q3CanvasSprite::collidesWith(const Q3CanvasItem* i) const{ return i->collidesWith(this,0,0,0,0);}/*! Returns true if the canvas item collides with any of the given items; otherwise returns false. The parameters, \a s, \a p, \a r, \a e and \a t, are all the same object, this is just a type resolution trick.*/bool Q3CanvasSprite::collidesWith(const Q3CanvasSprite* s, const Q3CanvasPolygonalItem* p, const Q3CanvasRectangle* r, const Q3CanvasEllipse* e, const Q3CanvasText* t) const{ return collision_double_dispatch(s,p,r,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -