/********************************************************************************
* 实验一 二维弹球游戏设计
*
*(1)掌握在VS2010或以上版本环境下如何配置OpenGL环境的方法;
*(2)熟悉OpenGL应用程序基本架构;
*(3)培养良好的编程习惯和风格,学习撰写实验报告;
*(4)学习交互式游戏设计;
*(5)通过小球移动、反弹、击中等功能实现学习二维几何的基本运算;
*(6)菜单的使用。
*********************************************************************************/
#include <stdlib.h>
#include <GL/glut.h>
#include <stdio.h>
#include <Windows.h>
#include <math.h>
const GLfloat Pi = 3.14159265f;
int w=700,h=600;
int count=0;
GLfloat radius; //球的半径
GLfloat ball_speedx; //球在X方向的速度
GLfloat ball_speedy; //球的Y方向的速度
GLfloat ball_Pos[2]; //球的位置
GLfloat board_width,board_height; //挡板的长度和高度
GLfloat board_speed; //挡板的速度
GLfloat board_Pos[2]; //挡板的位置
GLfloat brick_width,brick_height; //砖块的长度和高度
float brick_Pos[][2] = {{-2.2,1.9},{-1.3,1.9},{-0.4,1.9},{0.5,1.9},{1.4,1.9}, //砖块的位置坐标
{-2.0,1.6},{-0.9,1.6},{0.2,1.6},{1.3,1.6},
{-2.2,1.3},{-1.3,1.3},{-0.4,1.3},{0.5,1.3},{1.4,1.3},
{-2.0,1.0},{-0.9,1.0},{0.2,1.0},{1.3,1.0},
{-2.2,0.7},{-1.3,0.7},{-0.4,0.7},{0.5,0.7},{1.4,0.7}};
bool start = false; //游戏是否开始
void TanqiuInit()
{
glClearColor( 0.0, 0.0, 0.0, 0.0);
glColor3f(1.0,0.0,0.0);
glMatrixMode(GL_PROJECTION); //指定希望修改的矩阵为投影矩阵
glLoadIdentity(); //重置为单位矩阵
gluOrtho2D(-2.0,2.0,-2.0,2.0); //设置二维剪裁区域,左下角坐标为(-2,2),右上角坐标为(2,2)
radius = 0.1f; //小球的半径
ball_speedx = 0.001; ball_speedy = 0.001;
ball_Pos[0] = -1.6; ball_Pos[1] = -1.75;
board_Pos[0] = -2.0; board_Pos[1] = -2.0;
board_width = 0.8; board_height = 0.15;
board_speed = 0.15;
brick_width = 0.8;brick_height = 0.2;
}
void draw_ball()
{
glColor3f(1.0,0.0,0.0);
const int n = 50;
glBegin(GL_POLYGON);
for (int i = 0; i < n; i++)
{
glVertex2f(radius*cos(2 * Pi / n*i), radius*sin(2 * Pi/n*i)); //连续的画点
}
glEnd();
}
void draw_board()
{
glColor3f(0.0,1.0,0.0);
glBegin(GL_POLYGON);
glVertex2f(board_Pos[0],board_Pos[1]);
glVertex2f(board_Pos[0]+board_width,board_Pos[1]);
glVertex2f(board_Pos[0]+board_width,board_Pos[1]+board_height);
glVertex2f(board_Pos[0],board_Pos[1]+board_height);
glEnd();
}
void boardPosition()
{
//挡板与墙壁的碰撞检测
if(board_Pos[0]<=-2.0*w/h) //左侧墙壁
{
board_Pos[0] = -2.0*w/h;
board_speed = -board_speed;
}
else if(board_Pos[0]+board_width>=2.0*w/h) //右侧墙壁
{
board_Pos[0] = 2.0*w/h-board_width;
board_speed = -board_speed;
}
}
void draw_brick()
{
glColor3f(1.0,1.0,0.0);
for(int i=0;i<5;i++)
{
int j = 0;
//判断brick_Pos[i][j]是否为零,若不为零,则此处有砖块;若为零,无砖块
if (brick_Pos[i][j] != 0)
{
glBegin(GL_POLYGON);
glVertex2f(brick_Pos[i][j],brick_Pos[i][j+1]);
glVertex2f(brick_Pos[i][j]+brick_width,brick_Pos[i][j+1]);
glVertex2f(brick_Pos[i][j]+brick_width,brick_Pos[i][j+1]-brick_height);
glVertex2f(brick_Pos[i][j],brick_Pos[i][j+1]-brick_height);
glEnd();
}
}
glColor3f(0.0,1.0,1.0);
for(int i=5;i<9;i++)
{
int j = 0;
//判断brick_Pos[i][j]是否为零,若不为零,则此处有砖块;若为零,无砖块
if (brick_Pos[i][j] != 0)
{
glBegin(GL_POLYGON);
glVertex2f(brick_Pos[i][j],brick_Pos[i][j+1]);
glVertex2f(brick_Pos[i][j]+brick_width,brick_Pos[i][j+1]);
glVertex2f(brick_Pos[i][j]+brick_width,brick_Pos[i][j+1]-brick_height);
glVertex2f(brick_Pos[i][j],brick_Pos[i][j+1]-brick_height);
glEnd();
}
}
glColor3f(1.0,0.0,1.0);
for(int i=9;i<14;i++)
{
int j = 0;
//判断brick_Pos[i][j]是否为零,若不为零,则此处有砖块;若为零,无砖块
if (brick_Pos[i][j] != 0)
{
glBegin(GL_POLYGON);
glVertex2f(brick_Pos[i][j],brick_Pos[i][j+1]);
glVertex2f(brick_Pos[i][j]+brick_width,brick_Pos[i][j+1]);
glVertex2f(brick_Pos[i][j]+brick_width,brick_Pos[i][j+1]-brick_height);
glVertex2f(brick_Pos[i][j],brick_Pos[i][j+1]-brick_height);
glEnd();
}
}
glColor3f(0.8,0.5,0.2);
for(int i=14;i<18;i++)
{
int j = 0;
//判断brick_Pos[i][j]是否为零,若不为零,则此处有砖块;若为零,无砖块
if (brick_Pos[i][j] != 0)
{
glBegin(GL_POLYGON);
glVertex2f(brick_Pos[i][j],brick_Pos[i][j+1]);
glVertex2f(brick_Pos[i][j]+brick_width,brick_Pos[i][j+1]);
glVertex2f(brick_Pos[i][j]+brick_width,brick_Pos[i][j+1]-brick_height);
glVertex2f(brick_Pos[i][j],brick_Pos[i][j+1]-brick_height);
glEnd();
}
}
glColor3f(0.2,0.5,0.8);
for(int i=18;i<23;i++)
{
int j = 0;
//判断brick_Pos[i][j]是否为零,若不为零,则此处有砖块;若为零,无砖块
if (brick_Pos[i][j] != 0)
{
glBegin(GL_POLYGON);
glVertex2f(brick_Pos[i][j],brick_Pos[i][j+1]);
glVertex2f(brick_Pos[i][j]+brick_width,brick_Pos[i][j+1]);
glVertex2f(brick_Pos[i][j]+brick_width,brick_Pos[i][j+1]-brick_height);
glVertex2f(brick_Pos[i][j],brick_Pos[i][j+1]-brick_height);
glEnd();
}
}
}
void ballPosition()
{
ball_Pos[0] += ball_speedx;
ball_Pos[1] += ball_speedy;
/*
*小球与砖块的碰撞检测
*/
for(int i=0;i<23;i++)
{
int j = 0;
if(brick_Pos[i][j]!=0)
{
//与砖块的下面碰撞
if(ball_Pos[1]>=brick_Pos[i][1]-brick_height-radius && ball_Pos[1]<=brick_Pos[i][1]-brick_height
&& ball_Pos[0]>=brick_Pos[i][0] && ball_Pos[0]<=brick_Pos[i][0]+brick_width)
{
ball_Pos[1] = brick_Pos[i][1]-brick_height-radius;
ball_speedy = -ball_speedy;
brick_Pos[i][j]=0; //使砖块消失
count++;
}
//与砖块的上面碰撞
else if(ball_Pos[1]<=brick_Pos[i][1]+radius && ball_Pos[1]>=brick_Pos[i][1]
&& ball_Pos[0]>=brick_Pos[i][0] && ball_Pos[0]<=brick_Pos[i][0]+brick_width)
{
ball_Pos[1] = brick_Pos[i][1]+radius;
ball_speedy = -ball_speedy;
brick_Pos[i][j]=0; //使砖块消失
count++;
}
//与砖块的左面碰撞
else if(ball_Pos[0]>=brick_Pos[i][0]-radius && ball_Pos[0]<=brick_Pos[i][0]
&& ball_Pos[1]<=brick_Pos[i][1] && ball_Pos[1]>=brick_Pos[i][1]-brick_height)
{
ball_Pos[0] = brick_Pos[i][0]-radius;
ball_speedx = -ball_speedx;
brick_Pos[i][j]=0; //使砖块消失
count++;
}
//与砖块的右面碰撞
else if(ball_Pos[0]<=brick_Pos[i][0]+brick_width+radius && ball_Pos[0]>=brick_Pos[i][0]+brick_width
&& ball_Pos[1]<=brick_Pos[i][1] && ball_Pos[1]>=brick_Pos[i][1]-brick_height)
{
ball_Pos[0] = brick_Pos[i][0]+brick_width+radius;
ball_speedx = -ball_speedx;
brick_Pos[i][j]=0; //使砖块消失
count++;
}
}
}
if(count==23)
{
MessageBoxA(NULL,"恭喜你过关啦!","胜利",0);
exit(0);
}
/*
*小球与墙的碰撞检测
*/
//与右侧墙壁碰撞
if(ball_Pos[0]>=2.0* w / h-radius)
{
ball_Pos[0] = 2.0* w / h-radius;
ball_speedx = -ball_speedx;
}
//与左侧墙壁碰撞
else if(ball_Pos[0]<=-2.0 * w / h+radius)
{
ball_Pos[0] = -2.0* w / h+radius;
ball_speedx = -ball_speedx;
}
//与上方墙壁碰撞
else if(ball_Pos[1]>=2.0-radius)
{
ball_Pos[1] = 2.0-radius;
ball_speedy = -ball_speedy;
}
//与挡板碰撞
else if(ball_Pos[1]<=-2.0+board_height+radius && ball_Pos[0]>=board_Pos[0] && ball_Pos[0]<=board_Pos[0]+board_width)
{
ball_Pos[1] = -2.0+board_height+radius;
ball_speedy = -ball_speedy;
}
//与下方墙壁碰撞
else if(ball_Pos[1]<=-2.0+radius)
{
ball_Pos[1] = -2.0+radius;
ball_speedy = 0;
ball_speedx = 0;
MessageBoxA(NULL, "游戏结束", "失败", 0);
exit(0);
}
glutPostRedisplay();
}
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glTransla