コード:
#include "main.h"
//グローバル変数
GameState g_gamestate = GAME_TITLE;
//box2d関連
b2Vec2 gravity(0.0f, GRAVITY_Y); //重力加速度
b2World g_world(gravity, true); //Box2DWorld
//ゲームデータ
Images g_images; //画像データ
Sounds g_sounds; //音声データ
StageInfo g_stage; //ステージデータ
//メインループ
void MyMain(){
//ゲーム開始からの時間を計る
g_stage.gametime = g_lasttime - g_stage.gamestarttime;
//b2bの時間を進める
g_world.Step(g_frametime, VELOCITYITE, POSITIONITE);
//各画面の描画
switch(g_gamestate){
case GAME_TITLE:
DrawGameTitle();
break;
case GAME_MAIN:
DrawGameMain();
break;
case GAME_CLEAR:
DrawGameClear();
break;
case GAME_OVER:
DrawGameOver();
break;
}
}
//ファイルの読み込み
int LoadFiles(){
//ファイル読み込み処理をここに書く
if( LoadDivGraph("media\\chara_hero_l.png",
6, 6, 1, 46, 96, g_images.hero) == -1)
{
return -1;
}
//壁床
g_images.wall[WALL_568]=LoadGraph("media\\wall_s.png");
if(g_images.wall[568]==-1)return -1;
g_images.wall[WALL_48]=DerivationGraph(0,0,48,48,g_images.wall[WALL_568]);
g_images.wall[WALL_192]=DerivationGraph(0,0,192,48,g_images.wall[WALL_568]);
g_images.wall[WALL_284]=DerivationGraph(0,0,284,48,g_images.wall[WALL_568]);
g_images.wall[EASY]=DerivationGraph(0,0,192,12,g_images.wall[WALL_568]);
g_images.wall[MEDIUM]=DerivationGraph(0,0,96,12,g_images.wall[WALL_568]);
g_images.wall[DIFFICULT]=DerivationGraph(0,0,48,12,g_images.wall[WALL_568]);
//g_images.wall[EASY]=LoadGraph("media\\goalflag.png");
//if(g_images.wall[EASY]==-1)return -1;
//玉
g_images.ball[3] = LoadGraph("media\\ball_s.png");
if(g_images.ball[3] == -1) return -1;
g_images.ball[BALL_24] = DerivationGraph(0, 0, 24, 24,
g_images.ball[3]);
g_images.ball[BALL_48] = DerivationGraph(24, 0, 48, 48,
g_images.ball[3]);
g_images.ball[BALL_96] = DerivationGraph(0, 48, 96, 96,
g_images.ball[3]);
//読み込み成功
return 1;
}
//タイトル画面描画
void GoGameTitle(){
g_gamestate = GAME_TITLE;
}
void DrawGameTitle(){
//テキスト表示
DrawStringToHandle(100, 340, "Zキーでゲームスタート",
0x666666, g_middlefont);
//キーをチェックして画面切り替え
int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
if(IsAKeyTrigger(key)==true) GoGameMain();
}
//ゲーム本編描画
void GoGameMain(){
g_gamestate = GAME_MAIN;
InitStage(); //ステージデータの初期化
}
void DrawGameMain(){
//スクロール座標調整
b2Vec2 pos=g_stage.hero->GetPosition();
int hx=(int)(pos.x*WLDSC);
if(hx-SCROLL_LIMIT<g_stage.screen_x){
g_stage.screen_x=hx-SCROLL_LIMIT-640;
}
if(640-SCROLL_LIMIT<hx-g_stage.screen_x){
g_stage.screen_x=hx+SCROLL_LIMIT-640;
}
int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
//ボールあたり判定
for(int i=0;i<30;i++){
if(g_stage.ball[i].used == false) continue;
b2Vec2 pos1 = g_stage.ball[i].body->GetPosition();
if(pos1.x>887&&pos.x<935){
if(pos1.y>360&&pos.y<408){
GoGameOver();
}
}
}
//衝突判定
Collision();
//画面外チェック
if(IsOutScreen(pos.x,pos.y)==true)GoGameOver();
DrawEnemyAndMap();//地形描画
//主人公の足下確認
g_stage.isontheground = true;
HeroState hstate = HERO_STANDING;
//主人公の位置と移動ベクトル
b2Vec2 vec = g_stage.hero->GetLinearVelocity();
float angle = g_stage.hero->GetAngle();
//キーチェック
//左右移動
if(key & PAD_INPUT_LEFT) {
vec.x += -PHS(4.0f);
g_stage.hero->SetLinearVelocity(vec);
hstate = HERO_RUNNING;
g_stage.isheroleft = true;
if(angle>-0.2f){
angle=-0.2f;
g_stage.hero->SetAngularVelocity(angle);
}
}
if(key & PAD_INPUT_RIGHT) {
vec.x += PHS(4.0f);
g_stage.hero->SetLinearVelocity(vec);
hstate = HERO_RUNNING;
g_stage.isheroleft = false;
if(fabs(angle)<0.2f){
angle=0.2f;
g_stage.hero->SetAngularVelocity(angle);
}
}
//転倒対策
if( fabs(angle) > 0.2f||fabs(angle) < -0.2f ){
g_stage.hero->SetAngularVelocity(-angle);
}
if( fabs(angle) < 0.01f&&fabs(angle) > -0.01f ){
g_stage.hero->SetAngularVelocity(0);
}
//主人公移動制限
if( vec.x > PHS(1000.0f)||vec.x < PHS(-1000.0f) ){
vec.x=(float)(vec.x*0.9);
g_stage.hero->SetLinearVelocity(vec);
}
vec.x=(float)(vec.x*0.995);
g_stage.hero->SetLinearVelocity(vec);
if( vec.x < PHS(1.5f)&&vec.x > PHS(-1.5f) ){
vec.x=0;
g_stage.hero->SetLinearVelocity(vec);
}
//スコア表示
DrawFormatStringToHandle(0, 0, 0xFF0000, g_middlefont,
"SCORE: %d", g_stage.score);
}
void DrawHero(int hstate){
b2Vec2 pos = g_stage.hero->GetPosition();
float angle = g_stage.hero->GetAngle();
//キャラクター描画
int animpat = (g_lasttime / (1000 / 12)) % 4;
switch(hstate){
case HERO_STANDING:
DrawRotaGraph(VIWX(pos.x), VIWY(pos.y), 1, angle,
g_images.hero[0], TRUE, g_stage.isheroleft);
break;
case HERO_RUNNING:
DrawRotaGraph(VIWX(pos.x), VIWY(pos.y), 1, angle,
g_images.hero[1 + animpat], TRUE,
g_stage.isheroleft);
break;
case HERO_JUMP:
DrawRotaGraph(VIWX(pos.x), VIWY(pos.y), 1, angle,
g_images.hero[5], TRUE, g_stage.isheroleft);
break;
}
}
//衝突判定
void Collision(){
//接触確認ループ
for(b2Contact* c = g_world.GetContactList(); c!=NULL;
c = c->GetNext())
{
for(int i=0;i<30;i++){
if(c->IsTouching() == false) continue;
//接触しているボディを取り出す
b2Body* b1 = c->GetFixtureA()->GetBody();
b2Body* b2 = c->GetFixtureB()->GetBody();
//主人公のチェック
b2Body* hb = NULL;
b2Body* ob = NULL;
if(b1 == g_stage.ball[i].body) {hb = b1; ob = b2;}
if(b2 == g_stage.ball[i].body) {hb = b2; ob = b1;}
if(hb != NULL){
Character *ch = (Character *)ob->GetUserData();
if(ch != NULL){
b2Vec2 vec = g_stage.ball[i].body->GetLinearVelocity();
if(vec.x!=0){
if(ch->type==EASY){
if(vec.x<0){
vec.x=-1*vec.x;
g_stage.score+=(int)(10*vec.x);//仮
}
if(vec.x>0){
g_stage.score+=(int)(10*vec.x);
}
}
if(ch->type==MEDIUM){
if(vec.x<0){
vec.x=-1*vec.x;
g_stage.score+=(int)(10*vec.x);
}
if(vec.x>0){
g_stage.score+=(int)(10*vec.x);
}
}
if(ch->type==DIFFICULT){
if(vec.x<0){
vec.x=-1*vec.x;
g_stage.score+=(int)(10*vec.x);
}
if(vec.x>0){
g_stage.score+=(int)(10*vec.x);
}
}
}
}
}
}
}
}
//ステージ初期化
void InitStage(){
//ゲームデータ全体のゼロ初期化
ZeroMemory(&g_stage, sizeof(g_stage));
//全ボディ・ジョイント削除
DeleteAllBody();
//地形読み込み
if(LoadMapData("media\\stage01.txt")==-1){
MessageBox(NULL, "マップデータ読み込み失敗",
"DXライブラリ", MB_OK);
}
//g_stage.hero = CreateBox(PHS(140),PHS(40),
//PHS(23), PHS(48), true);
//ゲーム開始時刻の記録
g_stage.gamestarttime = g_lasttime;
}
//ゲームクリア画面描画
void GoGameClear(){
g_gamestate = GAME_CLEAR;
g_stage.timerstart = g_lasttime;
}
void DrawGameClear(){
//5秒経ったらタイトル画面へ
if(g_lasttime - g_stage.timerstart > 5000) GoGameTitle();
}
//ゲームオーバー画面描画
void GoGameOver(){
g_gamestate = GAME_OVER;
g_stage.timerstart = g_lasttime;
}
void DrawGameOver(){
//5秒経ったらタイトル画面へ
if(g_lasttime - g_stage.timerstart > 5000) GoGameTitle();
}
//マップの読み込み
int LoadMapData(char *filepath){
int f; //ファイルハンドル
char buf[1024]; //テキスト読み込みバッファ
f = FileRead_open(filepath);
if (f==0) return -1; //読み込みエラー
//マップサイズと主人公初期位置読み込み
if(FileRead_gets( buf, 1023, f ) == -1) return -1;
float w, h, sx, sy;
sscanf_s(buf, "%f, %f, %f, %f", &w, &h, &sx, &sy);
g_stage.mapsize_w = w;
g_stage.mapsize_h = h;
//主人公キャラクター
g_stage.hero = CreateBox(PHS(sx), PHS(sy),
PHS(23), PHS(48), 0, true);
//地形オブジェクト読み込み
if(FileRead_gets( buf, 1023, f ) == -1) return -1;
int imax;
sscanf_s(buf, "%d" , &imax); //行数取得
float x, y, angle;
int id;
for(int i=0; i<imax; i++){
if(FileRead_gets( buf, 1023, f ) == -1) return -1;
sscanf_s( buf, "%f, %f, %f, %f, %f, %d",
&x, &y, &w, &h, &angle, &id);
//ボディ作成
Character ch;
ch.body=CreateBox(PHS(x), PHS(y),PHS(w/2), PHS(h/2), angle, false);
switch(id){
case 0:
if((int)w == 48) ch.ID = WALL_48;
if((int)w == 192) ch.ID = WALL_192;
if((int)w == 284) ch.ID = WALL_284;
if((int)w == 568) ch.ID = WALL_568;
break;
case 1:
ch.ID=EASY;
ch.type=EASY;
g_stage.flagbody=ch.body;
ch.body->SetUserData(&g_images.wall[g_stage.num_mapchara]);
break;
case 2:
//if(id==2)
ch.ID=MEDIUM;
ch.type=MEDIUM;
g_stage.flagbody=ch.body;
ch.body->SetUserData(&g_stage.wall[g_stage.num_mapchara]);
break;
case 3:
//if(id==3)
ch.ID=DIFFICULT;
ch.type=DIFFICULT;
g_stage.flagbody=ch.body;
ch.body->SetUserData(&g_stage.wall[g_stage.num_mapchara]);
break;
}
ch.used = true;
g_stage.wall[g_stage.num_mapchara] = ch;
g_stage.num_mapchara++;
}
FileRead_close(f);
return 0;
}
b2Body* CreateDynamicBall(float x, float y, float radius){
//ボディ定義
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody; //動的ボディ
bodyDef.position.Set(x, y);
//ボディ作成
b2Body* body = g_world.CreateBody(&bodyDef);
//シェイプ作成
b2CircleShape dynamicBall;
dynamicBall.m_radius = radius;
//フィクスチャ定義
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBall;
fixtureDef.density = 4.0f; //密度
fixtureDef.restitution = 0.7f; //反発力
body->CreateFixture(&fixtureDef);
return body;
}
b2Body* CreateBox(float x, float y, float w, float h,float angle, bool dynamic){
//ボディ定義
b2BodyDef bodyDef;
if(dynamic) bodyDef.type = b2_kinematicBody; //動的ボディ
else bodyDef.type = b2_staticBody; //静的ボディ
bodyDef.position.Set(x, y);
bodyDef.angle=angle;
///bodyDef.angle = 0.1f;
//ボディ作成
b2Body* body = g_world.CreateBody(&bodyDef);
//シェイプ作成
b2PolygonShape staticBox;
staticBox.SetAsBox(w, h);
//フィクスチャ定義
b2FixtureDef fixtureDef;
fixtureDef.shape = &staticBox;
fixtureDef.density = 4.0f; //密度
fixtureDef.restitution = 0.2f; //反発力
fixtureDef.friction = 0.2f; //摩擦係数
body->CreateFixture(&fixtureDef);
return body;
}
//地形などの描画
void DrawEnemyAndMap(){
int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
//地形の描画
for(int i=0; i<g_stage.num_mapchara; i++){
if(g_stage.wall[i].used == false) continue;
b2Vec2 pos = g_stage.wall[i].body->GetPosition();
float angle = g_stage.wall[i].body->GetAngle();
int id = g_stage.wall[i].ID;
DrawRotaGraph(VIWX(pos.x), VIWY(pos.y), 1, angle,g_images.wall[id], TRUE);//仮
}
//雪玉の描画
for(int i=0; i<MAXBALLCHARA; i++){
if(g_stage.ball[i].used == false) continue;
b2Vec2 pos = g_stage.ball[i].body->GetPosition();
float angle = g_stage.ball[i].body->GetAngle();
//int id = g_stage.ball[i].ID;
DrawRotaGraph(VIWX(pos.x), VIWY(pos.y), 1, angle,g_images.ball[0], TRUE);
//画面外に出たら消去
if(IsOutScreen(pos.x, pos.y)==true){
//g_world.DestroyBody(g_stage.ball[i].body);
//g_stage.ball[i].used = false;
}
}
//出現
if(IsAKeyTrigger(key)==true){
FallSnow(1);
}
}
//配列から空きキャラクターを探す
int FindBlankChara(Character *arr, int arraymax){
for(int i=0; i<arraymax; i++){
if(arr[i].used == false){
return i;
}
}
//空きが見つからない場合
return -1;
}
void FallSnow(int num){
b2Vec2 pos = g_stage.hero->GetPosition();
b2Vec2 vec = g_stage.hero->GetLinearVelocity();
int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
Character ch2;
for(int i=0;i<num;i++){
//空きキャラクターを探す
int blank = FindBlankChara(g_stage.ball, MAXBALLCHARA);
if(blank >= 0){
//種類を決める
float sz=24.0f; int ID=24;
//ボディ作成
ch2.body = CreateDynamicBall(pos.x,pos.y+2, PHS(sz/2));
b2Vec2 vec2 = ch2.body->GetLinearVelocity();
vec2.x=vec.x;
ch2.body->SetLinearVelocity(vec2);
ch2.used = true;
ch2.ID = ID;
g_stage.ball[blank] = ch2;
blank-=1;
}
}
}