Qt跑酷游戏开发,背景移动,人物跳跃_ide

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QDialog>
#include <QKeyEvent>
#include <QMediaPlayer>
#include <QTimer>
#include "director.h"

namespace Ui {
class MainWindow;
}

/*
* MainWindow - 游戏场景
* SLOT:
* @nextFrame(): 每个朋友会做什么
* @gameOver: 检查游戏是否结束
* @isPlaying: 检查游戏是否暂停
* @counter: 数一数朋友的数目
* @scene: 场景的所有组成部分
* @bgm: 游戏的背景音乐
*/
class MainWindow : public QDialog
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

public slots:
void next_frame();//每个fream更新屏幕
void pause_and_resume();//暂停并继续游戏
void mute_and_play();//静音和取消静音效果
void change_configuration();//应用配置更改
void update_ui();//更新配置设置框的ui
void save_configuration();//用输入的名称保存当前配置
void load_configuration(); //加载配置文件
protected:
void paintEvent(QPaintEvent *event);
void keyPressEvent(QKeyEvent *event);

private:
volatile bool gameOver = false;
volatile bool isPlaying = true;
volatile int counter = 0;

Ui::MainWindow *ui;
Scene* scene;//场景
QMediaPlayer bgm;//音效
QString exepath;//程序路径
QTimer* timer;
};


#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QFile>
#include <QFileInfo>
#include <QMediaPlaylist>
#include <QApplication>
#include <iostream>

//the path of the configuration file


MainWindow::MainWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::MainWindow)
{
//set up the UI
ui->setupUi(this);
exepath = QApplication::applicationDirPath();
qDebug()<<"exepath=="<<exepath;
this->resize(FRAME_WIDTH,FRAME_HEIGHT);
ui->EnterFileName->hide();
ui->MenuBox->hide();
ui->Configuration->hide();

//set up the soundeffect to play
QMediaPlaylist *playlist = new QMediaPlaylist();
playlist->addMedia(QUrl::fromLocalFile(QFileInfo("exepath/Audio/Lucid_Dreamer1.mp3").absoluteFilePath()));
playlist->setPlaybackMode(QMediaPlaylist::Loop);

bgm.setPlaylist(playlist);
bgm.setVolume(50);
bgm.play();
//创建一个计时器来更新每个fream
QTimer* timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(next_frame()));
timer->start(50);
//load from the configuration file
//从配置文件加载
load_configuration();//创建场景器

this->update();
}

MainWindow::~MainWindow()
{
gameOver = true;
delete ui;
delete scene;
}

/* SLOT */
//update the screen each fream每个fream更新屏幕
void MainWindow::next_frame()
{
update();
}

//pause and resume game暂停并继续游戏
void MainWindow::pause_and_resume()
{
isPlaying = !isPlaying;
mute_and_play();
}

//静音和取消静音效果
void MainWindow::mute_and_play()
{
isPlaying?bgm.setMuted(!bgm.isMuted()):bgm.setMuted(true);
}

//应用配置更改
void MainWindow::change_configuration()
{
//change stickman size
if (ui->playerSize->currentText() == "Tiny") scene->change_stickman_size(TINY);
else if (ui->playerSize->currentText() == "Normal") scene->change_stickman_size(NORMAL);
else if (ui->playerSize->currentText() == "Large") scene->change_stickman_size(LARGE);
else if (ui->playerSize->currentText() == "Giant") scene->change_stickman_size(GIANT);

//change starting point
scene->change_starting_point(ui->playerPosition->value());

//change speed
scene->change_speed(ui->playerVelocity->value());
scene->change_speed(ui->playerVelocity->value());

//change stickman image
scene->change_stickman_image(ui->playerImage->currentText().toInt());

//change background image
scene->change_background_image(ui->BackGroundImage->currentText().toInt());
}

