概述
- 2D 项目简介
项目的创意设想、实现功能、项目意义(200字左右)
作品代表图
项目名:机器人双人格斗游戏
项目的创意设想:当前ai大火,机器人也是日常生活中的一个热点,自己在小学乃至高中也经常玩格斗游戏。曾经也想过格斗游戏是怎么做的,可是那时候条件有限,而且也没有编程基础。这个想法就一直留到了大学。到大三学习计算机图形学,也有了一定的编程基础,认为这个格斗游戏可以自己完成了。便开始动手,经过几天的努力,终于把这个游戏实现了。
实现功能:画了机器人1(乌巢之子),机器人2(关山之月)实现其的技能有:
- 上下左右移动:实现了平移
- 弹跳:使用了重力加速度实现了起跳落下的算法,
- 眼睛发射镭射光线:实现了平移
- 肚载大炮发射:实现了平移
- 手臂可以伸长:实现了平移
- 被炮弹击中会倒退:使用了旋转变换之类函数,实现了旋转
- 法天相地(放大):实现了放大 - 经过一段时间也会缩放到原来的大小
- 计时功能:使用了时间回调函数
- 使用了win32API函数,可以插入声音
项目意义:自己在开始做这个游戏的时候,也上网百度看是否有类似的格斗游戏,这类型指的是使用opengl库制作的2D无游戏引擎的双人格斗游戏,发现找不到类似的游戏,可以说是网上几乎没人做过类似的2D无游戏引擎的双人格斗游戏。可以说这个游戏填补了当类游戏的空白,也可以给后来者加以参考。
作品代表图:
- 编程环境(电脑硬件、操作系统和VS平台)说明
-
电脑硬件:thinkpad x250,
cpu:i3
内存:4g
操作系统:win10
Vs:vs2017
- 程序操作说明
-
操作如下图:
编程环境(电脑硬件、操作系统和VS平台)说明
电脑硬件:thinkpad x250,
cpu:i3
内存:4g
操作系统:win10
Vs:vs2017
- 程序操作说明
操作如下图:
按键b:开始游戏
对角色1(乌巢之子)进行操作有:
1、wsad:上下左右移动
2、z:长拳攻击
3、x:从眼部发射镭射光线
4、c:肚载大炮,肚子发射大炮,攻击力强于镭射光线
5、e:法天相地,变大
6、r:弹跳
对角色2(关山之月)进行操作有:
- ikjl:上下左右移动
- n:长拳攻击
- m:镭射光线
- O:肚载大炮,肚子发射大炮,攻击力强于镭射光线
- U:法天相地(变大)
- P:弹跳
当两者的某一方血条为0时,游戏结束,效果如下:
- 程序实现
- 创意详细说明:
- 算法类、模拟类: 算法说明,想要实现的效果说明
1、注册这几个函数,才可以使窗口不断回画,并计时,也是基于这几个注册函数才仿佛实现了同步,而不必使用多线程。
glutTimerFunc(1000, mytime, 10); //注册闲时函数
glutDisplayFunc(&Display);//在程序运行时是自动调用的,即程序会自动调用display函数重绘窗口
glutMainLoop(); //进入事件处理循环
2、使用了重力加速度公式设计的弹跳-起跳落下的模拟
在机器人1里写了一个弹跳函数(机器人2类似)
类成员:
jumpTime = 0;
jflag = 0;
h = 5.0;
函数
void Robot1::skillr() //跳高
{
jumpTime++;
float g = 0.00005;
if (jflag == 1)
{
float addh = 1.0 / 2.0 * g * jumpTime * jumpTime;
this->y += addh;
this->h -= addh;
if (this->h <= 0)
{
jflag = 2;
jumpTime = 0;
}
}
else if(jflag == 2)
{
float addh = 1.0 / 2.0 * g * jumpTime * jumpTime;
this->y -= addh;
this->h += addh;
if (this->h >= 5.0)
{
jflag = 0;
jumpTime = 0;
}
}
}
主页面交互(键盘点击):
case 'R':
case 'r'://robot1跳高
if (rb1->jflag == 0)
{
rb1->jflag = 1;
rb1->skillr();
}
break;
- 炸弹类的设计:设计炸弹类首先要知道炸弹的坐标x,y,因为这个才可以在界面上绘出炸弹,炸弹的朝向goAhead,有了这个才可以知道炸弹的移动方向,炸弹生命live是否存活,存活才画此炸弹,
Who(谁的炸弹),因为这个炸弹类不止一个人使用,robot1和robot2都使用,zy第三参数,这个参数的作用是记录发送炸弹的机器人的中心坐标
注:在这里说明一下,因为当前游戏是使用2D制作,两个机器人在一条有长有宽的道路上打斗,如果只有长,就只要直接有炸弹的x,y和敌方机器人作边界检测就行了,可是这道路有宽,就要设计看炸弹射出的轨迹是否与敌人在一条轴线上,所以我用zy保存发出炸弹机器人的y坐标,引入了第三个参数,这时就可以把这个界面看出了三维,到时再使用敌方机器人的x,y坐标和己方炸弹的x,zy作边界检测,就可以看炸弹是否击中敌人了。
#pragma once
#pragma once
#include <glut.h>
//robot1子弹类
class myBullet
{
public:
float x;
float y;
bool live;
int goAhead; //子弹朝向
float mBsize; //子弹大小
int who; //谁的子弹
float zy; //第三参数
float zx; //第四参数
myBullet();
~myBullet();
void init(float x,float y,float size,int who, float zx, float zy);
void die();
};
void drawMyBullet(float x, float y, int goAhead, int size, int mBsize)
{
//绘制点
glColor3f(1, 0, 0); //设置蓝色绘制颜色
//glPointSize(2.0);//点的像素大小,默认值为1.0
if (goAhead == 0)
{
glRectf(x - 1 * size, y - 0.05 * size * mBsize, x, y + 0.05 * size * mBsize);
}
else if (goAhead == 1)
{
glRectf(x, y - 0.05 * size * mBsize, x + 1 * size, y + 0.05 * size * mBsize);
}
//glBegin(GL_POINTS);
//glVertex2f(x, y);
//glVertex2f(x+1, y+0.1);
//glEnd();
}
myBullet::myBullet()
{
x = -23;
y = 23;
live = false;
goAhead = -1;
mBsize = 1;
who = -1;
zx = -99;
zy = -99;
}
void myBullet::init(float x, float y, float size,int who,float zx, float zy)
{
this->x = x;
this->y = y;
this->mBsize = size;
live = true;
this->who = who;
this->zx = zx;
this->zy = zy;
}
myBullet::~myBullet()
{
}
void myBullet::die()
{
live = false;
}
炸弹是否击中敌人的边界检测函数:
//子弹边界检测函数
void checkBulletSide()
{
for (int i = 0; i < MAXRB1BULLET; i++)
{
if (mb[i].live == true)
{
if (mb[i].x > -22.0 && mb[i].x < 22.0 && mb[i].y > -12.0 && mb[i].y < 12.0)
{
if (mb[i].who == 1) //机器人1的子弹
{
if (abs(mb[i].x - rb2->x) < 0.6 * rb2->size && abs(mb[i].zy - rb2->y) < 0.7 * rb2->size) //机器人1的子弹击中机器人2
{
for (int j = 0; j < MAXBOMB; j++)
{
if (bomb[j].live == false)
{
bomb[j].init(mb[i].x, mb[i].y, mb[i].mBsize);
rb2->valueOfLife -= 20 * mb[i].mBsize;
if (mb[i].mBsize == 1)
{
PlaySound(L"midb.wav", NULL, SND_FILENAME | SND_ASYNC);
//PlaySound(L"background.wav", NULL, SND_FILENAME | SND_ASYNC);
}
else
{
PlaySound(L"bigb.wav", NULL, SND_FILENAME | SND_ASYNC);
//PlaySound(L"background.wav", NULL, SND_FILENAME | SND_ASYNC);
}
break;
}
}
if (mb[i].goAhead == 0) //子弹朝向左
{
//机器人robot2被左击中
rb2->beated = -1;
}
else if(mb[i].goAhead == 1)//子弹朝向右
{
//机器人robot2被右击中
rb2->beated = 1;
}
mb[i].die();
}
}
else if (mb[i].who == 2)//机器人2的子弹
{
if (abs(mb[i].x - rb1->x) < 0.6 * rb1->size && abs(mb[i].zy - rb1->y) < 0.7 * rb1->size) //机器人2的子弹击中机器人1
{
for (int j = 0; j < MAXBOMB; j++)
{
if (bomb[j].live == false)
{
bomb[j].init(mb[i].x, mb[i].y, mb[i].mBsize);
rb1->valueOfLife -= 20 * mb[i].mBsize;
if (mb[i].mBsize == 1)
{
PlaySound(L"midb.wav", NULL, SND_FILENAME | SND_ASYNC);
//PlaySound(L"background.wav", NULL, SND_FILENAME | SND_ASYNC);
}
else
{
PlaySound(L"bigb.wav", NULL, SND_FILENAME | SND_ASYNC);
//PlaySound(L"background.wav", NULL, SND_FILENAME | SND_ASYNC);
}
break;
}
}
if (mb[i].goAhead == 0) //子弹朝向左
{
//机器人robot1被左击中
rb1->beated = -1;
}
else if (mb[i].goAhead == 1)//子弹朝向右
{
//机器人robot1被右击中
rb1->beated = 1;
}
mb[i].die();
}
}
}
else //子弹已到边界
{
mb[i].live = false;
}
}
}
}
- 炸弹爆炸类的设计:x,y确定爆炸的位置,size确定爆炸的范围,强度,live是否存活,livelong存活的时间
#pragma once
#include <glut.h>
#include <math.h>
#include<stdlib.h>
#define MAXPOINTSIZE 200
class Bomb
{
public:
float x;
float y;
float size;
bool live;
int liveLong;
Bomb()
{
x = -99;
y = -99;
size = 1;
live = false;
liveLong = 40;
}
void init(float x, float y, float size)
{
this->x = x;
this->y = y;
this->size = size;
live = true;
liveLong = 160;
}
void setLiveLong(int liveLong)
{
this->liveLong = liveLong;
}
void die()
{
live = false;
}
最后
以上就是兴奋小甜瓜为你收集整理的基于opengl的2d机器人双人格斗游戏的全部内容,希望文章能够帮你解决基于opengl的2d机器人双人格斗游戏所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复