Opengl三维fps游戏

自由三维视角参考了http://t.csdnimg.cn/5hzu7

贴图资源在最上面,他也可以点击链接https://share.weiyun.com/GOcnS9dh下载,请解压至项目目录,源码放最下面了。

 

以下是针对其进行的开发:

目录

1搭建天空盒.


 

1搭建了天空盒

2墙壁物理碰撞

3透明图片

4创建怪物(Monster)类

5射击检测

成果在这

ff9681e162c0410ea8293001959b6f43.png

1搭建天空盒.

最早采用了三个数组,储存点的x,y,x坐标,再用一个面数组去调用点,不过实际操作挺麻烦的,后面采用结构体形式。

#define SNUM 5
#define PNUM 8
void LoadGLTextures()
{
	int i;
	const char* pictures[PICNUM] = {
		"test\\front.bmp",
		
		"test\\ground.bmp" ,
		"test\\top.bmp",
		"test\\gd.bmp" ,
		"test\\right.bmp",
		"test\\right.bmp" ,
		"test\\back.bmp",
		"test\\coverage.bmp" ,
		"test\\zombie.bmp",
		"test\\zombiecover.bmp" ,
		"test\\zombiep2.bmp" ,
		"test\\zombiep2cover.bmp" ,
		"test\\zombie0\\down.bmp",
		"test\\zombie0\\downcover.bmp",
		"test\\zombie0\\leftdown.bmp",
		"test\\zombie0\\leftdowncover.bmp",
		"test\\gun.bmp",
		"test\\guncover.bmp",
		"test\\ggg.bmp",
		"test\\gggcover.bmp",
		"test\\shot.bmp",
		"test\\shotcover.bmp",
		"test\\title.bmp"
	};

先宏定义点(PNUM)和面(SNUM)数量。并且把贴图加载进来

一共8个点(立方体8顶点),5个面(上下左右后,前面我没留,方便)。

点(point)我决定写个结构体

struct point
{
	float x;
	float y;
	float z;
};

下面我将天空盒的搭建封装在room函数中,想创建房子就调用下此函数

void room1(float x1, float z1, float x2, float z2)//四个参数为绘制房间的左下角与右上角坐标,注意此处水平面是xoz面,所以参数是x和z
{
	
	point points[PNUM] = { {x1,0,z1}, {x1,8,z1} ,{x2,8,z1} ,{x2,0,z1}, {x1,0,z2}, {x1,8,z2} , {x2,8,z2} ,{x2,0,z2} };//八个顶点坐标
	int surface[SNUM][4] = { {0,1,2,3},{0,1,5,4},{5,1,2,6},{0,3,7,4},{7,6,2,3} };//面调用点的序列{0,1,2,3}代表依次调用0,1,2,3四个顶点来绘制面。
	for (int k = 0; k < SNUM; k++)//绘制SUM数量的面
	{
		glColor3f(1.0, 1.0, 1.0);//先绘制白色四边形
		glBegin(GL_QUADS);
		for (int i = 0; i < 4; i++)//绘制四个点
		{
			glVertex3f(points[surface[k][i]].x, points[surface[k][i]].y, points[surface[k][i]].z);//用surface[k][i],k代表第几个面,i代表该面第几个点,从而调用点points
		}
		glEnd();
		glEnable(GL_TEXTURE_2D);//贴图
		glBindTexture(GL_TEXTURE_2D, texture[k]);
		glBegin(GL_QUADS);
		glTexCoord2f(0, 0);  glVertex3f(points[surface[k][0]].x, points[surface[k][0]].y, points[surface[k][0]].z);
		glTexCoord2f(0, 1);  glVertex3f(points[surface[k][1]].x, points[surface[k][1]].y, points[surface[k][1]].z);
		glTexCoord2f(1, 1);  glVertex3f(points[surface[k][2]].x, points[surface[k][2]].y, points[surface[k][2]].z);
		glTexCoord2f(1, 0);  glVertex3f(points[surface[k][3]].x, points[surface[k][3]].y, points[surface[k][3]].z);
		glEnd();
		glDisable(GL_TEXTURE_2D);
	}
}

create函数用来完成所有背景创造(考虑到后面可能有多个房间都要绘制)

void createbk()
{
	room2(-WIDTH, -16, WIDTH, -48);
	room1(-WIDTH, 16, WIDTH, -16);
}

此处写了两个不同的房间room1和room2,调用参数为房间地板坐下与右上角,WIDTH是我定义的宽度暂定为4.0。

最后在display里调用createbk函数

void display(void)
{
	
	// 清除屏幕
	if (shot > 0)
	{
		shot--;
	}
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   // 清除屏幕及深度缓存
	// 深度测试开启,实现遮挡关系
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	// 设置视角
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60, 1, 0.1, 100);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(cpos_x, cpos_y, cpos_z, cpos_x + look_x, cpos_y + look_y, cpos_z - look_z, 0, 1, 0);//注意因为相机是面朝z负方向,所以cpos_z - lookz
	//gluLookAt(cpos_x, cpos_y, cpos_z, 0, 0, 0, 0, 1, 0);//原固定视角
	if(flag)
		start();
	
	
		judge();

		createbk();
		if (!flag)
		{
			sort();
			gun();
		}
	glutSwapBuffers();
}

