弹跳小球
关键
1.清屏函数,system("cls");,来自于conio.h函数库
#include<conio.h>
结合循环达到刷新的目的。
2.利用两个for循环,将(x,y)位置的小球打印出来。
int i,j;
int x=N; //常熟N
int y=M; //常数M
for(i=0;i<x;i++)
printf("\n"); //第x行
for(j=0;j<y;j++)
printf(" "); //第y列
printf("o"); //打印出小球
3.利用小球的位置等于边界值更改速度正负达到弹跳的目的。
if(x==top||x==bottom) velocity_x=-velocity_x;
if(y==left||y==right) velocity_y=-velocity_y;
4.控制小球弹跳的速度:Sleep(int n)函数(windows.h库),n的含义为暂停n毫秒。
5.在初始化小球的位置时,注意x不能大于bottom,y不能大于right,这两个边界值,否则一开始就超出边界无法达到弹跳的目的。
完整代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
int main(){
int i,j;
int x=1;
int y=5;
int left=0;
int right=20;
int top=0;
int bottom=10;
int velocity_x=1;
int velocity_y=1;
while(1){
x+=velocity_x;
y+=velocity_y;
system("cls");
for(i=0;i<x;i++)
printf("\n");
for(j=0;j<y;j++)
printf(" ");
printf("o");
printf("\n");
Sleep(50);
if(x==top||x==bottom) velocity_x=-velocity_x;
if(y==left||y==right) velocity_y=-velocity_y;
}
return 0;
}
进阶
1.利用printf("\a")实现小球碰到边界时响铃的效果。
2.为反弹小球绘制边框。
解答
1.只需在达到边界值if语句中的执行语句加入printf("\a")即可。
2.难度最大的是第二个进阶。
1)光标
是输出的小窗口中,开始输出显示的小光标。
2)移动光标函数
#include<windows.h>
void gotoxy(int x,int y)
{
COORD pos; //定义结构体变量p
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE); //获取当前函数句柄
pos.X=x;
pos.Y=y; //将光标到达的位置传递给结构体
SetConsoleCursorPosition(handle,pos) ; //移动光标
}
这里可以联系到system函数的清屏操作,也是移动光标到(0,0)的位置将窗口缓冲区全部填充为空格并填充为默认颜色(清屏)。
3)显示光标函数
void ShowCursor(bool visible) { //显示或隐藏光标
CONSOLE_CURSOR_INFO cursor_info = {20, visible};
//CONSOLE_CURSOR_INFO结构体包含控制台光标信息,成员分别表示光标百分比厚度和是否可见
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
//SetConsoleCursorInfo设定控制台窗口的光标大小和是否可见
}
即在程序中,执行ShowCursor(true)为显示光标,ShowCursor(false)为隐藏光标。
隐藏光标的目的为减少光标闪烁的干扰。
问题:
1.利用for循环绘制出边框
for(j=0;j<=right;j++) printf("_"); printf("\n");//输出上边框
for(i=1;i<bottom;i++){
printf("|"); //循环输出左边框
for(j=0;j<right-1;j++) printf(" ");
printf("|\n"); //循环输出右边框
}
for(j=0;j<=right;j++) printf("="); //输出下边框
2.将小球那一行的左边框会被覆盖,因此在打印小球时重新输出。
for(j=0;j<y;j++){
if(j==0)printf("|"); //重新输出左边框
else printf(" ");
}
3.保证边框和小球不会重合
if(x==top+1||x==bottom-1){
velocity_x=-velocity_x;
printf("\a");
}
if(y==left+1||y==right-1){
velocity_y=-velocity_y;
printf("\a");
}
//对左边界+1,右边界值-1
最终进阶后的完整代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
void gotoxy(int x,int y)//光标定位函数
{
COORD pos;//定义结构体变量p
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);//获取当前函数句柄
pos.X=x;
pos.Y=y;//将光标的目标移动位置传递给结构体
SetConsoleCursorPosition(handle,pos);//移动光标
}
void ShowCursor(bool visible) { //显示或隐藏光标
CONSOLE_CURSOR_INFO cursor_info = {20, visible};
//CONSOLE_CURSOR_INFO结构体包含控制台光标信息,成员分别表示光标百分比厚度和是否可见
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
//SetConsoleCursorInfo设定控制台窗口的光标大小和是否可见
}
int main(){
int i,j;
int x=1;
int y=5;
int left=0;
int right=20;
int top=0;
int bottom=10;
ShowCursor(false);
int velocity_x=1;
int velocity_y=1;
while(1){
x+=velocity_x;
y+=velocity_y;
system("cls");
for(j=0;j<=right;j++) printf("_"); printf("\n");
for(i=1;i<bottom;i++){
printf("|");
for(j=0;j<right-1;j++) printf(" ");
printf("|\n");
}
for(j=0;j<=right;j++) printf("=");
gotoxy(0, 0);
for(i=0;i<x;i++)
printf("\n");
for(j=0;j<y;j++){
if(j==0)printf("|");
else printf(" ");
}
printf("o");
printf("\n");
Sleep(50);
if(x==top+1||x==bottom-1){
velocity_x=-velocity_x;
printf("\a");
}
if(y==left+1||y==right-1){
velocity_y=-velocity_y;
printf("\a");
}
}
return 0;
}