目前:食物吃了还在;可以从自己身上穿过去;永远不会碰到墙壁;
代码假定已经会在VC2008~VC2010中配置freeglut库了
#include <windows.h>
#include <iostream>
#include <string>
#include <list>
#include <vector>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <stdlib.h>
static int slices = 16;
static int stacks = 16;
using namespace std;
int worldl = -20;
int worldr = 20;
int worldb = -20;
int worldt = 20;
double boxw = 10;
double boxh = 10;
int tim = 6;
void drawBox(double x,double y,double w,double h,
double clor,double clog,double clob)
{
glColor3f(0.2,0.2,0.4);
glRectd(x-w/2.0+2.0,y-h/2.0+2.0,x+w/2.0-2.0,y+h/2.0-2.0);
glColor3f(clor,clog,clob);
glRectd(x-w/2.0+1.0,y-h/2.0+1.0,x+w/2.0-1.0,y+h/2.0-1.0);
}
void drawCoord(double clor,double clog,double clob)
{
glColor3d(clor,clog,clob);
glBegin(GL_POINTS);
for(int i = worldl;i<=worldr;i++)
for(int j = worldb;j<=worldt;j++)
glVertex3d(float(i)*boxw,float(j)*boxh,0.0);
glEnd();
}
struct pos
{
int x;
int y;
pos(int _x =0,int _y = 0):x(_x),y(_y)
{}
void draw(double clor,double clog,double clob)
{
drawBox(float(x)*boxw,float(y)*boxh,boxw,boxh,clor,clog, clob);
}
};
class cirlist:public std::list<pos>
{
public:
cirlist():std::list<pos>()
{
iHead = this->begin();
iTail = this->begin();
dir = pos(1,0);
}
cirlist::iterator next(cirlist::iterator iter)
{
cirlist::iterator temp_iter = iter;
temp_iter++;
if ( temp_iter == this->end() )
{
iter = this->begin();
return iter;
}
else
{
iter++;
return iter;
}
}
cirlist::iterator prev(cirlist::iterator iter)
{
if (iter == this->begin())
{
iter = --this->end();
return iter;
}
else
{
iter--;
return iter;
}
}
void add(pos f)
{
if (empty())
{
iHead = this->insert(iHead,f);
iTail = iHead;
}
else
{
iHead = this->insert(iHead,f);
}
}
void print()
{
if (empty())
return;
cirlist::iterator iter = iHead;
while(iter!=iTail)
{
std::cout<< "(" << iter->x <<", "<<iter->y << ")"<<std::endl;
iter = next(iter);
}
std::cout<< "(" << iter->x <<", "<<iter->y << ")"<<std::endl;
}
void draw()
{
if (empty())
return;
cirlist::iterator iter = iHead;
while(iter!=iTail)
{
iter->draw(0.8,0.8,0.8);
iter = next(iter);
}
iter->draw(0.8,0.8,0.8);
//std::cout<<"size = "<<int(size())<<endl;
}
void behav( pos yea)
{
if (empty())
return;
pos rk = pos(iHead->x + dir.x,iHead->y + dir.y);
if (yea.x == rk.x && yea.y == rk.y)
{
add(yea);
//print();
}
else
{
pos tempos = (*iHead);
iHead = iTail;
iTail = prev(iTail);
iHead->x = tempos.x + dir.x;
iHead->y = tempos.y + dir.y;
if(iHead->x > worldr)
iHead->x = worldl;
else if(iHead->x < worldl)
iHead->x = worldr;
if(iHead->y > worldt)
iHead->y = worldb;
else if(iHead->y < worldb)
iHead->y = worldt;
}
}
void left()
{
if(dir.x == 1)
return;
dir.x = -1;
dir.y = 0;
}
void right()
{
if(dir.x == -1)
return;
dir.x = 1;
dir.y = 0;
}
void down()
{
if(dir.y == 1)
return;
dir.x = 0;
dir.y = -1;
}
void top()
{
if(dir.y == -1)
return;
dir.x = 0;
dir.y = 1;
}
public:
cirlist::iterator iHead;
cirlist::iterator iTail;
pos dir;
};
cirlist slst;
pos ya(8,0);
/* GLUT callback Handlers */
static void resize(int width, int height)
{
const float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
glOrtho(-(float) width*0.5f,(float) width*0.5f,
-(float) height*0.5f,(float) height*0.5f,
2.f,100.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity() ;
}
static void display(void)
{
const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
const double a = t*90.0;
static int counter = 0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3d(1,0,0);
/*
glPushMatrix();
glTranslated(-2.4,1.2,-6);
glRotated(60,1,0,0);
glRotated(a,0,0,1);
glutSolidSphere(1,slices,stacks);
glPopMatrix();
*/
glPushMatrix();
gluLookAt(0,0,10,0,0,0,0,1,0);
if(counter == tim)
{
slst.behav(ya);
counter = 0;
}
drawCoord(0,1,0);
slst.draw();
ya.draw(1,0,0);
glPopMatrix();
counter++;
glutSwapBuffers();
}
static void key(unsigned char key, int x, int y)
{
switch (key)
{
case 27 :
exit(0);
break;
case '+':
slices++;
stacks++;
break;
case '-':
if (slices>3 && stacks>3)
{
slices--;
stacks--;
}
break;
case 'a':
slst.left();
break;
case 'd':
slst.right();
break;
case 's':
slst.down();
break;
case 'w':
slst.top();
break;
case ' ':
slst.print();
break;
}
glutPostRedisplay();
}
static void idle(void)
{
glutPostRedisplay();
}
const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };
const GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f };
const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat high_shininess[] = { 100.0f };
void init()
{
slst.add(pos(0,0));
//slst.behav(ya);
//slst.print();
}
/* Program entry point */
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(500,500);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("boxsnk");
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutIdleFunc(idle);
glClearColor(0.2,0.2,0.4,1);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
init();
glutMainLoop();
return EXIT_SUCCESS;
}