讲道理,半节课没上,在搞这个小游戏,直接上代码:
玩法:
#define FREEGLUT_STATIC
#include
#include
#include
#include
#include
#include
typedef struct { GLfloat x, y; } point; // define a 2D point
point p0 = { 400,200 }; // set initial co-ordinate values of the point 金币
point p1 = { 0,50 }; // set initial co-ordinate values of the point 小人
GLfloat finishx = 300; // declare position of vertical axis
//Task 2
GLfloat jump = 0; //跳跃步长
GLfloat step = 10; //移动步长
GLint count = 0;
int time_interval = 16; // declare refresh interval in ms
void when_in_mainloop()
{ // idle callback function
glutPostRedisplay(); // force OpenGL to redraw the current window
}
bool checkHug() {
if ((p0.x >= 0 && p0.x <= 20 )&& (p1.y + 20 >= 200)) {
return 1;
}
else return 0;
}
void OnTimer(int value)
{
p0.x -= step; //移动步长
if (p0.x >= 600)
p0.x = 0;
else if (p0.x <= 0) {
p0.x = 599;
step = rand()%10+5;//5以上的2位数
}//反向则从另一侧刷新
bool check = 0;
check = checkHug();
if (check == 1) {
p0.x = 400;
count++;
}
glutTimerFunc(time_interval, OnTimer, 1);
}
bool flag = 0;
void JumpOnTimer(int value) {
if (flag==0 && p1.y <= 200) {
p1.y += jump;
if (p1.y == 200) {
flag = 1;
}
}
if (flag == 1 && p1.y>=50) {
p1.y -= jump;
if (p1.y ==50) {
flag = 0;
jump = 0;
}
}
glutTimerFunc(time_interval, JumpOnTimer, 2);
}
//Task 3
void keyboard_input(unsigned char key, int x, int y) // keyboard interactions
{
if (key == 'q' || key == 'Q')
exit(0);
else if (key == 'w' || key == 'W') // change direction of movement
{
jump = 10;
}
else if (key == 's' || key == 'S') // stop movement
step = 0;
else if (key == 'r' || key == 'R') // reset step (resume movement)
p0.x=400;
else if (key == 'm' || key == 'M') // reset step (resume movement)
step = 2;
}
//Task 4
void display(void)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 600, 0, 400);
glClearColor(0, 0, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1, 1, 1);
glBegin(GL_LINES);
glVertex2f(finishx, 50);
glVertex2f(finishx, 350);
glEnd();
glColor3f(0, 1, 0);
glBegin(GL_POLYGON);
glVertex2f(0, 0);
glVertex2f(0, 50);
glVertex2f(600, 50);
glVertex2f(600, 0);
glEnd();
glPolygonMode(GL_BACK, GL_FILL); // 设置反面为填充方式
// guy
for (int i = 0; i < count; i++)
{
glColor3f(i & 0x04, i & 0x02, i & 0x01);
}
//glColor3f(1, 0, 0);
glBegin(GL_POLYGON);
glVertex2f(p1.x, p1.y);
glVertex2f(p1.x, p1.y + 20);
glVertex2f(p1.x + 20, p1.y + 20);
glVertex2f(p1.x + 20, p1.y);
glEnd();
glPolygonMode(GL_FRONT, GL_LINE); // 设置正面(顺时针)为边缘绘制方式
glColor3f(0, 0, 0);
glBegin(GL_POLYGON);
glVertex2f(p1.x, p1.y);
glVertex2f(p1.x + 20, p1.y);
glVertex2f(p1.x + 20, p1.y + 20);
glVertex2f(p1.x, p1.y + 20); //换为反向顺序
glEnd();
glPolygonMode(GL_BACK, GL_FILL); // 设置正面为填充方式
// gold
glColor3f(1, 1, 0);
glBegin(GL_POLYGON);
glVertex2f(p0.x, p0.y);
glVertex2f(p0.x, p0.y + 10);
glVertex2f(p0.x + 10, p0.y + 10);
glVertex2f(p0.x + 10, p0.y);
glEnd();
glPolygonMode(GL_FRONT, GL_LINE); // 设置反面为边缘绘制方式
glColor3f(0, 0, 0); //黑色边框
glBegin(GL_POLYGON);
glVertex2f(p0.x, p0.y);
glVertex2f(p0.x + 10, p0.y);
glVertex2f(p0.x + 10, p0.y + 10);
glVertex2f(p0.x, p0.y + 10);
glEnd();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(600, 400);
glutCreateWindow("My Interactive Window");
glutDisplayFunc(display);
//Task 2
//Task 3
glutIdleFunc(when_in_mainloop);
/* glutIdleFunc sets the global idle callback to be func so a GLUT program can perform background
processing tasks or continuous animation when window system events are not being received.
If enabled, the idle callback is continuously called when events are not being received. The callback
routine has no parameters. The current window and current menu will not be changed before the idle
callback. Programs with multiple windows and/or menus should explicitly set the current window and/or
current menu and not rely on its current setting. The amount of computation and rendering done in an idle
callback should be minimized to avoid affecting the program's interactive response. In general, not more
than a single frame of rendering should be done in an idle callback.
Assigning NULL to glutIdleFunc disables the generation of the idle callback. */
glutTimerFunc(time_interval, OnTimer, 1);
glutTimerFunc(time_interval, JumpOnTimer, 2);
glutKeyboardFunc(keyboard_input); // keyboard callback function
glutMainLoop();
}