贪吃蛇
来源:互联网 发布:手机公司记账软件 编辑:程序博客网 时间:2024/04/24 06:49
第一次在这里写东西
Qt程序,参考了别人博客的贪吃蛇主体算法(抱歉网址不记得了),我又自己写了一份完整的,包括主界面、菜单和背景音乐等。
这是界面截图:
文章末尾有源代码下载地址
说一下主要部分吧:
先画这样一份地图QVector < QVector <int > > map,其值1表示墙壁,0表示空地
举个例子:
111111111111111
100000000000001
100000000000001
100000000000001
111111111111111
再做出一条蛇QVector< <QPoint> > snake和食物QPoint apple;apple的位置用随机函数确定.
然后用timer做定时器,每隔X ms进行更新,在map上画出snake,和apple.
这里可以很好的利用Qt的 信号/槽机制
QObject::connect(timer,SIGNAL(timeout()),this,SLOT(automove()));timer发出timeout信号时,automove函数实现蛇自动前进,本质是把snake中的数据进行更新,然后调用绘图函数
需要重载两个函数
void paintEvent(QPaintEvent *event);//绘图部分
void keyPressEvent(QKeyEvent *event);//捕获键盘操作,键盘的上下左右控制蛇的前进keyPressEvent函数根据捕获的按键更新snake数据
mainwindow.h
#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include<QtGui>#include<QVector>#include<QLabel>#include<QSound>#include<string>using namespace std;#define WIDTH 30#define HEIGHT 20int const LEVEL[]={0,1000,500,200,100,50};namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{ Q_OBJECTpublic: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); enum direction{UP,DOWN,LEFT,RIGHT};private slots: void automove(); void receiveData(string rec); void on_action_Quit_triggered(); void on_action_New_triggered(); void on_action_Pause_triggered(); void on_action_Continue_triggered(); void on_action_level1_triggered(); void on_action_level2_triggered(); void on_action_level3_triggered(); void on_action_level4_triggered(); void on_action_level5_triggered(); void on_action_help_triggered(); void on_action_author_triggered(); void on_action_Score_triggered(); void addscore();private: Ui::MainWindow *ui; QPoint apple; QVector<QPoint> snake; QVector< QVector<int> > map; enum direction direc; int speed; int level; QTimer *timer; int score; void eat(); void move(enum direction direc); void randapple(); void gameover(); void loadscore(); void getname(); void save(); void init_statuBar(); QLabel *first_statusLabel,*second_statusLabel; string player;signals: void gotin();protected: void paintEvent(QPaintEvent *event); void keyPressEvent(QKeyEvent *event);};#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"#include "ui_mainwindow.h"#include"dialog.h"#include"readname.h"#include<QDebug>#include<fstream>#define ON#ifdef ON#define NEW#define PEVENT#define KEVENT#endifstring nam[3]={"player1","player2","player3"};int sco[3]={0};MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this); setWindowTitle(tr("贪吃蛇")); setFixedSize(25*WIDTH,25*HEIGHT); //默认方向为RIGHT direc=RIGHT; //默认难度为LEVEL1 level=1; speed=LEVEL[level]; player="UnknowPlayer"; score=0; //重置蛇的初始位置 snake.clear(); snake.push_back(QPoint(5,4)); snake.push_back(QPoint(5,5)); snake.push_back(QPoint(5,6)); snake.push_back(QPoint(5,7)); //初始化地图,1表示砖块,0表示空地 QVector<int> temp1(WIDTH,1); map.push_back(temp1); QVector<int> temp2; temp2.push_back(1); for(int i=1;i<=WIDTH-2;i++) temp2.push_back(0); temp2.push_back(1); for(int i=1;i<=HEIGHT-2;i++) map.push_back(temp2); map.push_back(temp1); nam[0].clear(); nam[1].clear(); nam[2].clear(); player.clear(); loadscore(); init_statuBar(); //制作定时器,每x毫秒蛇自动前进 timer=new QTimer(this); QObject::connect(timer,SIGNAL(timeout()),this,SLOT(automove())); qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); QObject::connect(this,SIGNAL(gotin()),this,SLOT(addscore())); //update();}MainWindow::~MainWindow(){ delete ui;}void MainWindow::on_action_Quit_triggered(){ save(); qApp->exit();}#ifndef NEWvoid MainWindow::on_action_New_triggered(){}#elsevoid MainWindow::on_action_New_triggered(){ //默认方向为RIGHT direc=RIGHT; score=0; //重置蛇的初始位置 snake.clear(); snake.push_back(QPoint(5,4)); snake.push_back(QPoint(5,5)); snake.push_back(QPoint(5,6)); snake.push_back(QPoint(5,7)); //初始化地图,1表示砖块,0表示空地 /* 宽度WEIDTH,高度HEIGTH,"举个栗子"吧: 111111111 100000001 100000001 111111111 */ map.clear(); QVector<int> temp1(WIDTH,1); map.push_back(temp1); QVector<int> temp2; temp2.push_back(1); for(int i=1;i<=WIDTH-2;i++) temp2.push_back(0); temp2.push_back(1); for(int i=1;i<=HEIGHT-2;i++) map.push_back(temp2); map.push_back(temp1); randapple(); this->update(); //启动定时器 timer->start(speed); QSound sound("sound/darling.wav"); sound.play(); //QSound::play("F:/Code/Qt/snake2/sound/darling.wav"); qDebug()<<"New 运行成功";}#endifvoid MainWindow::randapple(){ apple.setX(qrand()%WIDTH); apple.setY(qrand()%HEIGHT); if(map[apple.y()][apple.x()]!=0) this->randapple(); else if(qFind(snake.begin(),snake.end(),apple)!=snake.end()) this->randapple(); else qDebug()<<"randapple 运行成功";}void MainWindow::move(direction direc){ QVector<QPoint> temp(snake.size()); switch(direc) { case UP: { temp[0]=QPoint(snake[0].x(),snake[0].y()-1); qCopy(snake.begin(),snake.end()-1,temp.begin()+1); snake=temp; break; } case DOWN: { temp[0]=QPoint(snake[0].x(),snake[0].y()+1); qCopy(snake.begin(),snake.end()-1,temp.begin()+1); snake=temp; break; } case LEFT: { temp[0]=QPoint(snake[0].x()-1,snake[0].y()); qCopy(snake.begin(),snake.end()-1,temp.begin()+1); snake=temp; break; } case RIGHT: { temp[0]=QPoint(snake[0].x()+1,snake[0].y()); qCopy(snake.begin(),snake.end()-1,temp.begin()+1); snake=temp; break; } } qDebug()<<"move 运行成功";}void MainWindow::eat(){ //这里需要注意容器的最后一个元素是end()-1,不是end() //蛇尾朝右前进 if(snake[snake.size()-1].x()==snake[snake.size()-2].x()&&snake[snake.size()-1].y()<snake[snake.size()-2].y()) snake.push_back(QPoint(snake[snake.size()-1].x(),snake[snake.size()-1].y()-1)); //蛇尾朝左前进 if(snake[snake.size()-1].x()==snake[snake.size()-2].x()&&snake[snake.size()-1].y()>snake[snake.size()-2].y()) snake.push_back(QPoint(snake[snake.size()-1].x(),snake[snake.size()-1].y()+1)); //蛇尾朝上前进 if(snake[snake.size()-1].y()==snake[snake.size()-2].y()&&snake[snake.size()-1].x()>snake[snake.size()-2].x()) snake.push_back(QPoint(snake[snake.size()-1].x()+1,snake[snake.size()-1].y())); //蛇尾朝下前进 if(snake[snake.size()-1].y()==snake[snake.size()-2].x()&&snake[snake.size()-1].x()<snake[snake.size()-2].x()) snake.push_back(QPoint(snake[snake.size()-1].x()-1,snake[snake.size()-1].y())); //撞墙 if(map[snake[snake.size()-1].y()][snake[snake.size()-1].x()]==1) snake.pop_back(); score+=level; emit gotin(); QSound sound("sound/eat.wav"); sound.play(); qDebug()<<"eat 运行成功";}#ifndef PEVENTvoid MainWindow::paintEvent(QPaintEvent *event){}#elsevoid MainWindow::paintEvent(QPaintEvent *event){ QPainter mypainter(this); mypainter.setPen(QPen(Qt::black,1)); //画地图 for(QVector< QVector<int> >::size_type i=0;i!=WIDTH;i++) for(QVector<int>::size_type j=0;j!=HEIGHT;j++ ) switch(map.at(j).at(i)) { case 0: mypainter.setBrush(Qt::black); mypainter.drawPixmap(i*25,j*25,QPixmap(":/xsd/images/ground.png")); break; case 1: mypainter.setBrush(Qt::red); mypainter.drawPixmap(i*25,j*25,QPixmap(":/xsd/images/stone.png")); break; } //画苹果 mypainter.drawPixmap(apple.x()*25,apple.y()*25,QPixmap(":/xsd/images/apple.png")); //画蛇 //蛇头 switch(direc) { case UP: mypainter.drawPixmap(snake[0].x()*25,snake[0].y()*25,QPixmap(":/xsd/images/head_up.png")); break; case DOWN: mypainter.drawPixmap(snake[0].x()*25,snake[0].y()*25,QPixmap(":/xsd/images/head_down.png")); break; case LEFT: mypainter.drawPixmap(snake[0].x()*25,snake[0].y()*25,QPixmap(":/xsd/images/head_left.png")); break; case RIGHT: mypainter.drawPixmap(snake[0].x()*25,snake[0].y()*25,QPixmap(":/xsd/images/head_right.png")); break; } //蛇身 for(QVector<QPoint>::size_type i=1;i!=snake.size();i++) { mypainter.drawPixmap(snake[i].x()*25,snake[i].y()*25,QPixmap(":/xsd/images/body.png")); } //qDebug()<<"painter 运行成功"; event->accept();}#endif#ifndef KEVENTvoid MainWindow::keyPressEvent(QKeyEvent *event){}#elsevoid MainWindow::keyPressEvent(QKeyEvent *event){ switch(event->key()) { case Qt::Key_Up: //蛇头和脖子没有都朝上前进 if(snake[0].y()!=snake[1].y()+1) move(UP); if(snake[0]==apple) { eat(); randapple(); } if(map[snake[0].y()][snake[0].x()]==1) { timer->stop(); QMessageBox::information(this,tr("游戏结束"),tr("你撞墙了!")); gameover(); } if(qFind(snake.begin()+1,snake.end(),snake[0])!=snake.end()) { timer->stop(); QMessageBox::information(this,tr("游戏结束"),tr("你撞蛇了")); gameover(); } direc=UP; update(); break; case Qt::Key_Down: if(snake[0].y()!=snake[1].y()-1) move(DOWN); if(snake[0]==apple) { eat(); randapple(); } if(map[snake[0].y()][snake[0].x()]==1) { timer->stop(); QMessageBox::information(this,tr("游戏结束"),tr("你撞墙了!")); gameover(); } if(qFind(snake.begin()+1,snake.end(),snake[0])!=snake.end()) { timer->stop(); QMessageBox::information(this,tr("游戏结束"),tr("你撞蛇了")); gameover(); } direc=DOWN; update(); break; case Qt::Key_Right: if(snake[0].x()!=snake[1].x()-1) move(RIGHT); if(snake[0]==apple) { eat(); randapple(); } if(map[snake[0].y()][snake[0].x()]==1) { timer->stop(); QMessageBox::information(this,tr("游戏结束"),tr("你撞墙了!")); gameover(); } if(qFind(snake.begin()+1,snake.end(),snake[0])!=snake.end()) { timer->stop(); QMessageBox::information(this,tr("游戏结束"),tr("你撞蛇了")); gameover(); } direc=RIGHT; update(); break; case Qt::Key_Left: if(snake[0].x()!=snake[1].x()+1) move(LEFT); if(snake[0]==apple) { eat(); randapple(); } if(map[snake[0].y()][snake[0].x()]==1) { timer->stop(); QMessageBox::information(this,tr("游戏结束"),tr("你撞墙了!")); gameover(); } if(qFind(snake.begin()+1,snake.end(),snake[0])!=snake.end()) { timer->stop(); QMessageBox::information(this,tr("游戏结束"),tr("你撞蛇了")); gameover(); } direc=LEFT; update(); break; } qDebug()<<"kevent 运行成功"; event->accept();}#endifvoid MainWindow::automove(){ move(direc); if(snake[0]==apple) { eat(); randapple(); } if(map[snake[0].y()][snake[0].x()]==1) { timer->stop(); QMessageBox::information(this,tr("游戏结束"),tr("你撞墙了!")); gameover(); } if(qFind(snake.begin()+1,snake.end(),snake[0])!=snake.end()) { timer->stop(); QMessageBox::information(this,tr("游戏结束"),tr("你撞蛇了")); gameover(); } update(); qDebug()<<"automove 运行成功";}void MainWindow::gameover(){ int f=-1; for(int i=0;i<3;i++) { if(score>=sco[i]) { f=i; break; } } if(0<=f&&f<=2) { getname(); switch(f) { case 0: sco[2]=sco[1]; sco[1]=sco[0]; sco[0]=score; nam[2]=nam[1]; nam[1]=nam[0]; nam[0]=player; break; case 1: sco[2]=sco[1]; sco[1]=score; nam[2]=nam[1]; nam[1]=player; break; case 2: sco[2]=score; nam[2]=player; break; default:break; } save(); } exit(EXIT_SUCCESS);}void MainWindow::save(){ fstream file1; file1.open("score.dat",ios::out); if(file1) { for(int i=0;i<3;i++) { if(nam[i].length()==0) nam[i]="UnknowPlayer"; file1<<nam[i]<<" "<<sco[i]<<endl; } file1.close(); } else { QMessageBox message(QMessageBox::NoIcon, "报告", "保存失败"); message.exec(); }}void MainWindow::on_action_Pause_triggered(){ timer->stop();}void MainWindow::on_action_Continue_triggered(){ timer->start(speed);}void MainWindow::on_action_level1_triggered(){ timer->stop(); level=1; speed=LEVEL[level];}void MainWindow::on_action_level2_triggered(){ timer->stop(); level=2; speed=LEVEL[level];}void MainWindow::on_action_level3_triggered(){ timer->stop(); level=3; speed=LEVEL[level];}void MainWindow::on_action_level4_triggered(){ timer->stop(); level=4; speed=LEVEL[level];}void MainWindow::on_action_level5_triggered(){ timer->stop(); level=5; speed=LEVEL[level];}void MainWindow::on_action_help_triggered(){ QMessageBox message(QMessageBox::NoIcon, "说明", "使用键盘上的 ↑ ↓ ← → 四个按键控制蛇\n"); message.setIconPixmap(QPixmap(":/fire/icon/snake.ico")); message.exec();}void MainWindow::on_action_author_triggered(){ QMessageBox message(QMessageBox::NoIcon, "作者", "Made by Fire\nQQ:759378563\nE-mail:dd759378563@126.com\n\t2013.11\n"); message.setIconPixmap(QPixmap(":/fire/icon/author.ico")); message.exec();}void MainWindow::loadscore(){ fstream file1; file1.open("score.dat",ios::in); if(file1) { for(int i=0;i<3;i++) file1>>nam[i]>>sco[i]; file1.close(); } else { QMessageBox message(QMessageBox::NoIcon, "报告", "读取失败"); message.exec(); }}void MainWindow::on_action_Score_triggered(){ Dialog dia; dia.exec();}void MainWindow::getname(){ readname *rname; rname=new readname(); if(connect(rname,SIGNAL(sendData(string)),this,SLOT(receiveData(string)))) qDebug()<<"rname 连接成功"; else qDebug()<<"rname 连接失败"; rname->exec();}void MainWindow::receiveData(string rec){ player=rec; qDebug( )<<"用户名字是:"<< QString::fromStdString(player);}void MainWindow::init_statuBar(){ QStatusBar * bar=ui->statusBar; first_statusLabel=new QLabel; first_statusLabel->setMinimumSize(150,20); first_statusLabel->setFrameShape(QFrame::WinPanel); first_statusLabel->setFrameShadow(QFrame::Sunken); second_statusLabel=new QLabel; second_statusLabel->setMinimumSize(150,20); second_statusLabel->setFrameShape(QFrame::WinPanel); second_statusLabel->setFrameShadow(QFrame::Sunken); bar->addWidget(first_statusLabel); bar->addWidget(second_statusLabel); first_statusLabel->setText(tr("欢迎使用贪食蛇")); second_statusLabel->setText(tr("Fire制作"));}void MainWindow::addscore(){ second_statusLabel->setText(tr("当前得分: %1").arg(score));}
源代码下载地址:
http://download.csdn.net/detail/d759378563/6618471
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 贪吃蛇
- 汉诺塔,逆波兰表达式,苹果放置递归实现
- USBKey技术在J2EE项目中的应用
- Windows中常见的文件后缀名解释表
- ora-12528 TNS 监听程序所有适用例程都无法建立新连接
- 第十四周 项目4--数组的排序
- 贪吃蛇
- android发送http请求
- PHP字符截取函数。兼容中文,英文,中英文混杂等情况
- Oracle中打开10046 Trace的各种方法
- POJ 2752 KMPnext的应用
- Redis 非关系型数据库简介
- 学校校园无盘教学系统
- mysql命令行操作
- 笔记本Y400遇到的问题