首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QT如何使用setPixmap skin.copy()来制作动画?

QT如何使用setPixmap skin.copy()来制作动画?
EN

Stack Overflow用户
提问于 2015-07-25 00:17:31
回答 1查看 118关注 0票数 1

我想在我的应用程序中做一些动画。我有一个小行星,当他向右移动时,动画就会向右移动,当他向左移动时,动画就会向左移动,角度在0到360°之间。我已经为你添加了瓷砖,向我解释如何完美地切割它。我在类中有一个整数,他们的数字在0和34之间(图像上的小行星),我在每个动画中减少-1或添加+1到这个变量。

为小行星设置动画的方法:

代码语言:javascript
复制
void Asteroid::animation(){
    int x = 1; 
    int y = 1;
    int width = 5;
    int height = 5;
    // what should I add here?    

    if(this->angle >= 0 && this->angle < 180){
        // cut image go to the right
        setPixmap(this->skin.copy(x,y,width,height));

        this->frame++;
        if(frame > 34) this->frame = 1;
    } else {
        // cut image go to the left
        setPixmap(this->skin.copy(x,y,width,height));

        this->frame--;
        if(frame < 1) this->frame = 34;
    }
}

skin像素图的内容:

接口

代码语言:javascript
复制
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include <QPoint>
#include <QVector>
#include <QPixmap>
#include <QString>
#include <QTimer>
#include <QObject>
#include <time.h>
#include <QtCore/qmath.h>

#include "SettingsAsteroid.h"

class Asteroid : public QObject, public QGraphicsPixmapItem
{
    Q_OBJECT

    // Animation
    QPixmap skin;
    int frame; // 32 images

    // Data
    int speed;
    int size;
    int pv;
    float angle;

public:  
    Asteroid(int size);
    Asteroid(QPointF position, int size);
    ~Asteroid();

    int getPosX();
    int getPosY();

    void setPosX(int newPos);
    void setPosY(int newPos);

    int getSpeed();
    int getSize();
    int getPV();
    int getAngle();

    // météorite détruite
    void destroyed();

    // toucher par un tir
    void touched(int damage);

    bool isDestroyed();

private slots:
    // mouvement de la météorite
    void move();

    // animation de la météorite
    void animation();

signals:
    //void notKilled();

    // transmet la taille du météorite détruit
    void killed(int);
};

实现

代码语言:javascript
复制
#include "Asteroid.h"

Asteroid::Asteroid(int size)
{
    this->skin = QPixmap(SettingsAsteroid::getRandomSkin());
    this->speed = SettingsAsteroid::getRandomSpeed(4,8);
    this->pv = SettingsAsteroid::getPV(size);
    this->angle = SettingsAsteroid::getRandomAngle();
    this->frame = 1;

    // Position de départ random
    QPointF position = QPointF(SettingsAsteroid::getRandomStartPosition());
    this->setPos(position.x(), position.y());

    this->size = size;

    // mouvement de l'astéroide
    QTimer* timer2 = new QTimer();
    connect(timer2,SIGNAL(timeout()),this,SLOT(move()));
    timer2->start(this->speed);

    // animation de l'astéroide
    QTimer* timer = new QTimer();
    connect(timer,SIGNAL(timeout()),this,SLOT(animation()));
    timer->start(100);
}

Asteroid::Asteroid(QPointF position, int size)
{
    this->skin = QPixmap(SettingsAsteroid::getRandomSkin());
    this->speed = SettingsAsteroid::getRandomSpeed(4,8);
    this->pv = SettingsAsteroid::getPV(size);
    this->angle = SettingsAsteroid::getRandomAngle();
    this->frame = 1;


    this->setPos(position.x(), position.y());

    this->size = size;

    QTimer* timer2 = new QTimer();
    connect(timer2,SIGNAL(timeout()),this,SLOT(move()));
    timer2->start(this->speed);

    //Decoupe sprite et anmiation
    QTimer* timer = new QTimer();
    connect(timer,SIGNAL(timeout()),this,SLOT(animation()));
    timer->start(150);
}

Asteroid::~Asteroid()
{
}

int Asteroid::getPosX(){
    return this->pos().x();
}

int Asteroid::getPosY(){
    return this->pos().y();
}

void Asteroid::setPosX(int newPos){
    this->setPos(newPos, this->pos().y());
}

void Asteroid::setPosY(int newPos){
    this->setPos(this->pos().x(), newPos);
}

int Asteroid::getSpeed(){
    return this->speed;
}

int Asteroid::getSize(){
    return this->size;
}

int Asteroid::getPV(){
    return this->pv;
}

int Asteroid::getAngle(){
    return this->angle;
}

bool Asteroid::isDestroyed(){

    if(pv > 0) return false;
    else return true;
}

void Asteroid::destroyed(){
    // AVERTIR CLASSE PRINCIPALE QUE DETRUIT
}

void Asteroid::touched(int damage){
    this->pv -= damage;
    if(pv<=0) destroyed();
}

void Asteroid::move(){
    double dx = getSpeed() * qCos(qDegreesToRadians(angle)) ;
    double dy = getSpeed() * qSin(qDegreesToRadians(angle)) ;

    setPos(QPointF(getPosX() + dx, getPosY() + dy)) ;

    // place la météorite de l'autre coté de la scène
    if (getPosX()<=0) setPosX(799);
    else if (getPosY()<=0) setPosY(659);
    else if (getPosX()>= 800) setPosX(1);
    else if (getPosY()>= 600) setPosY(1);
}

void Asteroid::animation(){
    // what add here?
    int x = 1;
    int y = 1;
    int width = 5;
    int height = 5;

    if(this->angle >= 0 && this->angle < 180){
        // cut image go to the right
        setPixmap(this->skin.copy(x,y,width,height));

        this->frame++;
        if(frame > 34) this->frame = 1;
    } else {
        // cut image go to the left
        setPixmap(this->skin.copy(x,y,width,height));
        this->frame--;
        if(frame < 1) this->frame = 34;
    }
}

角度是场景中小行星的方向。将会有一艘宇宙飞船来摧毁小行星。我想制作在现场移动的小行星的动画

EN

回答 1

Stack Overflow用户

发布于 2015-07-25 02:38:09

假设皮肤中的小行星图像是方形的,您可以执行以下操作。

你的皮肤只有32个项目,而不是34个,顺便说一下。

代码语言:javascript
复制
void Asteroid::animation() {
  int step = skin.height();
  int N = skin.width() / step; // Number of images in the skin.
  Q_ASSERT(skin.width() % step == 0); // ensure proper format of the skin

  if (angle >= 0 && angle < 180) {    
    frame ++;
    if (frame > N) frame -= N;
  } else {
    frame --;
    if (frame < 1) frame += N; 
  }

  int x = (frame - 1) * step;
  setPixmap(skin.copy(x, 0, step, step));
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31615286

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档