先写到这,别的后面再更新,源码如下。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cmath>
#include<windows.h>
#include<stdlib.h>
#include<math.h>
#include<gl/glaux.h>
#include <tchar.h>
#define _CRT_SECURE_NO_WARNINGS
#define WindowWidth  1200
#define WindowHeight 600
#define WindowTitle  "第一人称视角漫游demo"
#define SNUM 5
#define PNUM 8
#define WIDTH 4
#define PICNUM 50
#define MW 0.8
#define MH 5
#define MNUM 5

#include <gl\glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<iostream>
using namespace std;
#pragma comment(lib, "glaux")
float rot = 0;
GLuint texture[PICNUM];
void LoadGLTextures();
void picture(int i);
bool lose = false;
float PI = 3.14;
//视角控制
float look_x = 0,
look_y = 0,
look_z = 0,
look_x_temp = 0,
look_z_temp = 0;
float screenrate_x, screenrate_y;//鼠标屏幕坐标相对于中心点移动的比例
float r = 10;
//相机位置
float cpos_x = 0,
cpos_y = 3,
cpos_z = 10;
const float step = 0.01;
int centerpoint_x = WindowWidth / 2,
centerpoint_y = WindowHeight / 2;
int shot = 0;
int myscore = 0;
int shottime = 0;
void transp(int i1, int i2, float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4);
void timefunction(int value);
int ord = 0;
struct point
{
	float x;
	float y;
	float z;
};
void room1(float x1, float z1, float x2, float z2)//四个参数为绘制房间的左下角与右上角坐标,注意此处水平面是xoz面,所以参数是x和z
{

	point points[PNUM] = { {x1,0,z1}, {x1,8,z1} ,{x2,8,z1} ,{x2,0,z1}, {x1,0,z2}, {x1,8,z2} , {x2,8,z2} ,{x2,0,z2} };//八个顶点坐标
	int surface[SNUM][4] = { {0,1,2,3},{0,1,5,4},{5,1,2,6},{0,3,7,4},{7,6,2,3} };//面调用点的序列{0,1,2,3}代表依次调用0,1,2,3四个顶点来绘制面。
	for (int k = 0; k < SNUM; k++)//绘制SUM数量的面
	{
		glColor3f(1.0, 1.0, 1.0);//先绘制白色四边形
		glBegin(GL_QUADS);
		for (int i = 0; i < 4; i++)//绘制四个点
		{
			glVertex3f(points[surface[k][i]].x, points[surface[k][i]].y, points[surface[k][i]].z);//用surface[k][i],k代表第几个面,i代表该面第几个点,从而调用点points
		}
		glEnd();
		glEnable(GL_TEXTURE_2D);//贴图
		glBindTexture(GL_TEXTURE_2D, texture[k+ord]);
		glBegin(GL_QUADS);
		glTexCoord2f(0, 0);  glVertex3f(points[surface[k][0]].x, points[surface[k][0]].y, points[surface[k][0]].z);
		glTexCoord2f(0, 1);  glVertex3f(points[surface[k][1]].x, points[surface[k][1]].y, points[surface[k][1]].z);
		glTexCoord2f(1, 1);  glVertex3f(points[surface[k][2]].x, points[surface[k][2]].y, points[surface[k][2]].z);
		glTexCoord2f(1, 0);  glVertex3f(points[surface[k][3]].x, points[surface[k][3]].y, points[surface[k][3]].z);
		glEnd();
		glDisable(GL_TEXTURE_2D);
	}
}

bool flag = true;