//更新配置设置框的ui
//确保更新了配置设置框中显示的值
void MainWindow::update_ui()
{
if (scene->get_stickman_size() == TINY) ui->playerSize->setCurrentIndex(0);
else if (scene->get_stickman_size() == NORMAL) ui->playerSize->setCurrentIndex(1);
else if (scene->get_stickman_size() == LARGE) ui->playerSize->setCurrentIndex(2);
else if (scene->get_stickman_size() == GIANT) ui->playerSize->setCurrentIndex(3);

ui->playerVelocity->setValue(scene->get_speed());
ui->playerPosition->setValue(scene->get_starting_point());
ui->playerImage->setCurrentIndex(scene->get_player_graph_index());
ui->BackGroundImage->setCurrentIndex(scene->get_background_graph_index()-1);
}

//用输入的名称保存当前配置
void MainWindow::save_configuration()
{
//get the name player entered from ui(QLineEdit)
QString file_name = ui->insertFileName->text();

//if they enter no name, send a warning message如果没有输入姓名,则发送警告消息
if (file_name == "")
{
ui->tipBox->setText(QString("Please enter a file name."));
return;
}

//create a text file and store the configuration
QString file_path = QString().append("../Base1A/").append(file_name).append(".config");
QFile file(file_path);

if (!file.exists()) {
if (file.open(QIODevice::WriteOnly|QFile::Text))
{
QTextStream input(&file);
QString stickman_size;

if (scene->get_stickman_size() == TINY) stickman_size = "tiny";
else if (scene->get_stickman_size() == NORMAL) stickman_size = "normal";
else if (scene->get_stickman_size() == LARGE) stickman_size = "large";
else if (scene->get_stickman_size() == GIANT) stickman_size = "giant";

input<<"stickman size = "<<stickman_size<<"\n";
input<<"starting position = "<<QString::number(scene->get_starting_point())<<"\n";
input<<"starting velocity = "<<QString::number(scene->get_speed())<<"\n";
input<<"background imgae = "<<QString::number(scene->get_background_graph_index())<<"\n";
input<<"stickman figure = "<<QString::number(scene->get_player_graph_index())<<"\n";

ui->EnterFileName->hide();
file.close();

//the game is paused when we save the configuration
isPlaying = true;

}
//fail to create a file with the given name
else
{
ui->tipBox->setText(QString("Invalid file name, try again."));
}
}
//the file with the given name has already existed
else
{
ui->tipBox->setText(QString("The file already exists, try again."));
}

}
/* EVENT */
void MainWindow::keyPressEvent(QKeyEvent *event)
{
//show menu when press Esc
if (event->key() == Qt::Key_Escape)
{
if (ui->MenuBox->isHidden())
ui->MenuBox->show();
else
ui->MenuBox->close();
update();
}

//按W下时增加音量
if (event->key() == Qt::Key_W)
{
bgm.setVolume(bgm.volume()+0.1);
}
//按下S键时减小音量
if (event->key() == Qt::Key_S)
{
bgm.setVolume(bgm.volume()-0.1);
}
//按上 跳跃
if (event->key() == Qt::Key_Up)
{
scene->action_jump();
}

}

void MainWindow::paintEvent(QPaintEvent *event) {
Q_UNUSED(event)
//渲染背景、前景和播放器
QPainter painter(this);
scene->render(painter, counter);

//如果游戏没有暂停,增加计数器
if (isPlaying) counter++;

//游戏结束后清理数据
if (gameOver) delete timer;
}

