Mercurial > hg > Game > Cerium
view Renderer/Test/collision_effect.cc @ 1479:163220e54cc0 draft
remove hard code for TaskLog
author | Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 24 Jul 2012 17:15:15 +0900 |
parents | 5f12d99e95ac |
children |
line wrap: on
line source
#include <math.h> #include <stdlib.h> #include "SceneGraphRoot.h" #include "MainLoop.h" #include "collision_effect.h" // prototype static void ball_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h); static void ball_collision(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h, SceneGraphPtr tree); static void jump_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h); static void fall_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h); static void effect_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h); static const float ball_radius = 88.0f; static const float target_radius = 88.0f; static int targetID;//targetのオブジェクトのIDを保存 /* * 変数stat でボールの状態を表す。 * 0:地上 * 1:ジャンプ * 2:左方向へジャンプ * 3:右方向へジャンプ */ static int stat; static void ball_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h) { SceneGraphRoot *sgroot = (SceneGraphRoot *)sgroot_; Pad *pad = sgroot->getController(); const float player_speed = 24.0f; if ( pad->up.isPush() || pad->up.isHold()) { if ( pad->left.isPush() || pad->left.isHold() ){ stat = 2; }else if ( pad->right.isPush() || pad->right.isHold() ){ stat = 3; } node->set_move_collision(jump_move,ball_collision); } if ( pad->left.isPush() || pad->left.isHold() ) { node->xyz[0] -= player_speed; }else if ( pad->right.isPush() || pad->right.isHold() ) { node->xyz[0] += player_speed; }else if ( pad->down.isPush() || pad->down.isHold() ) { // node->xyz[1] += player_speed; } } static void jump_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h) { float vy = 0.0f; const float g = 9.8f; const float player_speed = 30.0f; float dt = 2.0f;//frame rate if ( stat == 2 ){ node->xyz[0] -= player_speed; }else if ( stat == 3 ){ node->xyz[0] += player_speed; } vy += g * dt; node->xyz[1] -= vy * dt; if ( node->xyz[1] < 0 ){ node->set_move_collision(fall_move,ball_collision); } } static void fall_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h) { float vy = 0.0f; const float g = -9.8f; const float dt = 2.0f;//frame rate const float player_speed = 30.0f; if ( stat == 2 ){ node->xyz[0] -= player_speed; }else if ( stat == 3 ){ node->xyz[0] += player_speed; } vy += g * dt; node->xyz[1] -= vy * dt; if (node->xyz[1] >= screen_h/2){ node->xyz[1] = screen_h/2; node->set_move_collision(ball_move,ball_collision); } } static void effect_move(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h) { node->remove(); } static void ball_collision(SceneGraphPtr node, void *sgroot_, int screen_w, int screen_h, SceneGraphPtr tree) { SceneGraphRoot *sgroot = (SceneGraphRoot *)sgroot_; SceneGraphIteratorPtr it = sgroot->getIterator(tree); float x_distance,y_distance,distance; float target_speed = 48.0f; //IDが"target"のSceneGraphまですすめる it->next(targetID); //targetのシーングラフを取得 SceneGraphPtr target = it->get(); x_distance = node->xyz[0] - target->xyz[0]; y_distance = node->xyz[1] - target->xyz[1]; //二点間の距離を求める distance = hypotf(x_distance,y_distance); //二点間の距離が2つの半径の合計以下なら、衝突 if(distance <= (ball_radius + target_radius)){ /* * 交点でエフェクト発生 * 接点の座標を(x,y)としたとき、 * (x - target->xyz[0]) : (x_distance) = target_radius : distance * (x - target->xyz[0]) = (target_radius / distance)*(x_distance) * 同様に、 * (y - target->xyz[1]) = (target_radius / distance)*(y_distance) */ float rate = target_radius / distance; float x = rate * x_distance + target->xyz[0]; float y = rate * y_distance + target->xyz[1]; SceneGraphPtr effect = sgroot->createSceneGraph("BLAST3"); effect->set_move_collision(effect_move); node->addBrother(effect); //点(x,y)にエフェクト effect->xyz[0] = x; effect->xyz[1] = y; effect->xyz[3] = -30.0f; if (node->xyz[1] > target->xyz[1]){ //上からぶつかられた場合はのけぞりを大きく target_speed += ball_radius; } if ( node->xyz[0] > target->xyz[0] ){ //右からぶつかられた場合 target->xyz[0] -= target_speed; } else{ //左からぶつかられた場合 target->xyz[0] += target_speed; } } } MainLoopPtr collision_effect::init(Viewer *sgroot, int screen_w, int screen_h) { sgroot->OnLightSysSwitch(); //ライト設置 SceneGraphPtr light = sgroot->getLight(0); sgroot->OnLightSwitch(0); light->xyz[0] = screen_w / 2; light->xyz[1] = screen_h / 2; light->xyz[2] = -100; SceneGraphPtr root = sgroot->createSceneGraph(); //effectのシーングラフ作成 sgroot->createFromXMLfile("xml_file/blast.xml"); //ボールのシーングラフ作成 SceneGraphPtr ball; sgroot->createFromXMLfile("xml_file/ball.xml"); ball = sgroot->createSceneGraph("Ball"); // ball_moveは最初、絶対地上にいるのでstatを0(地上判定)に更新 stat = 0; //初期化 ball->xyz[0] = screen_w; ball->xyz[1] = screen_h/2; ball->xyz[2] = 60.0f; //rootの子に追加 root->addChild(ball); //targetのシーングラフ作成 SceneGraphPtr target = sgroot->createSceneGraph("Ball"); //IDの登録 targetID = target->sgid; target->xyz[0] = screen_w/2; target->xyz[1] = screen_h/2; target->xyz[2] = 60.f; //ボールの動きと当たり判定をセット ball->set_move_collision(ball_move, ball_collision); root->addChild(target); sgroot->setSceneData(root); return sgroot; } extern Application * application() { return new collision_effect(); } const char *usr_help_str = "Usage: ./test_nogl [OPTION]\n"; extern int init(TaskManager *manager, int argc, char *argv[]); extern void task_initialize(); static void TMend(TaskManager *manager); int TMmain(TaskManager *manager, int argc, char *argv[]) { task_initialize(); manager->set_TMend(TMend); return init(manager, argc, argv); } void TMend(TaskManager *manager) { printf("test_nogl end\n"); } /* end */