#概要
OpenGL/GLUTを使ったインベーダーゲームもどきです。
mac環境での制作になっています。
まだまだ未完成で当たり判定も出来てないレベルのものです。
コードも非常に見にくいかと思いますが素人なりに頑張ってみました。
#Invaderコード
//Invader.cpp
#include <GLUT/glut.h>
#include <ctime>
#include <cmath>
#include <cstdlib>
#include <iostream>
using namespace std;
#define WIDTH 640
#define HEIGHT 480
#define PI 3.1411592 //π
int VV; //ユニットの名前
int shut; //ユニットが弾を撃つ
int ort; //インベーダーの撃つ
//int dan;
static GLfloat l = 0.0; //インベーダー移動する距離
static int dim = 0; //ユニットの動くときの定数
//弾丸の元
void Point(int x,int y,float size){
glPointSize(size); //弾のサイズ
glBegin(GL_POINTS);
glVertex2i(x,y);
//ここに弾自体に当たり判定をつける
glEnd();
}
//インベーダーの実態元
void InvaderPoint(int x,int y){
glColor3d(1.0,0.0,0.0);
glBegin(GL_QUADS);
glVertex2f(x * 4 - 40, y * 4 + 40);
glVertex2f(x * 4 - 40, y * 4 + 4 + 40);
glVertex2f(x * 4 + 4 - 40, y * 4 + 4 + 40);
glVertex2f(x * 4 + 4 - 40, y * 4 + 40);
}
//インベーダーのクラス
class Invader{
public:
Invader(); //インベーダーのコンストラクタ
/*Shotを一つ作った後にそれを独立させたものに適用させていく。
弾自体に当たり判定を入れておく*/
void InvaderShot0(); //インベーダーの弾を撃つ
void InvaderShot1();
void InvaderShot2();
void InvaderShot3();
void InvaderShot4();
void InvaderShot5();
void InvaderShot6();
void InvaderShot7();
};
//インベーダーの設計図
Invader::Invader(){
static GLboolean isUp = GL_TRUE;
//配列に直して一つ一つに独立させたものにする。
for(int i = 0; i < WIDTH; i += 20){
InvaderPoint(0+l+10+i,5);
InvaderPoint(0+l+10+i,6);
InvaderPoint(0+l+10+i,7);
InvaderPoint(1+l+10+i,4);
InvaderPoint(1+l+10+i,5);
InvaderPoint(2+l+10+i,1);
InvaderPoint(2+l+10+i,3);
InvaderPoint(2+l+10+i,4);
InvaderPoint(2+l+10+i,5);
InvaderPoint(2+l+10+i,6);
InvaderPoint(2+l+10+i,7);
InvaderPoint(3+l+10+i,2);
InvaderPoint(3+l+10+i,3);
InvaderPoint(3+l+10+i,5);
InvaderPoint(3+l+10+i,6);
InvaderPoint(3+l+10+i,8);
InvaderPoint(4+l+10+i,3);
InvaderPoint(4+l+10+i,4);
InvaderPoint(4+l+10+i,5);
InvaderPoint(4+l+10+i,6);
InvaderPoint(5+l+10+i,3);
InvaderPoint(5+l+10+i,4);
InvaderPoint(5+l+10+i,5);
InvaderPoint(5+l+10+i,6);
InvaderPoint(6+l+10+i,2);
InvaderPoint(6+l+10+i,3);
InvaderPoint(6+l+10+i,5);
InvaderPoint(6+l+10+i,6);
InvaderPoint(6+l+10+i,8);
InvaderPoint(7+l+10+i,1);
InvaderPoint(7+l+10+i,3);
InvaderPoint(7+l+10+i,4);
InvaderPoint(7+l+10+i,5);
InvaderPoint(7+l+10+i,6);
InvaderPoint(7+l+10+i,7);
InvaderPoint(8+l+10+i,4);
InvaderPoint(8+l+10+i,5);
InvaderPoint(9+l+10+i,5);
InvaderPoint(9+l+10+i,6);
InvaderPoint(9+l+10+i,7);
}
//インベーダーの移動処理
if(l > 10)isUp = GL_FALSE;
else if(l <= 0)isUp = GL_TRUE;
l += (isUp == GL_TRUE ? 0.07:-0.07);
glutPostRedisplay(); //Idleの代わり
glFlush();
}
void Invader::InvaderShot0(){
static int y0 = 80; //y軸の値
static int x0; //x軸の値
glColor3d(0.5,0.7,0.3); //弾の色
ort = 1; //インベーダーの弾を撃つときの値
if(ort == 1){ //ortが1になったときに動く
if(y0 == 80){
x0 = l * 4 + 20; //弾のX軸とY軸の場所
}
y0 += 4; //弾が撃たれた時のY軸の移動スピード
Point(x0, y0, 5);
if(y0 > 480){ //Y軸がここまで移動したら初期位置に戻る処理
y0 = 80;
}
}
}
void Invader::InvaderShot1(){
static int y2 = 80;
static int x2;
glColor3d(0.5,0.7,0.3);
ort = 1;
if(ort == 1){
if(y2 == 80){
x2 = l * 4 + 100;
}
y2 += 4;
Point(x2, y2, 5);
if(y2 > 480){
y2 = 80;
}
}
}
void Invader::InvaderShot2(){
static int y3 = 80;
static int x3;
glColor3d(0.5,0.7,0.3);
ort = 1;
if(ort == 1){
if(y3 == 80){
x3 = l * 4 + 180;
}
y3 += 4;
Point(x3, y3, 5);
if(y3 > 480){
y3 = 80;
}
}
}
void Invader::InvaderShot3(){
static int y4 = 80;
static int x4;
glColor3d(0.5,0.7,0.3);
ort = 1;
if(ort == 1){
if(y4 == 80){
x4 = l * 4 + 260;
}
y4 += 4;
Point(x4, y4, 5);
if(y4 > 480){
y4 = 80;
}
}
}
void Invader::InvaderShot4(){
static int y5 = 80;
static int x5;
glColor3d(0.5,0.7,0.3);
ort = 1;
if(ort == 1){
if(y5 == 80){
x5 = l * 4 + 340;
}
y5 += 4;
Point(x5, y5, 5);
if(y5 > 480){
y5 = 80;
}
}
}
void Invader::InvaderShot5(){
static int y5 = 80;
static int x5;
glColor3d(0.5,0.7,0.3);
ort = 1;
if(ort == 1){
if(y5 == 80){
x5 = l * 4 + 420;
}
y5 += 4;
Point(x5, y5, 5);
if(y5 > 480){
y5 = 80;
}
}
}
void Invader::InvaderShot6(){
static int y6 = 80;
static int x6;
glColor3d(0.5,0.7,0.3);
ort = 1;
if(ort == 1){
if(y6 == 80){
x6 = l * 4 + 500;
}
y6 += 4;
Point(x6, y6, 5);
if(y6 > 480){
y6= 80;
}
}
}
void Invader::InvaderShot7(){
static int y7 = 80;
static int x7;
glColor3d(0.5,0.7,0.3);
ort = 1;
if(ort == 1){
if(y7 == 80){
x7 = l * 4 + 580;
}
y7 += 4;
Point(x7, y7, 5);
if(y7 > 480){
y7 = 80;
}
}
}
class Life{
public:
float v; //ユニットの生死判定の際の値
float i; //インベーダーの生死判定の際の値
float Life; //生死判定
//ユニットの生死判定
//エネミーの生死判定
};
//ユニットの元を構成する形
void UnitPoint(int x,int y){
glColor3d(1.0,1.0,1.0);
glBegin(GL_QUADS);
x = x * 4; //x軸の大きさを4倍する
y = y * 4; //y軸の大きさを4倍する
glVertex2f(x + 300, y + 400);
glVertex2f(x + 4 + 300, y + 400);
glVertex2f(x + 4 + 300, y + 4 + 400);
glVertex2f(x + 300, y + 4 + 400);
glEnd();
}
//ユニットのクラス
class Unit{
public:
Unit(); //コンストラクタ
//void MyLife();
void specialKey(); //矢印keyの所得
void specialUpKey(); //矢印keyの離れるを所得
void keyboard(); //スペースkeyの所得
void keyboardUp(); //スペースkeyの離れるを所得
void UnitShot(); //ユニットが弾を撃つ
};
//ユニットの設計図
Unit::Unit(){
static GLboolean isUp = GL_TRUE;
if(VV == 1){ //左に移動する処理
dim -= 1; //移動スピード
}else
if(VV == 2){ //右に移動する処理
dim += 1; //移動スピード
}
//ユニットを構成するもの
UnitPoint(0 + dim, 5);
UnitPoint(0 + dim, 6);
UnitPoint(0 + dim, 7);
UnitPoint(0 + dim, 8);
UnitPoint(1 + dim, 5);
UnitPoint(1 + dim, 6);
UnitPoint(1 + dim, 7);
UnitPoint(1 + dim, 8);
UnitPoint(2 + dim, 5);
UnitPoint(2 + dim, 6);
UnitPoint(2 + dim, 7);
UnitPoint(2 + dim, 8);
UnitPoint(3 + dim, 2);
UnitPoint(3 + dim, 3);
UnitPoint(3 + dim, 4);
UnitPoint(3 + dim, 5);
UnitPoint(3 + dim, 6);
UnitPoint(3 + dim, 7);
UnitPoint(3 + dim, 8);
UnitPoint(4 + dim, 2);
UnitPoint(4 + dim, 3);
UnitPoint(4 + dim, 4);
UnitPoint(4 + dim, 5);
UnitPoint(4 + dim, 6);
UnitPoint(4 + dim, 7);
UnitPoint(4 + dim, 8);
UnitPoint(5 + dim, 2);
UnitPoint(5 + dim, 3);
UnitPoint(5 + dim, 4);
UnitPoint(5 + dim, 5);
UnitPoint(5 + dim, 6);
UnitPoint(5 + dim, 7);
UnitPoint(5 + dim, 8);
UnitPoint(6 + dim, 2);
UnitPoint(6 + dim, 3);
UnitPoint(6 + dim, 4);
UnitPoint(6 + dim, 5);
UnitPoint(6 + dim, 6);
UnitPoint(6 + dim, 7);
UnitPoint(6 + dim, 8);
UnitPoint(7 + dim, 5);
UnitPoint(7 + dim, 6);
UnitPoint(7 + dim, 7);
UnitPoint(7 + dim, 8);
UnitPoint(8 + dim, 5);
UnitPoint(8 + dim, 6);
UnitPoint(8 + dim, 7);
UnitPoint(8 + dim, 8);
UnitPoint(9 + dim, 5);
UnitPoint(9 + dim, 6);
UnitPoint(9 + dim, 7);
UnitPoint(9 + dim, 8);
glFlush();
}
//スペースを押したときに弾を出す
void keyboard(unsigned char key,int x,int y){
switch(key){
case ' ': shut = 1;
break;
}
}
//スペースを離す
void keyboardUp(unsigned char key,int x,int y){
switch(key){
case ' ':
break;
}
}
//左右の移動のコマンドkey
void specialKey(int key,int x,int y){
switch(key){
case GLUT_KEY_LEFT: VV = 1; //左に移動
break;
case GLUT_KEY_RIGHT: VV = 2; //右に移動
break;
}
}
//keyから離れた場合の処理
void specialUpKey(int key, int x, int y){
switch(key){
case GLUT_KEY_LEFT: VV = 0; //左に移動してるのを止める
break;
case GLUT_KEY_RIGHT: VV = 0; //右に移動してるのを止める
break;
}
}
//ユニットの弾を撃つの処理
void Unit::UnitShot(){
static int Uy1 = 400; //y軸の値
static int Ux1; //x軸の値
glColor3d(0.0,0.7,1.0); //ユニットの打ったときの色
if(shut == 1){
if(Uy1 == 400){
Ux1 = dim * 4 + 320;
}
Uy1 -= 10;
Point(Ux1, Uy1, 5);
if(Uy1 < 0){
Uy1 = 400;
shut = 0;
}
}
}
//ディスプレイ
void display(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Invader i; //インベーダー
i.InvaderShot0(); //インベーダーが撃つ描画
i.InvaderShot1(); //残りも同じだがひとまとめにする
i.InvaderShot2();
i.InvaderShot3();
i.InvaderShot4();
i.InvaderShot5();
i.InvaderShot6();
i.InvaderShot7();
Unit u; //ユニット
u.UnitShot(); //ユニットが撃つ描画
glutSwapBuffers(); //ダブルバッファ
}
void Init(void){
glClearColor(0.0,0.0,0.0,0.0);
glOrtho(0,WIDTH,HEIGHT,0,-1,1);
}
int main(int argc, char* argv[]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(WIDTH,HEIGHT);
glutCreateWindow("Invader");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboardUp);
glutSpecialFunc(specialKey);
glutSpecialUpFunc(specialUpKey);
Init();
glutMainLoop();
return 0;
}