/* INITIALIZATION */
void MainWindow::load_configuration()
{

double stickman_size;
int starting_point;
int starting_velocity;
int stickman_graph_index;
int background_graph_index;

//load configuration file
QString config_path = exepath + "/config/init.config";
QFile config_file(config_path);

qDebug()<<"_________________________________";
qDebug()<<"配置文件加载..."<<config_path;

//ERROR CHECK
//if the configuration file is not valid, use the default setting
//如果配置文件无效,请使用默认设置
if (!config_file.exists())
{
qDebug()<<"CAN NOT READ CONFIGURATION FILE.";
qDebug()<<"DEFAULT SETTINGS LOADED.";

//default settings
stickman_size = NORMAL;
starting_velocity = 10;
starting_point = 100;
stickman_graph_index = 0;
background_graph_index = 1;
} else {
if (config_file.open(QIODevice::ReadOnly)) {
QTextStream input(&config_file);
while (!input.atEnd()){
QStringList line = input.readLine().toLower().split(" = ");
//设置人物大小
if (line.at(0) == "stickman size")
{
if (line.at(1) == "tiny")
{
stickman_size = TINY;
qDebug()<<"将粘胶工的尺寸设置为小号.\n";
}

else if (line.at(1) == "normal")
{
stickman_size = NORMAL;
qDebug()<<"将粘接器大小设置为正常.\n";
}

else if (line.at(1) == "large")
{
stickman_size = LARGE;
qDebug()<<"设置粘贴器大小为大.\n";
}

else if (line.at(1) == "giant")
{
stickman_size = GIANT;
qDebug()<<"将粘人大小设置为GIANT.\n";
}
else
{
stickman_size = NORMAL;
qDebug()<<"无效的曲棍球手大小!";
qDebug()<<"接受值:小,正常,大,巨大";
qDebug()<<"默认大小加载:正常.\n";
}

}

//设置起点
else if (line.at(0) == "starting position")
{
int x = line.at(1).toInt();
if (x < 0 || x > 1000)
{
starting_point = 100;
qDebug()<<"无效的起点!";
qDebug()<<"ACCEPTED VALUE: FROM 0 TO 1000";
qDebug()<<"DEFAULT STARTING POINT LOADED: 100.\n";
}
else
{
starting_point = x;
qDebug()<<"SET STARTING POINT TO X ="<<starting_point<<"\n";
}
}

//set starting velocity
else if (line.at(0) == "starting velocity")
{
int speed = line.at(1).toInt();
if (speed < 0 || speed > 40)
{
starting_velocity = 10;
qDebug()<<"INVALID SPEED!";
qDebug()<<"ACCEPTED VALUE: FROM 0 TO 40";
qDebug()<<"DEFAULT SPEED LOADED: 10.\n";
}

else
{
starting_velocity = speed;
qDebug()<<"SET SPEED TO"<<speed<<"\n";
}
}

//set background image
else if (line.at(0) == "background imgae")
{
int index = line.at(1).toInt();
if (index != 1 && index != 2 && index != 3)
{
background_graph_index = 1;
qDebug()<<"INVALID BACKGROUND IMAGE PATH!";
qDebug()<<"ACCEPTED VALUE: 1,2,3";
qDebug()<<"DEFAULT BACKGROUND IMAGE LOADED: 1.\n";
}
else{
background_graph_index = index;
qDebug()<<"SET BACKGROUND IMAGE TO "<<index<<"\n";
}
}

//set stickman figure
else if (line.at(0) == "stickman figure")
{
int index = line.at(1).toInt();
if (index != 0 && index != 1)
{
stickman_graph_index = 0;
qDebug()<<"INVALID STICKMAN FIGURE!";
qDebug()<<"ACCEPTED VALUE: 0 AND 1";
qDebug()<<"DEFAULT STICKMAN FIGURE LOADED: 0.\n";
}
else
{
stickman_graph_index = index;
qDebug()<<"SET STIACKMAN FIGURE TO"<<index<<"\n";
}
}

else if (line.at(0) != "")
{
qDebug()<<"INVALID COMMAND: "<<line<<"\n";
}
}
}
}

//使用director和builder生成场景
GameSceneGenerator scene_builder = GameSceneGenerator(stickman_size,
starting_point,
starting_velocity,
background_graph_index,
stickman_graph_index);
scene = SceneDirector(&scene_builder).generate();
qDebug()<<"完成";
config_file.close();
}