java弹力球程序_使用WindowsAPI编写在控制台中弹力球游戏小程序

#include

#include

#include

#include

#include

# define timer 10//毫秒单位,控制球的移速,与dx,dy也有关

char ch1[]={"Win"};

char ch2[]={"Game Over"};

//球的参数

int r=4;

int dx=1,dy=1;//球的步进,成45°角

//砖墙左上角第一块砖的红色区域的左上角坐标

int startx=250,starty=30;

//边界墙的参数

int boundaryx;

int boundaryy;

POINT positionboundary[5];

//每块砖的参数

int sizex1=20;

int sizey1=15;

int sizet1=3;

//砖墙的参数

int horizontal=15;

int vertical_1=6;

int vertical_2=9;

int gap_end=4;

//挡板的参数

int sizex2=60;

int sizey2=5;

int sizet2=3;

int mousedx=4;//挡板步进。控制挡板移速,与timer也有关

int mousex=0;

//用于鼠标定位

RECT rcClient;

RECT rect_mouse;

POINT positionmouse;

int status=0;

int positionmousestatus=0;

int positionmouseflag=0;

HWND hwnd;

HDC hdc;

HDC hdc_screen;

HBRUSH hbrushred,hbrushwhite,hbrushblack;

HPEN hpenyellow,hpenblack,hpenwhite;

//客户区尺寸

int sizeclientx=600;

int sizeclienty=600;

//菜单的参数

int id_menu=0;

int key_1_menu=0;

//屏幕尺寸

int width_screen;

int long_screen;

//储存砖墙中每块砖的红色区域左上角的坐标,不包括白色边界墙

struct wallarray

{

int x;

int y;

int flag;//用于标记砖是否被撞掉

}wall[50][50];

//初始化HDC

void creathdc()

{

hwnd=GetConsoleWindow();

hdc=GetDC(hwnd);

hdc_screen=GetDC(NULL);

hbrushred=CreateSolidBrush(RGB(255,0,0));

hbrushwhite=CreateSolidBrush(RGB(255,255,255));

hbrushblack=CreateSolidBrush(RGB(0,0,0));

hpenblack=CreatePen(PS_SOLID,1,RGB(0,0,0));

hpenyellow=CreatePen(PS_SOLID,1,RGB(255,255,0));

hpenwhite=CreatePen(PS_SOLID,1,RGB(255,255,255));

}

//置顶光标到客户区的指定位置,与printf函数配合使用

void cursor(int x,int y)//x,y是在客户区坐标系中的坐标

{

COORD position;

HANDLE handle;

handle=GetStdHandle(STD_OUTPUT_HANDLE);

position.X=x;

position.Y=y;

SetConsoleCursorPosition(handle,position);

}

//进行游戏中...,提示按键功能

void key_1()

{

cursor(1,1);

printf("按Enter暂停游戏");

cursor(1,2);

printf("按Space继续游戏");

cursor(1,3);

printf("按ESC返回主菜单");

}

//菜单界面...,提示按键功能

void key_2()

{

cursor(1,1);

printf("按上、下键选择");

cursor(1,2);

printf("按Enter确认选项");

}

//获取客户区尺寸

void clientsizeget()

{

GetClientRect(hwnd,&rcClient);

}

//获取屏幕尺寸(像素)

void screensizeget()

{

long_screen=GetDeviceCaps(hdc_screen,HORZRES);//屏幕水平尺寸

width_screen=GetDeviceCaps(hdc_screen,VERTRES);//屏幕垂直尺寸

}

//设置窗口位置;根据需要的客户区尺寸设置大约的窗口大小

void clientsizeset(int x,int y)

{

screensizeget();

MoveWindow(hwnd,long_screen/2-x/2,0,x,y,1);//移动窗口(并不是客户区)在显示器上的位置和设置窗口大小

}

//创建一块转

void stonedraw(int x,int y,int sizex,int

sizey,int sizet)//创建一块转

