⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainwindow.cpp

📁 QStars is a Qt-based screen saver. It displays an image within a field of moving stars.
💻 CPP
字号:
// Copyright (C) 2004, 2005 Andi Peredri <andi@ukr.net>#include <math.h>#include <qapplication.h>#include <qbitmap.h>#include <qdir.h>#include <qimage.h>#include <qpainter.h>#include <qsettings.h>#include <stdio.h>#include <stdlib.h>#include <time.h>#include "mainwindow.h"static int w = 600;static int h = 420;static QImage background;// Star --------------------------------------------------------------------Star::Star(){    restart();}void Star::restart(){    x = rand() % (w + Border);    y = rand() % h;    color = (rand() % 16) * (rand() % 16) + 30;    movecounter = 0;}void Star::paint(QPainter *p){    if(x < -1)    {	x = w + rand() % Border;	y = rand() % h;        return;    }    if(movecounter--) return;    movecounter = (255 - color) >> 4;    if(color == 255)    {	clearPoint(p, x + 1, y);        clearPoint(p, x + 1, y + 1);    }    else clearPoint(p, x, y);    drawPoint(p, --x, y);    if(color == 255) drawPoint(p, x, y + 1);}void Star::drawPoint(QPainter* p, int px, int py){    if(background.valid(px, py))    {	p->setPen(QColor(color, color, color));	p->drawPoint(px, py);    }}void Star::clearPoint(QPainter* p, int px, int py){    if(background.valid(px, py))    {	p->setPen(background.pixel(px, py));	p->drawPoint(px, py);    }}// Demo --------------------------------------------------------------------class Demo{public:    virtual              ~Demo();    virtual void          paint(QPainter*) = 0;    static const QString& shareDir();    static QImage         loadRandomImage(const QString& dirname);};Demo::~Demo(){}const QString& Demo::shareDir(){    static const QString dir1 = qApp->applicationDirPath();    static const QString dir2 = dir1 + "/../share/qstars";    return QFile::exists(dir2) ? dir2 : dir1;}QImage Demo::loadRandomImage(const QString& dirname){    QString path = shareDir() + "/" + dirname + "/";    QDir dir(path);    dir.setFilter(QDir::Files);    unsigned int count = dir.count();    if(count)	return QImage(path + dir[rand() % count]);    return QImage();}// Asteroid ----------------------------------------------------------------class Asteroid{public:    Asteroid(QPixmap* pix);    void paint(QPainter* p);private:    void restart();    int      x;    int      y;    int      nextframe;    int      frame;    int      movecounts;    int      movecounter;    int      rottimeout;    QTime    timer;    QPixmap* pixmap;};Asteroid::Asteroid(QPixmap* pix){    timer.start();    pixmap = pix;    restart();}void Asteroid::restart(){    rottimeout  = rand() % 20 + 20;    nextframe   = rand() % 2 ? 1 : -1;    frame       = rand() % (pixmap->width() / pixmap->height());    movecounts  = rand() % 5;    movecounter = movecounts;    x = rand() % (2 * w);    y = rand() % (h - pixmap->height());}void Asteroid::paint(QPainter* p){    if(timer.elapsed() > rottimeout)    {        timer.restart();	frame += nextframe;	const int maxframe = pixmap->width() / pixmap->height() - 1;	if(frame < 0) frame = maxframe;	if(frame > maxframe) frame = 0;    }    if(x + pixmap->height() < 0)    {        restart();	x = w + rand() % w;        return;    }    if(!movecounter--)    {	movecounter = movecounts;        x--;    }    p->drawPixmap(x, y, *pixmap, pixmap->height() * frame, 0, pixmap->height());}// Asteroids ---------------------------------------------------------------class Asteroids : public Demo{public:    Asteroids();    void paint(QPainter* p);private:    QPtrList<QPixmap>  pixmaps;    QPtrList<Asteroid> asteroids;};Asteroids::Asteroids(){    pixmaps.setAutoDelete(true);    asteroids.setAutoDelete(true);    const QString path = shareDir() + "/asteroids/";    QDir dir(path);    dir.setFilter(QDir::Files);    for(unsigned int i = 0; i < dir.count(); i++)    {        QPixmap* pixmap = new QPixmap(path + dir[i]);	pixmaps.append(pixmap);	int num = 80 / pixmap->height();	for(int i = 0; i < num; i++)	    asteroids.append(new Asteroid(pixmap));    }}void Asteroids::paint(QPainter* p){    for(Asteroid* a = asteroids.first(); a; a = asteroids.next())	a->paint(p);}// Planet ------------------------------------------------------------------class Planet : public Demo{public:    Planet();    void paint(QPainter* p);private:    struct Map    {	int texturex;	int texturey;	int spherex;	int spherey;    };    int           radius;    QBitmap       mask;    QImage        texture;    QImage        image;    QPixmap       pixmap;    QPtrList<Map> maps;};Planet::Planet(){    texture = loadRandomImage("planets");    radius = (int) (texture.height() / 3.14);    image.create(2 * radius, 2 * radius, 32);    image.fill(0);    maps.setAutoDelete(true);    for(double spherey = -radius; spherey < radius; spherey++)    {	const double angley = asin(spherey / radius);	const double xmax = radius * cos(angley);	const double texturey = angley * radius;	for(double spherex = -xmax; spherex < xmax; spherex++)	{	    const double texturex = radius * asin(spherex / xmax);	    Map* map = new Map;	    map->texturex = (int) (texture.height() / 2 + texturex);	    map->texturey = (int) (texture.height() / 2 + texturey);	    map->spherex  = (int) (radius + spherex);	    map->spherey  = (int) (radius + spherey);	    maps.append(map);	}    }    for(Map* map = maps.first(); map; map = maps.next())    {	QRgb* line = (QRgb*) image.scanLine(map->spherey);	line[map->spherex] = qRgb(255, 255, 255);    }    pixmap.convertFromImage(image);    mask = pixmap.createHeuristicMask();}void Planet::paint(QPainter* p){    static int counter = 0;    if(counter > texture.width()) counter = 0;    for(Map* map = maps.first(); map; map = maps.next())    {	int x = map->texturex + counter;	if(x >= texture.width()) x -= texture.width();	QRgb* line = (QRgb*) image.scanLine(map->spherey);	line[map->spherex] = texture.pixel(x, map->texturey);    }    counter++;    pixmap.convertFromImage(image);    pixmap.setMask(mask);    p->drawPixmap(w / 2 - radius, h / 2 - radius, pixmap);}// Ship --------------------------------------------------------------------class Ship : public Demo{public:    Ship();    void    paint(QPainter* p);private:    int     x;    int     y;    QPixmap pixmap;};Ship::Ship(){    QImage image = loadRandomImage("ships");    x = (w - image.width()) / 2;    y = (h - image.height()) / 2;    pixmap.convertFromImage(image);    pixmap.setMask(pixmap.createHeuristicMask());}void Ship::paint(QPainter* p){    p->drawPixmap(x, y, pixmap);}// MainWindow --------------------------------------------------------------MainWindow::MainWindow(WId wid) : QWidget(){    if(wid)    {	create(wid);	w = width();	h = height();    }    else setFixedSize(w, h);    demo = 0;    restarttimer = 0;    stars.setAutoDelete(true);    starground.resize(w, h);    workground.resize(w, h);    background.create(w, h, 32);    setBackgroundMode(NoBackground);    setIcon(QPixmap::fromMimeSource("qstars.png"));    setCaption("QStars");    srand(time(0));    QSettings settings;    settings.beginGroup("QStars");    speed = settings.readNumEntry("Speed", 50);    showships = settings.readBoolEntry("ShowShips", true);    showplanets = settings.readBoolEntry("ShowPlanets", true);    showgalaxies = settings.readBoolEntry("ShowGalaxies", true);    showasteroids = settings.readBoolEntry("ShowAsteroids", true);    restarttimeout = settings.readNumEntry("Timer", 30);    unsigned int density = settings.readNumEntry("Density", 50);    int numstars = (w + Star::Border) * h * (density + 1) / 5000;    for(int i = 0; i < numstars; i++)	stars.append(new Star());    if(restarttimeout)	restarttimer = startTimer(restarttimeout * 1000);    restart();    updateRepaintTimer();}MainWindow::~MainWindow(){    QSettings settings;    settings.writeEntry("/QStars/Speed", speed);    delete demo;}void MainWindow::updateRepaintTimer(){    static int repainttimer = 0;    if(speed < 0)   speed = 0;    if(speed > 100) speed = 100;    killTimer(repainttimer);    repainttimer = startTimer(1000 / (speed + 20));}void MainWindow::restart(){    delete demo;    demo = 0;    background.fill(0);    starground.fill(black);    for(Star* star = stars.first(); star; star = stars.next())	star->restart();    QValueList<int>   list;    if(showasteroids) list << 1;    if(showplanets)   list << 2 << 2 << 2 << 2;    if(showships)     list << 3;    if(list.count() && (w > 300) && (h > 200))    {	int random = list[rand() % list.count()];	if(random == 1)      demo = new Asteroids;        else if(random == 2) demo = new Planet;	else                 demo = new Ship;    }    if(showgalaxies)    {	QWMatrix matrix;	QImage galaxy = Demo::loadRandomImage("galaxies");	galaxy = galaxy.xForm(matrix.rotate(rand() % 360));	int x = (rand() % 2) ? 0 : (w - galaxy.width());	int y = (rand() % 2) ? 0 : (h - galaxy.height());	bitBlt(&background, x, y, &galaxy);	bitBlt(&starground, 0, 0, &background);    }    update();}void MainWindow::timerEvent(QTimerEvent* e){    if(e->timerId() == restarttimer)	restart();    else    {	QPainter p(&starground);	for(Star* star = stars.first(); star; star = stars.next())	    star->paint(&p);	p.end();	bitBlt(&workground, 0, 0, &starground);	p.begin(&workground);	if(demo) demo->paint(&p);	bitBlt(this, 0, 0, &workground);    }}void MainWindow::keyPressEvent(QKeyEvent* e){    switch(e->key())    {    case Key_Up:        speed += 20;	updateRepaintTimer();        break;    case Key_Down:        speed -= 20;	updateRepaintTimer();        break;    case Key_Right:	if(restarttimeout)	{            killTimer(restarttimer);	    restarttimer = startTimer(restarttimeout * 1000);	}	restart();        break;    case Key_Q:	QApplication::exit();    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -