实验名称:二维射击游戏
实验要求:
实验步骤:方向键移动我军,空格键发射炮弹
实验缺陷:未能实现一边移动一边打炮的良好体验
实验截图:
项目源码(共分为4个头文件和4个源文件):
Bullet.h,子弹对象的封装类:
#include
#include
#include
class Bullet
{
public:
Bullet(int x,int y);
~Bullet(void);
void move();
public:
GLfloat x;
GLfloat y;
GLfloat width;
GLfloat height;
GLfloat speed;
};
#define WIN_WIDTH 500
#define WIN_HEIGHT 500
#define VIEW_WIDTH 500
#define VIEW_HEIGHT 500
Scene.h,场景对象的封装类,用来绘制其他对象:
#include
#include
#include
#include
#include
#include "Bullet.h"
#include "Worm.h"
#define BOX_WIDTH 10
#define BOX_HEIGHT 10
using namespace std;
class Scene
{
public:
Scene(void);
~Scene(void);
void drawBullets();
void drawMe();
void drawHim();
void display();
void addBullet();
void moveMe(int x,int y);
private:
GLfloat box_x;
GLfloat box_y;
GLfloat speed;
list bullets;//存放所有子弹的方法
Worm *worm;//敌军
};
#include
#include
#include
#include "Main.h"
class Worm
{
public:
GLfloat x ;
GLfloat y ;
GLfloat speed;
GLfloat width;
GLfloat height;
GLfloat d_x;
GLfloat d_y;
int times ;
bool isAlive;
GLfloat worm_color[3];
public:
Worm(int x,int y);
~Worm(void);
void moveRand();
void die();
};
#include "Bullet.h"
Bullet::Bullet(int x,int y)
{
this->x = x;
this->y = y;
speed = 5;
width = 10;
height = 10;
}
Bullet::~Bullet(void)
{
}
void Bullet::move()
{
glColor3f(1.0,1.0,1.0);
glBegin(GL_POLYGON);
glVertex2f(x-width/2,y+height/2);
glVertex2f(x-width/2,y-height/2);
glVertex2f(x+width/2,y-height/2);
glVertex2f(x+width/2,y+height/2);
glEnd();
y = y + speed;
}
#include
#include
#include
#include
#include
#include "Scene.h"
#include "Main.h"
Scene *myScene = new Scene();
void myDisplay(){
//清除缓存
glClear(GL_COLOR_BUFFER_BIT);
//绘制场景
myScene->display();
//绘制
glFlush();
}
void myInit(){
glClearColor(0.0, 0.0, 0.0, 1.0);
}
void myRreshape(int w, int h){
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-VIEW_WIDTH/2,VIEW_WIDTH/2,-VIEW_HEIGHT/2,VIEW_HEIGHT/2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mySpecial(int key, int x, int y){
int px = 0;
int py = 0;
if(key == GLUT_KEY_LEFT)
px += -1;
if(key == GLUT_KEY_RIGHT)
px += 1;
if(key == GLUT_KEY_UP)
py += 1;
if(key == GLUT_KEY_DOWN)
py += -1;
myScene->moveMe(px,py);
}
void myKeyboard(unsigned char key, int x, int y){
switch (key)
{
case VK_SPACE:
myScene->addBullet();
break;
}
}
void OnTimer(int value)
{
//重绘
glutPostRedisplay();
glutTimerFunc(1000/60,OnTimer,1);
}
void main(int argc,char** argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("OpenGL_02");
myInit();
glutReshapeFunc(myRreshape);
glutDisplayFunc(myDisplay);
glutKeyboardFunc(myKeyboard);
glutSpecialFunc(mySpecial);
glutTimerFunc(1000/60,OnTimer,1223);
glutMainLoop();
}
Scene.cpp,场景对象的封装类,用来绘制其他对象:
#include "Scene.h"
Scene::Scene(void)
{
box_x = 0;
box_y = -200;
speed = 10;
worm = new Worm(0,0);
}
Scene::~Scene(void)
{
}
//场景绘制的函数
void Scene::display(){
this->drawMe();
this->drawHim();
this->drawBullets();
for(list::iterator iter = bullets.begin(); iter != bullets.end(); ++iter)
{
Bullet *bullet = (*iter);
if( abs(bullet->x - worm->x) < worm->width && abs(bullet->y - worm->y) < worm->height )
{
worm->die();
}
}
}
//绘制子弹
void Scene::drawBullets()
{
for(list::iterator iter = bullets.begin(); iter != bullets.end(); ++iter)
{
(*iter)->move();
}
}
void Scene::addBullet()
{
Bullet *newb = new Bullet(box_x,box_y);
bullets.push_back(newb);
}
void Scene::moveMe(int x,int y)
{
this->box_x += x*speed;
this->box_y += y*speed;
}
//绘制我军
void Scene::drawMe(){
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);
glVertex2f(box_x-BOX_WIDTH/2,box_y+BOX_HEIGHT/2);
glVertex2f(box_x-BOX_WIDTH/2,box_y-BOX_HEIGHT/2);
glVertex2f(box_x+BOX_WIDTH/2,box_y-BOX_HEIGHT/2);
glVertex2f(box_x+BOX_WIDTH/2,box_y+BOX_HEIGHT/2);
glEnd();
}
//绘制敌军
void Scene::drawHim()
{
worm->moveRand();
}
Worm.cpp,也就是屏幕中随机移动的蓝色方块。
#include "Worm.h"
Worm::Worm(int x,int y)
{
this->x = x;
this->y = y;
speed = 0.5;
width = 30;
height = 30;
d_x = rand()%10 * speed;
d_y = rand()%10 * speed;
times = 0;
worm_color[0] = 0.0;
worm_color[1] = 0.0;
worm_color[2] = 1.0;
isAlive = true;
}
Worm::~Worm(void)
{
}
void Worm::die()
{
worm_color[0] = 1.0;
worm_color[1] = 0.0;
worm_color[2] = 0.0;
isAlive = false;
}
void Worm::moveRand()
{
glColor3f(worm_color[0],worm_color[1],worm_color[2]);
glBegin(GL_POLYGON);
glVertex2f(x-width/2,y+height/2);
glVertex2f(x-width/2,y-height/2);
glVertex2f(x+width/2,y-height/2);
glVertex2f(x+width/2,y+height/2);
glEnd();
if(!isAlive)
return ;
if(x>WIN_WIDTH/2){
d_x = -rand()%10 * speed;
}
if(x<-WIN_WIDTH/2){
d_x = rand()%10 * speed;
}
if(y>WIN_HEIGHT/2){
d_y = -rand()%10 * speed;
}
if(y<-WIN_HEIGHT/2){
d_y = rand()%10 * speed;
}
if(times == 3000){
times = 0;
if(rand()%4 == 0){
d_x = rand()%10 * speed;
d_y = rand()%10 * speed;
}
if(rand()%4 == 1){
d_x = -rand()%10 * speed;
d_y = rand()%10 * speed;
}
if(rand()%4 == 2){
d_x = rand()%10 * speed;
d_y = -rand()%10 * speed;
}
if(rand()%4 == 3){
d_x = -rand()%10 * speed;
d_y = -rand()%10 * speed;
}
}
x = x + d_x;
y = y + d_y;
times ++;
}