《c语言程序设计及应用》打砖块
- 格式:docx
- 大小:26.26 KB
- 文档页数:19
MFC课程设计说明书●设计题目:打砖块游戏●所属系部:计算机工程系●专业:计算机科学与技术●学号:XXXX XXX●姓名:XXXX●指导教师:XXXX●设计日期:12-26一、设计任务1.1任务描述使用MFC框架设计一个打砖块游戏。
在客户区内显示砖块分布,小球和托盘。
按空格键开始游戏,Esc键结束游戏。
开始游戏小球可以跳起来打砖块,移动鼠标实现托盘的移动,打到的砖块消失。
如果托盘没有接到小球,那么生命值减一,共有三次生命,生命都用完时,可以继续或结束。
1.2设计要求1.自定义屏幕二维坐标系:x轴水平向右为正,y轴垂直向上为正,坐标系原点位于客户区中心。
2.新加上两个类Brick类和Baffle类,分别用来定义并绘制砖块和托盘。
3.使用定时器函数控制小球的运动。
4.使用双缓冲技术实现动画。
5.在TestView类中实现砖块的分布6.添加函数实现小球各种的碰撞速度大小和方向的改变。
7.添加函数实现鼠标移动控制托盘。
1.3效果图设计效果图如图1所示。
图1 小球打砖块效果图二、设计思路本设计首先构建双缓冲框架,小球和砖块、客户区边界发生碰撞后,改变运动方向。
设置游戏关卡并绘制砖块分布。
鼠标移动控制托盘。
托盘没有接住小球,生命值则减一。
游戏结束时显示对话框以便继续或退出游戏。
三、关键源代码及注释3.1 关于窗口外观设计的代码:int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CFrameWnd::OnCreate(lpCreateStruct) == -1)return -1;SetMenu(NULL);//去掉菜单栏CMenu* p=GetSystemMenu(FALSE);p->RemoveMenu(SC_SIZE,MF_BYCOMMAND);//禁止改变窗口大小return 0;}BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs){if( !CFrameWnd::PreCreateWindow(cs) )return FALSE;the CREATESTRUCT cscs.style &=~(WS_MAXIMIZEBOX); //过滤最大化cs.x = 100;cs.y = 100;cs.cx = 809;cs.cy = 610;return TRUE;}3.2 Baffle类中的各种定义CBaffle::CBaffle(double x,double y,double w,double h,double s) {m_XPos=x,m_YPos=y;m_Width=w,m_Height=h,m_HalfW=w/2.0,m_HalfH=h/2.0;m_Speed=s,m_PreXPos=x;}void CBaffle::SetPositionX(double x)//设置x方向位置{m_PreXPos=m_XPos;m_XPos=x;}void CBaffle::SetPositionY(double y)//设置y方向位置{m_YPos=y;}void CBaffle::SetWidth(double w)//设置宽度{m_Width=w;m_HalfW=w/2.0;}void CBaffle::SetHeight(double h)//设置高度{m_Height=h;m_HalfH=h/2.0;}void CBaffle::CalculateSpeed()//速度计算{m_Speed=(m_XPos-m_PreXPos);}void CBaffle::DrawBaffle(CDC* pDC)//绘制托盘{CDC MemDC;MemDC.CreateCompatibleDC(pDC);CBitmap NewBitmap,*pOldBitmap;NewBitmap.LoadBitmap(IDB_BAFFLE);pOldBitmap=MemDC.SelectObject(&NewBitmap);pDC->BitBlt(int(m_XPos-m_HalfW),int(m_YPos-m_HalfH+2),int(m_Width),int(m_Height) ,&MemDC,0,0,SRCCOPY);MemDC.DeleteDC();}void CBaffle::SetSpeed(double s){m_Speed=s;//设置速度}3.3 Brick类中的各种定义CBrick::CBrick(double x,double y,double w,double h){m_XPos=x,m_YPos=y;m_Width=w,m_Height=h;m_HalfW=w/2.0,m_HalfH=h/2.0;m_Enable=TRUE;m_Score=0;m_Color=RGB(255,255,255);}void CBrick::SetEnable(){m_Enable=TRUE;}void CBrick::SetDisable(){m_Enable=FALSE;}void CBrick::SetPosition(double x,double y)//设置坐标{m_XPos=x,m_YPos=y;}void CBrick::SetWidth(double w){m_Width=w,m_HalfW=w/2;}void CBrick::SetHeight(double h){m_Height=h,m_HalfH=h/2;}void CBrick::SetColor(COLORREF clr){m_Color=clr;}void CBrick::SetScore(int value){m_Score=value;}void CBrick::DrawBrick(CDC *pDC,double& c,double& d)//绘制砖块{CDC MemDC;MemDC.CreateCompatibleDC(pDC);CBitmap NewBitmap,*pOldBitmap;NewBitmap.LoadBitmap(IDB_BRICK);double dx=c-m_HalfW;double dy=d-m_HalfH;pOldBitmap=MemDC.SelectObject(&NewBitmap);pDC->BitBlt(int(dx),int(dy),int(m_Width),int(m_Height),&MemDC,0,0,SRCCOPY);MemDC.DeleteDC();}3.4 双缓冲函数void CTestView::DoubleBuffer()//双缓冲{CDC* pDC=GetDC();GetClientRect(&rect);//获得客户区的大小pDC->SetMapMode(MM_ANISOTROPIC);//pDC自定义坐标系pDC->SetWindowExt(rect.Width(),rect.Height());//设置窗口范围pDC->SetViewportExt(rect.Width(),-rect.Height());//x轴水平向右,y轴垂直向上pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//屏幕中心为原点CDC MemDC;//内存DCCBitmap NewBitmap,*pOldBitmap;//内存中承载图像的临时位图MemDC.CreateCompatibleDC(pDC);//建立与屏幕pDC兼容的MemDCNewBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());//创建兼容位图pOldBitmap=MemDC.SelectObject(&NewBitmap);//将兼容位图选入MemDCMemDC.SetMapMode(MM_ANISOTROPIC);//MemDC自定义坐标系MemDC.SetWindowExt(rect.Width(),rect.Height());MemDC.SetViewportExt(rect.Width(),-rect.Height());MemDC.SetViewportOrg(rect.Width()/2,rect.Height()/2);DrawObject(&MemDC);BorderTest();pDC->BitBlt(-rect.Width()/2,-rect.Height()/2,rect.Width(),rect.Height(),&MemDC, -rect.Width()/2,-rect.Height()/2,SRCCOPY);//将内存位图拷贝到屏幕MemDC.SelectObject(pOldBitmap);//恢复位图NewBitmap.DeleteObject();//删除位图MemDC.DeleteDC();//删除MemDCReleaseDC(pDC);//释放DC}3.5 插入背景位图函数CBitmap m_bmp;m_bmp.LoadBitmap(IDB_BITMAP2);BITMAP bm;m_bmp.GetBitmap(&bm);CDC dcMem;dcMem.CreateCompatibleDC(pDC);CBitmap*pOldbmp=dcMem.SelectObject(&m_bmp);pDC->BitBlt(-Rect.Width()/2,-Rect.Height()/2,Rect.Width(),Rect.Height(),&dcMem,0,0,SR CCOPY);dcMem.SelectObject(pOldbmp);3.6 插入文字代码:CString str;str="打砖块游戏";int x,y;CSize size;pDC->SetTextColor(RGB(255,0,180));str.Format("%s",str);size=pDC->GetTextExtent(str,str.GetLength());x=(int)((double)(-25));y=(int)((double)(Rect.Height()/2-10));pDC->TextOut(x,y,str);str="游戏规则:按空格键或鼠标右键开始,按Esc键暂停。
打砖块代码课程设计一、课程目标知识目标:1. 让学生掌握编程语言的基本语法和结构,理解打砖块游戏的逻辑和规则。
2. 学习运用循环、条件语句和函数等编程概念,实现打砖块游戏的基本功能。
3. 了解游戏开发中的坐标系和碰撞检测原理。
技能目标:1. 培养学生独立编写代码、调试程序和解决问题的能力。
2. 提高学生在团队协作中沟通、分享和共同解决问题的能力。
3. 培养学生的创新思维和审美意识,能够设计美观、有趣的游戏界面。
情感态度价值观目标:1. 激发学生对编程和计算机科学的兴趣,树立学习自信心。
2. 培养学生面对困难和挑战时,保持积极、主动、坚持的态度。
3. 培养学生的团队精神和责任感,学会尊重和欣赏他人的成果。
课程性质:本课程为实践性强的编程课程,结合具体案例,让学生在动手实践中掌握编程知识和技能。
学生特点:学生处于好奇心强、求知欲旺盛的年级,喜欢探索新事物,有一定的逻辑思维能力。
教学要求:注重理论与实践相结合,关注学生个体差异,提供个性化指导,鼓励学生发挥创意,培养解决问题和团队协作能力。
通过本课程的学习,使学生达到预定的学习成果。
二、教学内容1. 编程语言基础:回顾变量、数据类型、运算符等基本概念,确保学生能够熟练运用。
2. 控制结构:讲解循环结构(for、while)、条件语句(if-else)的使用,为游戏逻辑提供支持。
3. 函数与模块:介绍函数的定义、调用和返回值,使学生能够模块化编程,提高代码可读性。
4. 游戏设计原理:学习坐标系、运动和碰撞检测等游戏开发基本原理。
5. 打砖块游戏实现:根据教材相关章节,分解游戏开发步骤,包括:- 游戏界面的设计和绘制- 砖块和球拍对象的创建与控制- 球的运动和碰撞处理- 游戏逻辑和得分系统6. 调试与优化:教授学生如何调试程序、查找和修复错误,以及优化代码性能。
7. 项目实践:安排课时让学生团队协作,完成打砖块游戏的开发,鼓励创新和美化界面。
教学进度安排:- 第一周:复习编程语言基础,讲解控制结构。
C语言小游戏源代码《打砖块》#include "graphics.h"#include "stdio.h"#include "conio.h" /*所需的头文件*/int on; /*声明具有开关作用的全局变量*/static int score; /*声明静态的记分器变量*//* 定义开始界面函数*/int open(){setviewport(100,100,500,380,1); /*设置图形窗口区域*/ setcolor(4); /*设置作图色*/rectangle(0,0,399,279); /*以矩形填充所设的图形窗口区域*/ setfillstyle(SOLID_FILL,7); /*设置填充方式*/floodfill(50,50,4); /*设置填充范围*/setcolor(8);settextstyle(0,0,9); /*文本字体设置*/outtextxy(90,80,"BALL"); /*输出文本内容*/ settextstyle(0,0,1);outtextxy(110,180,"version 1.0");outtextxy(110,190,"made by ddt");setcolor(128);settextstyle(0,0,1);outtextxy(120,240,"Press any key to continue......");}/*定义退出界面函数*/int quitwindow(){char s[100]; /*声明用于存放字符串的数组*/setviewport(100,150,540,420,1);setcolor(YELLOW);rectangle(0,0,439,279);setfillstyle(SOLID_FILL,7);floodfill(50,50,14);setcolor(12);settextstyle(0,0,8);outtextxy(120,80,"End");settextstyle(0,0,2);outtextxy(120,200,"quit? Y/N");sprintf(s,"Your score is:%d",score);/*格式化输出记分器的值*/ outtextxy(120,180,s);on=1; /*初始化开关变量*/}/*主函数*/main(){int gdriver,gmode;gdriver=DETECT; /*设置图形适配器*/gmode=VGA; /*设置图形模式*/registerbgidriver(EGAVGA_driver); /*建立独立图形运行程序*/ initgraph(&gdriver,&gmode,""); /*图形系统初试化*/ setbkcolor(14);open(); /*调用开始界面函数*/getch(); /*暂停*/while(1) /*此大循环体控制游戏的反复重新进行*/{intdriver,mode,l=320,t=400,r,a,b,dl=5,n,x=200,y=400,r1=10,dx=-2,dy=-2;/*初始化小球相关参数*/intleft[100],top[100],right[100],bottom[100],i,j,k,off=1,m,num[100][ 100];/*方砖阵列相关参数*/static int pp;static int phrase; /*一系列起开关作用的变量*/int oop=15;pp=1;score=0;driver=DETECT;mode=VGA;registerbgidriver(EGAVGA_driver);initgraph(&driver,&mode,"");setbkcolor(10);cleardevice(); /*图形状态下清屏*/clearviewport(); /*清除现行图形窗口内容*/b=t+6;r=l+60;setcolor(1);rectangle(0,0,639,479);setcolor(4);rectangle(l,t,r,b);setfillstyle(SOLID_FILL,1);floodfill(l+2,t+2,4);for(i=0,k=0;i<=6;i++) /*此循环绘制方砖阵列*/ {top[i]=k;bottom[i]=top[i]+20;k=k+21;oop--;for(j=0,m=0;j<=7;j++){left[j]=m;right[j]=left[j]+80;m=m+81;setcolor(4);rectangle(left[j],top[i],right[j],bottom[i]); setfillstyle(SOLID_FILL,j+oop);floodfill(left[j]+1,top[i]+1,4);num[i][j]=pp++;}}while(1) /*此循环控制整个动画*/{while(!kbhit()){x=x+dx; /*小球运动的圆心变量控制*/y=y+dy;if(x+r1>r||x+r1<r){ phrase=0;}if((x-r1<=r||x+r1<=r)&&x+r1>=l){if(y<t)phrase=1;if(y+r1>=t&&phrase==1){dy=-dy;y=t-1-r1;}}if(off==0)continue;for(i=0;i<=6;i++) /*此循环用于判断、控制方砖阵列的撞击、擦除*/for(j=0;j<=7;j++){if((x+r1<=right[j]&&x+r1>=left[j])||(x-r1<=right[j]&&x-r1>=left[j])){if(( y-r1>top[i]&&y-r1<=bottom[i])||(y+r1>=top[i]&&y+r1<=bottom[i] )) {if(num[i][j]==0){continue; }setcolor(10);rectangle(left[j],top[i],right[j],bottom[i]);setfillstyle(SOLID_FILL,10);floodfill(left[j]+1,top[i]+1,10);dy=-dy;num[i][j]=0;score=score+10;printf("%d\b\b\b",score);}}if((y+r1>=top[i]&&y+r1<=bottom[i])||(y-r1>=top[i]&&y-r1<=bottom[i])){if((x+r1>=left[j]&&x+r1<right[j])||(x-r1<=right[j]&&x-r1>left[j])){if(num[i][j]==0){ continue;}setcolor(10);rectangle(left[j],top[i],right[j],bottom[i]);setfillstyle(SOLID_FILL,10);floodfill(left[j]+1,top[i]+1,10);dx=-dx;num[i][j]=0;score=score+10;printf("%d\b\b\b",score);}}}if(x+r1>639) /*控制小球的弹射范围*/{dx=-dx;x=638-r1;}if(x<=r1){dx=-dx;x=r1+1;}if(y+r1>=479){off=0;quitwindow();break;}if(y<=r1){dy=-dy;y=r1+1;}if(score==560){off=0;quitwindow();break;}setcolor(6);circle(x,y,r1);setfillstyle(SOLID_FILL,14);floodfill(x,y,6);delay(1000);setcolor(10);circle(x,y,r1);setfillstyle(SOLID_FILL,10);floodfill(x,y,10);}a=getch();setcolor(10);rectangle(l,t,r,b);setfillstyle(SOLID_FILL,10);floodfill(l+2,t+2,10);if(a==77&&l<=565) /*键盘控制设定*/ {dl=20;l=l+dl;}if(a==75&&l>=15){dl=-20;l=l+dl;}if(a=='y'&&on==1)break;if(a=='n'&&on==1)br</right[j])||(x-r1<=right[j]&&x-r1></t) </r)eak;if(a==27){quitwindow();off=0;}r=l+60;setcolor(4);rectangle(l,t,r,b);setfillstyle(SOLID_FILL,1);floodfill(l+5,t+5,4);delay(100);}if(a=='y'&&on==1) /*是否退出游戏*/ {break;}if(a=='n'&&on==1){ continue;}}closegraph();}。
课程设计基于c 打砖块游戏一、教学目标本次课程的教学目标是让学生通过学习C语言编程,掌握使用C语言开发一个简单的“打砖块”游戏。
具体目标如下:1.理解C语言的基本语法和数据结构。
2.掌握C语言的函数定义和调用。
3.学习C语言的图形库,了解如何绘制图形和处理图形事件。
4.能够使用C语言编写简单的程序。
5.能够使用C语言的图形库开发图形界面。
6.能够独立完成一个简单的“打砖块”游戏的设计和开发。
情感态度价值观目标:1.培养学生对编程的兴趣和热情。
2.培养学生解决问题的能力和创新精神。
3.培养学生团队合作和分享的意识。
二、教学内容本次课程的教学内容主要包括C语言的基本语法、数据结构、函数定义和调用,以及C语言的图形库。
具体安排如下:1.C语言的基本语法和数据结构(2课时)2.C语言的函数定义和调用(2课时)3.C语言的图形库和图形界面设计(2课时)4.“打砖块”游戏的设计和开发(4课时)三、教学方法为了激发学生的学习兴趣和主动性,本次课程将采用多种教学方法,包括讲授法、讨论法、案例分析法和实验法。
1.讲授法:用于讲解C语言的基本语法、数据结构和函数定义和调用。
2.讨论法:用于讨论“打砖块”游戏的设计思路和解决方案。
3.案例分析法:通过分析已有的“打砖块”游戏案例,帮助学生理解游戏开发的流程和技巧。
4.实验法:让学生通过实际编写代码和调试程序,掌握C语言编程和游戏开发的方法。
四、教学资源为了支持教学内容和教学方法的实施,丰富学生的学习体验,我们将准备以下教学资源:1.教材:《C程序设计语言》2.参考书:《C语言编程实例教程》3.多媒体资料:教学PPT、视频教程4.实验设备:计算机、编程软件以上教学资源将帮助学生更好地学习和掌握C语言编程和“打砖块”游戏开发的知识和技能。
五、教学评估本次课程的评估方式包括平时表现、作业和考试三个方面,以全面客观地评价学生的学习成果。
1.平时表现(30%):通过学生在课堂上的参与度、提问回答、小组讨论等表现来评估。
打砖块游戏源代码说明本游戏的设计步骤:一、布局界面(把图片资源拉进Main。
storyboard)二、让小球动起来(给他一个初速度)三、碰撞检测1、屏幕碰撞2、砖块碰撞3、挡板碰撞四、挡板移动//ViewController。
h#import<UIKit/UIKit。
h>@interfaceViewController:UIViewController@property(strong,nonatomic)IBOutletCollection(UIImageView)NSArray*blockImageArray;@property(weak,nonatomic)IBOutletUIImageView*paddleImage;@property(weak,nonatomic)IBOutletUIImageView*ballImage;@end//ViewController。
m#import"ViewController。
h"@interfaceViewController(){//用这个布尔值标示游戏是否正在进行中BOOLisPlaying;//加一个游戏时钟CADisplayLink*_gameTimer;//小球移动的速度CGPoint_speed;//手指移动位置的差值CGFloatchaX;}//1.检测屏幕碰撞-(BOOL)checkWithScreen;//2.砖块碰撞检测-(BOOL)checkWithBlock;//3.挡板碰撞-(void)checkWithPandle;@end@implementationViewController-(void)viewDidLoad{[superviewDidLoad];}#pragmamark1之前进行了页面的布局//开始游戏-(void)touchesEnded:(NSSet<UITouch*>*)toucheswithEvent:(UIEvent*)event{//游戏是否在进行中,如果游戏还没有开始就让游戏开始if(!isPlaying){isPlaying=YES;//初始化一个游戏时钟,让step方法1/60秒执行一次_gameTimer=[CADisplayLinkdisplayLinkWithTarget:selfselector:@selector(step)];//将游戏放在runloop中/***runLoop做两件事情1.监听输入源,一般自动放到runLoop中2.监听定时器,一般需手动放到runLoop中*///[_gameTimeraddToRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSDefaultRunLoopMode];[_gameTimeraddToRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSDefaultRunLoopMode];//给小球一个初始的速度_speed=CGPointMake(0,-5);}else{chaX=0;}}#pragmamark2让小球动起来//让小球按照1/60的频率动起来-(void)step{//如果返回值是yes就代表游戏失败if([selfcheckWithScreen]){[selfgameOver:@"再来一次"];}if([selfcheckWithBlock]){[selfgameOver:@"你真棒"];}[selfcheckWithPandle];//小球每次的移动都是以上一次的位置作为参考_ballImage。
*************面向对象方法及程序设计课程设计报告打砖块游戏的设计与开发分组:第九组组员姓名:********************班级: ***********指导教师: ****完成日期:2014年 06月21日题目:打砖块游戏的开发与设计为了加强计算机科学与技术专业学生的学科实践能力,巩固和强化所学专业知识,提高学生的学习兴趣,本课程设计实践周特别强调理论与实践相结合,利用所学专业知识,进行实践项目的开发,提高学生的实践编程能力和技术文档的写作能力,提高学生的学习兴趣,,为后期的学习奠定一定的实践基础。
目录第一章课程设计的目的与要求 (3)1.1课程设计目的 (3)1.2 课程设计的实验环境 (3)1.3 课程设计的预备知识 (3)1.4课程设计要求 (3)1.4.1人员分配,形成课程设计小组 (3)1.4.2 分析课程设计的题目要求 (3)1.4.3写出详细的设计说明 (3)第二章课程设计内容 (3)2.1设计思路 (3)2.2功能介绍 (4)2.3相关素材 (4)2.4程序整体设计说明 (4)2.5程序部分源代码及注释 (4)2.6程序结构流程图 (6)2.7程序代码 (6)2.8运行程序 (17)第三章课程设计总结 (17)第一章课程设计的目的与要求1.1课程设计目的本次课程设计是计算机科学与技术专业最重要的实践环节之一。
本次课程设计的目的和任务:1.巩固和加深学生对VC++语言的基本知识的理解和掌握;2.掌握VC++语言编程和程序调试的基本技能;3.利用VC++语言进行基本的软件设计;4.掌握书写程序设计说明文档的能力;5.提高运用VC++解决实际问题的能力;1.2 课程设计的实验环境硬件环境要求能运行Windows 2000/XP操作系统的微机系统,VC++程序设计及相应的开发环境。
1.3 课程设计的预备知识熟悉C语言及C语言的开发工具1.4课程设计要求1.4.1人员分配,形成课程设计小组按照指导教师的要求,参与课程设计的同学根据彼此学习间的默契度以及在游戏设计上想法的不谋而合,自由的选择自己的队友,形成课题设计小组。
c 课程设计打砖块一、教学目标本课程的教学目标是使学生掌握C语言的基本语法和编程技巧,学会使用C语言进行程序设计,培养学生的逻辑思维能力和创新能力。
具体分解为以下三个方面的目标:1.知识目标:使学生了解C语言的基本概念、语法规则和编程方法,掌握常用的数据类型、运算符、控制结构、函数等编程基础,理解面向对象编程的基本思想。
2.技能目标:培养学生使用C语言进行程序设计的能力,学会调试和优化程序,能够独立完成中等难度的编程任务。
3.情感态度价值观目标:培养学生对计算机科学的兴趣和热情,增强学生的自信心和自主学习能力,培养学生在面对困难时勇于挑战、积极解决问题的精神。
二、教学内容根据教学目标,本课程的教学内容主要包括以下几个部分:1.C语言的基本概念:变量、数据类型、运算符、表达式等。
2.控制结构:顺序结构、选择结构、循环结构等。
3.函数:函数的定义、声明、调用、返回值等。
4.数组和字符串:一维数组、多维数组、字符串的基本操作等。
5.指针:指针的基本概念、指针与数组、指针与函数等。
6.面向对象编程:类和对象、构造函数、析构函数、继承和多态等。
7.编程实践:使用C语言编写简单的程序,学会调试和优化程序。
三、教学方法为了实现教学目标,本课程将采用以下几种教学方法:1.讲授法:教师讲解C语言的基本概念、语法规则和编程方法,引导学生掌握编程基础。
2.案例分析法:通过分析典型的编程案例,使学生理解编程思想,培养学生的实际编程能力。
3.实验法:安排上机实验,让学生亲自动手编写程序,巩固所学知识,提高编程技巧。
4.讨论法:学生进行小组讨论,分享学习心得和经验,互相促进,共同提高。
四、教学资源为了支持教学内容和教学方法的实施,本课程将采用以下教学资源:1.教材:《C程序设计语言》(K&R著)或《C Primer Plus》(Stephen Prata著)。
2.参考书:《C语言程序设计教程》(谭浩强著)、《C++ Primer》(Stanley B. Lippman著)。
C打砖块源代码1.课程设计的具体工作内容:1) 弹球区域下方为横板接球,上方为砖块。
2) 通过键盘的左、右光标键控制接球横版的移动。
3) 小球落到横板水平线,横板未接注小球,本局结束。
4) 小球弹起碰到的砖块自动打碎、消失。
5) 每隔一定时间(例如5s,可适当调整),砖块上方增加一行,原有砖块下移,砖块增加到横板水平线本局结束结束。
6) 小球与横板为完全弹性碰撞,不考虑能量损耗。
7) 每次游戏开始后有三局(或更多,可适当调整),三局都结束游戏重新开始。
2. 打砖块小游戏C语言源代码:#include#include#include#include#define R 4 /*球半径*/struct box{ int x;int y;int color;}a[6][14];int Keystate;int MouseExist;int MouseButton;int MouseX;int MouseY=400;int dx=1,dy=1; /*计算球的反弹*/int sizex=18,sizey=10; /*box的宽度和长度*/void draw(int x,int y) /* x, y为左上角坐标sizex,sizey 为长和宽*/{int sizx=sizex-1;int sizy=sizey-1;setcolor(15);/*这里最好用白色*/line(x,y,x+sizx-1,y);line(x,y+1,x+sizx-2,y+1);line(x,y,x,y+sizy-1);line(x+1,y,x+1,y+sizy-2);setcolor(8);/*这里最好用深灰色*/line(x+1,y+sizy,x+sizx,y+sizy);line(x+2,y+sizy-1,x+sizx,y+sizy-1);line(x+sizx-1,y+1,x+sizx-1,y+sizy);line(x+sizx,y+2,x+sizx,y+sizy);setcolor(7);/*这里最好用灰色*/putpixel(x,y+sizy,3);putpixel(x+1,y+sizy-1,3);putpixel(x+sizx,y,3);putpixel(x+sizx-1,y+1,3);setfillstyle(1, 7);/*这里最好用灰色,设置填充模式*/ bar(x+2,y+2,x+sizx-2,y+sizy-2);}void picture() /*画box*/{ int i,j;setcolor(15);rectangle(99,49,413,451);for(i=0;i<6;i++)for(j=0;j<14;j++){ a[i][j].color=0;a[i][j].x=104+j*22;a[i][j].y=54+i*14;draw(104+j*22,54+i*14);}sizex=50,sizey=5;}/*鼠标光标显示*/void MouseOn(int x,int y){draw(x,y);}/*隐藏鼠标*/void MouseOff(){int x,y;x=MouseX;y=MouseY;setfillstyle(1,0);bar(x,y,x+sizex,y+sizey);}/*鼠标是否加载MouseExist:1=加载0=未加载MouseButton:鼠标按键数目*/ void MouseLoad() {_AX=0x00;geninterrupt(0x33); MouseExist=_AX; MouseButton=_BX;}/*鼠标状态值初始化*/void MouseReset(){_AX=0x00;geninterrupt(0x33);}/*设置鼠标左右边界lx:左边界gx:右边界*/void MouseSetX(int lx,int rx) { _CX=lx;_DX=rx;_AX=0x07;geninterrupt(0x33);}/*设置鼠标上下边界uy:上边界dy:下边界*/void MouseSetY(int uy,int dy) {_CX=uy;_DX=dy;_AX=0x08;geninterrupt(0x33);}/*设置鼠标当前位置x:横向坐标y:纵向坐标*/void MouseSetXY(int x,int y) {_CX=x;_DX=y;_AX=0x04;geninterrupt(0x33);}/*设置鼠标速度(缺省值:vx=8,vy=1) 值越大速度越慢*/ void MouseSpeed(int vx,int vy){_CX=vx;_DX=vy;_AX=0x0f;geninterrupt(0x33);}/*获取鼠标当前位置*/void MouseGetXY(){_AX=0x03;geninterrupt(0x33);MouseX=_CX;MouseY=_DX;}void MouseStatus()/*鼠标按键情况*/ {int x;int status;status=0;/*默认鼠标没又移动*/x=MouseX;if(x==MouseX&&status==0) /*鼠标没动*/ { MouseGetXY();if(MouseX!=x)if(MouseX+50<413)status=1;}if(status)/*移动情况才重新显示鼠标*/{setfillstyle(1,0);bar(x,MouseY,x+sizex,MouseY+sizey);MouseOn(MouseX,MouseY);/*新位置显示*/ }}void Move(){int ballX; /*球的圆心*/int ballY=MouseY-R;int i,j,t=0;randomize();while(ballX=random(409))if(ballX>=105 && ballX<=408)break;while(kbhit){MouseStatus();if(ballY<=(58-R)) /*碰上反弹*/dy*=(-1);if(ballX>=(413-R)||ballX<=(108-R)) /*碰左右反弹*/ dx*=(-1);setcolor(YELLOW);circle(ballX+=dx,ballY-=dy,R-1);delay(2500);setcolor(0);circle(ballX,ballY,R-1);for(i=0;i<6;i++)for(j=0;j<14;j++) /*判断是否传记撞击box*/if(t<84&&a[i][j].color==0 && ballX>=a[i][j].x && ballX<=a[i][j].x+18&& ballY>=a[i][j].y && ballY<=a[i][j].y+10)dy*=(-1);a[i][j].color=1;setfillstyle(1,0);bar(a[i][j].x,a[i][j].y,a[i][j].x+18,a[i][j].y+10);}if(ballX==MouseX||ballX==MouseX-1||ballX==MouseX-2&&ballX==(MouseX+50+2)||ballX==(MouseX+50+1)||ballX==(MouseX+50)) /* 碰板反弹*/ if(ballY>=(MouseY-R)){ dx*=(-1);dy*=(-1); /*原路返回*/}if(ballX>MouseX && ballX<(MouseX+50)) /*碰板反弹*/ if(ballY>=(MouseY-R))dy*=(-1);if(t==84){ sleep(1);cleardevice();setcolor(RED);settextstyle(0,0,4);outtextxy(100,200,"Win");sleep(1);break;}if(ballY>MouseY){ sleep(1);cleardevice();setcolor(RED);settextstyle(0,0,4);outtextxy(100,200,"Game Over");sleep(1);}}}void main(){int gd=DETECT,gm;initgraph(&gd,&gm,"c:\\tc");picture();MouseSetX(100,362); /*设置鼠标移动的范围*/ MouseSetY(MouseY,MouseY); /*鼠标只能左右移动*/ MouseSetXY(150,MouseY); /*鼠标的初始位置*/ MouseOn(MouseX,MouseY); /*第一次显示鼠标*/ Move();closegraph();}。
——《打砖块》学院:班级:学号:姓名:一.游戏设计规则游戏开始时,小球会停在挡板正中间,且此时挡板可左右自由移动,当按下空格键后小球会弹出,并在程序设定的区域内不停的碰撞反弹。
当小球碰到墙壁、挡板和砖块时,均会以相反的速度反弹,并且砖块被碰撞后会自动消失。
挡板可左右移动以接住小球,若小球没有被接住,超出指定区域下边缘,则程序会自动提示“游戏结束”,点击“确定”后退出程序。
当所有的砖块均消失时,程序会弹出提示“恭喜你,你赢了”。
二.游戏设计思路整个游戏可以分为三个类:小球类、挡板类和砖块类。
其中最简单的当然是挡板了,在回调函数中增加“WM_KEYDOWN”的按键消息,在里面编写控制挡板移动的代码,挡板的移动是通过“上、下、左、右”四个键来实现的。
砖块在整个程序中负责两件事情,其一是程序初始化时随着小球和挡板出现在游戏界面中,再就是被小球碰到后消失。
控制砖块出现与否是通过一个bool变量“blockExist”来实现的,当该变量为“true”时,就将砖块贴到目标DC上,否则就不贴。
由于砖块数量很多,故可以用一个for循环来实现,所有的砖块用的都是一张图片,而变化的只是砖块的坐标。
本游戏中最复杂的要数小球了,因为小球要涉及到很多碰撞检测和反弹,而且这其中还和砖块、挡板有联系。
小球涉及到的碰撞有:小球与墙壁碰撞、小球与挡板碰撞、小球与砖块碰撞。
碰撞检测实际上是检测小球的坐标是否进入了某个特定的区域,若进入了,则小球要反弹;否则,按原来的路线继续前进。
小球能不断的反弹,事实上靠的是小球速度方向的改变,对于小球而言,它能出现在某个点上,是它所在坐标系中的坐标导致的。
若设小球的坐标为(x_ball,y_ball),其速度为水平:vx,竖直:vy,将其坐标与速度之间建立赋值关系,即:x_ball+=vx,y_ball-=vy。
只要对其坐标进行相对应的计算,就能控制小球的反弹了。
三.游戏主要代码int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){// TODO: Place code here.MSG msg;HACCEL hAccelTable;// Initialize global stringsLoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);LoadString(hInstance, IDC_APIDEMOGAME, szWindowClass, MAX_LOADSTRING);MyRegisterClass(hInstance);// Perform application initialization:if (!InitInstance (hInstance, nCmdShow)){return FALSE;}hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_APIDEMOGAME);// Main message loop:while (GetMessage(&msg, NULL, 0, 0)){if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){TranslateMessage(&msg);DispatchMessage(&msg);}}return msg.wParam;}A TOM MyRegisterClass(HINSTANCE hInstance){WNDCLASSEX wcex;wcex.cbSize = sizeof(WNDCLASSEX);wcex.style = CS_HREDRAW | CS_VREDRAW;wcex.lpfnWndProc = (WNDPROC)WndProc;wcex.cbClsExtra = 0;wcex.cbWndExtra = 0;wcex.hInstance = hInstance;wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_APIDEMOGAME);wcex.hCursor = LoadCursor(NULL, IDC_ARROW);wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wcex.lpszMenuName = (LPCSTR)IDC_APIDEMOGAME;wcex.lpszClassName = szWindowClass;wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);return RegisterClassEx(&wcex);}BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){hInst = hInstance; // Store instance handle in our global variablehWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW ,400, 100, 400, 500, NULL, NULL, hInstance, NULL);if (!hWnd){return FALSE;}ShowWindow(hWnd, nCmdShow);UpdateWindow(hWnd);GetClientRect(hWnd,&rect); //取得内部窗口区域大小HBITMAP bmp;m_bg=(HBITMAP)LoadImage(NULL,"matlab.bmp",IMAGE_BITMAP,0,0, LR_LOADFROMFILE);m_board=(HBITMAP)LoadImage(NULL,"Board.bmp",IMAGE_BITMAP,0, 0,LR_LOADFROMFILE);m_ball=(HBITMAP)LoadImage(NULL,"ball_0.bmp",IMAGE_BITMAP,0,0, LR_LOADFROMFILE);bgDC=GetDC(hWnd);mdc=CreateCompatibleDC(bgDC);scDC=CreateCompatibleDC(bgDC);boardDC=CreateCompatibleDC(bgDC);ballDC=CreateCompatibleDC(bgDC);bmp=CreateCompatibleBitmap(bgDC,1024,745);SelectObject(mdc,bmp);SelectObject(scDC,m_bg);SelectObject(ballDC,m_ball);SelectObject(boardDC,m_board);int i;int bx=40,by=30; //控制砖块坐标//初始化砖块for(i=0;i<BN;i++){if(block[i].blockExist)block[i].bKilled=0;block[i].blockDC=CreateCompatibleDC(bgDC);m_block[i]=(HBITMAP)LoadImage(NULL,"block.bmp",IMAGE_BITMAP, 32,21,LR_LOADFROMFILE);SelectObject(block[i].blockDC,m_block[i]);block[i].rc.left=bx;block[i].rc.top=by;block[i].rc.right=block[i].rc.left+64;block[i].rc.bottom=block[i].rc.top+32;bx+=60;}return TRUE;}/********控制小球碰壁后反弹*************/ void DrawBall(){//计算X轴方向贴图坐标与速度x_ball+=vx;if(x_ball<=0){x_ball=0;vx=-vx;bHeng=false;}else if(x_ball>=rect.right-32){x_ball=rect.right-32;vx=-vx;bHeng=true;}//计算Y轴方向贴图坐标与速度y_ball-=vy;if(y_ball<=0){y_ball=0;vy=-vy;bZong=false;}/* if(y_ball>=rect.bottom-32){y_ball= rect.bottom-32;vy=-vy;}*/}/*****判断小球是否与砖块相碰*******/void CheckCrashBlock(){int i;float WIDTH = 96;float HEIGHT = 64;float tan=HEIGHT / WIDTH;//tanθ的值for(i=0;i<BN;i++){float x_ =(float)(x_ball - block[i].rc.left);float y_ =(float)(y_ball - block[i].rc.top);if((x_ball>=block[i].rc.left-32&&x_ball<=block[i].rc.right)&&(y_ball>=bloc k[i].rc.top-32&&y_ball<=block[i].rc.bottom)){block[i].bKilled=1;block[i].blockExist=false;num--;}else if(tan > abs(y_ / x_)) //在1、3区域{vx=-vx;x_ball=vx;}else //在2、4区域{vy=-vy;y_ball-=vy;}*/}}}/*****判断小球是否与挡板相碰******/void CheckCrashBoard(){if((y_ball+32)>y){if(((x_ball+64)>=x)&&(x_ball<=(x+128))){vy=-vy;y_ball-=vy;// vx=10;}else{MessageBox(hWnd,"游戏结束","提示",MB_OK|MB_ICONSTOP);exit(0);}}}void DrawMap(){GetClientRect(hWnd,&rect); //取得内部窗口区域大小int i;if(!win){BitBlt(mdc,0,0,1024,745,scDC,0,0,SRCCOPY);for(i=0;i<BN;i++){CheckCrashBlock();if(block[i].bKilled) //||block[i].blockDC==0continue;else{BitBlt(mdc,block[i].rc.left,block[i].rc.top,block[i].rc.right-block[i].rc.left,blo ck[i].rc.bottom-block[i].rc.top,block[i].blockDC,0,0,SRCCOPY);}}//挡板贴图BitBlt(mdc,x,y,128,32,boardDC,0,0,SRCCOPY);//小球贴图if(isKeyDown){DrawBall();CheckCrashBoard();}BitBlt(mdc,x_ball,y_ball,32,32,ballDC,32,0,SRCAND);BitBlt(mdc,x_ball,y_ball,32,32,ballDC,0,0,SRCPAINT);}//将整个图贴到目的DC上BitBlt(bgDC,0,0,1024,745,mdc,0,0,SRCCOPY);}DWORD WINAPI ThreadProc(LPVOID lpParameter ){void *ct = (void *)lpParameter;while(1){DrawMap();Sleep(80);}delete ct;return 0;}LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){int wmId, wmEvent;PAINTSTRUCT ps;HDC hdc;void *ct;TCHAR szHello[MAX_LOADSTRING];LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);GetClientRect(hWnd,&rect);switch (message){case WM_COMMAND:wmId = LOWORD(wParam);wmEvent = HIWORD(wParam);// Parse the menu selections:switch (wmId){case IDM_START:{CreateThread(NULL,1024,ThreadProc,ct,0,NULL);}break;case IDM_STARTAGAIN:{x=300;y=300;x_ball=319;y_ball=270;DrawMap();}break;case IDM_ABOUT:DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);break;case IDM_EXIT:DestroyWindow(hWnd);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}break;case WM_PAINT:{hdc = BeginPaint(hWnd, &ps);// TODO: Add any drawing code here...HBITMAPm_bottom=(HBITMAP)LoadImage(NULL,"matlab.bmp",IMAGE_BITMAP,102 4,745,LR_LOADFROMFILE);HDC hDC=CreateCompatibleDC(hdc);SelectObject(hDC,m_bottom);BitBlt(hdc,0,0,1024,745,hDC,0,0,SRCCOPY);DeleteObject(m_bottom);DeleteDC(hDC);ReleaseDC(hWnd,hdc);EndPaint(hWnd, &ps);}break;case WM_KEYDOWN:{switch(wParam){case VK_LEFT:x-=30;if(x<=0)x=0;if(!isKeyDown)x_ball-=30;break;case VK_RIGHT:x+=30;if(x>=rect.right-128)x=rect.right-128;if(!isKeyDown)x_ball+=30;break;case VK_SPACE:isKeyDown=1;break;}}break;case WM_DESTROY:PostQuitMessage(0);KillTimer(hWnd,1);DeleteObject(m_ball);DeleteDC(ballDC);DeleteObject(m_bg);DeleteObject(m_board);DeleteDC(scDC);DeleteDC(boardDC);ReleaseDC(hWnd,bgDC);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;}// Mesage handler for about box.LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){switch (message){case WM_INITDIALOG:return TRUE;case WM_COMMAND:if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL){EndDialog(hDlg, LOWORD(wParam));return TRUE;}break;}return FALSE;}四.游戏截图游戏截图(一)游戏截图(二)。
编程实现的有趣打砖块游戏指南打砖块游戏(Brick breaker game)是一款经典的街机游戏,已经在电脑和手机上流行了很多年。
如果你对编程有一定了解,并想挑战自己创建一个有趣的游戏,那么本文将为你提供一个简单的指南,帮助你使用编程语言来实现一个打砖块游戏。
1. 游戏的基本原理在开始编写游戏之前,我们首先需要了解游戏的基本原理。
打砖块游戏的目标是使用一个移动的板挡住从顶部下落的小球,同时击碎顶部的砖块。
如果球碰到板或砖块,它会反弹。
当所有砖块都被击碎后,游戏胜利。
如果小球触底,游戏失败。
2. 游戏的基本元素打砖块游戏通常由以下几个基本元素组成:- 小球:代表游戏中的球体,会从顶部开始下落。
- 板:用于挡住小球,并反弹它。
- 砖块:顶部出现的多个砖块,玩家需要击碎它们。
- 壁:游戏区域的四周,小球碰到壁会反弹。
3. 编程语言的选择你可以根据自己的编程经验选择适合你的编程语言。
常用的语言如Python、JavaScript、C++等都可以完成该项目。
这里我们以Python为例进行讲解。
4. 游戏的实现在代码编写过程中,首先我们需要创建一个窗口来显示游戏,然后绘制出小球、板、砖块和壁等元素。
我们可以利用Python的图形库,如Pygame或Turtle来实现窗口和绘图的功能。
下面是一个简单的Python代码示例:```python# 导入所需的库import pygame# 初始化游戏pygame.init()# 创建游戏窗口screen = pygame.display.set_mode((800, 600))pygame.display.set_caption("打砖块游戏")# 游戏主循环running = Truewhile running:for event in pygame.event.get():if event.type == pygame.QUIT:running = Falsescreen.fill((0, 0, 0)) # 设置背景颜色为黑色pygame.display.flip()# 退出游戏pygame.quit()```在以上代码中,我们首先导入Pygame库,然后初始化游戏,并创建一个800x600像素的窗口。
游戏默认地图均采用for循环+逻辑构建所以,并没有直接初始化地图bug:1.目前对角相碰是进行的直接打破该方块,因为测试到进行正常的碰撞返回会重复之前的路。
(算是优化)2.未知的原因导致开局影子脱节,目前已经优化到后期几乎看不到脱节。
优化:实现类似贪吃蛇玩法,制造跟随的移动轨迹,并且交叉的移动轨迹不会直接清除导致脱节。
配色优化---------------------------------*/#include <conio.h> //用于getch()#include <math.h>#include <stdio.h>#include <stdlib.h> //用于rand#include <string.h>#include <windows.h>#define pi 3.14const double g = 10; //标准数越模糊,轨迹越连贯。
//----------------------------------------------------------------------------------------------------------------------------------// 系统默认生成关卡地图,若想自己改造关卡请将1 设置为0并且再下方初始化地图(黏贴地图)int auto_made_map = 1;char man_made_map[1000][1000];//---------------------------------------------------------------------------------------------------------------------------------char map[1000][1000];char End[200][800] = {{"## ## ## ## # "},{" ## # ##### ###### ## ## "},{" ##### ###### ###### ## # "},{" ####### ## ###### "},{"## ## # ##### ########## "},{" ## #### ##### ## ###### "},{" #### ## ## ## ## # "},{" ## # ###### ### ## ## "},{" # ## # ###### ## ## ## "},{" # ## # ## #### ### "},{" ## ## # ## ## # ## #"},{" # ## # ## ## #### ##"},{"## ### # ### # ### ####"},{"## ## ## ## ## ###"},{" "},{" ## ## ## "},{" ## ######### ###############"},{" ## ######### ###############"},{"## ## ## ## "},{"###### ####### ############ "},{" ## ####### ############ "},{" ## ## ## ## "},{"###### ####### ############ "},{"###### ####### ##### "},{" ## ## ## #### "},{" ### ## ## ## ## ## "},{"###### ####### ### ## ### "},{"### ####### ## ## ## "},{" ## ## ## "},{" "},{" 按两次回车继续"},};char menu[40][40] = {{" <---------------> "},{" < 打砖块> "},{" <---------------> "},{" "},{" <1> 开始游戏<$> "},{" "},{" <2> 贪吃蛇mod <$> "},{" "},{" <3> 编辑地图<$> "},{" "},{" <4> 退出游戏<$> "},{" "}};//全局变量区,在init里面改变char wall, food, air, brick;int width, length;double X, Y, x, y, Vx, Vy, t, V; //默认向下向右为正int old_x, old_y, head, tail, max, step, if_miss, food_num, goal, color;int if_start, if_load_snake_mod, debug, life; //debug模式调成1手动开启int temp_x, temp_y, menu_x, menu_y, left, right; //临时坐标double C[8] = {0, 10, 30, 70, 90}; //初始斜抛的角度,自右向上转角(目前已调整好最好的角度)struct Step //轨迹{int x;int y;} s[1000];void HideCursor() //光标隐藏{CONSOLE_CURSOR_INFO cursor_info = {1, 0}; //后边的0代表光标不可见SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);}void gotoxy(int x, int y) //坐标函数{HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos;pos.X = x;pos.Y = y;SetConsoleCursorPosition(handle, pos);}void init(){int i, j, a, b;HideCursor();width = 40, length = 150;wall = '#', food = '*', air = ' ', brick = 'O';head = 0, tail = 0, max = 60, step = 0, if_miss = 0, food_num = 400, goal = 0, color = 0;debug = 0, life = 3; //debug 模式调成1手动开启temp_x = 2, temp_y = 2, menu_x = 18, menu_y = 68, left = 4, right = 20; //临时坐标gotoxy(0, 0);//菜单模式if (if_start == 0){ //首页for (i = 0; i <= width; i++){ //生成地图模板for (j = 0; j <= length; j++){if (i == 0 || i == width || j == 0 || j == length)map[i][j] = wall;else if ((i == width / 3 || i == width * 2 / 3) && (j >= length * 2 / 5 && j <= length * 3 / 5))map[i][j] = wall;else if ((i >= width / 3 && i <= width * 2 / 3) && (j == length * 2 / 5 || j ==length * 3 / 5))map[i][j] = wall;elsemap[i][j] = air;}}while (food_num--){ //贪吃蛇生成食物int a = rand() % width;int b = rand() % length;if ((a >= width / 3 && a <= width * 2 / 3) && (b >= length * 2 / 5 && b <= length * 3 / 5) || a == 0 || b == 0)continue;map[a][b] = food;}for (i = 0; i <= width; i++){ //布置砖块brickfor (j = 0; j <= length; j++){if ((i == 15 || i == 20) && ((j >= 4 && j <= 50) || (j >= 100 && j <= 130)))map[i][j] = brick;}}}//游戏模式else if (if_start == 1 || if_start == -1){if (auto_made_map == 1){for (i = 0; i <= width; i++){ //生成地图模板for (j = 0; j <= length; j++){if (i == 0 || i == width || j == 0 || j == length)map[i][j] = wall;else if ((i == width * 2 / 3) && (j >= length * 2 / 5 && j <= length * 3 / 5))map[i][j] = wall;else if (i == width - 1 && j >= left && j <= right)map[i][j] = wall;elsemap[i][j] = air;}}if (if_load_snake_mod == 1){food_num = 400;while (food_num--){ //贪吃蛇生成食物a = rand() % width;b = rand() % length;if ((a >= width / 3 && a <= width * 2 / 3) && (b >= length * 2 / 5 && b <= length * 3 / 5) || a == 0 || b == 0)continue;map[a][b] = food;}}for (i = 0; i <= width; i++){ //布置砖块brickfor (j = 0; j <= length; j++){if (((i >= 14 && i <= 15) && (j >= 1 && j <= 20)) || ((i >= 14 && i <= 15) && (j >= 130 && j <= 149)))map[i][j] = brick;if (((i >= 20 && i <= 22) && (j >= 10 && j <= 50)) || ((i >= 20 && i <= 22) && (j >= 100 && j <= 140)))map[i][j] = brick;if ((i == 10 || i == 11) && ((j >= 10 && j <= 50) || (j >= 100 && j <= 140)))map[i][j] = brick;}}}else{for (i = 0; i <= width; i++){strcpy(map[i], man_made_map[i]);}auto_made_map = 1;}gotoxy(2, width + 3);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 07);printf("life:");for (i = 0; i < life; i++)printf("■");}gotoxy(0, 0);for (i = 0; i <= width; i++){ //打印地图for (j = 0; j <= length; j++){if (if_start == 0 && i >= 14 && i <= 25 && j >= 61 && j <= 89)map[i][j] = menu[i - 14][j - 61];if (map[i][j] == wall && if_start != -1)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 60);else if (map[i][j] == brick && if_start != -1)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 80);elseSetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 07);if (i == width)printf("!");elseprintf("%c", map[i][j]);}printf("\n");}//构建初始位置以及速度和方向角度X = width - 5;Y = 4;old_x = (int)X;old_y = (int)Y;s[step].x = old_x;s[step].y = old_y;V = 26;Vx = -V * sin(C[3] * pi / 180.0); //速度向右向下为正方向Vy = V * cos(C[3] * pi / 180.0);}void gameover(){int i, j;gotoxy(0, 0);for (i = 0; i <= width + 6; i++){for (j = 0; j <= length; j++){printf(" ");}Sleep(20);}gotoxy(0, 0);printf("即将退出游戏");Sleep(2000);exit(1);}void move(int *x, int *y, int limit_x1, int limit_x2, int limit_y1, int limit_y2, int xx, int yy, char ch) {//主要函数:灵活的实现选择指针;//参数:开始坐标x y 限制活动空间x上下y左右移动距离xx yychar ch1, turn, temp;int tx = *x, ty = *y, i;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 52);while (ch != 'b'){tx = *x, ty = *y, i;if (if_start == -1){gotoxy(2, width + 4);printf("直接按下相应数字改变状态:|1墙体|2.砖块|3空气|4退出编译|");}gotoxy(*y, *x);temp = map[*x][*y];printf("$"); //可自定义1个字节的指针图标if (ch == -32){ch1 = getch();switch (ch1){case 72:ch = 'w';break;case 75:ch = 'a';break;case 80:ch = 's';break;case 77:ch = 'd';break;}}switch (ch){case 'a':*y = *y - yy;break;case 'd':*y = *y + yy;break;case 'w':*x = *x - xx;break;case 's':*x = *x + xx;break;case ' ':break;}if (*x < limit_x1 || *x > limit_x2 || *y < limit_y1 || *y > limit_y2){*x = tx;*y = ty;}SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 60); gotoxy(*y, *x);printf("$");gotoxy(12, width + 1);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 07); printf("X:%3d Y:%3d", *x, *y);if (map[tx][ty] == wall && if_start != -1)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 60); elseSetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 07); gotoxy(ty, tx);printf("%c", temp);if (ch == ' ' && if_start != -1) //进行功能处理{int flag = map[*x][*y] - '0';if (flag == 1){if_start = 1;init();return;}else if (flag == 2){if (if_load_snake_mod == 0)if_load_snake_mod = 1;else if (if_load_snake_mod == 1)if_load_snake_mod = 0;return;}else if (flag == 3){if_start = -1;init();return;}else if (flag == 4){gameover();return;}}if (ch >= '1' && ch <= '4' && if_start == -1){turn = '?';switch (ch){case '1':turn = wall;break;case '2':turn = brick;break;case '3':turn = air;break;case '4':ch = 'b';break;}if ((turn == wall || turn == brick || turn == air) && *x != width) {map[*x][*y] = turn;gotoxy(*y, *x);printf("%c", turn);}else{gotoxy(2, width + 4);printf("不规范的输入");}}if (ch == 'b' && if_start == -1){for (i = 0; i <= width; i++)strcpy(man_made_map[i], map[i]);gotoxy(2, width + 4);printf("");return;}if (if_start != -1)break;ch = getch();}if (ch == 'b' && if_start == -1){for (i = 0; i <= width; i++)strcpy(man_made_map[i], map[i]);gotoxy(2, width + 4);printf("");return;}return;}void end(){int i, j;int flag = max;SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 07);while (flag != 0){if (step < 0)step += max;gotoxy(s[step].y, s[step].x);map[s[step].x][s[step].y]--;if (map[s[step].x][s[step].y] == air && !(s[step].x == 0 && s[step].y == 0)) //防止自己吃自己printf("%c", air);s[step].x = 0;s[step].y = 0;step--;flag--;Sleep(20);gotoxy(2, width + 1);printf("len:%5d", flag);}for (i = 0; i <= 30; i++){gotoxy(60, 03 + i);printf("%s\n", End[i]);Sleep(100);}getchar();getchar();if_start = 0;init();}void manchange() //人为输入更新{char ch, ch1, ch2;if (kbhit()){ch = getch(), ch1;if (ch != ' ' && ch != 'w' && ch != 's' && ch != 'a' && ch != 'd' && ch != -32 && ch != 'p' && ch != 'b')return;if (ch == -32){ //同时启用wasd 和上下左右键ch1 = getch();switch (ch1){case 72:ch = 'w';break;case 75:ch = 'a';break;case 80:ch = 's';break;case 77:ch = 'd';break;}}if (ch == 'a' || ch == 's' || ch == 'd' || ch == 'w' || ch == ' ' || ch == 'p' || ch == 'b') {if (if_start == 0)move(&menu_x, &menu_y, 18, 24, 68, 68, 2, 0, ch);else if (if_start == 1){if (ch == 'a' && left > 1){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 60);left--;gotoxy(left, width - 1);map[width - 1][left] = wall;printf("%c", wall);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 07);gotoxy(right, width - 1);map[width - 1][right] = air;printf(" ");right--;}else if (ch == 'd' && right < length - 1){SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 60);right++;gotoxy(right, width - 1);map[width - 1][right] = wall;printf("%c", wall);SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 07);gotoxy(left, width - 1);map[width - 1][left] = air;printf(" ");left++;}else if (ch == 'p'){gotoxy(2, width + 5);printf("游戏暂停,按'p'继续游戏");ch2 = getch();while (ch2 != 'p'){ch2 = getch();}gotoxy(2, width + 5);printf(" ");}else if (ch == 'b'){if_start = 0;init();}}}}//function = move(&temp_x,&temp_y,0,width,0,length,1,1,ch);//function = move(&menu_x,&menu_y,18,24,68,68,2,0,ch);}void autochange() //自动更新{int flag = 1, i;double t1, t2;double s1, s2;double temp;double x1_t1;double x2_t1;double x3_t1;double x4_t1;if (if_start == -1){auto_made_map = 0;move(&temp_x, &temp_y, 0, width, 0, length, 1, 1, 'd');if_start = 0;init();}/*-------------------------------------------------------核心公式:X = X0 + Vx*t + 1/2*VX*t*t;Y = Y0 + Vy*t;核心思想:如果选择时间作为移动参考,则每秒会出现点相差太远这里反过来,以连续为前提,尝试实现:分别算出X 增加一个单位长度应该增加的Y 的距离s1Y 增加一个单位长度应该增加的X 的距离s2优先选择更短的作为下一次移动的基准。