void start()
{
	float t1 = sqrt(look_x * look_x + look_z * look_z);
	float  y = cpos_y + look_y / 20;
	float x0 = cpos_x + (look_x_temp / 20) * cos(-screenrate_y + 0.2 * PI) ;
	float z0 = cpos_z - (look_z_temp / 20) * cos(-screenrate_y + 0.2 * PI) ;
	float x00 = cpos_x + (look_x_temp / 20) * cos(-screenrate_y - 0.2 * PI);
	float z00 = cpos_z - (look_z_temp / 20) * cos(-screenrate_y - 0.2 * PI);
	float x1 = x0 + 0.25 * (look_z) / t1;
	float z1 = z0 + 0.25 * (look_x) / t1;
	float x2 = x0 - 0.25 * (look_z) / t1 ;
	float z2 = z0 - 0.25 * (look_x) / t1;
	float x3 = x00 + 0.25 * (look_z) / t1;
	float z3 = z00 + 0.25 * (look_x) / t1;
	float x4 = x00 - 0.25 * (look_z) / t1;
	float z4 = z00 - 0.25 * (look_x) / t1;
	int d = 15;
	float yd = cpos_y+r * sin(-screenrate_y+0.2*PI)/20;
	float yd2 = cpos_y + r * sin(-screenrate_y - 0.2 * PI)/20;
	transp(27, 22, x3 ,  yd2, z3 ,
		x1 ,  yd , z1 ,
		x2 ,  yd , z2 ,
		x4 ,   yd2 , z4);
	printf("%f,%f,%f\n", cpos_x + look_x / 10 + look_z_temp / 10, cpos_y + look_y, cpos_z - look_z / 10 + look_x_temp / 10);
}
class monster
{
private:
	float x;
	float y;
	float health;
	float angle;
	float angle2;
	float time;
	float direction;
	int death;
	float dx;
	float dy;
	float angle1;
	int pic2;
	int cover2;
	int pic;
	int cover;
	int willdie;
	int count;
	int diep;
	int diec;
public:
	void changeskin(int p1,int p2,int p3,int p4,int p5,int p6)
	{
		pic = p1;
		cover = p2;
		pic2 = p3;
		cover2 = p4;
		diep = p5;
		diec = p6;
	}
	monster(float setx, float sety, int h)
	{
		x = setx;
		y = sety;
		health = h;
		time = 0;
		direction = 1;
		death = 0;
		pic = 8;
		willdie = 0;
		cover = 9;
		count = 0;
		pic2 = 12;
		cover2 = 13;
		diep = 23;
		diec = 24;
	}
	void walk()
	{
		dx = (cpos_x - x) / sqrt((cpos_x - x) * (cpos_x - x) + (cpos_z - y) * (cpos_z - y));
		dy = (cpos_z - y) / sqrt((cpos_x - x) * (cpos_x - x) + (cpos_z - y) * (cpos_z - y));
		if (!death)
		{
			x += dx * step;
			y += dy * step;

			draw();
			time += direction / 2;
			if (time == 20)direction = -1;
			if (time == -20)direction = 1;
		}
	}
	float getlength()
	{
		return sqrt((cpos_x - x) * (cpos_x - x) + (cpos_z - y) * (cpos_z - y));
	}
	void body(float x1, float y1, float x2, float y2, float speed1, float speed2)
	{
		glEnable(GL_BLEND);
		glBlendFunc(GL_DST_COLOR, GL_ZERO);
		glEnable(GL_TEXTURE_2D);

		glBindTexture(GL_TEXTURE_2D, texture[cover2]);

		glBegin(GL_QUADS);
		glTexCoord2f(x1, y1);  glVertex3f(x + 2 * MW * angle2 * (x1 - 0.5) + time / 20 * dx * speed1, MH * y1, y - 2 * MW * angle * (x1 - 0.5) + time / 20 * dy * speed1);
		glTexCoord2f(x1, y2);  glVertex3f(x + 2 * MW * angle2 * (x1 - 0.5) + time / 20 * dx * speed2, MH * y2, y - 2 * MW * angle * (x1 - 0.5) + time / 20 * dy * speed2);
		glTexCoord2f(x2, y2);  glVertex3f(x + 2 * MW * angle2 * (x2 - 0.5) + time / 20 * dx * speed2, MH * y2, y - 2 * MW * angle * (x2 - 0.5) + time / 20 * dy * speed2);
		glTexCoord2f(x2, y1);  glVertex3f(x + 2 * MW * angle2 * (x2 - 0.5) + time / 20 * dx * speed1, MH * y1, y - 2 * MW * angle * (x2 - 0.5) + time / 20 * dy * speed1);
		glEnd();

		glBindTexture(GL_TEXTURE_2D, texture[pic2]);

		glBlendFunc(GL_ONE, GL_ONE);
		glBegin(GL_QUADS);
		glTexCoord2f(x1, y1);  glVertex3f(x + 2 * MW * angle2 * (x1 - 0.5) + time / 20 * dx * speed1, MH * y1, y - 2 * MW * angle * (x1 - 0.5) + time / 20 * dy * speed1);
		glTexCoord2f(x1, y2);  glVertex3f(x + 2 * MW * angle2 * (x1 - 0.5) + time / 20 * dx * speed2, MH * y2, y - 2 * MW * angle * (x1 - 0.5) + time / 20 * dy * speed2);
		glTexCoord2f(x2, y2);  glVertex3f(x + 2 * MW * angle2 * (x2 - 0.5) + time / 20 * dx * speed2, MH * y2, y - 2 * MW * angle * (x2 - 0.5) + time / 20 * dy * speed2);
		glTexCoord2f(x2, y1);  glVertex3f(x + 2 * MW * angle2 * (x2 - 0.5) + time / 20 * dx * speed1, MH * y1, y - 2 * MW * angle * (x2 - 0.5) + time / 20 * dy * speed1);
		glEnd();
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_BLEND);
	}
	void draw()
	{
		if (willdie)
		{
			count++;
		}
		if (count >= 40)
		{
			health = 0;
			death = 1;
			myscore += 5;
		}
		glColor3f(1, 1, 1);
		glBegin(GL_QUADS);
		glVertex3f(x - MW * angle2 * health / 5, MH, y + MW * angle * health / 5);
		glVertex3f(x - MW * angle2 * health / 5, MH + 0.2, y + MW * angle * health / 5);
		glVertex3f(x + MW * angle2 * health / 5, MH + 0.2, y - MW * angle * health / 5);
		glVertex3f(x + MW * angle2 * health / 5, MH, y - MW * angle * health / 5);
		glEnd();
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[25]);
		glBegin(GL_QUADS);
		glTexCoord2f(0, 0); glVertex3f(x - MW * angle2 * health / 5, MH, y + MW * angle * health / 5);
		glTexCoord2f(0, 1); glVertex3f(x - MW * angle2 * health / 5, MH + 0.2, y + MW * angle * health / 5);
		glTexCoord2f(1, 1); 		glVertex3f(x + MW * angle2 * health / 5, MH + 0.2, y - MW * angle * health / 5);
		glTexCoord2f(1, 0); 	glVertex3f(x + MW * angle2 * health / 5, MH, y - MW * angle * health / 5);
		glEnd();
		glDisable(GL_TEXTURE_2D);
		const float cut = 0.36;
		const float cut3 = 0.2;
		const float cut2 = 0.48;
		angle = (cpos_x - x) / sqrt((cpos_x - x) * (cpos_x - x) + (cpos_z - y) * (cpos_z - y));
		angle2 = (cpos_z - y) / sqrt((cpos_x - x) * (cpos_x - x) + (cpos_z - y) * (cpos_z - y));
		glEnable(GL_BLEND);
		glBlendFunc(GL_DST_COLOR, GL_ZERO);
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[cover]);
		glBegin(GL_QUADS);
		glTexCoord2f(0, cut2);  glVertex3f(x - MW * angle2, MH * cut2, y + MW * angle);
		glTexCoord2f(0, 1);  glVertex3f(x - MW * angle2, MH, y + MW * angle);
		glTexCoord2f(1, 1);  glVertex3f(x + MW * angle2, MH, y - MW * angle);
		glTexCoord2f(1, cut2);  glVertex3f(x + MW * angle2, MH * cut2, y - MW * angle);
		glEnd();
		glBindTexture(GL_TEXTURE_2D, texture[pic]);
		glBlendFunc(GL_ONE, GL_ONE);
		glBegin(GL_QUADS);
		glTexCoord2f(0, cut2);  glVertex3f(x - MW * angle2, MH * cut2, y + MW * angle);
		glTexCoord2f(0, 1);  glVertex3f(x - MW * angle2, MH, y + MW * angle);
		glTexCoord2f(1, 1);  glVertex3f(x + MW * angle2, MH, y - MW * angle);
		glTexCoord2f(1, cut2);  glVertex3f(x + MW * angle2, MH * cut2, y - MW * angle);
		glEnd();
		glDisable(GL_TEXTURE_2D);
		glDisable(GL_BLEND);
		body(0, 0.1, 0.5, 0.3, 1, 1);
		body(0, 0.3, 0.5, 0.48, 1, 0);
		body(0.5, 0.1, 1, 0.3, -1.2, -1);
		body(0.5, 0.3, 1, 0.48, -1, 0);
	}
	bool create()
	{
		if (death == 1)
		{
			death = 0;
			willdie = 0;
			count = 0;
			health = 5;
			x = 0, y = -30;
			pic = 8;
			cover = 9;
			diep = 23;
			diec = 24;
			pic2 = 12;
			cover2 = 13;
			return true;
		}
		else return false;
	}
	bool die()
	{
		float len = getlength();
		float r = ((x - cpos_x) / (look_x)) / ((y - cpos_z) / (-look_z));
		float ry = ((MH - cpos_y) / len) / (look_y / 10);
		printf("%f\n", ry);
		if (death == 1)return false;

		else if ((r) > 1 - 3 / len && (r) < 1 + 3 / len)
		{
			printf("\n%f", ry);
			if (ry > 1.4 && ry < 1.9)
			{
				pic = diep;
				cover = diec;
				willdie = 1;
			}
			health -= 10 / getlength();
			if (health <= 0)
			{
				death = 1;
				myscore++;
			}
			return true;
		}
		return false;
	}
	bool willlose()
	{
		if (getlength() <= 1 && !death)
		{
			float t1 = sqrt(look_x * look_x + look_z * look_z);
			float  y = cpos_y + look_y / 20;
			float x = cpos_x + (look_x / 20);
			float z = cpos_z - (look_z / 20);
			float x1 = x + 0.3 * (look_z) / t1;
			float z1 = z + 0.3 * (look_x) / t1;
			float x2 = x - 0.3 * (look_z) / t1;
			float z2 = z - 0.3 * (look_x) / t1;
			lose = true;
			transp(27, 26, x2 + (look_y / 15) * (look_x) / t1, y - 0.35, z2 - (look_y / 15) * (look_z) / t1, x2 - (look_y / 15) * (look_x) / t1, y + 0.35, z2 + (look_y / 15) * (look_z) / t1, x1 - (look_y / 15) * (look_x) / t1, y + 0.35, z1 + (look_y / 15) * (look_z) / t1, x1 + (look_y / 15) * (look_x) / t1, y - 0.35, z1 - (look_y / 15) * (look_z) / t1);
			printf("%f,%f,%f\n", cpos_x + look_x / 10 + look_z_temp / 10, cpos_y + look_y, cpos_z - look_z / 10 + look_x_temp / 10);
			printf("%f,%f,%f", cpos_x, cpos_y, cpos_z);
			glFlush();
			return true;
		}
		return false;
	}
};
void transp(int i1, int i2, float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4)
{
	glEnable(GL_BLEND);
	glBlendFunc(GL_DST_COLOR, GL_ZERO);
	glEnable(GL_TEXTURE_2D);

	glBindTexture(GL_TEXTURE_2D, texture[i1]);

	glBegin(GL_QUADS);
	glTexCoord2f(0, 0);  glVertex3f(x1, y1, z1);
	glTexCoord2f(0, 1);  glVertex3f(x2, y2, z2);
	glTexCoord2f(1, 1);  glVertex3f(x3, y3, z3);
	glTexCoord2f(1, 0);  glVertex3f(x4, y4, z4);
	glEnd();
	glBindTexture(GL_TEXTURE_2D, texture[i2]);
	glBlendFunc(GL_ONE, GL_ONE);
	glBegin(GL_QUADS);
	glTexCoord2f(0, 0);  glVertex3f(x1, y1, z1);
	glTexCoord2f(0, 1);  glVertex3f(x2, y2, z2);
	glTexCoord2f(1, 1);  glVertex3f(x3, y3, z3);
	glTexCoord2f(1, 0);  glVertex3f(x4, y4, z4);
	glEnd();
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_BLEND);
}
monster m1(1, -10, 5);
monster m2(-1, -15, 5);
monster m3(-2, -20, 5);
monster m4(0, -25, 5);
monster m5(3, -30, 5);
monster m[MNUM] = { m1,m2,m3,m4,m5 };
int order[MNUM];
void recreate()
{
	for (int i = 0; i < MNUM; i++)
	{
		if (m[i].create())
			break;
	}
}
void sort()
{

	for (int i = 0; i < MNUM; i++)
	{
		order[i] = i;
	}

	int temp = 0;
	for (int i = 0; i < MNUM; i++)
	{
		for (int j = MNUM - i - 1; j >= i; j--)
		{
			if (m[order[i]].getlength() < m[order[j]].getlength())
			{
				temp = order[i];
				order[i] = order[j];
				order[j] = temp;
			}
		}
	}
	for (int i = 0; i < MNUM; i++)
	{
		m[order[i]].walk();
	}
}
void gun()
{
	float t = sqrt(look_x * look_x + look_z * look_z + look_y * look_y);
	glLineWidth(5);
	glBegin(GL_LINES);
	glVertex3f(cpos_x + look_x / t, cpos_y + look_y / t + 0.03, cpos_z - look_z / t);
	glVertex3f(cpos_x + look_x / t, cpos_y + look_y / t + 0.01, cpos_z - look_z / t);
	glVertex3f(cpos_x + look_x / t, cpos_y + look_y / t - 0.03, cpos_z - look_z / t);
	glVertex3f(cpos_x + look_x / t, cpos_y + look_y / t - 0.01, cpos_z - look_z / t);
	glVertex3f(cpos_x + look_x / t + 0.01 * look_z / t, cpos_y + look_y / t, cpos_z - look_z / t + 0.01 * look_x / t);
	glVertex3f(cpos_x + look_x / t + 0.03 * look_z / t, cpos_y + look_y / t, cpos_z - look_z / t + 0.03 * look_x / t);
	glVertex3f(cpos_x + look_x / t - 0.01 * look_z / t, cpos_y + look_y / t, cpos_z - look_z / t - 0.01 * look_x / t);
	glVertex3f(cpos_x + look_x / t - 0.03 * look_z / t, cpos_y + look_y / t, cpos_z - look_z / t - 0.03 * look_x / t);
	glEnd();
	float t1 = sqrt(look_x * look_x + look_z * look_z);
	float  y = cpos_y + look_y / 15;
	float x = cpos_x + (look_x / 15);
	float z = cpos_z - (look_z / 15);
	float x1 = x + (look_z / 4) / t1;
	float z1 = z + (look_x / 4) / t1;
	if (shot == 0)
	{
		transp(19, 18, x1 + (look_y / 15) * (look_x) / t1, y - 0.5, z1 - (look_y / 15) * (look_z) / t1, x1, y, z1, x, y, z, x + (look_y / 15) * (look_x) / t1, y - 0.5, z - (look_y / 15) * (look_z) / t1);
	}
	else
	{
		transp(21, 20, x1 + (look_y / 15) * (look_x) / t1, y - 0.5, z1 - (look_y / 15) * (look_z) / t1, x1, y, z1, x, y, z, x + (look_y / 15) * (look_x) / t1, y - 0.5, z - (look_y / 15) * (look_z) / t1);

	}
	//printf("%f,%f,%f,%f,%f,%f,%f,%f,%f\n", x1 + (look_y / 15) * (look_x / 20), y - 0.5, z1 - (look_y / 15) * (look_z / 20), x1, y, z1, x, y, z, x + (look_y / 15) * (look_x / 20), y - 0.5, z - (look_y / 15) * (look_z / 20));
}

