C语言版桌球游戏台球游戏源代码,含完整程序设计文档及答辩PPT,含可执行文件
C语言实现,图形库使用Easy_X,开发环境使用VS2013。
init 初始化
show 游戏画面显示
refreshWithInput 与输入有关的刷新
refreshWithoutInput 与输入无关的刷新
碰撞模型:
碰撞条件:
球移动到边界或者两球的距离小于阈值
碰撞过程:
假设所有的球质量相等,,根据动量定理,一个球碰撞一个静止的小球或者两个运动的球相撞,两个球交换速度,根据矢量合成,两球交换x y上的速度;
判断碰墙:碰墙后,速度反向。
更新小球坐标,防止小球出边界
核心代码
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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];
}
}
}
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;
}
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);
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();
}
else if (begin == 3){
loadimage(NULL, L"resourse/vic.jpg");
FlushBatchDraw();
}
}
EndBatchDraw();
return 0;
}
完整源代码下载地址:
https://download.csdn.net/download/weixin_42756970/87253754