本文主要是介绍【c语言小项目】基于easyX实现的《是男人就下一百层》小游戏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
创作不易,本篇文章如果帮助到了你,还请点赞 关注支持一下♡>𖥦<)!!
主页专栏有更多知识,如有疑问欢迎大家指正讨论,共同进步!
🔥c语言系列专栏:c语言之路重点知识整合 🔥
给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ
EeayX是针对 C/C++ 的简单图形库插件,本项目基于easyX游戏框架下实现是男人就下一百层游戏。
更多【c语言】小项目:
【c语言小项目】基于easyX的俄罗斯方块
【c语言小项目】基于easyX的贪吃蛇游戏
是男人就下一百层小游戏 目录
- 游戏介绍
- 游戏官网
- 运行示例:
- 全部代码:
- 图片文件
- easyX游戏框架
游戏介绍
NS-SHAFT是草薙昭彦开发的一款休闲过关小游戏。
此游戏于2002年开始在中国网络流行,被普遍命名为“是男人就下100层”,从名字上就能体现出此游戏的难度。
游戏玩法
使用方向键左右控制小人,防止被托上去挤死、掉下去摔死
游戏官网
游戏原版官网:NS-SHAFT 1.3J
运行示例:
全部代码:
(直接复制并配置图片文件路径就可以执行)
#include <easyx.h>
#include <time.h>
#include <conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string>
#include<graphics.h>
#include <mmsystem.h>
#include <windows.h>
//音乐
#include <graphics.h>
#include <mmsystem.h> // 包含MCI API函数的头文件
/*游戏界面绘制*/
void gamePaint();
/*游戏初始化绘制*/
void gameInit();
/*游戏定时处理*/
void gameInterval();
/*游戏键盘按下*/
void gameKeypress(int key);
/*游戏鼠标按下*/
void gameMouseDown(int mouseX,int mouseY);
/*游戏鼠标抬起*/
void gameMouseUp(int mouseX,int mouseY);
/*游戏鼠标移动*/
void gameMousemove(int mouseX,int mouseY);/*透明图绘制*/
void drawImage(IMAGE* picture, int picture_x, int picture_y); //x为要载入图片的X坐标,y为Y坐标
/*矩形碰撞检测*/
int testHit(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2 );/*设置100即每隔100毫秒刷新以下界面绘图。*/
int interval = 100;//TODO: 1 设置定时器时间间隔(单位毫秒)
// TODO: 1 设置窗口: 宽度 高度
int screenWidth = 632;
int screenHeight=430;
int stop = 0;
//-----------------------------------//
int times = 0;
int score = 0;
/*初始化游戏 */
void initgame()
{srand((unsigned)time(NULL));//随机数初始化setbkcolor(NULL);//背景色setbkmode(TRANSPARENT);// 设置背景混合模式: TRANSPARENT为透明gameInit();
}
/*界面绘图演示案例
*/
void paintDemo()
{/* 颜色设置://设置线的颜色 Blue Green Red 十六进制表示三原色setlinecolor(0x0000ff);//红色的 线//-设置填充的颜色setfillcolor(0x00ff00);//绿色的 填充//-设置字体的颜色settextcolor(0xff0000);//蓝色的 字体颜色*//* 画直线的案例setlinestyle(PS_DASH, 粗细); //PS_DASH 虚线 PS_SOLID 实现 PS_DOT 点线...line(点1x坐标 ,点1y坐标,点2x坐标 ,点2y坐标); //两点确定一条直线例如:setlinestyle(PS_DASH, 3);line(50 ,50,300 ,200); *//*绘制矩形1.空心矩形rectangle( 顶点x,顶点y,右下点x,右下点的y);按宽度 和 高度计算为rectangle( 顶点x,顶点y,顶点x+宽度,顶点y+高度);rectangle(x,y,x+width,y+height);2.实心矩形(无边框)solidrectangle( 顶点x,顶点y,顶点x+宽度,顶点y+高度); 3.实心矩形(有边框)fillrectangle( 顶点x,顶点y,顶点x+宽度,顶点y+高度); 例如: 绘制一个宽50 高50 的正方形rectangle( 100,100,100+50,100+50);fillrectangle( 100,100,100+50,100+50);*//*绘制圆形1、空心圆circle( 圆心x坐标,圆心y坐标,半径);2、实心圆(无边框)solidcircle( 圆心x坐标,圆心y坐标,半径);3、实心圆(有边框)fillcircle( 圆心x坐标,圆心y坐标,半径);例如: circle( 75,75,50);fillcircle( 75,75,50);*//*绘制文字1、设置字体样式settextstyle(字高, 0, _T("字体名称"));2、设置文字位置与内容outtextxy(x,y,L"文字内容");例如:settextstyle(46, 0, _T("黑体"));outtextxy(300,400,L"helloworld你好世界");*/settextstyle(20, 0, _T("宋体"));outtextxy(40, 390, L"天喜Studio");/*模板化 动态文字TCHAR str[100];_stprintf (str, L"%s的数学成绩是%d", L"小明",61);outtextxy(300,400,str );*//*贴图1、声明一个存放图片变量(为了节省图片变量内存空间,通常把其放到全局变量位置)IMAGE img1 ; 2、加载硬盘的图片到图片变量的内存地址loadimage(&img1, L".\\图片路径\\图片文件名" ); //.代表项目硬盘存储的位置3、把内存中的图片显示到界面上。putimage(x,y,&img1); *//*例如:贴一张图 //loadimage(&img, L".\\images\\jpg\\1\\image0.jpg") ; //图片不透明IMAGE img1 ;loadimage(&img1, L".\\images\\1\\image0.png") ; putimage(10,10,&img1);*//*例如:再贴一张图IMAGE img2;loadimage(&img2, L".\\images\\2\\image8.png") ; putimage(10,200,&img2); *//*例如:连续贴图,要求相同尺寸的图IMAGE img3;TCHAR imgPath[100];int i;for (i = 0; i <=23; i++){_stprintf (imgPath, L".\\images\\%d\\image%d.png", 3,i);loadimage(&img3,imgPath ) ; putimage(100*i,300,&img3); }*/}/*绘制显示游戏界面*/
void paint()
{BeginBatchDraw();//打开双缓冲cleardevice();// 清屏gamePaint();paintDemo();//-----------------------------//EndBatchDraw();//关闭双缓冲
}/*游戏运行*/
void run()
{ExMessage mouse ;//ExMessage key;while (1) // 游戏主循环 可借助break 结束循环{/*if (peekmessage(&mouse, -1, true)){mouse=getmessage();if (mouse.message == WM_LBUTTONDOWN ){gameMouseDown(mouse.x,mouse.y);}else if (mouse.message == WM_LBUTTONUP ){gameMouseUp(mouse.x,mouse.y);}else if(mouse.message == WM_MOUSEMOVE){gameMousemove(mouse.x,mouse.y);}paint();}*/if (peekmessage(&mouse, -1, true)){switch (mouse.message){case WM_KEYDOWN:gameKeypress(mouse.vkcode);break;}paint();continue;}/*if (_kbhit()){int k=_getch();gameKeypress(k);paint();}*///------时间处理 勿动-----------//Sleep(1);times++;if(times%(interval/10)!=0){continue;}times=0;if(stop){printf("Gmae Over!\n\n你的分数为:%d\n", score);break;}gameInterval();//-------------------------------//paint();// 刷新显示游戏界面}
}/*绘制透明背景图*/void drawImage(IMAGE* picture, int picture_x, int picture_y) //x为载入图片的X坐标,y为Y坐标
{// 变量初始化DWORD *dst = GetImageBuffer(); // GetImageBuffer()函数,用于获取绘图设备的显存指针,EASYX自带DWORD *draw = GetImageBuffer(); DWORD *src = GetImageBuffer(picture); //获取picture的显存指针int picture_width = picture->getwidth(); //获取picture的宽度,EASYX自带int picture_height = picture->getheight(); //获取picture的高度,EASYX自带int graphWidth = getwidth(); //获取绘图区的宽度,EASYX自带int graphHeight = getheight(); //获取绘图区的高度,EASYX自带int dstX = 0; //在显存里像素的角标// 实现透明贴图 公式: Cp=αp*FP+(1-αp)*BP , 贝叶斯定理来进行点颜色的概率计算for (int iy = 0; iy < picture_height; iy++){for (int ix = 0; ix < picture_width; ix++){int srcX = ix + iy * picture_width; //在显存里像素的角标int sa = ((src[srcX] & 0xff000000) >> 24); //0xAArrggbb;AA是透明度int sr = ((src[srcX] & 0xff0000) >> 16); //获取RGB里的Rint sg = ((src[srcX] & 0xff00) >> 8); //Gint sb = src[srcX] & 0xff; //Bif (ix >= 0 && ix <= graphWidth && iy >= 0 && iy <= graphHeight && dstX <= graphWidth * graphHeight){dstX = (ix + picture_x )+ (iy + picture_y ) * graphWidth; //在显存里像素的角标int dr = ((dst[dstX] & 0xff0000) >> 16);int dg = ((dst[dstX] & 0xff00) >> 8);int db = dst[dstX] & 0xff;draw[dstX] = ((sr * sa / 255 + dr * (255 - sa) / 255) << 16) //公式: Cp=αp*FP+(1-αp)*BP ; αp=sa/255 , FP=sr , BP=dr| ((sg * sa / 255 + dg * (255 - sa) / 255) << 8) //αp=sa/255 , FP=sg , BP=dg| (sb * sa / 255 + db * (255 - sa) / 255); //αp=sa/255 , FP=sb , BP=db}}}
}int testHit(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2 )
{return !(x1 + w1 < x2||y1 + h1 < y2 ||x2 + w2 <x1 ||y2 + h2<y1 );
}
// 主函数,开启游戏
int main ()
{initgraph(screenWidth, screenHeight); initgame(); // 初始化游戏paint();// 刷新显示游戏界面flushmessage(); // 清空鼠标缓冲区while (_kbhit()) _getch(); // 清空键盘缓冲区run(); // 开始游戏closegraph();//关闭图形环//LPCWSTR music_path = L".\\music\\BGM.mp3"; // 设置音乐文件的路径//char music_path_mb[256]; // 定义存储多字节格式字符串的缓存区//WideCharToMultiByte(CP_ACP, 0, music_path, -1, music_path_mb, 256, NULL, NULL); // 将Unicode字符串转换为ANSI格式字符串//PlaySound(music_path, NULL, SND_FILENAME | SND_ASYNC); // 播放音乐文件return 0;
}//TODO: 2 全局变量声明位置
int boardXs[100];//每个板子的x坐标int boardY = 300;//首个板子距离顶端的距离int manX;//人的x坐标
int manY;//人的y坐标//TODO: 3 游戏初始化位置 void gameInit()
{//初始化板子int i;for( i=0 ;i<100 ;i++ ){boardXs[i]=rand()%290+40;}//初始化人manX=boardXs[0]+30;// 人初始化要站在第0个板子上manY=boardY-30;}//TODO: 4 绘图处理位置
void gamePaint()
{//------------显示背景-------------------// IMAGE imgBg ;loadimage(&imgBg, L".\\images\\bg.png") ; drawImage( &imgBg,0,0);//------------显示人-------------------// IMAGE imgMan;loadimage(&imgMan, L".\\images\\man.PNG");putimage(manX, manY, &imgMan);//------------显示板子-------------------// IMAGE imgBoard;loadimage(&imgBoard, L".\\images\\board.PNG");int i;for (i = 0; i < 100; i++){putimage(boardXs[i], boardY + i * 50, &imgBoard);}
}//TODO: 5 定时处理位置
void gameInterval()
{boardY-=5;//板子上升int manStandOn = 0;//假设人每站在任何的板子上int i;for(i=0;i<100;i++){if( testHit(manX,manY,32,30,boardXs[i],boardY+i*50,95,15 )){manStandOn = 1;}}if (manStandOn){manY-=5;score++;}else{manY+=10;}if( manY< 70 || manY>420)//< 70代表顶端出界 >420代表底边出界{stop=1;}
}
//TODO: 6 处理键盘控制位置
void gameKeypress(int key)
{switch (key){case 'A':case 'a': // 左if (manX > 40){manX -= 10;}else{manX = 40;}break; case 'S':case 's': // 下break; case 'D':case 'd': // 右if (manX < 390){manX += 10;}else{manX = 390;}break; case 'W': // 上case 'w': break; case 72: //上break;case 80://下break;//case 75 ://左// if (manX>40)// {// manX-=10; // }// else// {// manX=40;// }// // break;case VK_LEFT://左if (manX > 40){manX -= 10;}else{manX = 40;}break;//case 77://右// if (manX<390)// {// manX+=10; // }// else// {// manX=390;// }// // break;case VK_RIGHT://右if (manX < 390){manX += 10;}else{manX = 390;}break;default://任意键break;}}//TODO: 7 处理鼠标控制位置
void gameMouseDown(int mouseX,int mouseY)
{}
void gameMouseUp(int mouseX,int mouseY)
{}
void gameMousemove (int mouseX,int mouseY)
{}
图片文件
尺寸大小可自己修改
easyX游戏框架
#define _CRT_SECURE_NO_WARNINGS 1
#include <easyx.h>
#include <time.h>
#include <conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string>
#include<graphics.h>/*游戏界面绘制*/
void gamePaint();
/*游戏初始化绘制*/
void gameInit();
/*游戏定时处理*/
void gameInterval();
/*游戏键盘按下*/
void gameKeypress(int key);
/*游戏鼠标按下*/
void gameMouseDown(int mouseX,int mouseY);
/*游戏鼠标右键按下*/
void gameMouseRightDown(int mouseX,int mouseY);
/*游戏鼠标抬起*/
void gameMouseUp(int mouseX,int mouseY);
/*游戏鼠标移动*/
void gameMousemove(int mouseX,int mouseY);/*
含透明的图的绘制
x为要载入图片的X坐标,y为Y坐标
*/
void drawImage(int picture_x, int picture_y,IMAGE* picture);
/*调整图片透明度角度转弧度:PI/180*角度弧度转角度:180/PI*弧度
*/
void drawImageAlpha(int x0, int y0, IMAGE* img, double f);
/*两个矩形碰撞检测
即两个矩形是否相交。x1, y1, w1, h1是第一个矩形的xy宽高的四个参数x2, y2, w2, h2是第二个矩形的xy宽高的四个参数返回0代表不相交 返回1代表相交
*/
int testHit(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2 );/*设置100即每隔100毫秒刷新以下界面绘图。*/
int interval = 100;//TODO: 1 设置定时器时间间隔(单位毫秒)
// TODO: 1 设置窗口: 宽度 高度
int screenWidth = 800;
int screenHeight=600;
int stop = 0;//是否停止游戏
//-----------------------------------//
int times = 0;
/*初始化游戏 */
void initgame()
{srand((unsigned)time(NULL));//随机数初始化setbkcolor(NULL);//背景色setbkmode(TRANSPARENT);// 设置背景混合模式: TRANSPARENT为透明gameInit();
}
/*-----天喜Studio-----
*//*绘制显示游戏界面*/
void paint()
{BeginBatchDraw();//打开双缓冲cleardevice();// 清屏gamePaint();//-----------------------------//EndBatchDraw();//关闭双缓冲
}/*游戏运行*/
void run()
{ExMessage msg ;//ExMessage key;while (1) // 游戏主循环 可借助break 结束循环{if (peekmessage(&msg,-1,true)){switch (msg.message){case WM_MOUSEMOVE://鼠标移动gameMousemove(msg.x, msg.y);break;case WM_LBUTTONDOWN://左键按下gameMouseDown(msg.x, msg.y);break;case WM_LBUTTONUP://左键抬起gameMouseUp(msg.x, msg.y);break;case WM_LBUTTONDBLCLK://左键双击break;case WM_RBUTTONDOWN://右键按下break;case WM_RBUTTONUP://右键抬起gameMouseRightDown(msg.x, msg.y);break;case WM_RBUTTONDBLCLK://右键双击break;case WM_KEYDOWN:gameKeypress(msg.vkcode);break;}paint();continue;}//------时间处理 勿动-----------//Sleep(1);times++;if(times%(interval/10)!=0){continue;}times=0;if(stop){break;}gameInterval();//-------------------------------//paint();// 刷新显示游戏界面}
}/*绘制透明背景图*/void drawImage(int picture_x, int picture_y,IMAGE* picture ) //x为载入图片的X坐标,y为Y坐标
{// 变量初始化DWORD *dst = GetImageBuffer(); // GetImageBuffer()函数,用于获取绘图设备的显存指针,EASYX自带DWORD *draw = GetImageBuffer(); DWORD *src = GetImageBuffer(picture); //获取picture的显存指针int picture_width = picture->getwidth(); //获取picture的宽度,EASYX自带int picture_height = picture->getheight(); //获取picture的高度,EASYX自带int graphWidth = getwidth(); //获取绘图区的宽度,EASYX自带int graphHeight = getheight(); //获取绘图区的高度,EASYX自带int dstX = 0; //在显存里像素的角标// 实现透明贴图 公式: Cp=αp*FP+(1-αp)*BP , 贝叶斯定理来进行点颜色的概率计算for (int iy = 0; iy < picture_height; iy++){for (int ix = 0; ix < picture_width; ix++){int srcX = ix + iy * picture_width; //在显存里像素的角标int sa = ((src[srcX] & 0xff000000) >> 24); //0xAArrggbb;AA是透明度int sr = ((src[srcX] & 0xff0000) >> 16); //获取RGB里的Rint sg = ((src[srcX] & 0xff00) >> 8); //Gint sb = src[srcX] & 0xff; //Bif (ix >= 0 && ix <= graphWidth && iy >= 0 && iy <= graphHeight && dstX <= graphWidth * graphHeight){dstX = (ix + picture_x )+ (iy + picture_y ) * graphWidth; //在显存里像素的角标if (dstX<0) continue;int dr = ((dst[dstX] & 0xff0000) >> 16);int dg = ((dst[dstX] & 0xff00) >> 8);int db = dst[dstX] & 0xff;draw[dstX] = ((sr * sa / 255 + dr * (255 - sa) / 255) << 16) //公式: Cp=αp*FP+(1-αp)*BP ; αp=sa/255 , FP=sr , BP=dr| ((sg * sa / 255 + dg * (255 - sa) / 255) << 8) //αp=sa/255 , FP=sg , BP=dg| (sb * sa / 255 + db * (255 - sa) / 255); //αp=sa/255 , FP=sb , BP=db}}}
}
/*调整图片透明度*/
void drawImageAlpha(int x0, int y0, IMAGE* img, double f)
{//获得图片尺寸int qwidth, qheight;qwidth = img->getwidth();qheight = img->getheight();//P图为背景图,RS为目标图片static IMAGE RS(qwidth, qheight);static IMAGE P(qwidth, qheight);//背景图的绘制getimage(&P, x0, y0, qwidth, qheight);//获取指针,作为透明度计算DWORD* M = GetImageBuffer(&P);DWORD* N = GetImageBuffer(img);DWORD* R = GetImageBuffer(&RS);// 开启批量绘图模式,解决闪烁问题BeginBatchDraw();//计算与赋值int i, j;for (i = 0; i < qheight; i++) {for (j = 0; j < qwidth; j++) {int r, g, b;int ij;//计算ij = i * qwidth + j;r = (int)((GetRValue(N[ij])) * (1 - f) + GetRValue(M[ij]) * f);g = (int)((GetGValue(N[ij])) * (1 - f) + GetGValue(M[ij]) * f);b = (int)((GetBValue(N[ij])) * (1 - f) + GetBValue(M[ij]) * f);R[ij] = RGB(r, g, b);}}//贴出图片并释放内存putimage(x0, y0, &RS);FlushBatchDraw();// 绘制
}
//检测两个矩形是否相碰撞
int testHit(int x1,int y1,int w1,int h1,int x2,int y2,int w2,int h2 )
{return !(x1 + w1 < x2||y1 + h1 < y2 ||x2 + w2 <x1 ||y2 + h2<y1 );
}
// 主函数,开启游戏
int main ()
{initgraph(screenWidth, screenHeight,SHOWCONSOLE); initgame(); // 初始化游戏paint();// 刷新显示游戏界面flushmessage(); // 清空鼠标缓冲区while (_kbhit()) _getch(); // 清空键盘缓冲区run(); // 开始游戏closegraph();//关闭图形环return 0;
}//--------------------------------//
//TODO: 2 全局变量声明位置 //TODO: 3 游戏初始化位置 void gameInit()
{}//TODO: 4 绘图处理位置
void gamePaint()
{}//TODO: 5 定时处理位置
void gameInterval()
{}
//TODO: 6 处理键盘控制位置
void gameKeypress(int key)
{switch (key ){case VK_LEFT:printf("按 左\n");break;case VK_RIGHT:printf("按 右\n");break;case VK_UP:printf("按 上\n");break;case VK_DOWN:printf("按 下\n");break;}switch (key ){case 'A':case 'a':printf("按 A\n");break;case 'B':case 'b':printf("按 B\n");break;case 'c':case 'C':printf("按 C\n");break;case 'D':case 'd':printf("按 d\n");break;}
}//TODO: 7 处理鼠标控制位置
void gameMouseDown(int mouseX,int mouseY)
{printf("按下鼠标左键\n");}
void gameMouseUp(int mouseX,int mouseY)
{}
void gameMousemove (int mouseX,int mouseY)
{}void gameMouseRightDown(int mouseX,int mouseY)
{}
大家的点赞、收藏、关注将是我更新的最大动力! 欢迎留言或私信建议或问题。 |
大家的支持和反馈对我来说意义重大,我会继续不断努力提供有价值的内容!如果本文哪里有错误的地方还请大家多多指出(●'◡'●) |
这篇关于【c语言小项目】基于easyX实现的《是男人就下一百层》小游戏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!