void score()
{
	int a = clock();
	const char* str = "Score:";
	char score[16] = { 0 };
	_itoa(myscore, score, 10);
	int n = strlen(str);
	glRasterPos3f(cpos_x + look_x / 10 - look_z_temp / 20, cpos_y + look_y / 10, cpos_z - look_z / 10 - look_x_temp / 20);
	for (int i = 0; i < n; i++)
		glutBitmapCharacter(GLUT_BITMAP_9_BY_15, *(str + i));
	for (int i = 0; i < 16; i++)
		glutBitmapCharacter(GLUT_BITMAP_9_BY_15, score[i]);
	glFlush();
}

void LoadGLTextures()
{
	int i;
	const char* pictures[PICNUM] = {
		"test\\front.bmp",
		"test\\ground.bmp" ,
		"test\\top.bmp",
		"test\\gd.bmp" ,
		"test\\right.bmp",
		"test\\right.bmp" ,
		"test\\back.bmp",
		"test\\coverage.bmp" ,
		"test\\zombie.bmp",
		"test\\zombiecover.bmp" ,
		"test\\zombiep2.bmp" ,
		"test\\zombiep2cover.bmp" ,
		"test\\zombie0\\down.bmp",
		"test\\zombie0\\downcover.bmp",
		"test\\zombie0\\leftdown.bmp",
		"test\\zombie0\\leftdowncover.bmp",
		"test\\gun.bmp",
		"test\\guncover.bmp",
		"test\\ggg.bmp",
		"test\\gggcover.bmp",
		"test\\shot.bmp",
		"test\\shotcover.bmp",
		"test\\title.bmp",
		"test\\dead.bmp",
		"test\\deadcover.bmp",
		"test\\blood.bmp",
		"test\\lose.bmp",
		"test\\losecover.bmp",
		"test\\body\\warrior.bmp",
		"test\\body\\warriorcover.bmp",
		"test\\body\\wd.bmp",
		"test\\body\\wdc.bmp",
		"test\\body\\fox.bmp",
		"test\\body\\foxc.bmp",
		"test\\body\\fu.bmp",
		"test\\body\\fuc.bmp",
		"test\\body\\ph.bmp",
		"test\\body\\phc.bmp",
		"test\\body\\ac.bmp",
		"test\\body\\acc.bmp",
		"test\\bk1\\f.bmp",
		"test\\bk1\\l.bmp",
		"test\\bk1\\u.bmp",
		"test\\bk1\\l.bmp",
		"test\\bk1\\r.bmp",
		"test\\bk2\\f.bmp",
		"test\\bk2\\l.bmp",
		"test\\bk2\\u.bmp",
		"test\\bk2\\l.bmp",
		"test\\bk2\\r.bmp"
		
	};
	AUX_RGBImageRec* TextureImage[PICNUM];
	::memset(TextureImage, 0, sizeof(void*) * PICNUM);
	for (i = 0; i < PICNUM; i++)
	{
		TextureImage[i] = auxDIBImageLoad(pictures[i]);
		if (TextureImage[i])                         //纹理是否存在
		{
			glGenTextures(1, &texture[i]);           //创建纹理
			glBindTexture(GL_TEXTURE_2D, texture[i]); //绑定纹理
			glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[i]->sizeX, TextureImage[i]->sizeY, 0,
				GL_RGB, GL_UNSIGNED_BYTE, TextureImage[i]->data);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
			free(TextureImage[i]);            //释放图像结构变量占用的内存
		}
	}
}




