最近有我同学特意找到我让我给能不能给他女朋友做一个表白小程序,
我也是特意的学习了这个内容,用c/c++写了这个表白小程序。
现在我将这 个程序分享给需要的小伙伴们!写一个这样的程序需要准备一个
easyx图形库与之相应的vs版本。
exe程序的网盘地址: https://pan.baidu.com/s/1lgotVFD6iAwYVjRCgKRarw
提取码:4uvb
好的话不多说直接上代码:
#include<stdio.h>
#include<time.h>
#include<conio.h>
#include<graphics.h>//easyx图形库头文件
#include<math.h>
#include<string.h>
#include<iostream>
using namespace std;
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")
static time_t tt; //静态计时器
#define NUM 13
/*
程序里面用数据类型表示
*/
struct Jet {
int x, y; //烟花弹的坐标 当前的坐标
int hx, hy; //最高点坐标
bool shoot; //表示烟花弹的状态是否发射的状态
DWORD t1, t2, dt; //控制烟花弹的速度 //dt = d1-d2;
IMAGE img[2]; //定义两张图片 img[0]暗色img[1]亮色
byte n : 1; //微段 n是一个变量 n占一个位 也就是1/位
//img[n++]效果紧张内存奇怪的知识又增加了
}Jet[NUM];
struct HAPPY // 储存 Happy Birthday 艺术字图片
{
int x, y; // 每个字的图片的左上角坐标
IMAGE img; // 储存单个字图片
static int num; // 字母序号
}Happy[NUM];
int HAPPY::num = 0;
struct Fire {
int x, y; //烟花在窗口里面的坐标
int r; //烟花当前半径
int max_r; //烟花爆炸最大半径
int cent_x, cent_y;//在图片坐标系中心位置
int xy[240][240]; //240*240的像素点
bool show; //表示这个烟花是否开始爆炸
bool draw; //开始绘制
DWORD t1, t2, dt; //t2-t1=dt 单位时间控制爆炸速度
}Fire[NUM];
IMAGE flower, steping;
static int Count = 0;
void LoadSound() {
mciSendString(_T("open bk.mp3"), 0, 0, 0);
mciSendString(_T("open bomb.wav"), 0, 0, 0);
}
void style(time_t &t1) {
time_t t2;
setbkmode(TRANSPARENT);
COLORREF color = RGB(224, 255, 255);
//设置文本样式、
settextcolor(color);
settextstyle(100, 0, _T("黑体"));//字体的宽+字体的高+字体的风格
//输出文本信息
outtextxy(300, 50, _T("情书一封"));//文本坐标+文本内容
//设置文本颜色
settextcolor(WHITE);
//设置文本样式
settextstyle(50, 0, _T("微软雅黑"));//字体的宽+字体的高+字体的风格
//输出文本信息
time(&t2);
if (t2 - t1 == 2 && Count == 0) {
//cleardevice();
Count++;
}
if (t2 - t1 == 4 && Count == 1) {
//cleardevice();
Count++;
}
if (t2 - t1 == 6 && Count == 2) {
//cleardevice();
Count++;
}
if (t2 - t1 == 8 && Count == 3) {
//cleardevice();
Count++;
}
if (t2 - t1 == 8&& Count == 4) {
// cleardevice();
Count = 0;
}
if ((t2 - t1) < 2) {
//outtextxy(300, 50, _T("情书一封"));
outtextxy(250, 200, _T("我 听 见 雨 滴 落 在 青 青 草 地"));//本坐标+文本内容
outtextxy(250, 300, _T("我 听 见 远 方 下 课 钟 声 响 起"));
outtextxy(250, 400, _T("可 是 我 没 有 听 见 你 的 声 音"));//文//本坐标+文本内容
outtextxy(250, 500, _T("认 真 呼 唤 我 姓 名"));//文本坐标+文本内容
outtextxy(250, 600, _T("爱 上 你 的 时 候 还 不 懂 感 情"));//文本坐标+文本内容
}
else if ((t2 - t1) >= 6 && (t2 - t1) < 10) {
//outtextxy(300, 50, _T("情书一封"));
outtextxy(250, 300, _T("离 别 了 才 觉 得 刻 骨 铭 心"));//文本坐标+文本内容
outtextxy(250, 400, _T("为 什 么 没 有 发 现 遇 见 了 你"));
outtextxy(250, 500, _T("是 生 命 最 好 的 事 情"));//文本坐标+文本内容
outtextxy(250, 600, _T("也 许 当 时 忙 着 微 笑 和 哭 泣"));//文本坐标+文本内容
}
else if ((t2 - t1) >= 14 && (t2 - t1) < 18) {
//outtextxy(300, 50, _T("情书一封"));
outtextxy(250, 300, _T("忙 着 追 逐 天 空 中 的 流 星"));//文本坐标+文本内容
outtextxy(250, 400, _T("人 理 所 当 然 的 忘 记"));//文本坐标+文本内容
outtextxy(250, 500, _T("是 谁 风 里 雨 里 一 直 默 默 守 护 在 原 地"));//文本坐标+文本内容
outtextxy(250, 600, _T("原 来 你 是 我 最 想 留 住 的 幸 运"));//文本坐标+文本内容
}
else if ((t2 - t1) >= 22&&(t2-t1)<26) {
//outtextxy(300, 50, _T("情书一封"));
outtextxy(250, 300, _T("那 为 我 对 抗 世 界 的 决 定"));//文本坐标+文本内
outtextxy(250, 400, _T("那 陪 我 淋 的 雨"));//文本坐标+文本内容
outtextxy(250, 500, _T("一 幕 幕 都 是 你 一 尘 不 染 的 真 心"));//文本坐标+
outtextxy(250, 600, _T("与 你 相 遇 好 幸 运"));//文本坐标+
}
else if ((t2 - t1) >= 30 && (t2 - t1) < 34) {
settextstyle(125, 0, _T("黑体"));//字体的宽+字体的高+字体的风格
outtextxy(100, 400, _T("Hello Friends!"));//文本坐标+文本内
}
if (t2 - t1 >= 34) {
time(&t1);
}
}
//选择 出现! 一点时间间隔
void choose(DWORD &tt1) {
DWORD tt2 = GetTickCount();
if (tt2 - tt1 > 100) {
//1毫秒
int i = rand() % NUM; //0-12
if (Jet[i].shoot==false && Fire[i].show == false) {
//未发射状态 空闲
//数据重新规划
Jet[i].x = rand()%(1200-20); //初始化x坐标的范围
Jet[i].y = rand()%100+600;
Jet[i].hx = Jet[i].x; //直线上升
Jet[i].hy = rand()%400;
Jet[i].shoot = true;
putimage(Jet[i].x, Jet[i].y, &Jet[i].img[Jet[i].n]);
}
tt1 = tt2;
}
}
void init(int i) {
Jet[i].x = 0;
Jet[i].y = 0;
Jet[i].hx = 0;
Jet[i].hy = 0;
Jet[i].t1 = GetTickCount();//获取系统时间 返回值DWORD
Jet[i].t2 = 0;
Jet[i].dt = rand() % 10 + 1; //单位时间控制烟花弹是速度
Jet[i].n = 0;
Jet[i].shoot = false;
Fire[i].x = rand() % 1200;
Fire[i].y = rand() % 800; //烟花在窗口里面的坐标
Fire[i].r = 0; //烟花当前半径
Fire[i].max_r = 120; //烟花爆炸最大半径
Fire[i].cent_x = 120;
Fire[i].cent_y = 120; //在图片坐标系中心位置
//240*240的像素点
Fire[i].show = false; //表示这个烟花是否开始爆炸
Fire[i].draw = false; //开始绘制
Fire[i].t1 = GetTickCount();
Fire[i].dt = 5; //t2-t1=dt 单位时间控制爆炸速度
Fire[i].xy[240][240]; //保存图片的像素矩阵
}
void Load() {
mciSendString(_T("open bk.mp3"), 0, 0, 0);
//mciSendString(_T("open shoot.mp3"), 0, 0, 0);
//下午讲的是烟花
srand(time(NULL));
IMAGE bigimg; //一整张图片加载进去
loadimage(&bigimg, _T("shoot.jpg"), 200, 50);
SetWorkingImage(&bigimg);
// 搞事情
for (int i = 0; i < NUM; i++) {
int n = rand() % 5;
getimage(&Jet[i].img[0], 20 * n, 0, 20, 50);
getimage(&Jet[i].img[1], 20 * (n + 5), 0, 20, 50);
}
SetWorkingImage(NULL);//回到默认工作区
IMAGE flower, steping;
loadimage(&flower, _T("flower.jpg"));
for (int i = 0; i < NUM; i++) {
SetWorkingImage(&flower);
getimage(&steping, i * 240, 0, 240, 240);//第一张
SetWorkingImage(&steping);
for (int a = 0; a < 240; a++) {
for (int b = 0; b < 240; b++) {
Fire[i].xy[a][b] = getpixel(a, b); //获取小图片上的每一个像素,将每一个像素点放入数组中
}
}
}
SetWorkingImage(NULL);
IMAGE hm;
loadimage(&hm, _T("./fire/happy.jpg"), 689, 115);
SetWorkingImage(&hm);
for (int i = 0; i < 13; i++)
{
Happy[i].x = i * 90;
Happy[i].y = rand() % 100 + 500;
getimage(&Happy[i].img, i * 53, 0, 53, 115);
}
SetWorkingImage(); // 设置回绘图窗口
mciSendString(_T("play bk.mp3"), 0, 0, 0);
}
void shoot() {
for (int i = 0; i < NUM; i++) {
Jet[i].t2 = GetTickCount();
if (Jet[i].t2 - Jet[i].t1 > Jet[i].dt && Jet[i].shoot == true) {
putimage(Jet[i].x, Jet[i].y, &Jet[i].img[Jet[i].n], SRCINVERT); //n++
if (Jet[i].y > Jet[i].hy) {
Jet[i].n++;
Jet[i].y -= 5;
}
putimage(Jet[i].x, Jet[i].y, &Jet[i].img[Jet[i].n], SRCINVERT);
//到达最高点位置
if (Jet[i].y <= Jet[i].hy) {
mciSendString(_T("play shoot.mp3"), 0, 0, 0);
putimage(Jet[i].x, Jet[i].y, &Jet[i].img[Jet[i].n], SRCINVERT);
Fire[i].x = Jet[i].hx;
Fire[i].y = Jet[i].hy;
Fire[i].show = true;
Jet[i].shoot = false;
putimage(Happy[HAPPY::num].x, Happy[HAPPY::num].y, &Happy[HAPPY::num].img, SRCINVERT);
HAPPY::num++;
if (HAPPY::num > 12)
HAPPY::num = 0;
}
Jet[i].t1 = Jet[i].t2;
}
}
}
void flowerboomboomboom(DWORD* poem) {
//显存指针
for (int i = 0; i < NUM; i++) {
Fire[i].t2 = GetTickCount();
if (Fire[i].t2 - Fire[i].t1 >= Fire[i].dt && Fire[i].show == true) {
if (Fire[i].max_r > Fire[i].r) {
Fire[i].r++;//半径不断变大
Fire[i].draw = true;
}
//万一超过爆炸结束
if (Fire[i].r >= Fire[i].max_r - 1) {
Fire[i].draw = true;
init(i); //爆炸结束后给i重新初始化 其实这里面之用到了栈上面的13个内存,往返使用
}
//重置时间
Fire[i].t1 = Fire[i].t2;
//如果是可以绘制的状态
if (Fire[i].draw == true) {
//mciSendString(_T("open bomb.wav"), 0, 0, 0);
mciSendString(_T("play bomb.wav"), 0, 0, 0);
//不是贴图!! 输出像素点
for (double a = 0; a <= 6.28; a += 0.01) {
int x1 = (int)(Fire[i].cent_x + Fire[i].r * cos(a));
int y1 = (int)(Fire[i].cent_y - Fire[i].r * sin(a));
if (x1 > 0 && x1 < 240 && y1>0 && y1 < 240) {
//只取像素内部的点
int b = Fire[i].xy[x1][y1] & 0xff;
int g = (Fire[i].xy[x1][y1] >> 8) & 0xff;
int r = (Fire[i].xy[x1][y1] >> 16);
int xx = (int)(Fire[i].x + Fire[i].r * cos(a));
int yy = (int)(Fire[i].y - Fire[i].r * sin(a));
//这个点的颜色太黑不输出,防止越界
if (r > 0x20 && g > 0x20 && b > 0x20 && xx > 0 && xx < 1200 && yy>0 && yy < 800) {
poem[yy * 1200 + xx] = BGR(Fire[i].xy[x1][y1]);
}
}
Fire[i].draw = false;
}
}
}
}
}
void main() {
//mciSendString(_T("play shoot.wav"), 0, 0, 0);
initgraph(1200, 800);
//LoadSound();
//img[]
for (int i = 0; i < NUM; i++) {
init(i);
}
Load();
DWORD tt1 = GetTickCount();
IMAGE IMG;
//loadimage(&IMG, _T("shoot.jpg"), 200,50);
//putimage(0,0, &IMG);
DWORD* peom = GetImageBuffer();//获取显存指针
BeginBatchDraw();
time(&tt);
while (1) {
Sleep(10);
for (int c = 0; c < 1000; c++) {
for (int r = 0; r < 2; r++) {
int px1 = rand() % 1200;
int py1 = rand() % 800;
if (py1 < 799) {
peom[py1 * 1200 + px1] = peom[py1 * 1200 + px1 + 1] = BLACK;
}
//Sleep(10);
}
}
choose(tt1);
shoot();
flowerboomboomboom(peom);
style(tt);
FlushBatchDraw();
}
putimage(100, 100, &Jet[3].img[0]);
putimage(150, 100, &Jet[12].img[1]);
getchar();
return ;
}入代码片
我们做好后直接,当然这里面需要的图片素材我都上传上去了