C语言版桌球游戏台球游戏源代码,含完整程序设计文档及答辩PPT,含可执行文件
C语言实现,图形库使用Easy_X,开发环境使用VS2013。
init 初始化
show 游戏画面显示
refreshWithInput 与输入有关的刷新
refreshWithoutInput 与输入无关的刷新
碰撞模型:
碰撞条件:
球移动到边界或者两球的距离小于阈值
碰撞过程:
假设所有的球质量相等,,根据动量定理,一个球碰撞一个静止的小球或者两个运动的球相撞,两个球交换速度,根据矢量合成,两球交换x y上的速度;
判断碰墙:碰墙后,速度反向。
更新小球坐标,防止小球出边界

台球游戏代码java 台球小程序源码_c语言


核心代码

main.cpp

#include<graphics.h>
#include<conio.h>
#include<stdio.h>
#include<math.h>
#include<time.h>
#include<mmsystem.h>
#include<stdlib.h>
#pragma comment(lib,"winmm.lib")
const int High=483;
const int  Width = 917;
#define BallNum 10
int radius=15;
int identfy = 1;
float ball_x[BallNum], ball_y[BallNum];
float ballv_x[BallNum], ballv_y[BallNum];
float dist;
float sinA, cosA;
float start_y, start_x;
int i, j;
float f = 0.9;
int ball_show[BallNum];
float bd[BallNum][BallNum];
int firstboll=0;
int hitbool;
int begin = 0;
int Ascore=0, Bscore=0;
char TSA[100], TSB[100];
int vec = 1;
int end_true = 0;
int process = 2;
MOUSEMSG m;
void srand(unsigned int);
IMAGE head1, head2;
IMAGE midle,tiao;
IMAGE tiao2, tiao3, tiao4;
IMAGE back;
int msg=0;
TCHAR CharToTchar(const char * _char)
{
	int iLength;
	TCHAR tchar[100];
	iLength = MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, NULL, 0);
	MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, tchar, iLength);
	return  * tchar;
}
void msgshow()
{
	if (identfy == 1)
	{
		settextcolor(BLACK);//设置文本颜色
		msg = 0;
	}
	else{
		settextcolor(YELLOW);
		msg = 1;
	} 
	//加载提示信息
	if (msg == 0)
		outtextxy(Width + 63, High + 70, CharToTchar("魔王击球"));
	else if (msg == 1)
		outtextxy(Width + 63, High + 70, CharToTchar("勇者击球"));

}
void init()
{
	srand(time(NULL));//置随机数种子
	initgraph(Width + 50, High + 50);
	//加载图片资源
	loadimage(&head1, L"resourse/1.jpg", 150, 150);
	loadimage(&head2, L"resourse/2.jpg", 150, 150);
	loadimage(&midle, L"resourse/midle.png", 150, 233);
	loadimage(&tiao, L"resourse/tiao.png", Width+50, 50);
	loadimage(&tiao2, L"resourse/tiao2.png", Width + 50, 50);
	loadimage(&tiao3, L"resourse/tiao3.png", Width + 50, 50);
	loadimage(&tiao4, L"resourse/tiao4.png", Width + 50, 50);
	loadimage(&back, L"resourse/back.png", 150, 50);
	loadimage(NULL, L"resourse/menu.jpg");
	BeginBatchDraw();//开始绘图
	FlushBatchDraw();
	//初始化小球坐标
	ball_y[4] = 235;
	ball_x[4] = 680;

	ball_y[9] = 266;
	ball_x[9] = 680;

	ball_y[5] = 297;
	ball_x[5] = 680;

	ball_y[2] = 250;
	ball_x[2] = 654;

	ball_y[3] = 281;
	ball_x[3] = 654;

	ball_y[1] = 265;
	ball_x[1] = 624;

	ball_y[6] = 250;
	ball_x[6] = 706;

	ball_y[7] = 281;
	ball_x[7] = 706;

	ball_y[8] = 266;
	ball_x[8] = 733;
}
//球的坐标改变
void changeBall()
{
	for (i = 0; i < BallNum; i++)
	{
		if (ball_show[i] == 0)
		{
			ball_x[i] += ballv_x[i];
			ball_y[i] += ballv_y[i];//球随速度改变坐标
			ballv_x[i] = ballv_x[i] * 0.99;
			ballv_y[i] = ballv_y[i] * 0.99;//模仿阻尼使球的速度降低
			if (ballv_x[i] * ballv_x[i] + ballv_y[i] * ballv_y[i] <= 0.5)
			{
				ballv_x[i] = 0;
				ballv_y[i] = 0;
			}
			//进球	
			if (ball_y[i] <= 80 && ball_x[i] <= 80)
			{
				if (i != 0)
					ball_show[i] = 1;//将球的状态变为进球
				if (i == 0)
				{
					ball_show[i] = 0;//白球进球初始化
					ball_x[0] = 200;
					ball_y[0] = 266;
					ballv_y[0] = 0;
					ballv_x[0] = 0;
				}
				if (i != 0)
				{
					identfy *= -1;
					if (identfy == 1)
						Ascore+=i;//进球加分
					else Bscore+=i;
					ball_x[i] = -45;//进球后隐藏球
					ball_y[i] = -45;
				}

			}
			//2
			if (ball_y[i] >= 460 && ball_x[i] <= 80)
			{
				if (i != 0)
					ball_show[i] = 1;
				if (i == 0){
					ball_show[i] = 0;
					ball_x[0] = 200;
					ball_y[0] = 266;
					ballv_y[0] = 0;
					ballv_x[0] = 0;
				}
				if (i != 0){
					identfy *= -1;
					if (identfy == 1)
						Ascore += i;
					else Bscore += i;
					ball_x[i] = -45;
					ball_y[i] = -45;
				}

			}
			//3
			if (ball_x[i] >= 882 && ball_y[i] <= 70)
			{
				if (i != 0)
					ball_show[i] = 1;
				if (i == 0){
					ball_show[i] = 0;
					ball_x[0] = 200;
					ball_y[0] = 266;
					ballv_y[0] = 0;
					ballv_x[0] = 0;
				}
				if (i != 0){
					identfy *= -1;
					if (identfy == 1)
						Ascore += i;
					else Bscore += i;
					ball_x[i] = -45;
					ball_y[i] = -45;
				}

			}
			//4
			if (ball_x[i] > 888 && ball_y[i] >= 459)
			{
				if (i != 0)
					ball_show[i] = 1;
				if (i == 0){
					ball_show[i] = 0;
					ball_x[0] = 200;
					ball_y[0] = 266;
					ballv_y[0] = 0;
					ballv_x[0] = 0;
				}
				if (i != 0){
					identfy *= -1;
					if (identfy == 1)
						Ascore += i;
					else Bscore += i;
					ball_x[i] = -45;
					ball_y[i] = -45;
				}

			}
			//5
			if ((ball_x[i] > 450 && ball_x[i] < 511) && ball_y[i] <= 70)
			{
				if (i != 0)
					ball_show[i] = 1;
				if (i == 0){
					ball_show[i] = 0;
					ball_x[0] = 200;
					ball_y[0] = 266;
					ballv_x[0] = 0;
					ballv_y[0] = 0;
				}
				if (i != 0){
					identfy *= -1;
					if (identfy == 1)
						Ascore += i;
					else Bscore += i;
					ball_x[i] = -45;
					ball_y[i] = -45;
				}

			}
			//6
			if ((ball_x[i] > 450 && ball_x[i] < 511) && ball_y[i] >= 470)
			{
				if (i != 0)
					ball_show[i] = 1;
				if (i == 0){
					ball_show[i] = 0;
					ball_x[0] = 200;
					ball_y[0] = 266;
					ballv_x[0] = 0;
					ballv_y[0] = 0;
				}
				if (i != 0){
					identfy *= -1;
					if (identfy == 1)
						Ascore += i;
					else Bscore += i;
					ball_x[i] = -45;
					ball_y[i] = -45;
				}

			}

			//防止球出界
			if (ball_x[i] + radius >= 913 && ball_y[i] >= 64 && ball_y[i]<=452&&ball_show[i]==0){
				ball_x[i] = 913 - radius;
				ballv_x[i] = -ballv_x[i];
			}
			if (ball_x[i] - radius <= 50 && ball_y[i] >= 64 && ball_y[i] <= 452 && ball_show[i] == 0){
				ball_x[i] = radius + 50;
				ballv_x[i] = -ballv_x[i];
			}

			if (ball_y[i] + radius >= 480 && ball_x[i] >= 510 && ball_x[i] <= 890 && ball_show[i] == 0)
			{
				ball_y[i] = 480 - radius;
				ballv_y[i] = -ballv_y[i];
			}
			if (ball_y[i] + radius >= 480 && ball_x[i] >= 75 && ball_x[i] <= 452 && ball_show[i] == 0)
			{
				ball_y[i] = 480 - radius;
				ballv_y[i] = -ballv_y[i];
			}
			if (ball_y[i] - radius <= 47 && ball_x[i] >= 75 && ball_x[i] <= 452 && ball_show[i] == 0)
			{
				ball_y[i] = radius + 47;
				ballv_y[i] = -ballv_y[i];
			}
			if (ball_y[i] - radius <= 47 && ball_x[i] >= 510 && ball_x[i] <= 890 && ball_show[i] == 0)
			{
				ball_y[i] = radius + 47;
				ballv_y[i] = -ballv_y[i];
			}
		}
	}
	//检测到球的状态为进球后将球的速度置为0
	for (i = 1; i < BallNum;i++)
	if (ball_show[i])
	{
		ballv_x[i] = 0;
		ballv_y[i] = 0;
	}
}
//球球碰撞模型
void ballscollision()
{
	//计算球的距离
	for (int i = 0; i < BallNum;i++)
	if (ball_show[i] == 0)
		for (int j = 0; j < BallNum; j++){
			if (i == j)
				continue;
			float distance = (ball_x[i] - ball_x[j])* (ball_x[i] - ball_x[j]) + (ball_y[i] - ball_y[j])* (ball_y[i] - ball_y[j]);
			//首次碰球球的四散效果
			if (distance <= 4 * radius*radius){
				if (firstboll == 0){
					for (int i = 1; i < BallNum; i++){
						ballv_x[i] = 4 - rand() % 9;
						ballv_y[i] = 4 - rand() % 9;
					}
					firstboll = 1;
				}
				//如果球的距离小于2R将球拉开防止球的粘连
				if (distance < 4 * radius*radius){
					float needdis = 2 * radius - sqrt(distance);
					ball_x[i] -= needdis/2;
					ball_x[j] += needdis/2;
					ball_y[i] -= needdis / 2;
					ball_y[j] += needdis / 2;
				}
				float tx, ty;
				//交换球的速度
				if (ballv_x[i] == 0 && ballv_x[i] == 0){//动撞静模型
					tx = ballv_x[j];
					ty = ballv_y[j];

					ballv_x[i] = tx;
					ballv_y[i] = ty;

					ballv_x[j] = -tx/4;
					ballv_y[j] = -ty/4;
				}
				else if (ballv_x[j] == 0 && ballv_x[j] == 0){
					tx = ballv_x[i];
					ty = ballv_y[i];

					ballv_x[j] = tx;
					ballv_y[j] = ty;

					ballv_x[i] = -tx/4;
					ballv_y[i] = -ty/4;
				}
				else{
					//动动碰撞
					float temp = ballv_x[i]; ballv_x[i] = ballv_x[j]; ballv_x[j] = temp;
					temp = ballv_y[i]; ballv_y[i] = ballv_y[j]; ballv_y[j] = temp;
				}
				
			}
	}
		
	
}
//刷新球的位置显示
void refreshBall(){
	setlinestyle(PS_DASH, 1);//设置线条粗细为1 
	for (i = 0; i < BallNum; i++)
	{
		if (i == 0){
			setfillcolor(WHITE);//设置球的填充颜色和边缘颜色
			setcolor(WHITE);
		}
		else if (i == 1){
			setfillcolor(YELLOW);
			setcolor(YELLOW);
		}
		else if (i == 2){
			setfillcolor(BLUE);
			setcolor(BLUE);
		}
		else if (i == 3){
			setfillcolor(RED);
			setcolor(RED);
		}
		else if (i == 4){
			setfillcolor(MAGENTA);
			setcolor(MAGENTA);
		}
		else if (i == 5){
			setfillcolor(0xFFA500);
			setcolor(0xFFA500);
		}
		else if (i == 6){
			setfillcolor(GREEN);
			setcolor(GREEN);
		}
		else if (i == 7){
			setfillcolor(BROWN);
			setcolor(BROWN);
		}
		else if (i == 8){
			setfillcolor(0xFFB6C1);
			setcolor(0xFFB6C1);
		}
		else if (i == 9){
			setfillcolor(BLACK);
			setcolor(BLACK);
		}
		if (ball_show[i] == 0)
			fillcircle(ball_x[i], ball_y[i], radius);
	}
	//输出分数信息
	outtextxy(Width + 50, 200, CharToTchar(TSA));
	outtextxy(Width + 50, 200 + 150, CharToTchar(TSB));
	FlushBatchDraw();
	//刷新图片资源显示
	loadimage(NULL, L"resourse/table.png");
	putimage(Width + 50, 0, &head1);
	putimage(Width + 50, High - 100, &head2);
	putimage(Width + 50, 150, &midle);
	if (process==1)
		putimage(0, High + 50, &tiao);
	else if (process == 2)
		putimage(0, High + 50, &tiao2);
	else if (process == 3)
		putimage(0, High + 50, &tiao3);
	else if (process == 4)
		putimage(0, High + 50, &tiao4);

	putimage(Width + 50, 532, &back);
}
void hitball(){
	hitbool = 1;
	
	for (int i = 0; i < BallNum; i++){
		if (ballv_x[i] || ballv_x[j])
			hitbool = 0;
	}
	//如果所有球都静止了则加载球杆
	if (hitbool)
	{
		m = GetMouseMsg();
		setlinestyle(PS_SOLID, 10);
		dist = sqrt((m.x - ball_x[0])*(m.x - ball_x[0]) + (m.y - ball_y[0])*(m.y - ball_y[0]));  //鼠标到母球的距离
		sinA = (m.y - ball_y[0]) / dist;    //计算击球角度 
		cosA = (m.x - ball_x[0]) / dist;     
		start_x = ball_x[0] + 200*cosA;      
		start_y = ball_y[0] + 200*sinA;
		if (identfy == 1){//根据角色加载颜色不同的球杆
			setcolor(BLACK);
			line(start_x, start_y, ball_x[0], ball_y[0]);
		}	
		else if (identfy == -1){
			setcolor(YELLOW);
			line(start_x, start_y, ball_x[0], ball_y[0]);
		}



		//设置文字背景
		setbkmode(1);
		sprintf(TSA, "魔王点数:%d  ", Ascore);//刷新分数
		sprintf(TSB, "勇者点数:%d ", Bscore);
		//击球
		if (m.uMsg == WM_LBUTTONDOWN&&m.y<(High + 50) && m.x<(Width + 50)){
			float l = ball_x[0] - m.x;
			float w = ball_y[0] - m.y;
			float mod = sqrt(l*l + w*w);
			ballv_x[0] = (ball_x[0] - m.x)/mod*process*10;
			ballv_y[0] = (ball_y[0] - m.y) / mod*process * 10;
			identfy = -identfy;
		
		}
		//力度条调节
		if (m.uMsg == WM_LBUTTONDOWN
			&& (m.x<265 && m.y>550))
			process = 1;
		else if (m.uMsg == WM_LBUTTONDOWN 
			&& (m.x>260 && m.y>550&&m.x<470))
			process = 2;
		else if (m.uMsg == WM_LBUTTONDOWN
			&& (m.x>470 && m.y>550 && m.x<705))
			process = 3;
		else if (m.uMsg == WM_LBUTTONDOWN
			&& (m.x>700 && m.y>550 && m.x<920))
			process = 4;
		vec = 1;
		//游戏结束判定
		for (i = 1; i < BallNum; i++){
			if (ball_show[i]==0)
				vec = 0;
		}
		//胜负判断
		if (vec){
			if (Ascore>Bscore)
				begin = 2;
			else begin = 3;
		}
		
	}
}
int main()
{
	init();

	while (1){
		if (begin==1){
			changeBall();
			ballscollision();
			hitball();
			msgshow();
			refreshBall();
			if (end_true){
				break;
			}
				
		}
		else if(begin==0){
			m = GetMouseMsg();
			if (m.uMsg == WM_LBUTTONDOWN){
				if (m.x>=657&&m.x<=904)
				if (m.y >= 300 && m.y <= 500){
					closegraph();
					initgraph(Width + 200, High + 100);
					loadimage(NULL, L"table.png");
					putimage(Width+50,0,&head1);
					putimage(Width + 50, High-100, &head2);
					putimage(Width + 50, 150, &midle);
					putimage(0, High+50, &tiao);
					putimage(Width + 50, 532, &back);
					FlushBatchDraw();
					begin =1;
				}

			}
		}
		else if (begin == 2){
			loadimage(NULL, L"resourse/Devil.jpg");
			FlushBatchDraw();
			//loadimage(NULL, "Devil.jpg");
		}
		else if (begin == 3){
			loadimage(NULL, L"resourse/vic.jpg");
			FlushBatchDraw();
		}
	}
	EndBatchDraw();
	return 0;
}

台球游戏代码java 台球小程序源码_powerpoint_02