void createbk()
{
	room1(-WIDTH, -48, WIDTH, -16);
	room1(-WIDTH, 16, WIDTH, -16);
}

//不按鼠标移动事件
void onMouseMovePassive(int screen_x, int screen_y)
{
	float offsetx = screen_x - centerpoint_x;
	float offsety = screen_y - centerpoint_y;
	screenrate_x = offsetx / centerpoint_x * 1.5 * PI;//用于摄像机水平移动
	screenrate_y = offsety / centerpoint_y * 0.8 * PI;//用于摄像机上下移动
	//水平方向
	look_x_temp = r * sin(screenrate_x);
	look_z_temp = r * cos(screenrate_x);
	//最后使用时要和相机坐标相加/减
	//竖直方向
	look_y = r * sin(-screenrate_y);
	float r_castlenght = abs(r * cos(screenrate_y));
	//投影在xz面的长度
	//根据长度计算真正的look_x,look_z
	look_x = r_castlenght * look_x_temp / r;
	look_z = r_castlenght * look_z_temp / r;
}

//按下鼠标移动事件
void onMouseDownAndMove(int x, int y) {
}


void judge()
{
	if (shottime > 0)
	{
		shottime--;
	}
	if (cpos_x < -WIDTH)
	{
		cpos_x += step * 11;
	}
	if (cpos_x > WIDTH)
	{
		cpos_x -= step * 11;
	}if (cpos_z < -48)
	{
		cpos_z += step * 11;
	}if (cpos_z > 16)
	{
		cpos_z -= step * 11;
	}

}

