iリブロ
iリブロ
iリブロの管理人ブログにあるマリオもどき(2D)のプログラムを画像表示したりいろいろ改造してみたらゲームオーバーした時やゲームクリアしたときにはじめからやり直すとどんどんメモリ使用量が増えて2,3回の繰り返しだけで動かなくなってしまいます。これを解決するアイデアはなにかありますか#ifdef _DEBUG
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
↑これは意味ありませんでした
14歳からはじめるC言語ワクワクゲームプログラミングvisual2010のソースを改造してあるのでできれば読者の方返信お願いします
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
↑これは意味ありませんでした
14歳からはじめるC言語ワクワクゲームプログラミングvisual2010のソースを改造してあるのでできれば読者の方返信お願いします
最後に編集したユーザー ながもん on 2013年1月14日(月) 11:36 [ 編集 1 回目 ]
Re: iリブロ
返信ありがとうございます。
DXライブラリとBox2Dを使っているプログラムでいじったソースファイルを載せます。
プログラミングは勉強ですのでみずらかったらすみません。
#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; //ステージデータ
Character ch;
HeroState hstate;
//メインループ
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("私.png",7,7,1,60,80,g_images.hero)==-1)
return -1;
//敵
if(LoadDivGraph("敵.png",5,5,1,60,80,g_images.enemy)==-1)
return -1;
//背景
if(LoadDivGraph("back_cross.png",2,2,1,128,128,g_images.back)==-1)
return -1;
//壁
g_images.wall[WALL_13]=LoadGraph("wall.png");
g_images.wall[WALL_0]=DerivationGraph(0,0,200,300,g_images.wall[WALL_13]);
g_images.wall[WALL_1]=DerivationGraph(0,0,1500,100,g_images.wall[WALL_13]);
g_images.wall[WALL_2]=DerivationGraph(0,0,250,50,g_images.wall[WALL_13]);
g_images.wall[WALL_3]=DerivationGraph(0,0,48,48,LoadGraph("リンゴ.png"));
g_images.wall[WALL_4]=DerivationGraph(0,0,300,500,g_images.wall[WALL_13]);
g_images.wall[WALL_5]=DerivationGraph(0,0,300,50,g_images.wall[WALL_13]);
g_images.wall[WALL_6]=DerivationGraph(0,0,157,50,g_images.wall[WALL_13]);
g_images.wall[WALL_7]=DerivationGraph(0,0,600,50,g_images.wall[WALL_13]);
g_images.wall[WALL_8]=DerivationGraph(0,0,200,200,g_images.wall[WALL_13]);
g_images.wall[WALL_9]=DerivationGraph(0,0,60,20,g_images.wall[WALL_13]);
g_images.wall[WALL_11]=NULL;
g_images.wall[WALL_10]=DerivationGraph(0,0,500,100,g_images.wall[WALL_13]);
g_images.wall[WALL_12]=DerivationGraph(0,0,60,10,g_images.wall[WALL_13]);
g_images.wall[WALL_14]=DerivationGraph(0,0,300,0,g_images.wall[WALL_13]);
//ゴールの旗
g_images.wall[GOAL]=LoadGraph("goal.png");
g_images.wall[MOUNTAIN]=LoadGraph("山.png");
g_images.wall[TREE]=LoadGraph("木.png");
g_images.wall[LEAF]=LoadGraph("木の葉.png");
g_images.wall[FALL]=LoadGraph("川.png");
g_images.wall[ROCK]=LoadGraph("岩.png");
g_images.wall[CLOUD]=LoadGraph("雲.png");
//読み込み成功
return 1;
}
//マップの読み込み
int LoadMapDate(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=CreateBody(PHS(sx),PHS(sy),PHS(30),PHS(40),0,true,1,1+4,4.0f,0.1f,0.5f);
//地形オブジェクト
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);
//ボディ作成
switch(id){
case 0: //床壁
case 1: //抜け床
case 2: //ゴールフラグ
CreateStaticBlock(x,y,w,h,angle,id);
break;
case 3: //はてなボックス
CreateDynamicBlock(x,y,w,h,angle,id);
break;
}
}
FileRead_close(f);
return 0;
}
//ステージ初期化
void InitStage(){
//ゲームデータ全体のゼロ初期化
ZeroMemory(&g_stage, sizeof(g_stage));
ZeroMemory(&ch,sizeof(ch));
//全ボディ・ジョイント削除
DeleteAllBody();
//マウスジョイント用のグランドボディ作成
b2BodyDef bodydef;
g_stage.groundbody = g_world.CreateBody(&bodydef);
//地形読み込み
if(LoadMapDate("stage01.txt")==-1){
MessageBox(NULL,"マップデータ読み込み失敗","DXライブラリ",MB_OK);
}
//ゲーム開始時刻の記録
g_stage.gamestarttime = g_lasttime;
}
//タイトル画面描画
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);
int hy=(int)(pos.y*WLDSC);
//画像表示
DrawGraph(-g_stage.screen_x-300,-g_stage.screen_y-70,g_images.back[0],true);
if(hx-(SCROLL_LIMIT+100)<g_stage.screen_x)
g_stage.screen_x=hx-(SCROLL_LIMIT+100);
if(640-(SCROLL_LIMIT+100)<hx-g_stage.screen_x)
g_stage.screen_x=hx+(SCROLL_LIMIT+100)-640;
if(hy-SCROLL_LIMIT<g_stage.screen_y)
g_stage.screen_y=hy-SCROLL_LIMIT;
if(480-SCROLL_LIMIT<hy-g_stage.screen_y)
g_stage.screen_y=hy+SCROLL_LIMIT-480;
g_gamestate = GAME_MAIN;
if(IsOutScreen(pos.x,pos.y)==true)GoGameOver();
//衝突チェック
g_stage.heroontheground=false;
g_stage.enemyontheground=false;
Collision();
int key=GetJoypadInputState(DX_INPUT_KEY_PAD1);
hstate=HERO_STANDING;
//主人公の位置と移動ベクトル
b2Vec2 vec=g_stage.hero->GetLinearVelocity();
float angle=g_stage.hero->GetAngle();
DrawEnemyAndMap(); //地形描
//キーチェック
if(g_stage.heroontheground==true&&(key&PAD_INPUT_C)==false){
//左右移動
if(key&PAD_INPUT_LEFT){
vec.x=-PHS(120.0f);
g_stage.hero->SetLinearVelocity(vec);
hstate=HERO_RUNNING;
g_stage.isheroleft=true;
}
if(key&PAD_INPUT_RIGHT){
vec.x=PHS(120.0f);
g_stage.hero->SetLinearVelocity(vec);
hstate=HERO_RUNNING;
g_stage.isheroleft=false;
}
//ジャンプ
if(IsBKeyTrigger(key)==true){
vec.x=0;
vec.y=-62.0f;
g_stage.hero->ApplyLinearImpulse(vec,pos);
hstate=HERO_JUMP;
g_stage.heroontheground=false;
}
}
//ジャンプ姿勢へ
if(g_stage.heroontheground==false)
{
hstate=HERO_JUMP;
//ヒップドロップ
if(key&PAD_INPUT_C){
vec.x=0;
vec.y=100.0f;
g_stage.hero->ApplyLinearImpulse(vec,pos);
hstate=HERO_SQUAT;
g_stage.isheroleft=false;
}
}
//転倒対策
if(fabs(angle)>0.2f)
g_stage.hero->SetAngularVelocity(-angle*2);
DrawHero(hstate); //主人公描画
}
//主人公の描画
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;
case HERO_SQUAT:
DrawRotaGraph(VIWX(pos.x),VIWY(pos.y),1,angle,g_images.hero[6],TRUE,g_stage.isheroleft);
}
}
//主人公の作成
void CreateHero(float x,float y,float w,float h)
{
g_stage.hero=CreateBody(PHS(x),PHS(y),PHS(w),PHS(h),0,true,1,1+4,4.0f,0.1f,0.5f);
}
//動かない床壁
void CreateStaticBlock(float x,float y,float w,float h,float angle,int id)
{
ch.size=(int)w;
ch.used=true;
switch(id){
case 0: //床壁
ch.body=CreateBody(PHS(x),PHS(y),PHS(w/2),PHS(h/2),angle,false,4,1+4,4.0f,0.2f,0.4f);
break;
case 1: //抜け床
ch.body=CreateBody(PHS(x),PHS(y),PHS(w/2),PHS(h/2),angle,false,2,2,4.0f,0.2f,0.4f);
break;
case 2: //ゴールフラグ
ch.body=CreateBody(PHS(x),PHS(y),PHS(w/2),PHS(h/2),angle,false,4,1,4.0f,0.2f,0.4f);
g_stage.flagbody=ch.body;
break;
}
if((int)h==300&&(int)w==200)ch.ID=WALL_0;
if((int)w==1500)ch.ID=WALL_1;
if((int)w==250&&(int)h==50)ch.ID=WALL_2;
if((int)h==48)ch.ID=WALL_3;
if((int)h==500)ch.ID=WALL_4;
if((int)w==300&&(int)h==50)ch.ID=WALL_5;
if((int)w==300&&(int)h==1)ch.ID=WALL_14;
if((int)w==600&&(int)h==50)ch.ID=WALL_7;
if((int)h==200)ch.ID=WALL_8;
if((int)h==20)ch.ID=WALL_9;
if((int)w==500&&(int)h==10)ch.ID=WALL_11;
if((int)w==500&&(int)h==100)ch.ID=WALL_10;
if((int)w==60&&(int)h==10)ch.ID=WALL_12;
if(id==1)
{
switch((int)w)
{
case 156:ch.ID=WALL_6; //抜け床
break;
case 2159:ch.ID=MOUNTAIN; //山
break;
case 494:ch.ID=TREE; //木
break;
case 650:ch.ID=LEAF; //葉
break;
case 403:ch.ID=FALL; //滝
break;
case 70:ch.ID=ROCK; //岩
break;
case 60:ch.ID=CLOUD; //雲
break;
}
}
if(id==2)ch.ID=GOAL; //ゴールフラグ
g_stage.wall[g_stage.num_mapchara]=ch;
ch.body->SetUserData(&g_stage.wall[g_stage.num_mapchara]);
g_stage.num_mapchara++;
}
//動く床壁
void CreateDynamicBlock(float x,float y,float w,float h,float angle,int id)
{
ch.size=(int)w;
ch.used=true;
b2WeldJointDef wjointdef;
b2PrismaticJointDef pjointdef;
switch(id){
case 3:
ch.body=CreateBody(PHS(x),PHS(y),PHS(w/2),PHS(h/2),angle,true,4,1+4,4.0f,0.2f,0.4f);
pjointdef.Initialize(g_stage.groundbody,ch.body,ch.body->GetPosition(),b2Vec2(0.0f,-1.0f));
pjointdef.enableLimit=true; //制限有効
pjointdef.lowerTranslation=PHS(0); //下限
pjointdef.upperTranslation=PHS(50);//上限
g_world.CreateJoint(&pjointdef);
ch.type=HATENA_BOX;
if((int)h==48)ch.ID=WALL_3;
break;
}
g_stage.wall[g_stage.num_mapchara]=ch;
ch.body->SetUserData(&g_stage.wall[g_stage.num_mapchara]);
g_stage.num_mapchara++;
}
//地形の描画
void DrawEnemyAndMap()
{
int animpat=(g_lasttime/(1000/12)%4);
int kawapat=(g_lasttime/(500/12)%8);
for(int x=0;x<6;x++){
for(int y=0;y<5;y++){
int delta=(g_lasttime/(1000/50))%128;
DrawGraph(x*128-delta,y*128-delta,g_images.back[1],FALSE);
}
}
//地形の描画
for(int i=0;i<g_stage.num_mapchara;i++)
{
//床壁
if(g_stage.wall.used==false)continue;
b2Vec2 pos=g_stage.wall.body->GetPosition();
float angle=g_stage.wall.body->GetAngle();
int id=g_stage.wall.ID;
DrawRotaGraph(VIWX(pos.x),VIWY(pos.y),1,angle,g_images.wall[id],TRUE);
if(g_stage.wall.ID==FALL)
DrawRotaGraph(VIWX(pos.x),VIWY(pos.y+kawapat),1,angle,g_images.wall[FALL],TRUE);
}
EnterEnemy();
for(int i=0;i<MAXENEMYCHARA;i++)
{
if(g_stage.enemy.used==false)continue;
b2Vec2 pos=g_stage.enemy.body->GetPosition();
//画面外に出たら消去
if(g_stage.enemy.damage>0.0f||IsOutScreen(pos.x,pos.y)==true)
{
g_stage.enemy.used=false;
g_world.DestroyBody(g_stage.enemy.body);
continue;
}
b2Vec2 vec=g_stage.enemy[i].body->GetLinearVelocity();
DrawRotaGraph(VIWX(pos.x),VIWY(pos.y),1,0,g_images.enemy[animpat],TRUE);
switch(g_stage.enemy[i].type){
case ENEMY:
vec.x=g_stage.enemy[i].vecx;
g_stage.enemy[i].body->SetLinearVelocity(vec);
break;
}
float angle=g_stage.enemy[i].body->GetAngle();
if(fabs(angle)>0.1f)
g_stage.enemy[i].body->SetAngularVelocity(-angle*20);
}
}
//ゲームクリア画面描画
void GoGameClear(){
g_gamestate = GAME_CLEAR;
g_stage.timerstart = g_lasttime;
}
void DrawGameClear(){
DrawEnemyAndMap();
DrawHero(HERO_STANDING);
DrawGraph(-50,160,LoadGraph("gameclear.png"),TRUE);
//5秒経ったらタイトル画面へ
if(g_lasttime - g_stage.timerstart > 5000) GoGameTitle();
}
//ゲームオーバー画面描画
void GoGameOver(){
g_gamestate = GAME_OVER;
g_stage.timerstart = g_lasttime;
}
void DrawGameOver(){
DrawGraph(20,20,LoadGraph("gameover.png"),TRUE);
//5秒経ったらタイトル画面へ
if(g_lasttime - g_stage.timerstart > 5000) GoGameTitle();
}
b2Body* CreateBody(float x,float y,float w,float h,float angle,bool dynamic,int categoryBits,int maskBits
,float density,float restitution,float friction)
{
//ボディ定義
b2BodyDef bodydef;
if(dynamic)bodydef.type=b2_dynamicBody; //動的ボディ
else bodydef.type=b2_staticBody; //静的ボディ
bodydef.position.Set(x,y);
bodydef.angle=angle;
//ボディ作成
b2Body* body=g_world.CreateBody(&bodydef);
//シェイプ作成
b2PolygonShape staticBox;
staticBox.SetAsBox(w,h);
//フィクスチャ定義
b2FixtureDef fixturedef;
fixturedef.shape=&staticBox;
fixturedef.density=density; //密度
fixturedef.restitution=restitution; //反発力
fixturedef.friction=friction; //摩擦係数
fixturedef.filter.categoryBits=categoryBits;
fixturedef.filter.maskBits=maskBits;
body->CreateFixture(&fixturedef);
return body;
}
//主人公衝突判定
void Collision(){
//接触確認ループ
for(b2Contact* c = g_world.GetContactList(); c!=NULL;
c = c->GetNext())
{
if(c->IsTouching() == false) continue;
//接触しているボディを取り出す
b2Body* bd[2];
b2Fixture* fx[2];
fx[0]=c->GetFixtureA();
fx[1]=c->GetFixtureB();
bd[0]=fx[0]->GetBody();
bd[1]=fx[1]->GetBody();
//ボディチェック
for(int i=0;i<2;i++){
b2Body *obd=bd[(i+1)%2];
Character *ch = (Character *)bd[i]->GetUserData();
Character *och = (Character *)obd->GetUserData();
//接地チェック
if( bd[i]==g_stage.hero )
{
g_stage.heroontheground = true;
if(och->type==ENEMY)
{
b2Vec2 pos1=g_stage.hero->GetPosition();
b2Vec2 pos=och->body->GetPosition();
float hx=(float)(pos1.x*WLDSC);
float hy=(float)(pos1.y*WLDSC);
float ex=(float)(pos.x*WLDSC);
float ey=(float)(pos.y*WLDSC);
if(PHS(hy+40)>=PHS(ey-45)&&PHS(hx+30)>PHS(ex-30)&&PHS(hx-30)<PHS(ex+30))
{
DrawRotaGraph(VIWX(pos.x),VIWY(pos.y),1,0,g_images.enemy[4],TRUE);
och->damage=10.0f;
}
if(PHS(hx+30)>=PHS(ex-31)&&PHS(hy)>=PHS(ey-40))
GoGameOver();
}
if(obd==g_stage.flagbody)
GoGameClear();
}
if(ch!=NULL&&och!=NULL){
//モンスター左右方向転換
if(ch->type>=ENEMY){
g_stage.enemyontheground=true;
b2Manifold *manifold = c->GetManifold();
if(manifold->type >= b2Manifold::e_faceA){
//進行方向で衝突が起きていたら
if( (manifold->localNormal.x < 0.0f && ch->vecx > 0.0f)||
(manifold->localNormal.x > 0.0f && ch->vecx < 0.0f))
ch->vecx =-ch->vecx;
}
}
}
}
}
}
//敵を出現させる
void EnterEnemy()
{
for(int i=0;i<MAXENEMYCHARA;i++){
//空きキャラクターを探す
//位置を決める
float x=(float)GetRand((int)g_stage.mapsize_w);
int blank=FindBlankChara(g_stage.enemy,MAXENEMYCHARA);
if(blank>=0)
{ //ボディ作成
ch.body=CreateBody(PHS(x),0,PHS(30),PHS(40),0,true,4,5,4.0f,0.0f,0.1f);
ch.used=true;
ch.vecx=-PHS(speed);
ch.type=ENEMY;
ch.damage=0.0f;
g_stage.enemy[blank]=ch;
ch.body->SetUserData(&g_stage.enemy[blank]);
}
}
}
//配列から空きキャラクターを探す
int FindBlankChara(Character *arr,int arraymax)
{
for(int i=0;i<arraymax;i++){
if(arr[i].used==false)
return i;
}
//空きが見つからなかった場合
return -1;
}
DXライブラリとBox2Dを使っているプログラムでいじったソースファイルを載せます。
プログラミングは勉強ですのでみずらかったらすみません。
#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; //ステージデータ
Character ch;
HeroState hstate;
//メインループ
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("私.png",7,7,1,60,80,g_images.hero)==-1)
return -1;
//敵
if(LoadDivGraph("敵.png",5,5,1,60,80,g_images.enemy)==-1)
return -1;
//背景
if(LoadDivGraph("back_cross.png",2,2,1,128,128,g_images.back)==-1)
return -1;
//壁
g_images.wall[WALL_13]=LoadGraph("wall.png");
g_images.wall[WALL_0]=DerivationGraph(0,0,200,300,g_images.wall[WALL_13]);
g_images.wall[WALL_1]=DerivationGraph(0,0,1500,100,g_images.wall[WALL_13]);
g_images.wall[WALL_2]=DerivationGraph(0,0,250,50,g_images.wall[WALL_13]);
g_images.wall[WALL_3]=DerivationGraph(0,0,48,48,LoadGraph("リンゴ.png"));
g_images.wall[WALL_4]=DerivationGraph(0,0,300,500,g_images.wall[WALL_13]);
g_images.wall[WALL_5]=DerivationGraph(0,0,300,50,g_images.wall[WALL_13]);
g_images.wall[WALL_6]=DerivationGraph(0,0,157,50,g_images.wall[WALL_13]);
g_images.wall[WALL_7]=DerivationGraph(0,0,600,50,g_images.wall[WALL_13]);
g_images.wall[WALL_8]=DerivationGraph(0,0,200,200,g_images.wall[WALL_13]);
g_images.wall[WALL_9]=DerivationGraph(0,0,60,20,g_images.wall[WALL_13]);
g_images.wall[WALL_11]=NULL;
g_images.wall[WALL_10]=DerivationGraph(0,0,500,100,g_images.wall[WALL_13]);
g_images.wall[WALL_12]=DerivationGraph(0,0,60,10,g_images.wall[WALL_13]);
g_images.wall[WALL_14]=DerivationGraph(0,0,300,0,g_images.wall[WALL_13]);
//ゴールの旗
g_images.wall[GOAL]=LoadGraph("goal.png");
g_images.wall[MOUNTAIN]=LoadGraph("山.png");
g_images.wall[TREE]=LoadGraph("木.png");
g_images.wall[LEAF]=LoadGraph("木の葉.png");
g_images.wall[FALL]=LoadGraph("川.png");
g_images.wall[ROCK]=LoadGraph("岩.png");
g_images.wall[CLOUD]=LoadGraph("雲.png");
//読み込み成功
return 1;
}
//マップの読み込み
int LoadMapDate(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=CreateBody(PHS(sx),PHS(sy),PHS(30),PHS(40),0,true,1,1+4,4.0f,0.1f,0.5f);
//地形オブジェクト
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);
//ボディ作成
switch(id){
case 0: //床壁
case 1: //抜け床
case 2: //ゴールフラグ
CreateStaticBlock(x,y,w,h,angle,id);
break;
case 3: //はてなボックス
CreateDynamicBlock(x,y,w,h,angle,id);
break;
}
}
FileRead_close(f);
return 0;
}
//ステージ初期化
void InitStage(){
//ゲームデータ全体のゼロ初期化
ZeroMemory(&g_stage, sizeof(g_stage));
ZeroMemory(&ch,sizeof(ch));
//全ボディ・ジョイント削除
DeleteAllBody();
//マウスジョイント用のグランドボディ作成
b2BodyDef bodydef;
g_stage.groundbody = g_world.CreateBody(&bodydef);
//地形読み込み
if(LoadMapDate("stage01.txt")==-1){
MessageBox(NULL,"マップデータ読み込み失敗","DXライブラリ",MB_OK);
}
//ゲーム開始時刻の記録
g_stage.gamestarttime = g_lasttime;
}
//タイトル画面描画
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);
int hy=(int)(pos.y*WLDSC);
//画像表示
DrawGraph(-g_stage.screen_x-300,-g_stage.screen_y-70,g_images.back[0],true);
if(hx-(SCROLL_LIMIT+100)<g_stage.screen_x)
g_stage.screen_x=hx-(SCROLL_LIMIT+100);
if(640-(SCROLL_LIMIT+100)<hx-g_stage.screen_x)
g_stage.screen_x=hx+(SCROLL_LIMIT+100)-640;
if(hy-SCROLL_LIMIT<g_stage.screen_y)
g_stage.screen_y=hy-SCROLL_LIMIT;
if(480-SCROLL_LIMIT<hy-g_stage.screen_y)
g_stage.screen_y=hy+SCROLL_LIMIT-480;
g_gamestate = GAME_MAIN;
if(IsOutScreen(pos.x,pos.y)==true)GoGameOver();
//衝突チェック
g_stage.heroontheground=false;
g_stage.enemyontheground=false;
Collision();
int key=GetJoypadInputState(DX_INPUT_KEY_PAD1);
hstate=HERO_STANDING;
//主人公の位置と移動ベクトル
b2Vec2 vec=g_stage.hero->GetLinearVelocity();
float angle=g_stage.hero->GetAngle();
DrawEnemyAndMap(); //地形描
//キーチェック
if(g_stage.heroontheground==true&&(key&PAD_INPUT_C)==false){
//左右移動
if(key&PAD_INPUT_LEFT){
vec.x=-PHS(120.0f);
g_stage.hero->SetLinearVelocity(vec);
hstate=HERO_RUNNING;
g_stage.isheroleft=true;
}
if(key&PAD_INPUT_RIGHT){
vec.x=PHS(120.0f);
g_stage.hero->SetLinearVelocity(vec);
hstate=HERO_RUNNING;
g_stage.isheroleft=false;
}
//ジャンプ
if(IsBKeyTrigger(key)==true){
vec.x=0;
vec.y=-62.0f;
g_stage.hero->ApplyLinearImpulse(vec,pos);
hstate=HERO_JUMP;
g_stage.heroontheground=false;
}
}
//ジャンプ姿勢へ
if(g_stage.heroontheground==false)
{
hstate=HERO_JUMP;
//ヒップドロップ
if(key&PAD_INPUT_C){
vec.x=0;
vec.y=100.0f;
g_stage.hero->ApplyLinearImpulse(vec,pos);
hstate=HERO_SQUAT;
g_stage.isheroleft=false;
}
}
//転倒対策
if(fabs(angle)>0.2f)
g_stage.hero->SetAngularVelocity(-angle*2);
DrawHero(hstate); //主人公描画
}
//主人公の描画
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;
case HERO_SQUAT:
DrawRotaGraph(VIWX(pos.x),VIWY(pos.y),1,angle,g_images.hero[6],TRUE,g_stage.isheroleft);
}
}
//主人公の作成
void CreateHero(float x,float y,float w,float h)
{
g_stage.hero=CreateBody(PHS(x),PHS(y),PHS(w),PHS(h),0,true,1,1+4,4.0f,0.1f,0.5f);
}
//動かない床壁
void CreateStaticBlock(float x,float y,float w,float h,float angle,int id)
{
ch.size=(int)w;
ch.used=true;
switch(id){
case 0: //床壁
ch.body=CreateBody(PHS(x),PHS(y),PHS(w/2),PHS(h/2),angle,false,4,1+4,4.0f,0.2f,0.4f);
break;
case 1: //抜け床
ch.body=CreateBody(PHS(x),PHS(y),PHS(w/2),PHS(h/2),angle,false,2,2,4.0f,0.2f,0.4f);
break;
case 2: //ゴールフラグ
ch.body=CreateBody(PHS(x),PHS(y),PHS(w/2),PHS(h/2),angle,false,4,1,4.0f,0.2f,0.4f);
g_stage.flagbody=ch.body;
break;
}
if((int)h==300&&(int)w==200)ch.ID=WALL_0;
if((int)w==1500)ch.ID=WALL_1;
if((int)w==250&&(int)h==50)ch.ID=WALL_2;
if((int)h==48)ch.ID=WALL_3;
if((int)h==500)ch.ID=WALL_4;
if((int)w==300&&(int)h==50)ch.ID=WALL_5;
if((int)w==300&&(int)h==1)ch.ID=WALL_14;
if((int)w==600&&(int)h==50)ch.ID=WALL_7;
if((int)h==200)ch.ID=WALL_8;
if((int)h==20)ch.ID=WALL_9;
if((int)w==500&&(int)h==10)ch.ID=WALL_11;
if((int)w==500&&(int)h==100)ch.ID=WALL_10;
if((int)w==60&&(int)h==10)ch.ID=WALL_12;
if(id==1)
{
switch((int)w)
{
case 156:ch.ID=WALL_6; //抜け床
break;
case 2159:ch.ID=MOUNTAIN; //山
break;
case 494:ch.ID=TREE; //木
break;
case 650:ch.ID=LEAF; //葉
break;
case 403:ch.ID=FALL; //滝
break;
case 70:ch.ID=ROCK; //岩
break;
case 60:ch.ID=CLOUD; //雲
break;
}
}
if(id==2)ch.ID=GOAL; //ゴールフラグ
g_stage.wall[g_stage.num_mapchara]=ch;
ch.body->SetUserData(&g_stage.wall[g_stage.num_mapchara]);
g_stage.num_mapchara++;
}
//動く床壁
void CreateDynamicBlock(float x,float y,float w,float h,float angle,int id)
{
ch.size=(int)w;
ch.used=true;
b2WeldJointDef wjointdef;
b2PrismaticJointDef pjointdef;
switch(id){
case 3:
ch.body=CreateBody(PHS(x),PHS(y),PHS(w/2),PHS(h/2),angle,true,4,1+4,4.0f,0.2f,0.4f);
pjointdef.Initialize(g_stage.groundbody,ch.body,ch.body->GetPosition(),b2Vec2(0.0f,-1.0f));
pjointdef.enableLimit=true; //制限有効
pjointdef.lowerTranslation=PHS(0); //下限
pjointdef.upperTranslation=PHS(50);//上限
g_world.CreateJoint(&pjointdef);
ch.type=HATENA_BOX;
if((int)h==48)ch.ID=WALL_3;
break;
}
g_stage.wall[g_stage.num_mapchara]=ch;
ch.body->SetUserData(&g_stage.wall[g_stage.num_mapchara]);
g_stage.num_mapchara++;
}
//地形の描画
void DrawEnemyAndMap()
{
int animpat=(g_lasttime/(1000/12)%4);
int kawapat=(g_lasttime/(500/12)%8);
for(int x=0;x<6;x++){
for(int y=0;y<5;y++){
int delta=(g_lasttime/(1000/50))%128;
DrawGraph(x*128-delta,y*128-delta,g_images.back[1],FALSE);
}
}
//地形の描画
for(int i=0;i<g_stage.num_mapchara;i++)
{
//床壁
if(g_stage.wall.used==false)continue;
b2Vec2 pos=g_stage.wall.body->GetPosition();
float angle=g_stage.wall.body->GetAngle();
int id=g_stage.wall.ID;
DrawRotaGraph(VIWX(pos.x),VIWY(pos.y),1,angle,g_images.wall[id],TRUE);
if(g_stage.wall.ID==FALL)
DrawRotaGraph(VIWX(pos.x),VIWY(pos.y+kawapat),1,angle,g_images.wall[FALL],TRUE);
}
EnterEnemy();
for(int i=0;i<MAXENEMYCHARA;i++)
{
if(g_stage.enemy.used==false)continue;
b2Vec2 pos=g_stage.enemy.body->GetPosition();
//画面外に出たら消去
if(g_stage.enemy.damage>0.0f||IsOutScreen(pos.x,pos.y)==true)
{
g_stage.enemy.used=false;
g_world.DestroyBody(g_stage.enemy.body);
continue;
}
b2Vec2 vec=g_stage.enemy[i].body->GetLinearVelocity();
DrawRotaGraph(VIWX(pos.x),VIWY(pos.y),1,0,g_images.enemy[animpat],TRUE);
switch(g_stage.enemy[i].type){
case ENEMY:
vec.x=g_stage.enemy[i].vecx;
g_stage.enemy[i].body->SetLinearVelocity(vec);
break;
}
float angle=g_stage.enemy[i].body->GetAngle();
if(fabs(angle)>0.1f)
g_stage.enemy[i].body->SetAngularVelocity(-angle*20);
}
}
//ゲームクリア画面描画
void GoGameClear(){
g_gamestate = GAME_CLEAR;
g_stage.timerstart = g_lasttime;
}
void DrawGameClear(){
DrawEnemyAndMap();
DrawHero(HERO_STANDING);
DrawGraph(-50,160,LoadGraph("gameclear.png"),TRUE);
//5秒経ったらタイトル画面へ
if(g_lasttime - g_stage.timerstart > 5000) GoGameTitle();
}
//ゲームオーバー画面描画
void GoGameOver(){
g_gamestate = GAME_OVER;
g_stage.timerstart = g_lasttime;
}
void DrawGameOver(){
DrawGraph(20,20,LoadGraph("gameover.png"),TRUE);
//5秒経ったらタイトル画面へ
if(g_lasttime - g_stage.timerstart > 5000) GoGameTitle();
}
b2Body* CreateBody(float x,float y,float w,float h,float angle,bool dynamic,int categoryBits,int maskBits
,float density,float restitution,float friction)
{
//ボディ定義
b2BodyDef bodydef;
if(dynamic)bodydef.type=b2_dynamicBody; //動的ボディ
else bodydef.type=b2_staticBody; //静的ボディ
bodydef.position.Set(x,y);
bodydef.angle=angle;
//ボディ作成
b2Body* body=g_world.CreateBody(&bodydef);
//シェイプ作成
b2PolygonShape staticBox;
staticBox.SetAsBox(w,h);
//フィクスチャ定義
b2FixtureDef fixturedef;
fixturedef.shape=&staticBox;
fixturedef.density=density; //密度
fixturedef.restitution=restitution; //反発力
fixturedef.friction=friction; //摩擦係数
fixturedef.filter.categoryBits=categoryBits;
fixturedef.filter.maskBits=maskBits;
body->CreateFixture(&fixturedef);
return body;
}
//主人公衝突判定
void Collision(){
//接触確認ループ
for(b2Contact* c = g_world.GetContactList(); c!=NULL;
c = c->GetNext())
{
if(c->IsTouching() == false) continue;
//接触しているボディを取り出す
b2Body* bd[2];
b2Fixture* fx[2];
fx[0]=c->GetFixtureA();
fx[1]=c->GetFixtureB();
bd[0]=fx[0]->GetBody();
bd[1]=fx[1]->GetBody();
//ボディチェック
for(int i=0;i<2;i++){
b2Body *obd=bd[(i+1)%2];
Character *ch = (Character *)bd[i]->GetUserData();
Character *och = (Character *)obd->GetUserData();
//接地チェック
if( bd[i]==g_stage.hero )
{
g_stage.heroontheground = true;
if(och->type==ENEMY)
{
b2Vec2 pos1=g_stage.hero->GetPosition();
b2Vec2 pos=och->body->GetPosition();
float hx=(float)(pos1.x*WLDSC);
float hy=(float)(pos1.y*WLDSC);
float ex=(float)(pos.x*WLDSC);
float ey=(float)(pos.y*WLDSC);
if(PHS(hy+40)>=PHS(ey-45)&&PHS(hx+30)>PHS(ex-30)&&PHS(hx-30)<PHS(ex+30))
{
DrawRotaGraph(VIWX(pos.x),VIWY(pos.y),1,0,g_images.enemy[4],TRUE);
och->damage=10.0f;
}
if(PHS(hx+30)>=PHS(ex-31)&&PHS(hy)>=PHS(ey-40))
GoGameOver();
}
if(obd==g_stage.flagbody)
GoGameClear();
}
if(ch!=NULL&&och!=NULL){
//モンスター左右方向転換
if(ch->type>=ENEMY){
g_stage.enemyontheground=true;
b2Manifold *manifold = c->GetManifold();
if(manifold->type >= b2Manifold::e_faceA){
//進行方向で衝突が起きていたら
if( (manifold->localNormal.x < 0.0f && ch->vecx > 0.0f)||
(manifold->localNormal.x > 0.0f && ch->vecx < 0.0f))
ch->vecx =-ch->vecx;
}
}
}
}
}
}
//敵を出現させる
void EnterEnemy()
{
for(int i=0;i<MAXENEMYCHARA;i++){
//空きキャラクターを探す
//位置を決める
float x=(float)GetRand((int)g_stage.mapsize_w);
int blank=FindBlankChara(g_stage.enemy,MAXENEMYCHARA);
if(blank>=0)
{ //ボディ作成
ch.body=CreateBody(PHS(x),0,PHS(30),PHS(40),0,true,4,5,4.0f,0.0f,0.1f);
ch.used=true;
ch.vecx=-PHS(speed);
ch.type=ENEMY;
ch.damage=0.0f;
g_stage.enemy[blank]=ch;
ch.body->SetUserData(&g_stage.enemy[blank]);
}
}
}
//配列から空きキャラクターを探す
int FindBlankChara(Character *arr,int arraymax)
{
for(int i=0;i<arraymax;i++){
if(arr[i].used==false)
return i;
}
//空きが見つからなかった場合
return -1;
}
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: iリブロ
codeタグを使ってくださいね。
内容はこれから調べます。
内容はこれから調べます。
ながもん さんが書きました:返信ありがとうございます。
DXライブラリとBox2Dを使っているプログラムでいじったソースファイルを載せます。
プログラミングは勉強ですのでみずらかったらすみません。#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; //ステージデータ Character ch; HeroState hstate; //メインループ 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("私.png",7,7,1,60,80,g_images.hero)==-1) return -1; //敵 if(LoadDivGraph("敵.png",5,5,1,60,80,g_images.enemy)==-1) return -1; //背景 if(LoadDivGraph("back_cross.png",2,2,1,128,128,g_images.back)==-1) return -1; //壁 g_images.wall[WALL_13]=LoadGraph("wall.png"); g_images.wall[WALL_0]=DerivationGraph(0,0,200,300,g_images.wall[WALL_13]); g_images.wall[WALL_1]=DerivationGraph(0,0,1500,100,g_images.wall[WALL_13]); g_images.wall[WALL_2]=DerivationGraph(0,0,250,50,g_images.wall[WALL_13]); g_images.wall[WALL_3]=DerivationGraph(0,0,48,48,LoadGraph("リンゴ.png")); g_images.wall[WALL_4]=DerivationGraph(0,0,300,500,g_images.wall[WALL_13]); g_images.wall[WALL_5]=DerivationGraph(0,0,300,50,g_images.wall[WALL_13]); g_images.wall[WALL_6]=DerivationGraph(0,0,157,50,g_images.wall[WALL_13]); g_images.wall[WALL_7]=DerivationGraph(0,0,600,50,g_images.wall[WALL_13]); g_images.wall[WALL_8]=DerivationGraph(0,0,200,200,g_images.wall[WALL_13]); g_images.wall[WALL_9]=DerivationGraph(0,0,60,20,g_images.wall[WALL_13]); g_images.wall[WALL_11]=NULL; g_images.wall[WALL_10]=DerivationGraph(0,0,500,100,g_images.wall[WALL_13]); g_images.wall[WALL_12]=DerivationGraph(0,0,60,10,g_images.wall[WALL_13]); g_images.wall[WALL_14]=DerivationGraph(0,0,300,0,g_images.wall[WALL_13]); //ゴールの旗 g_images.wall[GOAL]=LoadGraph("goal.png"); g_images.wall[MOUNTAIN]=LoadGraph("山.png"); g_images.wall[TREE]=LoadGraph("木.png"); g_images.wall[LEAF]=LoadGraph("木の葉.png"); g_images.wall[FALL]=LoadGraph("川.png"); g_images.wall[ROCK]=LoadGraph("岩.png"); g_images.wall[CLOUD]=LoadGraph("雲.png"); //読み込み成功 return 1; } //マップの読み込み int LoadMapDate(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=CreateBody(PHS(sx),PHS(sy),PHS(30),PHS(40),0,true,1,1+4,4.0f,0.1f,0.5f); //地形オブジェクト 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); //ボディ作成 switch(id){ case 0: //床壁 case 1: //抜け床 case 2: //ゴールフラグ CreateStaticBlock(x,y,w,h,angle,id); break; case 3: //はてなボックス CreateDynamicBlock(x,y,w,h,angle,id); break; } } FileRead_close(f); return 0; } //ステージ初期化 void InitStage(){ //ゲームデータ全体のゼロ初期化 ZeroMemory(&g_stage, sizeof(g_stage)); ZeroMemory(&ch,sizeof(ch)); //全ボディ・ジョイント削除 DeleteAllBody(); //マウスジョイント用のグランドボディ作成 b2BodyDef bodydef; g_stage.groundbody = g_world.CreateBody(&bodydef); //地形読み込み if(LoadMapDate("stage01.txt")==-1){ MessageBox(NULL,"マップデータ読み込み失敗","DXライブラリ",MB_OK); } //ゲーム開始時刻の記録 g_stage.gamestarttime = g_lasttime; } //タイトル画面描画 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); int hy=(int)(pos.y*WLDSC); //画像表示 DrawGraph(-g_stage.screen_x-300,-g_stage.screen_y-70,g_images.back[0],true); if(hx-(SCROLL_LIMIT+100)<g_stage.screen_x) g_stage.screen_x=hx-(SCROLL_LIMIT+100); if(640-(SCROLL_LIMIT+100)<hx-g_stage.screen_x) g_stage.screen_x=hx+(SCROLL_LIMIT+100)-640; if(hy-SCROLL_LIMIT<g_stage.screen_y) g_stage.screen_y=hy-SCROLL_LIMIT; if(480-SCROLL_LIMIT<hy-g_stage.screen_y) g_stage.screen_y=hy+SCROLL_LIMIT-480; g_gamestate = GAME_MAIN; if(IsOutScreen(pos.x,pos.y)==true)GoGameOver(); //衝突チェック g_stage.heroontheground=false; g_stage.enemyontheground=false; Collision(); int key=GetJoypadInputState(DX_INPUT_KEY_PAD1); hstate=HERO_STANDING; //主人公の位置と移動ベクトル b2Vec2 vec=g_stage.hero->GetLinearVelocity(); float angle=g_stage.hero->GetAngle(); DrawEnemyAndMap(); //地形描 //キーチェック if(g_stage.heroontheground==true&&(key&PAD_INPUT_C)==false){ //左右移動 if(key&PAD_INPUT_LEFT){ vec.x=-PHS(120.0f); g_stage.hero->SetLinearVelocity(vec); hstate=HERO_RUNNING; g_stage.isheroleft=true; } if(key&PAD_INPUT_RIGHT){ vec.x=PHS(120.0f); g_stage.hero->SetLinearVelocity(vec); hstate=HERO_RUNNING; g_stage.isheroleft=false; } //ジャンプ if(IsBKeyTrigger(key)==true){ vec.x=0; vec.y=-62.0f; g_stage.hero->ApplyLinearImpulse(vec,pos); hstate=HERO_JUMP; g_stage.heroontheground=false; } } //ジャンプ姿勢へ if(g_stage.heroontheground==false) { hstate=HERO_JUMP; //ヒップドロップ if(key&PAD_INPUT_C){ vec.x=0; vec.y=100.0f; g_stage.hero->ApplyLinearImpulse(vec,pos); hstate=HERO_SQUAT; g_stage.isheroleft=false; } } //転倒対策 if(fabs(angle)>0.2f) g_stage.hero->SetAngularVelocity(-angle*2); DrawHero(hstate); //主人公描画 } //主人公の描画 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; case HERO_SQUAT: DrawRotaGraph(VIWX(pos.x),VIWY(pos.y),1,angle,g_images.hero[6],TRUE,g_stage.isheroleft); } } //主人公の作成 void CreateHero(float x,float y,float w,float h) { g_stage.hero=CreateBody(PHS(x),PHS(y),PHS(w),PHS(h),0,true,1,1+4,4.0f,0.1f,0.5f); } //動かない床壁 void CreateStaticBlock(float x,float y,float w,float h,float angle,int id) { ch.size=(int)w; ch.used=true; switch(id){ case 0: //床壁 ch.body=CreateBody(PHS(x),PHS(y),PHS(w/2),PHS(h/2),angle,false,4,1+4,4.0f,0.2f,0.4f); break; case 1: //抜け床 ch.body=CreateBody(PHS(x),PHS(y),PHS(w/2),PHS(h/2),angle,false,2,2,4.0f,0.2f,0.4f); break; case 2: //ゴールフラグ ch.body=CreateBody(PHS(x),PHS(y),PHS(w/2),PHS(h/2),angle,false,4,1,4.0f,0.2f,0.4f); g_stage.flagbody=ch.body; break; } if((int)h==300&&(int)w==200)ch.ID=WALL_0; if((int)w==1500)ch.ID=WALL_1; if((int)w==250&&(int)h==50)ch.ID=WALL_2; if((int)h==48)ch.ID=WALL_3; if((int)h==500)ch.ID=WALL_4; if((int)w==300&&(int)h==50)ch.ID=WALL_5; if((int)w==300&&(int)h==1)ch.ID=WALL_14; if((int)w==600&&(int)h==50)ch.ID=WALL_7; if((int)h==200)ch.ID=WALL_8; if((int)h==20)ch.ID=WALL_9; if((int)w==500&&(int)h==10)ch.ID=WALL_11; if((int)w==500&&(int)h==100)ch.ID=WALL_10; if((int)w==60&&(int)h==10)ch.ID=WALL_12; if(id==1) { switch((int)w) { case 156:ch.ID=WALL_6; //抜け床 break; case 2159:ch.ID=MOUNTAIN; //山 break; case 494:ch.ID=TREE; //木 break; case 650:ch.ID=LEAF; //葉 break; case 403:ch.ID=FALL; //滝 break; case 70:ch.ID=ROCK; //岩 break; case 60:ch.ID=CLOUD; //雲 break; } } if(id==2)ch.ID=GOAL; //ゴールフラグ g_stage.wall[g_stage.num_mapchara]=ch; ch.body->SetUserData(&g_stage.wall[g_stage.num_mapchara]); g_stage.num_mapchara++; } //動く床壁 void CreateDynamicBlock(float x,float y,float w,float h,float angle,int id) { ch.size=(int)w; ch.used=true; b2WeldJointDef wjointdef; b2PrismaticJointDef pjointdef; switch(id){ case 3: ch.body=CreateBody(PHS(x),PHS(y),PHS(w/2),PHS(h/2),angle,true,4,1+4,4.0f,0.2f,0.4f); pjointdef.Initialize(g_stage.groundbody,ch.body,ch.body->GetPosition(),b2Vec2(0.0f,-1.0f)); pjointdef.enableLimit=true; //制限有効 pjointdef.lowerTranslation=PHS(0); //下限 pjointdef.upperTranslation=PHS(50);//上限 g_world.CreateJoint(&pjointdef); ch.type=HATENA_BOX; if((int)h==48)ch.ID=WALL_3; break; } g_stage.wall[g_stage.num_mapchara]=ch; ch.body->SetUserData(&g_stage.wall[g_stage.num_mapchara]); g_stage.num_mapchara++; } //地形の描画 void DrawEnemyAndMap() { int animpat=(g_lasttime/(1000/12)%4); int kawapat=(g_lasttime/(500/12)%8); for(int x=0;x<6;x++){ for(int y=0;y<5;y++){ int delta=(g_lasttime/(1000/50))%128; DrawGraph(x*128-delta,y*128-delta,g_images.back[1],FALSE); } } //地形の描画 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); if(g_stage.wall[i].ID==FALL) DrawRotaGraph(VIWX(pos.x),VIWY(pos.y+kawapat),1,angle,g_images.wall[FALL],TRUE); } EnterEnemy(); for(int i=0;i<MAXENEMYCHARA;i++) { if(g_stage.enemy[i].used==false)continue; b2Vec2 pos=g_stage.enemy[i].body->GetPosition(); //画面外に出たら消去 if(g_stage.enemy[i].damage>0.0f||IsOutScreen(pos.x,pos.y)==true) { g_stage.enemy[i].used=false; g_world.DestroyBody(g_stage.enemy[i].body); continue; } b2Vec2 vec=g_stage.enemy[i].body->GetLinearVelocity(); DrawRotaGraph(VIWX(pos.x),VIWY(pos.y),1,0,g_images.enemy[animpat],TRUE); switch(g_stage.enemy[i].type){ case ENEMY: vec.x=g_stage.enemy[i].vecx; g_stage.enemy[i].body->SetLinearVelocity(vec); break; } float angle=g_stage.enemy[i].body->GetAngle(); if(fabs(angle)>0.1f) g_stage.enemy[i].body->SetAngularVelocity(-angle*20); } } //ゲームクリア画面描画 void GoGameClear(){ g_gamestate = GAME_CLEAR; g_stage.timerstart = g_lasttime; } void DrawGameClear(){ DrawEnemyAndMap(); DrawHero(HERO_STANDING); DrawGraph(-50,160,LoadGraph("gameclear.png"),TRUE); //5秒経ったらタイトル画面へ if(g_lasttime - g_stage.timerstart > 5000) GoGameTitle(); } //ゲームオーバー画面描画 void GoGameOver(){ g_gamestate = GAME_OVER; g_stage.timerstart = g_lasttime; } void DrawGameOver(){ DrawGraph(20,20,LoadGraph("gameover.png"),TRUE); //5秒経ったらタイトル画面へ if(g_lasttime - g_stage.timerstart > 5000) GoGameTitle(); } b2Body* CreateBody(float x,float y,float w,float h,float angle,bool dynamic,int categoryBits,int maskBits ,float density,float restitution,float friction) { //ボディ定義 b2BodyDef bodydef; if(dynamic)bodydef.type=b2_dynamicBody; //動的ボディ else bodydef.type=b2_staticBody; //静的ボディ bodydef.position.Set(x,y); bodydef.angle=angle; //ボディ作成 b2Body* body=g_world.CreateBody(&bodydef); //シェイプ作成 b2PolygonShape staticBox; staticBox.SetAsBox(w,h); //フィクスチャ定義 b2FixtureDef fixturedef; fixturedef.shape=&staticBox; fixturedef.density=density; //密度 fixturedef.restitution=restitution; //反発力 fixturedef.friction=friction; //摩擦係数 fixturedef.filter.categoryBits=categoryBits; fixturedef.filter.maskBits=maskBits; body->CreateFixture(&fixturedef); return body; } //主人公衝突判定 void Collision(){ //接触確認ループ for(b2Contact* c = g_world.GetContactList(); c!=NULL; c = c->GetNext()) { if(c->IsTouching() == false) continue; //接触しているボディを取り出す b2Body* bd[2]; b2Fixture* fx[2]; fx[0]=c->GetFixtureA(); fx[1]=c->GetFixtureB(); bd[0]=fx[0]->GetBody(); bd[1]=fx[1]->GetBody(); //ボディチェック for(int i=0;i<2;i++){ b2Body *obd=bd[(i+1)%2]; Character *ch = (Character *)bd[i]->GetUserData(); Character *och = (Character *)obd->GetUserData(); //接地チェック if( bd[i]==g_stage.hero ) { g_stage.heroontheground = true; if(och->type==ENEMY) { b2Vec2 pos1=g_stage.hero->GetPosition(); b2Vec2 pos=och->body->GetPosition(); float hx=(float)(pos1.x*WLDSC); float hy=(float)(pos1.y*WLDSC); float ex=(float)(pos.x*WLDSC); float ey=(float)(pos.y*WLDSC); if(PHS(hy+40)>=PHS(ey-45)&&PHS(hx+30)>PHS(ex-30)&&PHS(hx-30)<PHS(ex+30)) { DrawRotaGraph(VIWX(pos.x),VIWY(pos.y),1,0,g_images.enemy[4],TRUE); och->damage=10.0f; } if(PHS(hx+30)>=PHS(ex-31)&&PHS(hy)>=PHS(ey-40)) GoGameOver(); } if(obd==g_stage.flagbody) GoGameClear(); } if(ch!=NULL&&och!=NULL){ //モンスター左右方向転換 if(ch->type>=ENEMY){ g_stage.enemyontheground=true; b2Manifold *manifold = c->GetManifold(); if(manifold->type >= b2Manifold::e_faceA){ //進行方向で衝突が起きていたら if( (manifold->localNormal.x < 0.0f && ch->vecx > 0.0f)|| (manifold->localNormal.x > 0.0f && ch->vecx < 0.0f)) ch->vecx =-ch->vecx; } } } } } } //敵を出現させる void EnterEnemy() { for(int i=0;i<MAXENEMYCHARA;i++){ //空きキャラクターを探す //位置を決める float x=(float)GetRand((int)g_stage.mapsize_w); int blank=FindBlankChara(g_stage.enemy,MAXENEMYCHARA); if(blank>=0) { //ボディ作成 ch.body=CreateBody(PHS(x),0,PHS(30),PHS(40),0,true,4,5,4.0f,0.0f,0.1f); ch.used=true; ch.vecx=-PHS(speed); ch.type=ENEMY; ch.damage=0.0f; g_stage.enemy[blank]=ch; ch.body->SetUserData(&g_stage.enemy[blank]); } } } //配列から空きキャラクターを探す int FindBlankChara(Character *arr,int arraymax) { for(int i=0;i<arraymax;i++){ if(arr[i].used==false) return i; } //空きが見つからなかった場合 return -1; }
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: iリブロ
これ完全なコードじゃないですよね。
main関数もないし、LoadFilesの呼び出しもありませんが。
main関数もないし、LoadFilesの呼び出しもありませんが。
Re: iリブロ
さきほど載せたのはいじるようのソースファイルでこれから載せるのが基本的にいじらないソースファイルです。
次に前に乗せたソースファイルのヘッダーファイルを載せます
#include "main.h"
//グローバル変数
//時間計測用関数
int g_lasttime = 0; //直前の計測時刻
float g_frametime = 0; //1フレームにかかった時間
//終了フラグ
bool g_exitflag = FALSE;
//ボタン
bool g_akey_prev; //Aボタンを押したか
bool g_bkey_prev; //Bボタンを押したか
bool g_ckey_prev; //Cボタンを押したか
//デバッグドロー
#ifdef B2D_DEBUG_DRAW
DxDebugDraw g_debugdraw(WLDSC);
#endif
//フォント
int g_middlefont; //中サイズフォントハンドル
//WinMain関数
int WINAPI WinMain(HINSTANCE h1, HINSTANCE hP, LPSTR lpC, int nC){
//フルスクリーン/ウィンドウ切り替え
if (strcmp(lpC, "-f") != 0) ChangeWindowMode(TRUE);
//DXライブラリ初期化
if(DxLib_Init() == -1) return -1;
//フォント初期化
g_middlefont = CreateFontToHandle(
"メイリオ", 42, -1, DX_FONTTYPE_ANTIALIASING);
SetDrawScreen(DX_SCREEN_BACK);
//ファイルの読み込み
if( LoadFiles() == -1) {
MessageBox(NULL, "ファイル読み込み失敗", "DXライブラリ", MB_OK);
return -1;
}
g_lasttime = GetNowCount() & INT_MAX; //現在時刻の記録
while( ProcessMessage() == 0 && g_exitflag==FALSE )
{
//1ループにかかった時間を計測
int curtime = GetNowCount() & INT_MAX;
g_frametime = (float)(curtime - g_lasttime) / 1000.0f;
g_lasttime = curtime;
//フレーム間隔が異常に延びた場合は0.03秒とする
if (g_frametime > 0.03f) g_frametime = 0.03f;
ClsDrawScreen();
MyMain();
ScreenFlip();
}
//DXライブラリの終了処理
DxLib_End();
return 0;
}
//トリガーキーのチェック
bool IsAKeyTrigger(int key){
if( key & PAD_INPUT_A ){
if(g_akey_prev==false){
g_akey_prev = true;
return true;
}
}else{
g_akey_prev=false;
}
return false;
}
bool IsBKeyTrigger(int key){
if( key & PAD_INPUT_B ){
if( g_bkey_prev == false ){
g_bkey_prev = true;
return true;
}
} else {
g_bkey_prev = false;
}
return false;
}
bool IsCKeyTrigger(int key){
if( key & PAD_INPUT_C ){
if( g_ckey_prev == false ){
g_ckey_prev = true;
return true;
}
} else {
g_ckey_prev = false;
}
return false;
}
//全ボディの削除
void DeleteAllBody(){
if(g_world.GetBodyCount()>0){ //ボディ数を調べる
//ボディ削除ループ
b2Body* b = g_world.GetBodyList();
while(b != NULL){
b2Body* nb = b->GetNext();
g_world.DestroyBody(b);
b = nb;
}
}
}
//座標変換
int VIWX(float v){
return (int)(v*WLDSC) - g_stage.screen_x;
}
int VIWY(float v){
return (int)(v*WLDSC) - g_stage.screen_y;
}
float PHS(float v){
return (v)/WLDSC;
}
//画面外判定
bool IsOutScreen(float x, float y){
if( x < PHS(-SCREENAREA) ||
x > PHS(g_stage.mapsize_w+SCREENAREA) ||
y < PHS(-SCREENAREA) ||
y > PHS(g_stage.mapsize_h+SCREENAREA) )
{
return true;
}
return false;
}
#include <DxLib.h>
#include <Box2D/Box2D.h>
//定数
const int VELOCITYITE = 6; //速度計算精度
const int POSITIONITE = 2; //位置計算精度
const float GRAVITY_Y = 10.0f; //重力加速度
const float WLDSC = 50.0f; //世界倍率
const float SCREENAREA = 300.0f;//スクリーン範囲
const int SCROLL_LIMIT=150; //スクロール限界
const float speed=50.0f;
//画像読み込み用構造体
struct Images{
int back[2]; //背景画像
int logo[3]; //ロゴ(タイトル、オーバー、クリア)
int titleback;
int wall[26]; //床壁
int hero[7]; //主人公
int enemy[5]; //敵
};
//音声読み込み用構造体
struct Sounds{
};
//ゲームステート
enum GameState{
GAME_TITLE, GAME_MAIN, GAME_OVER, GAME_CLEAR
};
//キャラクター構造体
struct Character{
b2Body *body; //ボディ
bool used; //使用中フラグ
int type; //種類
int ID; //細かい種類
float vecx,vecy; //敵の移動向
float damage; //衝撃
int size;
};
const int MAXMAPCHARA=1024; //地形の最大数
const int MAXENEMYCHARA=5; //敵の最大数
//ゲームデータ記録用構造体
struct StageInfo{
int timerstart; //待機タイマーの開始時刻
int gamestarttime; //ゲームの開始時間
int gametime; //ゲーム開始からの経過ミリ秒
float mapsize_w, mapsize_h; //マップサイズ
int screen_x, screen_y; //表示原点(スクロール用)
Character wall[MAXMAPCHARA]; //床壁
int num_mapchara; //読み込んだ地形の数
b2Body *hero; //主人公
Character heroo;
bool isheroleft; //主人公の向き
int herotype;
bool heroontheground; //主人公乗っている?
bool enemyontheground; //敵乗っている?
b2Body *flagbody; //旗のボディ
b2Body *groundbody; //どことも接触しない静的ボディ
Character enemy[MAXENEMYCHARA]; //敵
};
//HEROステート(アニメーション表示に使う列挙体)
enum HeroState
{
//立つ,走る,ジャンプ,しゃがむ(ヒップドロップ,つぶれる)
HERO_STANDING,HERO_RUNNING,HERO_JUMP,HERO_SQUAT
};
//壁
enum WallID
{
FALL,WALL_0,WALL_1,MOUNTAIN,WALL_2,WALL_3,WALL_4,WALL_5,WALL_6,WALL_7,
WALL_8,WALL_9,WALL_10,WALL_11,WALL_12,WALL_13,WALL_14,GOAL,
TREE,ROCK,HOUSE,CLOUD,LEAF
};
//関数プロトタイプ宣言
void MyMain();
int LoadFiles();
void initGame();
void DeleteAllBody();
void InitStage();
void GoGameTitle();
void DrawGameTitle();
void GoGameMain();
void DrawGameMain();
void GoGameClear();
void DrawGameClear();
void GoGameOver();
void DrawGameOver();
int LoadMapDate(TCHAR *filepath);
b2Body* CreateBody(float x,float y,float w,float h,float angle,bool dynamic,
int categoryBits,int maskBits,float density,float destitution,float friction);
void CreateDynamicBlock(float x,float y,float w,float h,float angle,int id);
void CreateStaticBlock(float x,float y,float w,float h,float angle,int id);
void CreateHero(float x,float y,float w,float h);
void Collision();
void DrawHero(int hstate);
void DrawEnemyAndMap();
void EnterEnemy();
int FindBlankChara(Character *arr,int arraymax);
//ユーティリティ関数
bool IsAKeyTrigger(int key);
bool IsBKeyTrigger(int key);
bool IsCKeyTrigger(int key);
void DeleteAllBody();
int VIWX(float v);
int VIWY(float v);
float PHS(float v);
bool IsOutScreen(float x, float y);
//グローバル変数のエクスターン宣言
extern int g_lasttime;
extern float g_frametime;
extern bool g_exitflag;
extern b2World g_world;
#ifdef B2D_DEBUG_DRAW
extern DxDebugDraw g_debugdraw;
#endif
extern int g_middlefont;
extern StageInfo g_stage;
enum MapCharatype{
WALL,ENEMY,HERO,HATENA_BOX
};
最後に編集したユーザー ながもん on 2013年1月14日(月) 14:32 [ 編集 1 回目 ]
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: iリブロ
この書き方
DrawGraph(-50,160,LoadGraph("gameclear.png"),TRUE);
DrawGraph(20,20,LoadGraph("gameover.png"),TRUE);
では、画像ハンドルの解放ができないのとメモリに累積するので全部止めないとマズイです。gameclearは直していないのでしょうか?
LoadとDrawは分けるのと、Loadした画像ハンドルは解放タイミングを厳密に管理してください。
それとGoGameOverで読み込んでいるそうですが、ゲームオーバーのたびに読み込んではダメですよ。
DrawGraph(-50,160,LoadGraph("gameclear.png"),TRUE);
DrawGraph(20,20,LoadGraph("gameover.png"),TRUE);
では、画像ハンドルの解放ができないのとメモリに累積するので全部止めないとマズイです。gameclearは直していないのでしょうか?
LoadとDrawは分けるのと、Loadした画像ハンドルは解放タイミングを厳密に管理してください。
それとGoGameOverで読み込んでいるそうですが、ゲームオーバーのたびに読み込んではダメですよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: iリブロ
_CrtSetDbgFlagでフラグをセットしました?ながもん さんが書きました:#ifdef _DEBUG
#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
#endif
↑これは意味ありませんでした
それでもCRT以外で確保されたものは報告されないので本件の役には立たないかもですけど。
DXライブラリにDxLib_End時に自動解放した内容を報告してくれる機能ってなかったでしたっけ。
Re: iリブロ
GetGraphNumで有効なグラフィックハンドルの数は分かりますね。ISLe さんが書きました: DXライブラリにDxLib_End時に自動解放した内容を報告してくれる機能ってなかったでしたっけ。