{

POINT positionred[4],positionwhite[6];

//红砖

positionred[0].x=x;

positionred[0].y=y;

positionred[1].x=x+sizex;

positionred[1].y=y;

positionred[2].x=x+sizex;

positionred[2].y=y+sizey;

positionred[3].x=x;

positionred[3].y=y+sizey;

SelectObject(hdc,hpenblack);

SelectObject(hdc,hbrushred);

Polygon(hdc,positionred,4);

//砖的白边

positionwhite[0].x=x-sizet;

positionwhite[0].y=y-sizet;

positionwhite[1].x=x-sizet;

positionwhite[1].y=y+sizey;

positionwhite[2].x=x;

positionwhite[2].y=y+sizey;

positionwhite[3].x=x;

positionwhite[3].y=y;

positionwhite[4].x=x+sizex;

positionwhite[4].y=y;

positionwhite[5].x=x+sizex;

positionwhite[5].y=y-sizet;

SelectObject(hdc,hbrushwhite);

Polygon(hdc,positionwhite,6);

}

//创建砖墙及边界墙

void picture(int h,int v,int gap)

{

int i,j;

boundaryx=h*(sizex1+sizet1+gap)+gap;//正好是砖墙水平x轴的长度

boundaryy=v*(sizey1+sizet1+gap)+gap+250;//正好是砖墙垂直y轴的长度+250

//砖墙

for(i=0;i

for(j=0;j

{

stonedraw(startx+j*(sizex1+sizet1+gap),starty+i*(sizey1+sizet1+gap),sizex1,sizey1,sizet1);//gap是相邻砖的缝隙;(startx,starty)是砖墙左上角第一块砖的红色区域的左上角坐标

//初始化wall结构体数组

wall[i][j].x=startx+j*(sizex1+sizet1+gap);

wall[i][j].y=starty+i*(sizey1+sizet1+gap);

wall[i][j].flag=0;

}

//边界墙

positionboundary[0].x=startx-sizet1-gap;

positionboundary[0].y=starty-sizet1-gap;

positionboundary[1].x=startx-sizet1-gap;

positionboundary[1].y=starty-sizet1-gap+boundaryy;

positionboundary[2].x=startx-sizet1-gap+boundaryx;

positionboundary[2].y=starty-sizet1-gap+boundaryy;

positionboundary[3].x=startx-sizet1-gap+boundaryx;

positionboundary[3].y=starty-sizet1-gap;

positionboundary[4].x=startx-sizet1-gap;

positionboundary[4].y=starty-sizet1-gap;

SelectObject(hdc,hpenwhite);

Polyline(hdc,positionboundary,5);

}

//画挡板

void stonedraw_mouse(int x)//x水平移动。x=0时是初始位置:靠左侧

{

//覆盖删除

SelectObject(hdc,hpenblack);

SelectObject(hdc,hbrushblack);

if(status>x)//左移

Rectangle(hdc,startx-sizet2+x+mousedx,starty+boundaryy-50-sizet2,startx+sizex2+x+mousedx,starty+boundaryy-50+sizey2);

if(status

Rectangle(hdc,startx-sizet2+x-mousedx,starty+boundaryy-50-sizet2,startx+sizex2+x-mousedx,starty+boundaryy-50+sizey2);

//移动后,重画

stonedraw(startx+x,starty+boundaryy-50,sizex2,sizey2,sizet2);

status=x;

}

//将鼠标限制到客户区外侧正下方

void mouselimitxy()

{

//限制在固定区域

rect_mouse.left=long_screen/2-sizeclientx/2+40;

rect_mouse.top=sizeclienty-40;

rect_mouse.right=long_screen/2+sizeclientx/2-40;

rect_mouse.bottom=sizeclienty-35;

ClipCursor(&rect_mouse);

}

//获取鼠标在客户区的当前位置,以客户区坐标系为参考坐标

void mousegetxy()

{

GetCursorPos(&positionmouse);

ScreenToClient(hwnd,&positionmouse);

}

//根据鼠标状态控制挡板移动

void mousestatus()

{

if(GetKeyState(VK_LBUTTON)<0)

{

mousegetxy();

//鼠标移动

if(positionmouse.x>positionmousestatus &&

startx+sizex2+mousex+gap_end

{

mousex+=mousedx;

stonedraw_mouse(mousex);

positionmouseflag=0;

}

if(positionmouse.xpositionboundary[0].x)//左移

{

mousex-=mousedx;

stonedraw_mouse(mousex);

positionmouseflag=1;

}

//鼠标没有移动,保持鼠标没有移动前的左右移动其一功能

if(positionmouse.x==positionmousestatus)

{

if(positionmouseflag==0 &&

startx+sizex2+mousex+gap_end

{

mousex+=mousedx;

stonedraw_mouse(mousex);

}

if(positionmouseflag==1&&

startx-sizet2+mousex-gap_end>positionboundary[0].x )//左移

{

mousex-=mousedx;

stonedraw_mouse(mousex);

}

}

positionmousestatus=positionmouse.x;

}

Sleep(timer);

}

//进行游戏

void play(int ho,int ve)

{

void menuinitialize();//声明

int i,j,t=0;

//球的中心坐标

int ballx;

int bally=starty+boundaryy-50-sizet2-r-1;//球中心的初始位置y

srand((unsigned) time(NULL));

do

{

ballx=rand()`0;//球中心的初始位置x,在挡板上任意位置

if(ballx%2==0)//球的初始x轴移动方向:dx为正代表向右,dx为负代表向左

dx=dx*(-1);

}

while(ballx<=startx-sizet2 ||

ballx>=startx+sizex2);

while(1)

{

if(GetKeyState(VK_SPACE)<0)//空格:暂停

while(1)

{

if(GetKeyState(VK_RETURN)<0)//回车:继续

break;

if(GetKeyState(VK_ESCAPE)<0)//ESC:返回主菜单

{

//回复初始状态,以备下次执行play()

dx=1;

dy=1;

mousex=0;

status=0;

positionmousestatus=0;

menuinitialize();

}

}

if(GetKeyState(VK_ESCAPE)<0)//ESC:返回主菜单

{

//回复初始状态,以备下次执行play()

dx=1;

dy=1;

mousex=0;

status=0;

positionmousestatus=0;

menuinitialize();

}

mousestatus();

//撞上边界墙,反弹

if(bally==positionboundary[0].y+r+1)

dy*=(-1);

//撞左右边界墙,反弹

if(ballx==positionboundary[0].x+r+1 ||

ballx==positionboundary[2].x-r-1)

dx*=(-1);

//覆盖删除球

SelectObject(hdc,hpenblack);

MoveToEx(hdc,ballx+r,bally,NULL);

AngleArc(hdc,ballx,bally,r,0,360);

//球移动,步进(dx,dy)

SelectObject(hdc,hpenyellow);

MoveToEx(hdc,ballx+dx+r,bally-dy,NULL);

AngleArc(hdc,ballx+=dx,bally-=dy,r,0,360);//球的移动方向:dx为正代表向右,dx为负代表向左;dy为正代表向上,dy为负代表向下

//撞砖墙(包括红色区域和白色区域),反弹

for(i=0;i

for(j=0;j

{

if( t

{

//撞砖墙上面和下面,反弹

if( ballx>wall[i][j].x-sizet1-r && ballx

{

t++;//用于计算已消除多少块砖

dy*=(-1);

wall[i][j].flag=1;//代表此块砖被撞后消除

//覆盖消除

SelectObject(hdc,hpenblack);

SelectObject(hdc,hbrushblack);

Rectangle(hdc,wall[i][j].x-sizet1,wall[i][j].y-sizet1,wall[i][j].x+sizex1,wall[i][j].y+sizey1);

}

//撞砖墙左面和右面,反弹

if(ballywall[i][j].y-sizet1-r &&

(ballx==wall[i][j].x-sizet1-r ||

ballx==wall[i][j].x+sizex1+r))

{

t++;//用于计算已消除多少块砖

dx*=(-1);

wall[i][j].flag=1;//代表此块砖被撞后消除

//覆盖消除

SelectObject(hdc,hpenblack);

SelectObject(hdc,hbrushblack);

Rectangle(hdc,wall[i][j].x-sizet1,wall[i][j].y-sizet1,wall[i][j].x+sizex1,wall[i][j].y+sizey1);

}

//撞砖墙四角,原路返回,前提是:dx=1,dy=1,成45°步进

if((ballx==wall[i][j].x-sizet1-r &&

(bally==wall[i][j].y+sizey1+r || bally==wall[i][j].y-sizet1-r)) ||

( ballx==wall[i][j].x+sizex1+r &&

(bally==wall[i][j].y+sizey1+r ||

bally==wall[i][j].y-sizet1-r)))

{

t++;//用于计算已消除多少块砖

dx*=(-1);

dy*=(-1);

wall[i][j].flag=1;//代表此块砖被撞后消除

//覆盖消除

SelectObject(hdc,hpenblack);

SelectObject(hdc,hbrushblack);

Rectangle(hdc,wall[i][j].x-sizet1,wall[i][j].y-sizet1,wall[i][j].x+sizex1,wall[i][j].y+sizey1);

}

}

}

//撞挡板左上角上部白色部分,原路返回

if(ballx>=startx+mousex-sizet2 &&

ballx<=startx+mousex &&

bally==starty+boundaryy-50-sizet2-r-1)

{

dx*=(-1);

dy*=(-1);

}

//撞挡板非左上角上部白色区域,反弹

if(ballx>startx+mousex &&

ballx<=startx+mousex+sizex2 &&

bally==starty+boundaryy-50-sizet2-r-1)

dy*=(-1);

//判断砖是否全部清除,游戏成功

if(t==ve*ho)

{

Sleep(500);

system("cls");

SetTextColor(hdc,RGB(0,255,0));

TextOut(hdc,rcClient.right/2,rcClient.bottom/2,ch1,strlen(ch1)+1);

Sleep(1000);

break;

}

//判断未接住球,游戏失败

if(bally>starty+boundaryy-50+r)

{

Sleep(500);

system("cls");

SetTextColor(hdc,RGB(255,0,0));

TextOut(hdc,rcClient.right/2,rcClient.bottom/2,ch2,strlen(ch2)+1);

Sleep(1000);

break;

}

}

//回复初始状态,以备下次执行play()

dx=1;

dy=1;

mousex=0;

status=0;

positionmousestatus=0;

}

//子菜单:游戏规则介绍

void rule()

{

int n;

int sizech_rule;

char *s_rule[4]={"移动并点击鼠标左、右键控制挡板移动、反弹小球"," 小球撞击红砖后消除红砖"," 消除所有的红砖,游戏胜利"," 小球落地,游戏失败"};

SetTextColor(hdc,RGB(0,255,0));

SetBkColor(hdc,RGB(0,0,0));

for(n=0;n<4;n++)

{

sizech_rule=strlen(s_rule[n]);

if(n==3)

sizech_rule+=1;

TextOut(hdc,rcClient.right/3,rcClient.bottom/2+n*20,s_rule[n],sizech_rule);

}

}

//主菜单

void menuset(int j)

{

int n;

int sizech_menu;

char *s_menu[4]={"1.难度1","2.难度2","3.游戏规则","4.退出游戏"};

SetTextColor(hdc,RGB(0,255,0));

SetBkColor(hdc,RGB(0,0,0));

for(n=0;n<4;n++)

{

sizech_menu=strlen(s_menu[n]);

TextOut(hdc,rcClient.right/2,rcClient.bottom/2+n*20,s_menu[n],sizech_menu);

}

SetTextColor(hdc,RGB(255,0,0));

sizech_menu=strlen(s_menu[j]);

TextOut(hdc,rcClient.right/2,rcClient.bottom/2+j*20,s_menu[j],sizech_menu);

}

//选择主菜单后跳转执行

void judgeid(int id_judge)

{

void menuinitialize();//声明

system("cls");

switch(id_judge)

{

case 0:

key_1();

picture(horizontal,vertical_1,gap_end);

stonedraw_mouse(0);

mouselimitxy();

play(horizontal,vertical_1);

menuinitialize();

break;

case 1:

key_1();

picture(horizontal,vertical_2,gap_end);

stonedraw_mouse(0);

mouselimitxy();

play(horizontal,vertical_2);

menuinitialize();

break;

case 2:

rule();

Sleep(4000);

menuinitialize();

break;

case 3:

SetTextColor(hdc,RGB(0,255,0));

TextOut(hdc,rcClient.right/2,rcClient.bottom/2,"再见",strlen("再见")+1);

Sleep(2000);

exit(0);

}

}

//进行主菜单选择

void menuinitialize()

{

void judgeid(int id_judge);//声明

system("cls");

clientsizeget();

menuset(id_menu);

key_2();

do

{

if(GetKeyState(VK_DOWN)<0)//下

{

id_menu++;

id_menu=id_menu%4;

menuset(id_menu);

}

if(GetKeyState(VK_UP)<0)//上

{

if(id_menu==0)

id_menu=4;

id_menu--;

id_menu=id_menu%4;

menuset(id_menu);

}

Sleep(100);

}while(GetKeyState(VK_RETURN)>=0);//单击enter键确认选择,退出

judgeid(id_menu);

}

void main(int argc,char *argv[])

{

creathdc();

clientsizeset(sizeclientx,sizeclienty);

menuinitialize();

}

a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值