void los()
{
	for (int i = 0; i < MNUM; i++)
	{
		m[i].willlose();
	}
}
void OnMouse(int button, int state, int x, int y)
{
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
	{


		if (shottime == 0)
			for (int i = MNUM-1; i >=0; i--)
			{
				shot = 5;
				if (m[order[i]].die())break;
			}
		flag = false;
		if (shottime == 0)
			shottime = 30;
	}
}
void restart();

void restart()
{
	monster m1(1, -10, 5);
	monster m2(-1, -15, 5);
	monster m3(-2, -20, 5);
	monster m4(0, -25, 5);
	monster m5(3, -30, 5);
	m[0] = m1;
	m[1] = m2;
	m[2] = m3;
	m[3] = m4;
	m[4] = m5;
	cpos_x = 0;
	cpos_y = 3;
	cpos_z = 10;
	lose = false;
	glutTimerFunc(1, timefunction, 1);
}
void InitLight() {
	GLfloat light_position0[] = { 0,2,0,1 };
	GLfloat light_ambient0[] = { 1,1,1,1 };      //环境光,控制物体颜色 
	GLfloat light_diffuse0[] = { 1,1,1,1 };//可改变漫反射光颜色(默认值为(1,1,1,1)) 
	GLfloat light_specular0[] = { 1,1,1,1 };  //镜面反射RGBA强度值(默认值为(1,1,1,1))   
	GLfloat light_position1[] = { 1,2,-10,1 };
	GLfloat light_ambient1[] = { 1,1,1,1 };      //环境光,控制物体颜色 	
	GLfloat light_diffuse1[] = { 1,1,1,1 };      //漫反射 
	GLfloat light_specular1[] = { 1,1,1,1 };
	GLfloat light_position2[] = { 10,2,0,1 };
	GLfloat light_ambient2[] = { 1,1,1,1 };      //环境光,控制物体颜色
	GLfloat light_diffuse2[] = { 1,1,1,1 };//可改变漫反射光颜色(默认值为(1,1,1,1)) 
	GLfloat light_specular2[] = { 1,1,1,1 };  //镜面反射RGBA强度值(默认值为(1,1,1,1))   
	glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
	glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient0);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse0);
	glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular0);
	glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
	glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient1);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse1);
	glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular1);//光源号GL_LIGHT0  
	glLightfv(GL_LIGHT2, GL_POSITION, light_position2);
	glLightfv(GL_LIGHT2, GL_AMBIENT, light_ambient2);
	glLightfv(GL_LIGHT2, GL_DIFFUSE, light_diffuse2);
	glLightfv(GL_LIGHT2, GL_SPECULAR, light_specular2);//光源号GL_LIGHT0  
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHT1);
	glEnable(GL_LIGHT2);
}
void display(void)
{
	// 清除屏幕
	if (shot > 0)
	{
		shot--;
	}
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   // 清除屏幕及深度缓存
	// 深度测试开启,实现遮挡关系
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	glShadeModel(GL_SMOOTH);
	// 设置视角
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60, 1, 0.1, 100);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(cpos_x, cpos_y, cpos_z, cpos_x + look_x, cpos_y + look_y, cpos_z - look_z, 0, 1, 0);//注意因为相机是面朝z负方向,所以cpos_z - lookz
	//gluLookAt(cpos_x, cpos_y, cpos_z, 0, 0, 0, 0, 1, 0);//原固定视角
	if (flag)
		start();


	judge();

	createbk();
	if (!flag)
	{
		sort();
		gun();
	}
	score();
	los();
	glutSwapBuffers();
}
void display2()
{
	glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
	glViewport(0, 0, 800, 1600);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0, (double)800, 0, (double)1600);
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1, 0, 0);
	glBegin(GL_POLYGON);
	glVertex2f(0, 0);
	glVertex2f(0, 1);
	glVertex2f(1, 1);
	glVertex2f(1, 0);
	glEnd();
	glFlush();
	glutSwapBuffers();
	Sleep(100000);
}

