#include<iostream>
#include<string>
#include<stdio.h>
#include<math.h>//平方 pow()
#include<graphics.h>//图形库插件
#include<conio.h>//_kbhit(),_getch()
#include<time.h>//srand()和rand()
#include<stdlib.h>//sleep()
#include<mmsystem.h>//mci
#pragma comment(lib,"winmm.lib")//告诉编译器加载winmm.lib库文件
using namespace std;
const int windowsLenth = 600;//创建的窗口的长
const int windowsWidth = 400;//宽
const int vx = -8;//column speed
const int gravity = 3;
const int radius = 10;//圆半径
//窗口句柄
HWND hwnd = NULL;
int main()//请从 项目 属性中把字符集改成多字节字符集,以运行程序。
{
Bird bird;
const int Num = 4;
//同一时间,屏幕上只有四个柱子,用数组存储
Column column1, column2, column3, column4;
column2.xCol -= windowsLenth / 4;
column3.xCol -= windowsLenth / 2;
column4.xCol -= 3 * windowsLenth / 4;
Column cArr[4] = { column1,column2,column3,column4 };
hwnd = initgraph(windowsLenth,windowsWidth);//利用easyX创建窗口
mciSendString(_T("play happyFly.mp3 repeat"), 0, 0, 0);//播放背景音乐
BeginBatchDraw();//双缓冲,消除闪烁
while (1)
{
bird.moveBird();
moveColumn(cArr,Num);
changeColumn(cArr, Num);//当柱子移动出了窗口,更改他的height,gap和x坐标等属性,让他从右侧再进入窗口
bird.drawBird();
drawColumn(cArr,Num);
FlushBatchDraw();//双缓冲,消除闪烁
if (isDie(bird,cArr,Num))
{
MessageBox(hwnd, "game over", "", 0);//弹出死亡窗口
break;
}
if (_kbhit())//按下按键
{
char key = _getch();
if (key == 32)//按的是空格
bird.jump();
}
//show grade//显示分数 还没有做
Sleep(100);
cleardevice();
}
_getch();
EndBatchDraw();
closegraph();
return 0;
}
从图片中可以看出,有一个“Bird”类和一个“Column”类。
class Bird
{
public:
Bird();
//~Bird();
const int xBird = 40;//圆心的X坐标,固定。
int yBird;//圆心的y坐标
int vY;//竖直方向的速度
const int vAfterJump = -15;//跳跃后的速度。
void jump();//当按下空格,速度变为vAfterJump
void moveBird();//随着时间,按照vY的值移动Bird的y坐标
void drawBird();//利用easy X里的画图的函数,按照坐标和圆半径画出Bird
};
我用Column的向左移动来假装是Bird向前飞行,所以Bird的x坐标是固定的。
由于在easy X创建的窗口里面,坐标原点在左上角,所以速度v的值为负数的时候,才是Bird向上跳。
class Column
{
public:
Column();
//~Column();
const int widthOfColumn = 20;//柱子的宽度
int heightOfBottomColumn;//底部柱子的高度
int gapOfTwoColumn;//底部和顶部柱子的间距
int xCol, yCol;//底部柱子左上角的坐标
};
用底部柱子的数据可以得到顶部柱子的数据。
void moveColumn(Column column[],int Num)//和moveBird同理
void drawColumn(Column column[],int Num)//和drawBird同理
void changeColumn(Column column[],int Num)
{
srand((unsigned int)time(NULL));
for (int i = 0;i < Num;i++)
{
if (column[i].xCol <= -20)
{
column[i].xCol = windowsLenth - column[i].widthOfColumn;
column[i].heightOfBottomColumn = rand() % 100 + 50;//随机50-149
column[i].gapOfTwoColumn = rand() % 50 + 100;
column[i].yCol = windowsWidth - column[i].heightOfBottomColumn;
}
}
}
最后是isDie的实现,使用圆形和矩形(不旋转)的碰撞检测。
详情可以看大佬的博客https://www.cnblogs.com/cmt/p/14553189.html
思路是找到矩形上离圆心最近的点的坐标,计算他和圆心的距离,与圆的半径比较大小。
当圆位于矩形左侧,最近的点的X坐标为矩形左上角的X坐标。
当圆位于矩形上下,最近的点的X坐标为圆心的X坐标。
当圆位于矩形右侧,最近的点的X坐标为矩形右下角的X坐标。
Y坐标同理。
具体的代码可以看这里https://github.com/Ann000hjt/MyFlappyBird
我还想加背景图片,还想给矩形贴上图,想把圆形变成别的,还想做成联机,还想用QT做,不过现在我还啥都不会。
Column也没能用链表写。
加油加油。