一个opengl实现的很简陋的双人对战五子棋

开始自学openGL

对着红宝书撸了几天后做的,这书看着真心累,像个API手册一样

#include <GL/glut.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stack>
GLint length=600;
GLboolean isBlack;//轮到黑棋
GLboolean isStart;//是否开始
GLint chessboard[15][15];//记录棋盘棋子,0表示没有棋子,1表示黑子,-1表示白子
std::stack<int> steps;//记录下子步骤,用于悔棋
GLfloat rData[360][2];//保存一个圆的顶点信息,画棋子用
//判断是否五子连珠
bool isWin(int x,int y)
{
	int dir[][2]={0,1,1,0,1,1,1,-1};
	for(int i=0;i<4;++i)
	{
		int len=1;
		for(int j=1;chessboard[x][y]==chessboard[x+j*dir[i][0]][y+j*dir[i][1]];++j)
			++len;
		for(int j=1;chessboard[x][y]==chessboard[x-j*dir[i][0]][y-j*dir[i][1]];++j)
			++len;
		if(len>=5) return 1;
	}
	return 0;
}
//把屏幕坐标转换成棋盘上的坐标
void trans(int &x,int &y)
{
	y=length-y;	
	x=(int)((x<<4)/(length*1.0)-0.5);
	y=(int)((y<<4)/(length*1.0)-0.5);
}
//画棋子(即画一个圆)
void drawChess(int x,int y,int color)
{
	if(color==1) glColor3f(0,0,0);
	else glColor3f(1,1,1);
	glBegin(GL_TRIANGLE_FAN);
	for(int i=1;i<=360;i++)
		glVertex2f(rData[i-1][0]+x+1,rData[i-1][1]+y+1);
	glEnd();
}

//开始新一局游戏时用来初始化数据
void newGame()
{
	while(!steps.empty())
		steps.pop();
	isBlack=1;
	isStart=1;
	memset(chessboard,0,sizeof(chessboard));
}

void processMenu(int opt)
{
	switch(opt)
	{
		case 1:
			newGame();
			break;
		case 2:
			if(steps.empty()) break;
			int temp=steps.top();
			steps.pop();
			chessboard[temp>>4][temp&15]=0;
			isBlack=!isBlack;
			break;
	}
	glutPostRedisplay();
}

void init()
{
	glClearColor(0.5,0.5,0.5,0);
	//保存画圆时的各个顶点
	for(int i=0;i<360;++i)
	{
		rData[i][0]=0.37*cos(1.0*i);
		rData[i][1]=0.37*sin(1.0*i);
	}

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0,16,0,16,-1,1);
	//画棋盘的线
	static GLint vertices[120];
	for(int i=0;i<15;++i)
	{
		int j=i<<2;
		vertices[j]=i+1;
		vertices[j+1]=1;
		vertices[j+2]=i+1;
		vertices[j+3]=15;

		vertices[j+60]=1;
		vertices[j+61]=i+1;
		vertices[j+62]=15;
		vertices[j+63]=i+1;
	}
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(2,GL_INT,0,vertices);

	int newGameMenu = glutCreateMenu(processMenu);
	glutAddMenuEntry("start a new game",1);
	glutAddMenuEntry("go back",2);
	glutAttachMenu(GLUT_RIGHT_BUTTON);

	newGame();
}

void display()
{
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1,1,1);
	//画棋盘
	glDrawArrays(GL_LINES,0,60);
	//画棋子
	for(int i=0;i<15;++i)
		for(int j=0;j<15;++j)
			if(chessboard[i][j])
				drawChess(i,j,chessboard[i][j]);
	glFlush();
}

void keyboard(unsigned char key, int x, int y)
{
	switch(key)
	{
		case 27:
			exit(0);
	}
}

void mouse(int button, int state, int x, int y)
{
	switch(button)
	{
		case GLUT_LEFT_BUTTON:
			if(GLUT_DOWN==state&&1==isStart)
			{
				trans(x,y);
				if(chessboard[x][y]) break;
				chessboard[x][y]=isBlack*2-1;
				steps.push((x<<4)+y);
				if(isWin(x,y))
				{
					isStart=0;
					if(isBlack)
						glClearColor(0.7,0.7,0.7,0);
					else
						glClearColor(0.1,0.1,0.1,0);
				}
				isBlack=!isBlack;
				glutPostRedisplay();
			}
			break;
		case GLUT_RIGHT_BUTTON:
			newGame();
			glutPostRedisplay();
			break;
	}
}

void reshape(int x, int y)
{
	//为了使棋盘保持正方形,用x,y较小的那个作为视口(棋盘)边长
	if(x>y) x=y;
	else y=x;
	length=x;
	glViewport(0,0,(GLsizei)x,(GLsizei)y);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0,16,0,16,-1,1);
}

int main(int argc, char **argv)
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
	glutInitWindowSize(length,length);
	glutInitWindowPosition(100,100);
	glutCreateWindow("Gobang");
	init();
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);
	glutMouseFunc(mouse);
	glutReshapeFunc(reshape);
	glutMainLoop();
	return 0;
}




  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值