void keyboardFunc(unsigned char key, int x, int y)
{
	
	if (key == 'w') {
		//朝镜头方向前进look_x,look_z
		cpos_x += look_x_temp * step;
		cpos_z -= look_z_temp * step;

	}
	if (key == 's') {
		cpos_x -= look_x_temp * step;
		cpos_z += look_z_temp * step;
	}
	if (key == 'a') {
		//左 (x,y)对应(y,-x)
		//则(look_x,look_z)对应的为(-look_z,look_x)
		//Z轴取反
		cpos_x += -look_z_temp * step;
		cpos_z -= look_x_temp * step;
	}
	if (key == 'd') {
		//右 (x,y)对应(-y,x)
		//则(look_x,look_z)对应的为(look_z,-look_x)
		//Z轴取反
		cpos_x += look_z_temp * step;
		cpos_z -= -look_x_temp * step;
	}
	if (key == 'q')
	{
		recreate();
	}
	if (key == 'r')
	{
		if(lose)
		restart();
		
	}
	if (key == '1')
	{
		for (int i = 0; i < MNUM; i++)
		{
			m[i].changeskin(28, 29, 28, 29,30,31);
		}

	}
	if (key == '2')
	{
		for (int i = 0; i < MNUM; i++)
		{
			m[i].changeskin(32, 33, 32, 33, 32, 33);
		}

	}if (key == '3')
	{
		for (int i = 0; i < MNUM; i++)
		{
			m[i].changeskin(34, 35, 34, 35, 34, 35);
		}

	}if (key == '4')
	{
		for (int i = 0; i < MNUM; i++)
		{
			m[i].changeskin(36, 37, 36, 37, 36, 37);
		}

	}if (key == '5')
	{
		for (int i = 0; i < MNUM; i++)
		{
			m[i].changeskin(38, 39, 38, 39, 38, 39);
		}

	}
	if (key == '6')
	{
		ord = 40;

	}
	if (key == '7')
	{
		ord = 45;

	}
	if (key == '8')
	{
		ord = 0;

	}
}
void timefunction(int value)
{
	
	
	if (!lose)
		display();
	if (!lose)
		glutTimerFunc(1, timefunction, 1);
	if(lose)
	glutKeyboardFunc(keyboardFunc);
}
int main(int argc, char* argv[])
{

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(WindowWidth, WindowHeight);
	glutCreateWindow(WindowTitle);

	glutPassiveMotionFunc(onMouseMovePassive);
	glutMotionFunc(onMouseDownAndMove);
	glutKeyboardFunc(keyboardFunc);
	LoadGLTextures();
	//InitLight();
	//glEnable(GL_CULL_FACE);
	//glEnable(GL_DEPTH_TEST);
	glutDisplayFunc(&display);
	glutTimerFunc(1, timefunction, 1);
	glutMouseFunc(&OnMouse);
	glutMainLoop();
	return 0;
}

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值