这是一款2D横版摩托特技游戏。代码结构和传统写法有些差异,但是效果还算不错。

传统的写法可能会使用box2d引擎,或者至少模拟出一个简单的物理模型,这里代码有点另类,甚至连速度变量都没有,竟然也能做出个赛车游戏

代码重构一下,可以改出一个小型2D骨骼动画引擎和2D物理引擎。

碰撞部分参见截图,调试绘制了两条线,绿色线条比红色线条扩张了一个车轮半径,用于辅助碰撞检测。

人物动画简单的模拟了一个布娃娃系统。骨骼模拟类似简单的弹簧质点约束加关节旋转角度限制。

通过调整头部骨骼的位置按正弦波起伏,带动上身运动,模拟了车手的颠簸动画。

赛道是用小块纹理拼接出来的,适合编写随机生成算法。

自动驾驶算法准备用人工智能的方法写一个,写好了再贴出来。这个游戏用来做人工智能测试还是不错的。

代码风格有点像actionscript,因为有一个类似的flash版本。

具体实现细节详见源码。

源码:

//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/RacingMotor/RacingMotorPlayer.h
//  @Brief:     RacingCar
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================#ifndef  __RacingMotorPlayer__H__
#define  __RacingMotorPlayer__H__#include "Rpg/MiniGame.h"
#include "AI/Entity/LogicCharacter.h"class Skeleton2D
{
public:int  boneNum;vec2 bonePos[6];
};#define var doubleclass Movie2D
{
public:Movie2D();void gotoAndStop(int frame);void Render();     public:var _x;var _y;var _xscale;var _yscale;var _rotation;var _alpha;bool _visible;vec2 pivot;TexturePtr texture;
};
class RoadSegment
{
public:vec2 p1; vec2 p2; vec2 leftDir; var  data;
};
class Contact
{
public:vec2       point;vec2       normal;//float      depth;var        data;
};
//
enum BikePos
{BikeBody = 0,WheelB,WheelF,
};//也可以使用2D骨骼动画引擎
//也可以使用物理引擎实现 特技状态动画控制(融合切换),死亡状态布娃娃控制。
class RacingMotorPlayer: public LogicCharacter,public MiniPlayer
{
public:RacingMotorPlayer();virtual ~RacingMotorPlayer();virtual bool Start();//virtual bool Restart();virtual bool Stop();virtual void Update();virtual void Render();void UpdateCommon();enum{stateRacing   = 0,stateFalling ,stateGameover ,//到达终点或结束后 播放一段动画};int m_gameState;var m_score;var m_gameTime;var m_resetScore;var m_stateTime;var const19;vec2 startPos;var const36;var const39;var length1__;var length2__;var const0p05;var const0p075;var const0p1;var const0p3;vec2 m_bikePos[5];vec2 m_bikePos2[5];bool m_wheelBCollide;vec2 m_wheelBCollideNormal;vec2 m_wheelBSpeed;var  m_wheelBRotSpeed;bool m_wheelFCollide;vec2 m_wheelFCollideNormal;vec2 m_wheelFSpeed;var  m_wheelFRotSpeed;vec2 m_massPos;var  m_arriveX;bool m_bDead;bool m_bSkill;bool m_bJumping;var  m_jumpingRot;var  m_lastBikeBodyRot;var scale_man;var oriLenHead;var oriLenTorso;var oriLenArm;var oriLenForeArm;var oriLenThigh;var oriLenShin;var oriLenJian; //大臂偏移Movie2D m_wheelMovieB;Movie2D m_wheelMovieF;Movie2D m_bikeBackShaftMovie;Movie2D m_bikeFrontShockTipMovie;Movie2D m_bikeFrontShockBaseMovie;Movie2D m_bikeFrontShockShaftMovie;Movie2D m_bikeBodyMovie;Movie2D m_manShinMovie1;//胫部Movie2D m_manThighMovie1;Movie2D m_manArmMovie1;Movie2D m_manForearmMovie1;Movie2D m_manShinMovie2;Movie2D m_manThighMovie2;Movie2D m_manArmMovie2;Movie2D m_manForearmMovie2;Movie2D m_manHeadMovie;Movie2D m_manTorsoMovie;//躯干enum{boneHead , //0boneTorso, //1boneThigh = 2,boneShin  = 7,};
#define  bonePosNum 11vec2 m_bonePos [bonePosNum];vec2 m_bonePos2[bonePosNum];//关节限制  [bone a b c minang maxang]var BoneJoints[5][5];int BoneJointsNum;Skeleton2D  m_mixAnim;Skeleton2D* m_curAnim;var  m_headShake;int     curTrick;var     trickTime;var     trickX;var     trickContinueNum;int     TrickScoreMax;int     TrickScoreNum;bool    TrickScoreFlags[5];Movie2D m_trickScoreMovie[5];bool    m_trickScoreVisible[5];class Dirt{public:Movie2D movie;vec2    dirtSpeed;int     dirtLife;};int   DirtNum;Dirt  m_dirts[32];var   SpawnDirtRegulor;void InitBikeMovie();void FreeBike();void ResetBike();void UpdateBikeMovie();void UpdateBikePos();void UpdateBikeJoints();void Fnc15();void UpdateWheel();void Fnc20();void CheckJumpingRot();void InitBonePos();void UpdateManMovie();void UpdateBoneJoints();void UpdateBoneAngs();void UpdateBonePos();void HeadShake();void Fnc38(int boneA, int boneB);void CheckDead();void UpdateAnim();void SetNormalAnim();void AnimN();void AnimL();void AnimR();void AnimZ();void AnimX();void AnimC();void AnimV();void AnimB();bool IsAnimEnd(Skeleton2D& a);void InitTrickScore();void UpdateTrickScore();void SpawnTrickScore(int score, int frame);void FlagTrickScore();void CheckSpawnTrickScore(int i);void InitDirt();void SpawnDirt(const vec2& pos, const vec2& speed);void UpdateDirt();
};class RacingMotorPlayerRobot: public RacingMotorPlayer
{
public:RacingMotorPlayerRobot();virtual ~RacingMotorPlayerRobot();//virtual bool Start();virtual void Update();void SetWorkingWithAI(bool working);void UpdateInput();bool   m_workingWithAI;double m_thinkTime;
};class RacingMotorPlayerRole: public RacingMotorPlayerRobot
{
public:RacingMotorPlayerRole();virtual ~RacingMotorPlayerRole();//virtual bool Start();virtual void Update();virtual void Render();void UpdateInput();
};
#endif//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/RacingMotor/RacingMotorPlayer.cpp
//  @Brief:     RacingCar
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================#include "General/Pch.h"
#include "General/Window.h"
#include "RacingMotor/RacingMotorPlayer.h"
#include "RacingMotor/MiniGameRacingMotor.h"
#include "General/Timer.h"
#include "Rpg/SyncGameInfo.h"
#include "Sound/SoundManager.h"
#include "Packet/PacketMiniGame.h"
#include "Render/RendDriver.h"
#include "Render/MC_MovieClip.h"
#include "Input/InputMgr.h"
#include "General/Pce.h"
Movie2D::Movie2D()
{_x = 0;_y = 0;_xscale = 1;_yscale = 1;_rotation= 0;_visible= 1;_alpha= 1;
}
void Movie2D::Render()
{if (_visible==false){return;}G_RendDriver->Color4f(1,1,1,1);G_RendDriver->SetRenderStateEnable(RS_BLEND,true);G_RendDriver->BlendFunc(Blend_Filter);//G_ShaderMgr->PushShader();G_RendDriver->SetRenderStateEnable(RS_TEXTURE_2D,true);if (texture){texture->Bind();vec2 tex[4] = {vec2(0,0),vec2(0,1),vec2(1,1),vec2(1,0),};vec3 pos[4];pos[0] = vec3(-pivot.x,-pivot.y,0);pos[1] = vec3(-pivot.x,texture->GetHeight()-pivot.y,0);pos[2] = vec3(texture->GetWidth()-pivot.x,texture->GetHeight()-pivot.y,0);     pos[3] = vec3(texture->GetWidth()-pivot.x,-pivot.y,0);mat4 mat;mat.FromRotateZ(_rotation*DEG2RAD);mat.SetTranslate(vec3(_x,_y,0));pos[0] = mat*pos[0];pos[1] = mat*pos[1];pos[2] = mat*pos[2];       pos[3] = mat*pos[3];G_RendDriver->RendBegin(RS_QUADS);for (int i=0;i<4;i++){G_RendDriver->TexCoord2f(tex[i].x,tex[i].y);G_RendDriver->Vertex3fv(&pos[i].x);}G_RendDriver->RendEnd();}
}void Movie2D::gotoAndStop(int frame)
{
}RacingMotorPlayer::RacingMotorPlayer()
{
}
RacingMotorPlayer::~RacingMotorPlayer()
{
}bool RacingMotorPlayer::Start()
{MiniPlayer::Start();m_gameState = stateFalling;m_score = 0;m_gameTime = 0;m_resetScore = 0;m_liveNum = 100;m_stateTime = 0;const19 = 18;startPos = vec2(224, 2752);const19 = 19.2f;const36 = 30 * 1.2f;const39 = 33 * 1.2f;length1__ = 0;length2__ = 0;const0p05 = 0.05f;const0p075 = 0.075f;m_wheelBCollide = false;m_wheelBRotSpeed = 0;m_wheelFCollide = false;m_wheelFRotSpeed = 0;m_bJumping = false;m_lastBikeBodyRot = 0;m_jumpingRot = 0;m_arriveX = 0;scale_man = 0.96f;oriLenHead = 18 * scale_man;oriLenTorso = 34 * scale_man;oriLenArm = 20 * scale_man;oriLenForeArm = 19 * scale_man;oriLenThigh = 25 * scale_man;oriLenShin = 21 * scale_man;oriLenJian = 6 * scale_man; //肩宽m_bDead = false;m_bSkill = false;//关节限制  [bone a b c minang maxang]var BoneJointsData[5][5] = {{2, 1, 0, -0.1745329f, 0.1745329f}, {2, 7, 9, 0, 2.268928f}, {1, 2, 7, -2.356194f, 0.3490659f}, {2, 8, 10, 0, 2.268928f}, {1, 2, 8, -2.356194f, 0.3490659f}};for (int y=0;y<5;++y){for (int x=0;x<5;++x){BoneJoints[y][x] = BoneJointsData[y][x];}}BoneJointsNum = 5;curTrick = 0;trickTime = 0;trickX = 0;trickContinueNum = 0;TrickScoreMax = 5;TrickScoreNum = 3;m_mixAnim.boneNum  = 6;m_curAnim = NULL;m_headShake = 0;const0p1 = 0.1f;const0p3 = 0.3f;DirtNum = 32;SpawnDirtRegulor = 0;FreeBike();InitBikeMovie();InitDirt();InitTrickScore();return true;
}bool RacingMotorPlayer::Stop()
{return true;
}void RacingMotorPlayer::Update()
{MiniPlayer::Update();//UpdateCommon();
}void RacingMotorPlayer::UpdateCommon()
{UpdateBikePos();for (int i=0;i<2;i++){UpdateBikeJoints();Fnc15();}UpdateWheel();Fnc20();CheckJumpingRot();UpdateAnim();UpdateBonePos();for (int i=0;i<2;i++){UpdateBoneAngs();UpdateBoneJoints();CheckDead();}UpdateManMovie();UpdateBikeMovie();UpdateDirt();UpdateTrickScore();switch (m_gameState){case stateRacing:{} break;case stateGameover:{//2s 后退出游戏if(m_stateTime>2){G_RacingMotorGame->SetGameState(MS_End);}} break;case stateFalling:{if (m_bikePos[BikeBody].y > G_RacingMotorGame->mapExtend.x)//掉出边界 时间缩短{m_stateTime = max(m_stateTime, 1.5f);} if(m_stateTime>2){ResetBike();m_stateTime = 0;m_gameTime = 15000;m_score = m_resetScore;m_gameState = stateRacing;}} break;}if (m_gameState != stateGameover){m_gameTime = max(0, m_gameTime - 2);} m_stateTime += G_Timer->GetStepTimeLimited();
}void RacingMotorPlayer::Render()
{//LogicCharacter::Render();for (int i = 0; i < TrickScoreNum; ++i){m_trickScoreMovie[i].Render();} m_manShinMovie1.Render();m_manThighMovie1.Render();m_manArmMovie1.Render();m_manForearmMovie1.Render();m_wheelMovieB.Render();m_wheelMovieF.Render();m_bikeBackShaftMovie.Render();m_bikeFrontShockTipMovie.Render();m_bikeFrontShockBaseMovie.Render();m_bikeFrontShockShaftMovie.Render();m_bikeBodyMovie.Render();m_manShinMovie2.Render();m_manThighMovie2.Render();m_manTorsoMovie.Render();m_manHeadMovie.Render();m_manArmMovie2.Render();m_manForearmMovie2.Render();for (int i = 0; i < DirtNum; ++i){m_dirts[i].movie.Render();}G_RendDriver->DisableRendState(RS_TEXTURE_2D);G_RendDriver->DisableRendState(RS_LIGHTING);G_RendDriver->SetLineWidth(1);G_RendDriver->Color3f(0, 0, 1);   G_RendDriver->RendBegin(RS_POINTS);G_RendDriver->Vertex3f(m_massPos.x,m_massPos.y,0);G_RendDriver->RendEnd();G_RendDriver->EnableRendState(RS_LIGHTING);
}void RacingMotorPlayer::UpdateDirt()
{//CheckSpawnDirtif (m_wheelBCollide == true){var speed = m_wheelBRotSpeed;Clamp(speed, -10,10);if (abs(speed) > 5){vec2 pos = m_bikePos[WheelB] - m_wheelBCollideNormal * const19;var rot = RandRange(-55.0f,-10.0f) * DEG2RAD;var cosR = cos(rot);var sinR = sin(rot);var speedX = m_wheelBCollideNormal[0] * cosR - m_wheelBCollideNormal[1] * sinR;var speedY = m_wheelBCollideNormal[0] * sinR + m_wheelBCollideNormal[1] * cosR;speed = speed * 0.35;speedX = speedX * speed;speedY = speedY * abs(speed);SpawnDirt(pos, vec2(speedX, speedY));} }//UpdateDirtfor (int i = 0; i < DirtNum; ++i){Dirt& dirt = m_dirts[i];if (dirt.dirtLife != 0){Movie2D& movie = dirt.movie;--dirt.dirtLife;if (dirt.dirtLife == 0){movie._visible = false;}else{if (dirt.dirtLife < 10){movie._alpha = 10 * dirt.dirtLife;} movie._x += dirt.dirtSpeed.x;movie._y += dirt.dirtSpeed.y;dirt.dirtSpeed.y += 0.15f;} } }
}void RacingMotorPlayer::SpawnDirt(const vec2& pos, const vec2& speed)
{if (SpawnDirtRegulor != 0){--SpawnDirtRegulor;return;} SpawnDirtRegulor = ceil(RandRange(0.0f,1.0f) * 5) + 2;for (int i = 0; i < DirtNum; ++i){Dirt& dirt = m_dirts[i];if (dirt.dirtLife == 0){dirt.dirtLife = 50;Movie2D& movie = dirt.movie;movie._x = pos.x;movie._y = pos.y;//         dirt.gotoAndStop(floor(RandRange(0.0f,1.0f) * 8) + 1);movie._alpha = 100;var scale = 50 + RandRange(0.0f,1.0f) * 50;movie._xscale = scale;movie._yscale = scale;movie._visible = true;dirt.dirtSpeed = speed;return;} }
}void RacingMotorPlayer::InitDirt()
{for (int i = 0; i < DirtNum; ++i){Dirt& dirt = m_dirts[i];Movie2D& movie = dirt.movie;G_TextureMgr->AddTexture(movie.texture,"data/minigame/racingmotor/dirt.png");movie.pivot = vec2(3,4);movie._visible = false;dirt.dirtLife = 0;}
}void RacingMotorPlayer::UpdateAnim()
{Skeleton2D& backAnim  = G_RacingMotorGame->backAnim;Skeleton2D& normalAnim  = G_RacingMotorGame->normalAnim;Skeleton2D& frontAnim = G_RacingMotorGame->frontAnim;Skeleton2D& skillZAnim = G_RacingMotorGame->skillZAnim;Skeleton2D& skillXAnim = G_RacingMotorGame->skillXAnim;Skeleton2D& skillCAnim = G_RacingMotorGame->skillCAnim;Skeleton2D& skillVAnim = G_RacingMotorGame->skillVAnim;Skeleton2D& skillBAnim = G_RacingMotorGame->skillBAnim;m_bSkill = false;if (m_bDead==false){if (m_wheelBCollide == true || m_wheelFCollide == true){FlagTrickScore();} if (m_curAnim == &skillZAnim){m_bSkill = true;CheckSpawnTrickScore(0);AnimZ();} else if (m_curAnim == &skillXAnim){m_bSkill = true;CheckSpawnTrickScore(1);AnimX();} else if (m_curAnim == &skillCAnim){m_bSkill = true;CheckSpawnTrickScore(2);AnimC();} else if (m_curAnim == &skillVAnim){m_bSkill = true;CheckSpawnTrickScore(3);AnimV();} else if (m_curAnim == &skillBAnim){m_bSkill = true;CheckSpawnTrickScore(4);AnimB();} else if (m_curAnim == &backAnim){AnimL();} else if (m_curAnim == &frontAnim){AnimR();} else if (m_curAnim == &normalAnim){AnimN();} }
}void RacingMotorPlayer::SetNormalAnim()
{Skeleton2D& normalAnim = G_RacingMotorGame->normalAnim;for (int i = 0; i < 6; ++i){m_mixAnim.bonePos[i] = normalAnim.bonePos[i];}m_curAnim = &normalAnim;
}
bool RacingMotorPlayer::IsAnimEnd(Skeleton2D& a)
{var limitSq = 100;vec2 dif;for (int i=0;i<m_mixAnim.boneNum;i++){dif = m_mixAnim.bonePos[i] - a.bonePos[i];if (dif.LengthSq() > limitSq){return false;} }return true;
}void RacingMotorPlayer::AnimB()
{Skeleton2D& skillBAnim = G_RacingMotorGame->skillBAnim;var lerp = 0.075f;var rot = m_bikeBodyMovie._rotation * DEG2RAD;const var cosR = cos(rot);const var sinR = sin(rot);mat2 mat;mat.FromRotate(rot);vec2 newPos;m_mixAnim.bonePos[0] += (skillBAnim.bonePos[0] - m_mixAnim.bonePos[0]) * lerp;newPos = mat * m_mixAnim.bonePos[0];m_bonePos[0] = m_bikePos[BikeBody] + newPos;m_mixAnim.bonePos[1] += (skillBAnim.bonePos[1] - m_mixAnim.bonePos[1]) * lerp;newPos = mat * m_mixAnim.bonePos[1];m_bonePos[2] = m_bikePos[BikeBody] + newPos;m_mixAnim.bonePos[2] += (skillBAnim.bonePos[2] - m_mixAnim.bonePos[2]) * const0p1;newPos = mat * m_mixAnim.bonePos[2];m_bonePos[5] = m_bikePos[BikeBody] + newPos;m_mixAnim.bonePos[3] += (skillBAnim.bonePos[3] - m_mixAnim.bonePos[3]) * const0p1;newPos = mat * m_mixAnim.bonePos[3];m_bonePos[6] = m_bikePos[BikeBody] + newPos - vec2(2,2);Fnc38(7, 9);Fnc38(8, 10);m_mixAnim.bonePos[4] += (skillBAnim.bonePos[4] - m_mixAnim.bonePos[4]) * const0p1;newPos = mat * m_mixAnim.bonePos[4];m_bonePos[9] = m_bikePos[BikeBody] + newPos;m_mixAnim.bonePos[5] += (skillBAnim.bonePos[5] - m_mixAnim.bonePos[5]) * const0p1;newPos = mat * m_mixAnim.bonePos[5];m_bonePos[10] = m_bikePos[BikeBody] + newPos;
}void RacingMotorPlayer::AnimV()
{Skeleton2D& skillVAnim = G_RacingMotorGame->skillVAnim;var lerp = 0.075f;var rot = m_bikeBodyMovie._rotation * DEG2RAD;const var cosR = cos(rot);const var sinR = sin(rot);mat2 mat;mat.FromRotate(rot);vec2 newPos;m_mixAnim.bonePos[0] += (skillVAnim.bonePos[0] - m_mixAnim.bonePos[0]) * lerp;newPos = mat * m_mixAnim.bonePos[0];m_bonePos[0] = m_bikePos[BikeBody] + newPos;m_mixAnim.bonePos[1] += (skillVAnim.bonePos[1] - m_mixAnim.bonePos[1]) * lerp;newPos = mat * m_mixAnim.bonePos[1];m_bonePos[2] = m_bikePos[BikeBody] + newPos;var _loc6 = -sinR - cosR;var _loc7 = cosR - sinR;m_bonePos[3].x += _loc6;m_bonePos[3].y += _loc7;m_bonePos[4].x += _loc6;m_bonePos[4].y += _loc7;m_mixAnim.bonePos[2] += (skillVAnim.bonePos[2] - m_mixAnim.bonePos[2]) * const0p1;newPos = mat * m_mixAnim.bonePos[2];m_bonePos[5] = m_bikePos[BikeBody] + newPos;m_mixAnim.bonePos[3] += (skillVAnim.bonePos[3] - m_mixAnim.bonePos[3]) * const0p1;newPos = mat * m_mixAnim.bonePos[3];m_bonePos[6] = m_bikePos[BikeBody] + newPos - vec2(2,2);Fnc38(7, 9);Fnc38(8, 10);m_mixAnim.bonePos[4] += (skillVAnim.bonePos[4] - m_mixAnim.bonePos[4]) * const0p3;newPos = mat * m_mixAnim.bonePos[4];m_bonePos[9] = m_bikePos[BikeBody] + newPos;m_mixAnim.bonePos[5] += (skillVAnim.bonePos[5] - m_mixAnim.bonePos[5]) * const0p3;newPos = mat * m_mixAnim.bonePos[5];m_bonePos[10] = m_bikePos[BikeBody] + newPos;
}void RacingMotorPlayer::AnimC()
{Skeleton2D& skillCAnim = G_RacingMotorGame->skillCAnim;var lerp = 0.075f;var rot = m_bikeBodyMovie._rotation * DEG2RAD;const var cosR = cos(rot);const var sinR = sin(rot);mat2 mat;mat.FromRotate(rot);vec2 newPos;m_mixAnim.bonePos[0] += (skillCAnim.bonePos[0] - m_mixAnim.bonePos[0]) * lerp;newPos = mat * m_mixAnim.bonePos[0];m_bonePos[0] = m_bikePos[BikeBody] + newPos;m_mixAnim.bonePos[1] += (skillCAnim.bonePos[1] - m_mixAnim.bonePos[1]) * lerp;newPos = mat * m_mixAnim.bonePos[1];m_bonePos[2] = m_bikePos[BikeBody] + newPos;var _loc6 = sinR;var _loc7 = -cosR;m_bonePos[3].x += _loc6;m_bonePos[3].y += _loc7;m_bonePos[4].x += _loc6;m_bonePos[4].y += _loc7;m_mixAnim.bonePos[2] += (skillCAnim.bonePos[2] - m_mixAnim.bonePos[2]) * const0p1;newPos = mat * m_mixAnim.bonePos[2];m_bonePos[5] = m_bikePos[BikeBody] + newPos;m_mixAnim.bonePos[3] += (skillCAnim.bonePos[3] - m_mixAnim.bonePos[3]) * const0p1;newPos = mat * m_mixAnim.bonePos[3];m_bonePos[6] = m_bikePos[BikeBody] + newPos - vec2(2,2);Fnc38(7, 9);Fnc38(8, 10);m_mixAnim.bonePos[4] += (skillCAnim.bonePos[4] - m_mixAnim.bonePos[4]) * lerp;newPos = mat * m_mixAnim.bonePos[4];m_bonePos[9] = m_bikePos[BikeBody] + newPos;m_mixAnim.bonePos[5] += (skillCAnim.bonePos[5] - m_mixAnim.bonePos[5]) * lerp;newPos = mat * m_mixAnim.bonePos[5];m_bonePos[10] = m_bikePos[BikeBody] + newPos;
}void RacingMotorPlayer::AnimX()
{Skeleton2D& skillXAnim = G_RacingMotorGame->skillXAnim;var lerp = 0.075f;var rot = m_bikeBodyMovie._rotation * DEG2RAD;const var cosR = cos(rot);const var sinR = sin(rot);mat2 mat;mat.FromRotate(rot);vec2 newPos;vec2 newPos2  = (m_bikePos[WheelF] - m_bikePos2[WheelF])*-3;for (int i = 0; i < 6; ++i){m_mixAnim.bonePos[i] += (skillXAnim.bonePos[i] - m_mixAnim.bonePos[i]) * 0.075f;}newPos = mat * m_mixAnim.bonePos[0];m_bonePos[0] = m_bikePos[BikeBody] + newPos + newPos2;newPos = mat * m_mixAnim.bonePos[1];m_bonePos[2] = m_bikePos[BikeBody] + newPos + newPos2;newPos.x = -cosR;newPos.y = -sinR;m_bonePos[3] += newPos;m_bonePos[4] += newPos;newPos = mat * m_mixAnim.bonePos[2];m_bonePos[5] = m_bikePos[BikeBody] + newPos;newPos = mat * m_mixAnim.bonePos[3];m_bonePos[6] = m_bikePos[BikeBody] + newPos - vec2(2,2);Fnc38(7, 9);Fnc38(8, 10);newPos = mat * m_mixAnim.bonePos[4];m_bonePos[9] = m_bikePos[BikeBody] + newPos;newPos = mat * m_mixAnim.bonePos[5];m_bonePos[10] = m_bikePos[BikeBody] + newPos;
}void RacingMotorPlayer::AnimZ()
{Skeleton2D& skillZAnim = G_RacingMotorGame->skillZAnim;var lerp = 0.075f;var rot = m_bikeBodyMovie._rotation * DEG2RAD;const var cosR = cos(rot);const var sinR = sin(rot);mat2 mat;mat.FromRotate(rot);vec2 newPos;vec2 newPos2 ;// = (m_bikePos[WheelF] - m_bikePos2[WheelF])*-3;for (int i = 0; i < 6; ++i){m_mixAnim.bonePos[i] += (skillZAnim.bonePos[i] - m_mixAnim.bonePos[i]) * 0.075f;}newPos = mat * m_mixAnim.bonePos[0];m_bonePos[0] = m_bikePos[BikeBody] + newPos + newPos2;newPos = mat * m_mixAnim.bonePos[1];m_bonePos[2] = m_bikePos[BikeBody] + newPos + newPos2;newPos.x = -cosR;newPos.y = -sinR;m_bonePos[3] += newPos;m_bonePos[4] += newPos;newPos = mat * m_mixAnim.bonePos[2];m_bonePos[5] = m_bikePos[BikeBody] + newPos;newPos = mat * m_mixAnim.bonePos[3];m_bonePos[6] = m_bikePos[BikeBody] + newPos - vec2(2,2);Fnc38(7, 9);Fnc38(8, 10);newPos = mat * m_mixAnim.bonePos[4];m_bonePos[9] = m_bikePos[BikeBody] + newPos;newPos = mat * m_mixAnim.bonePos[5];m_bonePos[10] = m_bikePos[BikeBody] + newPos;
}void RacingMotorPlayer::AnimR()
{Skeleton2D& frontAnim = G_RacingMotorGame->frontAnim;var lerp = 0.075f;var rot = m_bikeBodyMovie._rotation * DEG2RAD;const var cosR = cos(rot);const var sinR = sin(rot);mat2 mat;mat.FromRotate(rot);vec2 newPos;for (int i = 0; i < 6; ++i){m_mixAnim.bonePos[i] += (frontAnim.bonePos[i] - m_mixAnim.bonePos[i]) * 0.075f;}newPos = mat * m_mixAnim.bonePos[0];m_bonePos[0] = m_bikePos[BikeBody] + newPos;newPos = mat * m_mixAnim.bonePos[1];m_bonePos[2] = m_bikePos[BikeBody] + newPos;newPos.x = -cosR;newPos.y = -sinR;m_bonePos[3] += newPos;m_bonePos[4] += newPos;newPos = mat * m_mixAnim.bonePos[2];m_bonePos[5] = m_bikePos[BikeBody] + newPos;newPos = mat * m_mixAnim.bonePos[3];m_bonePos[6] = m_bikePos[BikeBody] + newPos - vec2(2,2);Fnc38(7, 9);Fnc38(8, 10);newPos = mat * m_mixAnim.bonePos[4];m_bonePos[9] = m_bikePos[BikeBody] + newPos;newPos = mat * m_mixAnim.bonePos[5];m_bonePos[10] = m_bikePos[BikeBody] + newPos;HeadShake();
}void RacingMotorPlayer::AnimL()
{Skeleton2D& backAnim = G_RacingMotorGame->backAnim;var lerp = 0.075f;var rot = m_bikeBodyMovie._rotation * DEG2RAD;const var cosR = cos(rot);const var sinR = sin(rot);mat2 mat;mat.FromRotate(rot);vec2 newPos;for (int i = 0; i < 6; ++i){m_mixAnim.bonePos[i] += (backAnim.bonePos[i] - m_mixAnim.bonePos[i]) * 0.075f;}newPos = mat * m_mixAnim.bonePos[0];m_bonePos[0] = m_bikePos[BikeBody] + newPos;newPos = mat * m_mixAnim.bonePos[1];m_bonePos[2] = m_bikePos[BikeBody] + newPos;newPos.x = -cosR - sinR;newPos.y = -sinR + cosR;m_bonePos[3] += newPos;m_bonePos[4] += newPos;newPos = mat * m_mixAnim.bonePos[2];m_bonePos[5] = m_bikePos[BikeBody] + newPos;newPos = mat * m_mixAnim.bonePos[3];m_bonePos[6] = m_bikePos[BikeBody] + newPos - vec2(2,2);Fnc38(7, 9);Fnc38(8, 10);newPos = mat * m_mixAnim.bonePos[4];m_bonePos[9] = m_bikePos[BikeBody] + newPos;newPos = mat * m_mixAnim.bonePos[5];m_bonePos[10] = m_bikePos[BikeBody] + newPos;HeadShake();
}void RacingMotorPlayer::AnimN()
{Skeleton2D& normalAnim = G_RacingMotorGame->normalAnim;var lerp = 0.075f;var rot = m_bikeBodyMovie._rotation * DEG2RAD;const var cosR = cos(rot);const var sinR = sin(rot);mat2 mat;mat.FromRotate(rot);vec2 newPos;m_mixAnim.bonePos[0] += (normalAnim.bonePos[0] - m_mixAnim.bonePos[0]) * lerp;newPos = mat * m_mixAnim.bonePos[0];m_bonePos[0] = m_bikePos[BikeBody] + newPos; //headm_mixAnim.bonePos[1] += (normalAnim.bonePos[1] - m_mixAnim.bonePos[1]) * lerp;newPos = mat * m_mixAnim.bonePos[1];m_bonePos[2] = m_bikePos[BikeBody] + newPos;//thighnewPos.x = (-cosR - sinR)*2;newPos.y = (-sinR + cosR)*2;m_bonePos[3] += newPos;m_bonePos[4] += newPos;m_mixAnim.bonePos[2] += (normalAnim.bonePos[2] - m_mixAnim.bonePos[2]) * const0p1;newPos = mat * m_mixAnim.bonePos[2];m_bonePos[5] = m_bikePos[BikeBody] + newPos;m_mixAnim.bonePos[3] += (normalAnim.bonePos[3] - m_mixAnim.bonePos[3]) * const0p1;newPos = mat * m_mixAnim.bonePos[3];m_bonePos[6] = m_bikePos[BikeBody] + newPos - vec2(2,2);Fnc38(7, 9);Fnc38(8, 10);m_mixAnim.bonePos[4] += (normalAnim.bonePos[4] - m_mixAnim.bonePos[4]) * lerp;newPos = mat * m_mixAnim.bonePos[4];m_bonePos[9] = m_bikePos[BikeBody] + newPos;m_mixAnim.bonePos[5] += (normalAnim.bonePos[5] - m_mixAnim.bonePos[5]) * lerp;newPos = mat * m_mixAnim.bonePos[5];m_bonePos[10] = m_bikePos[BikeBody] + newPos;HeadShake();
}void RacingMotorPlayer::Fnc38(int boneA, int boneB)
{vec2 dif = m_bonePos[boneB] - m_bonePos[boneThigh]; //boneThigh 大腿根var len = dif.Length();if (len == 0){return;} dif = dif / len * 2;m_bonePos[boneA].x += dif.y;m_bonePos[boneA].y -= dif.x;
}void RacingMotorPlayer::HeadShake()
{m_bonePos[0].y += sin(m_headShake) * 4;m_headShake += 0.1047198f;
}void RacingMotorPlayer::CheckSpawnTrickScore(int i)
{if (curTrick != i){curTrick = i;trickTime = 0;}else{++trickTime;if (trickTime == 20){trickTime = 0;if (m_bikePos[BikeBody].x > trickX){trickX = m_bikePos[BikeBody].x;if (TrickScoreFlags[i] == false){TrickScoreFlags[i] = true;++trickContinueNum;} var add = 500 * trickContinueNum ;//连续得分m_score += add ;SpawnTrickScore(add, min(2, trickContinueNum));} } }
}void RacingMotorPlayer::FlagTrickScore()
{curTrick = -1;trickContinueNum = 0;for (int i = 0; i < TrickScoreMax; ++i){TrickScoreFlags[i] = false;}
}void RacingMotorPlayer::SpawnTrickScore(int score, int frame)
{for (int i = 0; i < TrickScoreNum; ++i){if (m_trickScoreVisible[i] == false){m_trickScoreVisible[i] = true;Movie2D& _loc1 = m_trickScoreMovie[i];_loc1._visible = true;_loc1._x = m_bikePos[BikeBody].x;_loc1._y = m_bikePos[BikeBody].y - 60;_loc1._alpha = 100;_loc1.gotoAndStop(frame); //0,  1 combo//_loc1._s = score;//_loc1._s2 = score;return;} }
}void RacingMotorPlayer::UpdateTrickScore()
{for (int i = 0; i < TrickScoreNum; ++i){if (m_trickScoreVisible[i] == true){Movie2D& it = m_trickScoreMovie[i];it._y = it._y - 0.5;it._alpha -= 2;if (it._alpha <= 0){it._visible = false;m_trickScoreVisible[i] = false;} } }
}void RacingMotorPlayer::InitTrickScore()
{for (int i = 0; i < TrickScoreNum; ++i){G_TextureMgr->AddTexture(m_trickScoreMovie[i].texture,"data/minigame/racingmotor/trickscore.png");m_trickScoreMovie[i]._visible = false;m_trickScoreMovie[i].pivot = vec2(32,32);m_trickScoreVisible[i] = false;}
}void RacingMotorPlayer::CheckDead()
{//if (m_bDead == true)// return;//骑手掉下地面vec2 pos;for (int i = 0; i < bonePosNum; i++){Contact res;if (G_RacingMotorGame->CollideRoad(m_bonePos2[i], m_bonePos[i],res)){m_bonePos[i] = res.point; //防止骑手掉下地面pos = m_bonePos[i] - m_bonePos2[i];m_bonePos2[i] += pos * 0.03f;if (i == 1)//躯干 撞墙死{m_bDead = true;} if (m_bSkill == true) //特技状态 撞墙死{m_bDead = true;} } }if (m_wheelBCollide == true || m_wheelFCollide == true)//特技状态 着陆死{if (m_bSkill == true){m_bDead = true;} }if (m_bikePos[BikeBody].y > G_RacingMotorGame->mapExtend.x)  //掉出边界{m_bDead = true;}//if (m_bDead == true && m_gameState==stateRacing){--m_liveNum;if (m_liveNum == 0){m_gameState = stateGameover;m_stateTime = 0;}else{m_gameState = stateFalling;m_stateTime = 0;} }if (m_wheelBCollide == true && m_gameState==stateRacing){if (m_bikePos[BikeBody].x > G_RacingMotorGame->mapExtend.y){//达到终点m_score += m_gameTime;m_gameState = stateGameover;}}
}void RacingMotorPlayer::UpdateBonePos()
{vec2 pos;for (int i = 0; i < bonePosNum; i++){pos = m_bonePos[i];m_bonePos[i].x  += (pos.x - m_bonePos2[i].x);m_bonePos[i].y  += (pos.y - m_bonePos2[i].y + 0.15);m_bonePos2[i]  = pos;}
}void RacingMotorPlayer::UpdateBoneAngs()
{for (int i = 0; i < BoneJointsNum; ++i){var* item = BoneJoints[i];int boneA = item[0];int boneB = item[1];int boneC = item[2];var minAng = item[3];var maxAng = item[4];var ax = m_bonePos[boneA].x;var ay = m_bonePos[boneA].y;var bx = m_bonePos[boneB].x;var by = m_bonePos[boneB].y;var cx = m_bonePos[boneC].x;var cy = m_bonePos[boneC].y;var _loc14 = bx - ax;var _loc13 = by - ay;var angBA = atan2(_loc13, _loc14);var _loc23 = sqrt(_loc14 * _loc14 + _loc13 * _loc13);_loc14 = cx - bx;_loc13 = cy - by;var angCA = atan2(_loc13, _loc14);var _loc17 = sqrt(_loc14 * _loc14 + _loc13 * _loc13);var ang = angCA - angBA;//ca ba夹角if (ang > _PI){ang = ang - TWOPI;} if (ang < -_PI){ang = ang + TWOPI;} var movAng = 0;if (ang < minAng){movAng = minAng - ang;}else if (ang > maxAng){movAng = maxAng - ang;} if (movAng != 0){var _loc25 = (ax + bx + cx) / 3;var _loc24 = (ay + by + cy) / 3;movAng *= 0.15f;angCA += movAng;m_bonePos[boneC].x = m_bonePos[boneB].x + cos(angCA) * _loc17;m_bonePos[boneC].y = m_bonePos[boneB].y + sin(angCA) * _loc17;angBA = angBA + _PI - movAng;m_bonePos[boneA].x = m_bonePos[boneB].x + cos(angBA) * _loc23;m_bonePos[boneA].y = m_bonePos[boneB].y + sin(angBA) * _loc23;var _loc8  = (m_bonePos[boneA].x + bx + m_bonePos[boneC].x) / 3;var _loc10 = (m_bonePos[boneA].y + by + m_bonePos[boneC].y) / 3;_loc8 -=  _loc25;_loc10 -=  _loc24;m_bonePos[boneA].x -=   _loc8;m_bonePos[boneA].y -=   _loc10;m_bonePos[boneB].x -=   _loc8;m_bonePos[boneB].y -=   _loc10;m_bonePos[boneC].x -=   _loc8;m_bonePos[boneC].y -=   _loc10;} }
}void RacingMotorPlayer::UpdateBoneJoints()
{vec2 dif = m_bonePos[1] - m_bonePos[0];var len = dif.Length();var _loc3 = (len - oriLenHead) / len;_loc3 = _loc3 * -0.5;dif = dif * _loc3;m_bonePos[0] -= dif;m_bonePos[1] += dif;dif = m_bonePos[2] - m_bonePos[1];len = dif.Length();_loc3 = (len - oriLenTorso) / len;_loc3 = _loc3 * -0.5;dif = dif * _loc3;m_bonePos[1] -= dif;m_bonePos[2] += dif;dif = m_bonePos[3] - m_bonePos[1];len = dif.Length();_loc3 = (len - oriLenArm) / len;_loc3 = _loc3 * -0.5;dif = dif * _loc3;m_bonePos[1] -= dif;m_bonePos[3] += dif;dif = m_bonePos[5] - m_bonePos[3];len = dif.Length();_loc3 = (len - oriLenForeArm) / len;_loc3 = _loc3 * -0.5;dif = dif * _loc3;m_bonePos[3] -= dif;m_bonePos[5] += dif;dif = m_bonePos[4] - m_bonePos[1];len = dif.Length();_loc3 = (len - oriLenArm) / len;_loc3 = _loc3 * -0.5;dif = dif * _loc3;m_bonePos[1] -= dif;m_bonePos[4] += dif;dif = m_bonePos[6] - m_bonePos[4];len = dif.Length();_loc3 = (len - oriLenForeArm) / len;_loc3 = _loc3 * -0.5;dif = dif * _loc3;m_bonePos[4] -= dif;m_bonePos[6] += dif;dif = m_bonePos[7] - m_bonePos[2];len = dif.Length();_loc3 = (len - oriLenThigh) / len;_loc3 = _loc3 * -0.5;dif = dif * _loc3;m_bonePos[2] -= dif;m_bonePos[7] += dif;dif = m_bonePos[9] - m_bonePos[7];len = dif.Length();_loc3 = (len - oriLenShin) / len;_loc3 = _loc3 * -0.5;dif = dif * _loc3;m_bonePos[7] -= dif;m_bonePos[9] += dif;dif = m_bonePos[8] - m_bonePos[2];len = dif.Length();_loc3 = (len - oriLenThigh) / len;_loc3 = _loc3 * -0.5;dif = dif * _loc3;m_bonePos[2] -= dif;m_bonePos[8] += dif;dif = m_bonePos[10] - m_bonePos[8];len = dif.Length();_loc3 = (len - oriLenShin) / len;_loc3 = _loc3 * -0.5;dif = dif * _loc3;m_bonePos[8] -= dif;m_bonePos[10] += dif;
}void RacingMotorPlayer::UpdateManMovie()
{vec2 dir;dir = m_bonePos[1] - m_bonePos[0];var rot = atan2(dir.y, dir.x) * RAD2DEG;m_manHeadMovie._x = m_bonePos[boneHead].x;m_manHeadMovie._y = m_bonePos[boneHead].y;m_manHeadMovie._rotation = rot;dir = m_bonePos[2] - m_bonePos[1];rot = atan2(dir.y, dir.x) * RAD2DEG;m_manTorsoMovie._x = m_bonePos[1].x;m_manTorsoMovie._y = m_bonePos[1].y;m_manTorsoMovie._rotation = rot;dir.Normalize();//此处最好多加一根骨骼vec2 armOffset = dir*oriLenJian;vec2 armPos = m_bonePos[1] + armOffset;dir = m_bonePos[3] - m_bonePos[1];rot = atan2(dir.y, dir.x) * RAD2DEG;m_manArmMovie1._x = armPos.x;m_manArmMovie1._y = armPos.y;m_manArmMovie1._rotation = rot;dir = m_bonePos[4] - m_bonePos[1];rot = atan2(dir.y, dir.x) * RAD2DEG;m_manArmMovie2._x = armPos.x;m_manArmMovie2._y = armPos.y;m_manArmMovie2._rotation = rot;dir = m_bonePos[5] - armOffset - m_bonePos[3];rot = atan2(dir.y, dir.x) * RAD2DEG;m_manForearmMovie1._x = m_bonePos[3].x + armOffset.x;m_manForearmMovie1._y = m_bonePos[3].y + armOffset.y;m_manForearmMovie1._rotation = rot;dir = m_bonePos[6] - armOffset - m_bonePos[4];rot = atan2(dir.y, dir.x) * RAD2DEG;m_manForearmMovie2._x = m_bonePos[4].x + armOffset.x;m_manForearmMovie2._y = m_bonePos[4].y + armOffset.y;m_manForearmMovie2._rotation = rot;dir = m_bonePos[7] - m_bonePos[2];rot = atan2(dir.y, dir.x) * RAD2DEG;m_manThighMovie1._x = m_bonePos[2].x;m_manThighMovie1._y = m_bonePos[2].y;m_manThighMovie1._rotation = rot;dir = m_bonePos[8] - m_bonePos[2];rot = atan2(dir.y, dir.x) * RAD2DEG;m_manThighMovie2._x = m_bonePos[2].x;m_manThighMovie2._y = m_bonePos[2].y;m_manThighMovie2._rotation = rot;dir = m_bonePos[9] - m_bonePos[7];rot = atan2(dir.y, dir.x) * RAD2DEG;m_manShinMovie1._x = m_bonePos[7].x;m_manShinMovie1._y = m_bonePos[7].y;m_manShinMovie1._rotation = rot;dir = m_bonePos[10] - m_bonePos[8];rot = atan2(dir.y, dir.x) * RAD2DEG;m_manShinMovie2._x = m_bonePos[8].x;m_manShinMovie2._y = m_bonePos[8].y;m_manShinMovie2._rotation = rot;
}void RacingMotorPlayer::InitBonePos()
{var x = startPos[0];var y = startPos[1];m_bonePos[0].x = x;m_bonePos[0].y = y;m_bonePos[1].x = x;m_bonePos[1].y = y + oriLenHead;m_bonePos[2].x = x;m_bonePos[2].y = y + oriLenHead + oriLenTorso;m_bonePos[3].x = x;m_bonePos[3].y = y + oriLenHead + oriLenArm;m_bonePos[4].x = x;m_bonePos[4].y = y + oriLenHead + oriLenArm;m_bonePos[5].x = x;m_bonePos[5].y = y + oriLenHead + oriLenArm + oriLenForeArm;m_bonePos[6].x = x;m_bonePos[6].y = y + oriLenHead + oriLenArm + oriLenForeArm;m_bonePos[7].x = x;m_bonePos[7].y = y + oriLenHead + oriLenTorso + oriLenThigh;m_bonePos[8].x = x;m_bonePos[8].y = y + oriLenHead + oriLenTorso + oriLenThigh;m_bonePos[9].x = x;m_bonePos[9].y = y + oriLenHead + oriLenTorso + oriLenThigh + oriLenShin;m_bonePos[10].x = x;m_bonePos[10].y = y + oriLenHead + oriLenTorso + oriLenThigh + oriLenShin;for (int i = 0; i < bonePosNum; i++){m_bonePos2[i] = m_bonePos[i];}
}void RacingMotorPlayer::CheckJumpingRot()
{var bikeBodyRot = m_bikeBodyMovie._rotation;if (bikeBodyRot < 0){bikeBodyRot += 360;} if (m_bJumping == false){if (m_wheelBCollide == false && m_wheelFCollide == false){m_bJumping = true;m_lastBikeBodyRot = bikeBodyRot;m_jumpingRot = 0;m_arriveX = max(m_arriveX, m_bikePos[BikeBody].x);} } if (m_bJumping == false){return;} var rot = m_lastBikeBodyRot - bikeBodyRot;if (rot < -180){rot = -(rot + 360);}else if (rot > 180){rot = 360 - rot;} m_lastBikeBodyRot = bikeBodyRot;m_jumpingRot += rot;if (m_wheelBCollide == true || m_wheelFCollide == true){m_bJumping = false;if (m_bDead == false){var _loc3 = abs(m_jumpingRot);if (_loc3 >= 180) //空中翻滚得分{if (m_bikePos[BikeBody].x - m_arriveX > 20){_loc3 = floor(_loc3);m_jumpingRot = 0;var _loc4 = _loc3 * (trickContinueNum + 1);m_score += _loc4 ;SpawnTrickScore(_loc4, 1);} } } }
}void RacingMotorPlayer::Fnc20()
{vec2 pos(10,-20);var  rot = m_bikeBodyMovie._rotation * DEG2RAD;vec2 newpos = m_bikePos[BikeBody] + Rotate(pos,rot);if (m_massPos[0] == -1){m_massPos = newpos;return;} Contact hit;if (G_RacingMotorGame->CollideExpand(m_massPos, newpos,hit)){//质心和扩展线段发生碰撞 回退vec2 dif = hit.point - newpos;m_bikePos[BikeBody] += dif;m_bikePos[3] += dif;m_bikePos[4] += dif;vec2 speed = m_bikePos[BikeBody] - m_bikePos2[BikeBody];m_bikePos2[BikeBody] += speed * 0.3f;newpos = hit.point;} m_massPos = newpos;
}void RacingMotorPlayer::UpdateWheel()
{m_wheelBCollide = false;m_wheelFCollide = false;vec2 dir = m_bikePos[WheelF] - m_bikePos[WheelB];var len = dir.Length();if (len > 0){vec2 left = LeftDir(dir)*2;Contact hit;if (G_RacingMotorGame->CollideExpand(m_bikePos[WheelB], m_bikePos[WheelB] + left,hit)){m_wheelBCollide = true;} if (G_RacingMotorGame->CollideExpand(m_bikePos[WheelF], m_bikePos[WheelF] + left,hit)){m_wheelFCollide = true;} } var const38pi = TWOPI * const19;if (m_wheelBCollide == true){m_wheelBRotSpeed = m_wheelBCollideNormal.Cross(m_wheelBSpeed)/ const38pi * 360;if (G_Keyboard->IsKeyPressed(DIK_UP))  //可以打滑{if (m_bDead == false){m_wheelBRotSpeed = max(30, m_wheelBRotSpeed);} } } if (m_wheelFCollide == true){m_wheelFRotSpeed = m_wheelFCollideNormal.Cross(m_wheelFSpeed) / const38pi * 360;} m_wheelMovieB._rotation = m_wheelMovieB._rotation + m_wheelBRotSpeed;m_wheelMovieF._rotation = m_wheelMovieF._rotation + m_wheelFRotSpeed;
}void RacingMotorPlayer::Fnc15()
{Contact hit;if (G_RacingMotorGame->CollideExpand(m_bikePos2[WheelB], m_bikePos[WheelB],hit))//??{m_bikePos[WheelB] = hit.point;m_wheelBSpeed = m_bikePos[WheelB] - m_bikePos2[WheelB];m_wheelBCollideNormal = hit.normal;var time = 0.05f;if (G_Keyboard->IsKeyPressed(DIK_DOWN) || G_Keyboard->IsKeyPressed(DIK_SPACE)) {time = 0.5f;} m_bikePos2[WheelB] += m_wheelBSpeed * time;} if (G_RacingMotorGame->CollideExpand(m_bikePos2[WheelF], m_bikePos[WheelF],hit)){m_bikePos[WheelF] = hit.point;m_wheelFSpeed = m_bikePos[WheelF] - m_bikePos2[WheelF];m_wheelFCollideNormal = hit.normal;if (G_Keyboard->IsKeyPressed(DIK_DOWN) || G_Keyboard->IsKeyPressed(DIK_SPACE)) {m_bikePos2[WheelF] += m_wheelFSpeed * 0.5f;} }
}void RacingMotorPlayer::UpdateBikeJoints()
{vec2 dif;var len;var mov;dif = m_bikePos[WheelB] - m_bikePos[BikeBody];len = dif.Length();mov = (len - const36) / len * -0.5;dif *= mov;m_bikePos[BikeBody] -= dif;m_bikePos[WheelB] += dif;dif = m_bikePos[WheelF] - m_bikePos[BikeBody];len = dif.Length();mov = (len - const39) / len * -0.5;dif *= mov;m_bikePos[BikeBody] = m_bikePos[BikeBody] - dif;m_bikePos[WheelF] = m_bikePos[WheelF] + dif;dif = m_bikePos[3] - m_bikePos[BikeBody];len = dif.Length();mov = (len - const36) / len * -0.5;dif *= mov;m_bikePos[BikeBody] = m_bikePos[BikeBody] - dif;m_bikePos[3] += dif;dif = m_bikePos[4] - m_bikePos[BikeBody];len = dif.Length();mov = (len - const39) / len * -0.5;dif *= mov;m_bikePos[BikeBody] = m_bikePos[BikeBody] - dif;m_bikePos[4] += dif;dif = m_bikePos[3] - m_bikePos[WheelB];len = dif.Length();mov = (len - length1__) / len;mov = mov * (-0.5 * const0p05);dif *= mov;m_bikePos[WheelB] = m_bikePos[WheelB] - dif;m_bikePos[3] += dif;dif = m_bikePos[4] - m_bikePos[WheelF];len = dif.Length();mov = (len - length2__) / len * (-0.5 * const0p075);dif *= mov;m_bikePos[WheelF] = m_bikePos[WheelF] - dif;m_bikePos[4] += dif;vec2 dif2;dif2 = m_bikePos[BikeBody] - m_bikePos[4];var ang1 = atan2(dif2.y, dif2.x);var len1 = dif2.Length();dif2 = m_bikePos[3] - m_bikePos[BikeBody];var ang2 = atan2(dif2.y, dif2.x);var len2 = dif2.Length();var difAng = ang2 - ang1;if (difAng > _PI){difAng = difAng - TWOPI;} if (difAng < -_PI){difAng = difAng + TWOPI;} var _loc17 = _PI/2;var limAng = _loc17 - difAng;vec2 pos9;pos9 = (m_bikePos[BikeBody] + m_bikePos[3] + m_bikePos[4]) / 3;limAng = limAng * 0.05;ang2 = ang2 + limAng;m_bikePos[3].x = m_bikePos[BikeBody].x + cos(ang2) * len2;m_bikePos[3].y = m_bikePos[BikeBody].y + sin(ang2) * len2;ang1 = ang1 + _PI;ang1 = ang1 - limAng;m_bikePos[4].x = m_bikePos[BikeBody].x + cos(ang1) * len1;m_bikePos[4].y = m_bikePos[BikeBody].y + sin(ang1) * len1;vec2 pos6;pos6 = (m_bikePos[BikeBody] + m_bikePos[3] + m_bikePos[4]) / 3;pos6 = pos6 - pos9;m_bikePos[BikeBody] = m_bikePos[BikeBody] - pos6;m_bikePos[3] -=  pos6;m_bikePos[4] -=  pos6;dif2.x = m_bikePos[WheelF].x - m_bikePos[BikeBody].x;dif2.y = m_bikePos[WheelF].y - m_bikePos[BikeBody].y;ang1 = atan2(dif2.y, dif2.x);len1 = dif2.Length();dif2.x = m_bikePos[4].x - m_bikePos[BikeBody].x;dif2.y = m_bikePos[4].y - m_bikePos[BikeBody].y;ang2 = atan2(dif2.y, dif2.x);len2 = dif2.Length();difAng = ang2 - ang1;if (difAng > _PI){difAng = difAng - TWOPI;} if (difAng < -_PI){difAng = difAng + TWOPI;} var minAng = -1.221730f;var maxAng = -0.6981317f;limAng = 0;if (difAng < minAng){limAng = minAng - difAng;}else if (difAng > maxAng){limAng = maxAng - difAng;} if (limAng != 0){pos9.x = (m_bikePos[BikeBody].x + m_bikePos[WheelF].x + m_bikePos[4].x) / 3;pos9.y = (m_bikePos[BikeBody].y + m_bikePos[WheelF].y + m_bikePos[4].y) / 3;limAng = limAng * 0.25;ang2 = ang2 + limAng;m_bikePos[4].x = m_bikePos[BikeBody].x + cos(ang2) * len2;m_bikePos[4].y = m_bikePos[BikeBody].y + sin(ang2) * len2;ang1 = ang1 - limAng;m_bikePos[WheelF].x = m_bikePos[BikeBody].x + cos(ang1) * len1;m_bikePos[WheelF].y = m_bikePos[BikeBody].y + sin(ang1) * len1;pos6 = (m_bikePos[BikeBody] + m_bikePos[WheelF] + m_bikePos[4]) / 3;pos6 = pos6 - pos9;m_bikePos[BikeBody] = m_bikePos[BikeBody] - pos6;m_bikePos[WheelF] = m_bikePos[WheelF] - pos6;m_bikePos[4] -=  pos6;} dif2 = m_bikePos[WheelB] - m_bikePos[BikeBody];ang1 = atan2(dif2.y, dif2.x);len1 = dif2.Length();dif2 = m_bikePos[3] - m_bikePos[BikeBody];ang2 = atan2(dif2.y, dif2.x);len2 = dif2.Length();difAng = ang2 - ang1;if (difAng > _PI){difAng = difAng - TWOPI;} if (difAng < -_PI){difAng = difAng + TWOPI;} minAng = 0.7853982f;maxAng = 0.9599311f;limAng = 0;if (difAng < minAng){limAng = minAng - difAng;}else if (difAng > maxAng){limAng = maxAng - difAng;} if (limAng != 0){pos9.x = (m_bikePos[BikeBody].x + m_bikePos[WheelB].x + m_bikePos[3].x) / 3;pos9.y = (m_bikePos[BikeBody].y + m_bikePos[WheelB].y + m_bikePos[3].y) / 3;limAng = limAng * 0.25;ang2 = ang2 + limAng;m_bikePos[3].x = m_bikePos[BikeBody].x + cos(ang2) * len2;m_bikePos[3].y = m_bikePos[BikeBody].y + sin(ang2) * len2;ang1 = ang1 - limAng;m_bikePos[WheelB].x = m_bikePos[BikeBody].x + cos(ang1) * len1;m_bikePos[WheelB].y = m_bikePos[BikeBody].y + sin(ang1) * len1;pos6 = (m_bikePos[BikeBody] + m_bikePos[WheelB] + m_bikePos[3]) / 3;pos6 = pos6 - pos9;m_bikePos[BikeBody] = m_bikePos[BikeBody] - pos6;m_bikePos[WheelB] = m_bikePos[WheelB] - pos6;m_bikePos[3] -=  pos6;}
}void RacingMotorPlayer::UpdateBikePos()
{vec2 pos;for (int i=0;i<5;i++){pos = m_bikePos[i];m_bikePos[i] += (m_bikePos[i] - m_bikePos2[i]);m_bikePos[i].y += 0.13f;m_bikePos2[i] = pos;}
}
void RacingMotorPlayer::UpdateBikeMovie()
{var const18 = 18 ;//车轮m_wheelMovieB._x = m_bikePos[WheelB].x;m_wheelMovieB._y = m_bikePos[WheelB].y;m_wheelMovieF._x = m_bikePos[WheelF].x;m_wheelMovieF._y = m_bikePos[WheelF].y;//链盒m_bikeBackShaftMovie._x = m_bikePos[BikeBody].x;m_bikeBackShaftMovie._y = m_bikePos[BikeBody].y;vec2 dif = m_bikePos[WheelB] - m_bikePos[BikeBody];var ang = atan2(dif.y, dif.x) * RAD2DEG;m_bikeBackShaftMovie._rotation = ang;var len = dif.Length()/40;m_bikeBackShaftMovie._xscale = len*100;m_bikeBackShaftMovie._yscale = len*100;//前叉m_bikeFrontShockTipMovie._x = m_bikePos[WheelF].x;m_bikeFrontShockTipMovie._y = m_bikePos[WheelF].y;ang = m_bikeBodyMovie._rotation * DEG2RAD;vec2 newPos = Rotate(vec2(22,-30),ang)  + m_bikePos[BikeBody];dif = newPos - m_bikePos[WheelF];ang = atan2(dif.y, dif.x) * RAD2DEG;m_bikeFrontShockTipMovie._rotation = ang;//车把m_bikeFrontShockBaseMovie._x = newPos.x;m_bikeFrontShockBaseMovie._y = newPos.y;ang = ang + 180;m_bikeFrontShockBaseMovie._rotation = ang;//车把2m_bikeFrontShockShaftMovie._x = newPos.x;m_bikeFrontShockShaftMovie._y = newPos.y;m_bikeFrontShockShaftMovie._rotation = ang;len = dif.Length();len = 100 * (len / const18);m_bikeFrontShockShaftMovie._xscale = len;//主体m_bikeBodyMovie._x = m_bikePos[BikeBody].x;m_bikeBodyMovie._y = m_bikePos[BikeBody].y;//dif = bikePos[WheelF] - bikePos[WheelB];dif = m_bikePos[4] - m_bikePos[3];len = dif.Length();ang = atan2(dif.y, dif.x) * RAD2DEG;m_bikeBodyMovie._rotation = ang;
}void RacingMotorPlayer::FreeBike()
{//m_manMovie1.removeMovieClip();//m_manMovie2.removeMovieClip();
}void RacingMotorPlayer::InitBikeMovie()
{G_TextureMgr->AddTexture(m_wheelMovieB.texture,"data/minigame/racingmotor/wheel.png");m_wheelMovieB.pivot = vec2(25,25);G_TextureMgr->AddTexture(m_wheelMovieF.texture,"data/minigame/racingmotor/wheel.png");m_wheelMovieF.pivot = vec2(25,25);G_TextureMgr->AddTexture(m_bikeFrontShockShaftMovie.texture,"data/minigame/racingmotor/frontshockshaft.png");m_bikeFrontShockShaftMovie.pivot = vec2(0,2);G_TextureMgr->AddTexture(m_bikeFrontShockTipMovie.texture,"data/minigame/racingmotor/frontshocktip.png");m_bikeFrontShockTipMovie.pivot = vec2(4,3);G_TextureMgr->AddTexture(m_bikeFrontShockBaseMovie.texture,"data/minigame/racingmotor/frontshockbase.png");m_bikeFrontShockBaseMovie.pivot = vec2(1,3);G_TextureMgr->AddTexture(m_bikeBackShaftMovie.texture,"data/minigame/racingmotor/backshaft.png");m_bikeBackShaftMovie.pivot = vec2(7,7);G_TextureMgr->AddTexture(m_bikeBodyMovie.texture,"data/minigame/racingmotor/body.png");m_bikeBodyMovie.pivot = vec2(35,46);G_TextureMgr->AddTexture(m_manShinMovie1.texture,"data/minigame/racingmotor/manshin.png");m_manShinMovie1.pivot = vec2(2,15);m_manShinMovie1._xscale = 100 * scale_man;m_manShinMovie1._yscale = 100 * scale_man;G_TextureMgr->AddTexture(m_manThighMovie1.texture,"data/minigame/racingmotor/manThigh.png");m_manThighMovie1.pivot = vec2(3,9);m_manThighMovie1._xscale = 100 * scale_man;m_manThighMovie1._yscale = 100 * scale_man;G_TextureMgr->AddTexture(m_manArmMovie1.texture,"data/minigame/racingmotor/manArm.png");m_manArmMovie1.pivot = vec2(4,7);m_manArmMovie1._xscale = 100 * scale_man;m_manArmMovie1._yscale = 100 * scale_man;G_TextureMgr->AddTexture(m_manForearmMovie1.texture,"data/minigame/racingmotor/manForearm.png");m_manForearmMovie1.pivot = vec2(3,5);m_manForearmMovie1._xscale = 100 * scale_man;m_manForearmMovie1._yscale = 100 * scale_man;G_TextureMgr->AddTexture(m_manShinMovie2.texture,"data/minigame/racingmotor/manShin.png");m_manShinMovie2.pivot = vec2(2,15);m_manShinMovie2._xscale = 100 * scale_man;m_manShinMovie2._yscale = 100 * scale_man;G_TextureMgr->AddTexture(m_manThighMovie2.texture,"data/minigame/racingmotor/manThigh.png");m_manThighMovie2.pivot = vec2(3,9);m_manThighMovie2._xscale = 100 * scale_man;m_manThighMovie2._yscale = 100 * scale_man;G_TextureMgr->AddTexture(m_manTorsoMovie.texture,"data/minigame/racingmotor/manTorso.png");m_manTorsoMovie.pivot = vec2(2,12);m_manTorsoMovie._xscale = 100 * scale_man;m_manTorsoMovie._yscale = 100 * scale_man;G_TextureMgr->AddTexture(m_manHeadMovie.texture,"data/minigame/racingmotor/manHead.png");m_manHeadMovie.pivot = vec2(1,20);m_manHeadMovie._xscale = 100 * scale_man;m_manHeadMovie._yscale = 100 * scale_man;G_TextureMgr->AddTexture(m_manArmMovie2.texture,"data/minigame/racingmotor/manArm.png");m_manArmMovie2.pivot = vec2(4,7);m_manArmMovie2._xscale = 100 * scale_man;m_manArmMovie2._yscale = 100 * scale_man;G_TextureMgr->AddTexture(m_manForearmMovie2.texture,"data/minigame/racingmotor/manForearm.png");m_manForearmMovie2.pivot = vec2(3,5);m_manForearmMovie2._xscale = 100 * scale_man;m_manForearmMovie2._yscale = 100 * scale_man;ResetBike();
}
void RacingMotorPlayer::ResetBike()
{m_bikePos[BikeBody] = startPos;m_bikePos[WheelB].x = startPos.x - const36;m_bikePos[WheelB].y = startPos.y;m_bikePos[WheelF].x = startPos.x + const39;m_bikePos[WheelF].y = startPos.y;var const_125deg = -2.181662f;var const_45deg = -0.785398f;vec2 pos;pos.x = cos(const_125deg) * const36;pos.y = sin(const_125deg) * const36;m_bikePos[3] = startPos + pos;pos.x = cos(const_45deg) * const39;pos.y = sin(const_45deg) * const39;m_bikePos[4] = startPos + pos;vec2 dif = m_bikePos[WheelB] - m_bikePos[3];length1__ = dif.Length();dif = m_bikePos[WheelF] - m_bikePos[4];length2__ = dif.Length();m_bikePos2[BikeBody] = m_bikePos[BikeBody];m_bikePos2[WheelB] = m_bikePos[WheelB];m_bikePos2[WheelF] = m_bikePos[WheelF];m_bikePos2[3] = m_bikePos[3];m_bikePos2[4] = m_bikePos[4];UpdateBikeMovie();m_massPos[0] = -1;m_wheelBRotSpeed = 0;m_wheelFRotSpeed = 0;m_bJumping = false;m_arriveX = 0;InitBonePos();m_bDead = false;m_bSkill = false;for (int i = 0; i < 50; ++i){UpdateBonePos();AnimN();UpdateBoneAngs();UpdateBoneJoints();}//hide dirtfor (int i = 0; i < DirtNum; ++i){Dirt& dirt = m_dirts[i];dirt.movie._visible = false;dirt.dirtLife = 0;}//TrickScoretrickTime = 0;trickX = 0;FlagTrickScore();for (int i = 0; i < TrickScoreNum; ++i){Movie2D& _loc2 = m_trickScoreMovie[i];_loc2._visible = false;m_trickScoreVisible[i] = false;}SetNormalAnim();
}//==================^_^
RacingMotorPlayerRobot::RacingMotorPlayerRobot()
:m_thinkTime(0)
{m_workingWithAI = true;
}
RacingMotorPlayerRobot::~RacingMotorPlayerRobot()
{
}
void RacingMotorPlayerRobot::Update()
{RacingMotorPlayer::Update();UpdateCommon();switch (m_gameState){case stateRacing:{UpdateInput();break;} }//if (m_movDir!=lasMovDir){C2SPacketMiniGameCmd packet;packet.WriteHeader();packet.WriteValue(CMD_ManMove);packet.WriteValue(GetPlayerInfo()->roomSlot);for (int i=0;i<5;i++){packet.WriteValue(m_bikePos[i]);}for (int i=0;i<bonePosNum;i++){packet.WriteValue(m_bonePos[i]);}G_MiniGame->SendPacketToOther(&packet);}
}
void RacingMotorPlayerRobot::SetWorkingWithAI(bool working)
{m_workingWithAI = working;if (m_workingWithAI==false){}
}void RacingMotorPlayerRobot::UpdateInput()
{
}
//==================^_^
RacingMotorPlayerRole::RacingMotorPlayerRole()
{m_workingWithAI = false;
}
RacingMotorPlayerRole::~RacingMotorPlayerRole()
{
}void RacingMotorPlayerRole::Update()
{if(m_workingWithAI){RacingMotorPlayerRobot::Update();return;}RacingMotorPlayer::Update();UpdateCommon();switch (m_gameState){case stateRacing:{UpdateInput();break;} }//if (m_movDir!=lasMovDir){C2SPacketMiniGameCmd packet;packet.WriteHeader();packet.WriteValue(CMD_ManMove);packet.WriteValue(GetPlayerInfo()->roomSlot);for (int i=0;i<5;i++){packet.WriteValue(m_bikePos[i]);}for (int i=0;i<bonePosNum;i++){packet.WriteValue(m_bonePos[i]);}G_MiniGame->SendPacketToOther(&packet);}//UpdateListener();if (m_liveNum < 0){G_RacingMotorGame->SetGameState(MS_End);}
}void RacingMotorPlayerRole::Render()
{RacingMotorPlayer::Render();
}void RacingMotorPlayerRole::UpdateInput()
{Skeleton2D& backAnim   = G_RacingMotorGame->backAnim;Skeleton2D& normalAnim = G_RacingMotorGame->normalAnim;Skeleton2D& frontAnim  = G_RacingMotorGame->frontAnim;Skeleton2D& skillZAnim = G_RacingMotorGame->skillZAnim;Skeleton2D& skillXAnim = G_RacingMotorGame->skillXAnim;Skeleton2D& skillCAnim = G_RacingMotorGame->skillCAnim;Skeleton2D& skillVAnim = G_RacingMotorGame->skillVAnim;Skeleton2D& skillBAnim = G_RacingMotorGame->skillBAnim;if (m_bDead == true){return;} Skeleton2D* toAnim = &normalAnim;if (G_Keyboard->IsKeyPressed(DIK_Z)){if (m_wheelBCollide == false && m_wheelFCollide == false)//空中特技{toAnim = &skillZAnim;} }else if (G_Keyboard->IsKeyPressed(DIK_X)){if (m_wheelBCollide == false && m_wheelFCollide == false){toAnim = &skillXAnim;} }else if (G_Keyboard->IsKeyPressed(DIK_C)){if (m_wheelBCollide == false && m_wheelFCollide == false){toAnim = &skillCAnim;} }else if (G_Keyboard->IsKeyPressed(DIK_V)){if (m_wheelBCollide == false && m_wheelFCollide == false){toAnim = &skillVAnim;} }else if (G_Keyboard->IsKeyPressed(DIK_B)){if (m_wheelBCollide == false && m_wheelFCollide == false){toAnim = &skillBAnim;} }else if (G_Keyboard->IsKeyPressed(DIK_LEFT)) {toAnim = &backAnim;}else if (G_Keyboard->IsKeyPressed(DIK_RIGHT)) {toAnim = &frontAnim;}if (IsAnimEnd(*m_curAnim) == true) //上一动作结束才能切换{if (m_curAnim == &normalAnim){m_curAnim = toAnim;}else if (m_curAnim != toAnim){m_curAnim = &normalAnim;} }if (m_bSkill == false){if (m_wheelBCollide == false && m_wheelFCollide == false){vec2 left = LeftDir(m_bikePos[WheelF] - m_bikePos[WheelB]);if (G_Keyboard->IsKeyPressed(DIK_LEFT)) {m_bikePos2[WheelF] += left * 0.35f;}else if (G_Keyboard->IsKeyPressed(DIK_RIGHT)) {m_bikePos2[WheelF] -= left * 0.35f;} }else if (m_wheelBCollide == true){if (G_Keyboard->IsKeyPressed(DIK_LEFT)) {m_bikePos2[WheelB] += m_wheelBCollideNormal * 0.2f;m_bikePos2[WheelF] -= m_wheelBCollideNormal * 0.3f;}else if (G_Keyboard->IsKeyPressed(DIK_RIGHT)) {m_bikePos2[WheelF] += m_wheelBCollideNormal * 0.3f;} }} if (m_bDead == false){if (G_Keyboard->IsKeyPressed(DIK_UP)){if (m_wheelBCollide == true){vec2 left = LeftDir(m_wheelBCollideNormal);m_bikePos2[WheelB] -= left * 1.6f;} } }
}
//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/RacingMotor/MiniGameRacingMotor.h
//  @Brief:     MiniGameRacingMotor
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================#ifndef  __MiniGameRacingMotor__H__
#define  __MiniGameRacingMotor__H__#include "Math/MathLib.h"
#include "Render/Texture.h"
#include "Rpg/MiniGame.h"
#include <vector>
#include "RacingMotorPlayer.h"enum MiniRacingMotorCmd
{CMD_ManMove ,      //赛车移动CMD_GameOver,CMD_Restart ,
};
const char* RacingMotorCmdToString(int enumeration);namespace RendSys
{class MC_Frame;
}
class RacingMotorPlayerRole;
class MiniGameRacingMotor:public MiniGame
{
public:MiniGameRacingMotor();virtual ~MiniGameRacingMotor();virtual bool KeepResource(bool once,int& circle,String& nextTip);virtual bool Start();virtual bool Stop();virtual bool Render();virtual void RenderUI();virtual bool Update();virtual bool Free();virtual bool IsEnd();//三种类型结构virtual MiniPlayer*  CreatePlayer();virtual MiniPlayer*  CreateRobot ();virtual MiniPlayer*  CreateRole  ();//RacingMotorPlayer* GetTurnPlayer();    //处理游戏网络命令包virtual int  ProcessPacketCmd(PacketBase* packet);//virtual const char* CmdToString(const char* stream,int len);public:void InitMap();bool IsEqual(const vec2& p1,const vec2& p2);void PartionRoadSegment();void PartionExpandSegment();bool CollideRoad(const vec2& p1,const vec2& p2,Contact& res);bool CollideExpand(const vec2& p1,const vec2& p2,Contact& res);bool CollideSegment(const vec2& p1,const vec2& p2, RoadSegment* seg,vec2& res);void InitRoadSegments();public:RacingMotorPlayerRole* m_myRolePlayer;var const20;var const18_;var const20_;var const4;var enumX0;var enumX1;var enumX2;int*  mapData;vec2I mapGridNum;vec2  mapExtend;vec2I TileNum;int   TileExtend;std::vector<int> arrKK[735];RoadSegment  m_roadSegments[456]; //路的边int          m_roadSegmentNum;RoadSegment m_expandSegments[456];//扩了车轮半径的路的边int         m_expandSegmentNum;std::vector<int>* roadSegPartion;int roadSegPartionX;int roadSegPartionY;std::vector<int>* expandSegPartion;int expandSegPartionX;int expandSegPartionY;RectF m_minimapRect;var   miniScale;TexturePtr m_texBack;    TexturePtr m_texTile;TexturePtr m_texNeedle;TexturePtr m_texSpeedo;float      m_countDownTime;TexturePtr m_texCountdown[4];Skeleton2D backAnim;Skeleton2D normalAnim;Skeleton2D frontAnim;Skeleton2D skillZAnim;Skeleton2D skillXAnim;Skeleton2D skillCAnim;Skeleton2D skillVAnim;Skeleton2D skillBAnim;
};extern MiniGameRacingMotor* G_RacingMotorGame;
vec2 Rotate(const vec2& dir,float ang);
vec2 LeftDir(const vec2& dir);
#endif //========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/RacingMotor/MiniGameRacingMotor.cpp
//  @Brief:     MiniGameRacingMotor
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================#include "General/Pch.h"
#include "General/Window.h"
#include "General/Timer.h"
#include "Gui/GuiMgr.h"
#include "Gui/RpgGuis.h"
#include "Gui/GuiControlMisc.h"
#include "Input/InputMgr.h"
//#include "RacingMotor/RacingMotorPlayer.h"
#include "RacingMotor/MiniGameRacingMotor.h"
#include "RacingMotor/MiRacingMotor_PlayGui.h"
#include "Render/RendDriver.h"
#include "Render/Shader.h"
#include "Render/MC_Misc.h"
#include "Rpg/SyncGameInfo.h"
#include "Packet/PacketMiniGame.h"
//#include "Rpg/MiniGame.h"
#include "Net/PacketList.h"
#include "Render/Camera.h"
#include "General/StringUtil.h"
#include "RacingMotorPlayer.h"
#include "General/Pce.h"const char* RacingMotorCmdToString(int enumeration)
{switch(enumeration){case CMD_ManMove :return "CMD_ManMove ";     case CMD_GameOver:return "CMD_GameOver";      case CMD_Restart :return "CMD_Restart ";          default             :return "CMD_unknow";}return "CMD_unknow";
}MiniGameRacingMotor* G_RacingMotorGame;
MiniGameRacingMotor::MiniGameRacingMotor()
{G_RacingMotorGame = this;CmdEnumToString = RacingMotorCmdToString;
}MiniGameRacingMotor::~MiniGameRacingMotor()
{G_RacingMotorGame = NULL;
}bool MiniGameRacingMotor::Start()
{m_myRolePlayer = NULL;if(!MiniGame::Start())return false;m_3dMode = false;if (m_movieScene){Frame frame;frame.SetPos(m_startPos);m_movieScene->SetProgramFrame(&frame);m_movieScene->Advance();}m_gameState  = MS_Gamming;TileNum.x = 0;TileExtend = 32;mapGridNum.x = 200;mapGridNum.y = 100;    mapData = new int[mapGridNum.x*mapGridNum.y];File file;if (file.Fopen("data/minigame/racingmotor/map.txt","rt")){file.ReadInt();file.ReadInt();for (int y=0;y<mapGridNum.y;++y){for (int x=0;x<mapGridNum.x;++x){mapData[y*mapGridNum.x+x] = file.ReadInt();}}}mapExtend.x = mapGridNum.y * TileExtend;mapExtend.y = mapGridNum.x * TileExtend - 300;enumX0 = 0;enumX1 = 1;enumX2 = 2;const20 = 20;const18_ = 18;const20_ = 20;const4 =4;m_roadSegmentNum = 0;roadSegPartionX = 0;roadSegPartionY = 0;m_expandSegmentNum = 0;expandSegPartionX = 0;expandSegPartionY = 0;vec2 _leftArr[]  = {vec2(-10 , -70 )  , vec2(-50 , -50)  , vec2(15  , -43 ) , vec2(15  , -43 ) , vec2(-5  , -5 ) , vec2(-5  , -5 ) };vec2 _elseArr[]  = {vec2(0   , -85 )  , vec2(-10 , -45)  , vec2(15  , -43 ) , vec2(15  , -43 ) , vec2(-5  , -5 ) , vec2(-5  , -5 ) };vec2 _rightArr[] = {vec2(50  , -75 )  , vec2(10  , -50)  , vec2(15  , -43 ) , vec2(15  , -43 ) , vec2(-5  , -5 ) , vec2(-5  , -5 ) };vec2 _ZArr[]     = {vec2(50  , -65 )  , vec2(10  , -70)  , vec2(15  , -43 ) , vec2(15  , -43 ) , vec2(-15 , -95) , vec2(-20 , -85) };vec2 _XArr[]     = {vec2(-10 , -60 )  , vec2(-50 , -55)  , vec2(-15 , -30 ) , vec2(-15 , -30 ) , vec2(-95 , -75) , vec2(-90 , -85) };vec2 _CArr[]     = {vec2(25  , -90 )  , vec2(40  , -50)  , vec2(15  , -43 ) , vec2(15  , -43 ) , vec2(75  , -55) , vec2(80  , -60) };vec2 _VArr[]     = {vec2(-40 , -100)  , vec2(-15 , -45)  , vec2(-65 , -110) , vec2(-45 , -120) , vec2(20  , -32) , vec2(20  , -32) };vec2 _BArr[]     = {vec2(-50 , -45 )  , vec2(-10 , -35)  , vec2(-70 , -25 ) , vec2(-65 , -70 ) , vec2(40  , -35) , vec2(40  , -40) };for(int i=0;i<6;++i) {backAnim .bonePos[i]  = _leftArr [i];normalAnim .bonePos[i]  = _elseArr [i];frontAnim.bonePos[i]  = _rightArr[i];skillZAnim    .bonePos[i]  = _ZArr    [i];skillXAnim    .bonePos[i]  = _XArr    [i];skillCAnim    .bonePos[i]  = _CArr    [i];skillVAnim    .bonePos[i]  = _VArr    [i];skillBAnim    .bonePos[i]  = _BArr    [i];}backAnim .boneNum  = 6;normalAnim .boneNum  = 6;frontAnim.boneNum  = 6;skillZAnim    .boneNum  = 6;skillXAnim    .boneNum  = 6;skillCAnim    .boneNum  = 6;skillVAnim    .boneNum  = 6;skillBAnim    .boneNum  = 6;m_texTile  = new Texture(true);m_texTile->LoadTexture("data/minigame/racingmotor/ground.png");G_TextureMgr->AddTexture(m_texBack,"data/minigame/racingmotor/back.png");TileNum.x = ceil(var(m_texTile->GetWidth())/ TileExtend);TileNum.y = ceil(var(m_texTile->GetHeight())/ TileExtend);InitMap();InitRoadSegments();//进入miniplaygui,(选人、选关卡都已在房间里进行完毕)。if(GetStyle()) G_GuiMgr->PushGui(GetStyle()->playGUI.c_str(),GL_DIALOG);//for(int i = 0; i < m_allPlayerNum; i++){if(m_miniPlayer[i])m_miniPlayer[i]->Start();}//设置摄像机CameraCtrlerTarget* ctrler = new CameraCtrlerTarget(100,2000);ctrler->SetDistToTar(500);ctrler->SetTarPos(m_startPos);G_Camera->PushCtrler(ctrler);G_Camera->SetEuler(0, -60, 0);//片头摄像机PushIntroCamera();return true;
}MiniPlayer* MiniGameRacingMotor::CreatePlayer()
{return new RacingMotorPlayer;
}MiniPlayer* MiniGameRacingMotor::CreateRobot()
{return new RacingMotorPlayerRobot;
}MiniPlayer* MiniGameRacingMotor::CreateRole()
{m_myRolePlayer = new RacingMotorPlayerRole;return m_myRolePlayer;
}bool MiniGameRacingMotor::Stop()
{G_Camera->PopCtrler();//CameraCtrlerTarget* ctrlerTarget = G_Camera->IsCurCtrler<CameraCtrlerTarget>();//if(ctrlerTarget)//   ctrlerTarget->SetTarEntity(G_MyRole);{if (m_myPlayer && m_myPlayer->m_liveNum>0){G_GuiMgr->GetGui<Rpg_ResultDialog>()->ShowResult(true);}else{G_GuiMgr->GetGui<Rpg_ResultDialog>()->ShowResult(false);}G_GuiMgr->PushGui("Rpg_ResultDialog",GL_DIALOGBOTTOM); }return MiniGame::Stop();
}bool MiniGameRacingMotor::KeepResource(bool once,int& circle,String& nextTip)
{//if (m_movieScene == NULL){LoadConfig loader(LoadConfig::GenDonotReShrinkBound, true, true);m_movieScene = new RendSys::MovieClip;m_movieScene->LoadFromFile("data/minigame/RacingMotor/RacingMotorscene.movie", &loader);Frame frame;frame.SetPos(m_startPos);m_movieScene->SetProgramFrame(&frame);m_movieScene->Advance();}if (m_movieScene->IsLoadComplete() == false){m_gameState = MS_End;return false;}return true;
}bool MiniGameRacingMotor::Render()
{if (m_texBack){G_RendDriver->Color4f(1,1,1,1);G_RendDriver->SetRenderStateEnable(RS_TEXTURE_2D,true);G_RendDriver->SetRenderStateEnable(RS_BLEND,true);G_RendDriver->BlendFunc(Blend_Filter);m_texBack->Bind(); //G_RendDriver->RendTextureRect(RectF(bikePos[BikeBody].x-400,bikePos[BikeBody].y-300,800,600),RectF(0,1,1,-1));G_RendDriver->BeginUI();G_RendDriver->DrawTextureRect(RectF(0,0,G_Window->m_iWidth,G_Window->m_iHeight),RectF(0,0,1,1));G_RendDriver->EndUI();}if (m_texTile){for (int i=0;i<1;i++){G_RendDriver->SetSamplerState(i, SS_MINFILTER, TF_POINT);G_RendDriver->SetSamplerState(i, SS_MAGFILTER, TF_POINT);G_RendDriver->SetSamplerState(i, SS_ADDRESSU, TA_CLAMP);G_RendDriver->SetSamplerState(i, SS_ADDRESSV, TA_CLAMP);}G_RendDriver->Color4f(1,1,1,1);G_RendDriver->SetRenderStateEnable(RS_TEXTURE_2D,true);G_RendDriver->SetRenderStateEnable(RS_BLEND,true);G_RendDriver->BlendFunc(Blend_Filter);m_texTile->Bind();int bx = m_myRolePlayer->m_bikePos[BikeBody].x / TileExtend;int by = m_myRolePlayer->m_bikePos[BikeBody].y / TileExtend;Clamp(bx,0,mapGridNum.x-1);Clamp(by,0,mapGridNum.y-1);float minX = bx - 50;float maxX = bx + 50;float minY = by - 40;float maxY = by + 40;Clamp(minX,0,mapGridNum.x-1);Clamp(maxX,0,mapGridNum.x-1);Clamp(minY,0,mapGridNum.y-1);Clamp(maxY,0,mapGridNum.y-1);vec2   halfPixel(1.0f/m_texTile->GetWidth(),1.0f/m_texTile->GetHeight());double tExtendX = 1.0/TileNum.x;double tExtendY = 1.0/TileNum.y;vec2 tex[4];vec3 pos[4];G_RendDriver->RendBegin(RS_QUADS);for (int y = minY; y <= maxY; ++y){for (int x = minX; x <= maxX; ++x){int   data = mapData[y*mapGridNum.x +x];float rx = x*TileExtend;float ry = y*TileExtend;float tx = (data%TileNum.x)*tExtendX;float ty = (/*TileNum.y-1-*/data/TileNum.x)*tExtendY;pos[0] = vec3(rx,ry,0);pos[1] = vec3(rx,ry+TileExtend,0);pos[2] = vec3(rx+TileExtend,ry+TileExtend,0);        pos[3] = vec3(rx+TileExtend,ry,0);tex[0] = vec2(tx+halfPixel.x,ty+halfPixel.y);tex[1] = vec2(tx+halfPixel.x,ty+tExtendY);tex[2] = vec2(tx+tExtendX, ty+tExtendY);        tex[3] = vec2(tx+tExtendX, ty+halfPixel.y);if(data>0){for (int i=0;i<4;i++){G_RendDriver->TexCoord2f(tex[i].x,tex[i].y);G_RendDriver->Vertex3fv(&pos[i].x);}}} }      G_RendDriver->RendEnd();//for (int i=0;i<1;i++){G_RendDriver->SetSamplerState(i, SS_MINFILTER, TF_LINEAR);G_RendDriver->SetSamplerState(i, SS_MAGFILTER, TF_LINEAR);G_RendDriver->SetSamplerState(i, SS_ADDRESSU, TA_WRAP);G_RendDriver->SetSamplerState(i, SS_ADDRESSV, TA_WRAP);}}//for(int i = 0; i < m_allPlayerNum; i++){dynamic_cast<RacingMotorPlayer*>(m_miniPlayer[i])->Render();}G_RendDriver->DisableRendState(RS_TEXTURE_2D);G_RendDriver->DisableRendState(RS_LIGHTING);G_RendDriver->SetLineWidth(1);G_RendDriver->Color3f(1, 0, 0);  G_RendDriver->RendBegin(RS_LINES);for (int i = 0; i < m_roadSegmentNum; ++i){RoadSegment* seg = &m_roadSegments[i];if (seg->data==0)      G_RendDriver->Color3f(1, 0, 0); else if (seg->data==1) G_RendDriver->Color3f(1, 1, 0);  else if (seg->data==2) G_RendDriver->Color3f(1, 1, 1);  G_RendDriver->Vertex3f(seg->p1.x,seg->p1.y,0);G_RendDriver->Vertex3f(seg->p2.x,seg->p2.y,0);}G_RendDriver->RendEnd();G_RendDriver->Color3f(0, 1, 0);    G_RendDriver->RendBegin(RS_LINES);for (int i = 0; i < m_expandSegmentNum; ++i){RoadSegment* eSeg = &m_expandSegments[i];if (eSeg->data==0)      G_RendDriver->Color3f(0, 1, 0);   else if (eSeg->data==1) G_RendDriver->Color3f(0, 1, 1); else if (eSeg->data==2) G_RendDriver->Color3f(1, 1, 1); G_RendDriver->Vertex3f(eSeg->p1.x,eSeg->p1.y,0);G_RendDriver->Vertex3f(eSeg->p2.x,eSeg->p2.y,0);}G_RendDriver->RendEnd();G_RendDriver->EnableRendState(RS_LIGHTING);return true;
}void MiniGameRacingMotor::RenderUI()
{MiniGame::RenderUI();
}
bool MiniGameRacingMotor::Update()
{m_turnTime  += G_Timer->GetStepTimeLimited();MiRacingMotor_PlayGui* playGui = G_GuiMgr->GetGui<MiRacingMotor_PlayGui>();m_movieScene->Advance();for(int i = 0; i < m_allPlayerNum; i++){dynamic_cast<RacingMotorPlayer*>(m_miniPlayer[i])->Update();}CameraCtrlerTarget* ctrler = G_Camera->IsCurCtrler<CameraCtrlerTarget>();if (ctrler){G_Camera->SetDir(vec3(0,0,1),vec3(0,-1,0));G_Camera->SetEyePos(vec3(m_myRolePlayer->m_bikePos[BikeBody].x,m_myRolePlayer->m_bikePos[BikeBody].y,0) - G_Camera->GetHeadDir()*ctrler->GetDistToTar());}return true;
}bool MiniGameRacingMotor::Free()
{MiniGame::Free();return true;
}bool MiniGameRacingMotor::IsEnd()
{return m_gameState == MS_End;
}int  MiniGameRacingMotor::ProcessPacketCmd(PacketBase* packet)
{int cmd;int roomSlot;packet->ReadValue(cmd);switch(cmd){case CMD_ManMove:{packet->ReadValue(roomSlot);       RacingMotorPlayer* player = dynamic_cast<RacingMotorPlayer*>(GetPlayerFromSlot(roomSlot));if (player){for (int i=0;i<5;i++){packet->ReadValue(player->m_bikePos[i]);}for (int i=0;i<bonePosNum;i++){packet->ReadValue(player->m_bonePos[i]);}    }}break;case CMD_GameOver:break;case CMD_Restart:// Free();//   Start();break;}return 0;
}
void MiniGameRacingMotor::InitMap()
{m_expandSegmentNum = 0;for (int y = 0; y < mapGridNum.y; y++){for (int x = 0; x < mapGridNum.x; x++){vec2 tt;tt.x = x * TileExtend;tt.y = y * TileExtend;int data = mapData[y*mapGridNum.x +x];std::vector<int>& kk = arrKK[data];vec2 dd,ff,pp,qq,m3,m4,m5,m6;for (int m = 0; m < kk.size(); m = m + 5){dd.x = kk[m + 0] + tt.x;dd.y = kk[m + 1] + tt.y;ff.x = kk[m + 2] + tt.x;ff.y = kk[m + 3] + tt.y;vec2 leftDir = LeftDir(ff - dd);pp = dd + leftDir * const18_;qq = ff + leftDir * const18_;for (int n = 0; n < kk.size(); n = n + 5){if (m != n){m3.x = kk[n + 0] + tt.x;m3.y = kk[n + 1] + tt.y;m4.x = kk[n + 2] + tt.x;m4.y = kk[n + 3] + tt.y;leftDir = LeftDir(m4 - m3);m5 = m3 + leftDir * const18_;m6 = m4 + leftDir * const18_;if (IsEqual(dd, m4) == true){pp = (m6 + pp) * 0.5;} if (IsEqual(ff, m3) == true){qq = (m5 + qq) * 0.5;} } } int dir[] = {-1, 0, -1, -1, 0, -1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1};for (int i = 0; i < 16; i =  i + 2){int nx = x + dir[ i + 0];int ny = y + dir[ i + 1];if (nx >= 0 && nx < mapGridNum.x && ny >= 0 && ny < mapGridNum.y){data = mapData[ny*mapGridNum.x+nx];std::vector<int>& kkn = arrKK[data];var _loc17 = nx * TileExtend;var _loc18 = ny * TileExtend;for (int k = 0; k < kkn.size(); k = k + 5){m3.x = kkn[k + 0] + _loc17;m3.y = kkn[k + 1] + _loc18;m4.x = kkn[k + 2] + _loc17;m4.y = kkn[k + 3] + _loc18;leftDir = LeftDir(m4 - m3);m5 = m3 + leftDir * const18_;m6 = m4 + leftDir * const18_;if (IsEqual(dd, m4) == true){pp = (m6 + pp) * 0.5;} if (IsEqual(ff, m3) == true){qq = (m5 + qq) * 0.5;} } } } leftDir = LeftDir(qq - pp);RoadSegment* eSeg = &m_expandSegments[m_expandSegmentNum];eSeg->p1.x = pp.x;eSeg->p1.y = pp.y;eSeg->p2.x = qq.x;eSeg->p2.y = qq.y;eSeg->leftDir = leftDir;eSeg->data = kk[m + 4];++m_expandSegmentNum;}} } RoadSegment* eSeg = &m_expandSegments[m_expandSegmentNum];eSeg->p1.x = const18_; eSeg->p1.y = mapGridNum.y * TileExtend;eSeg->p2.x = const18_; eSeg->p2.y = 0; eSeg->leftDir.x = 1; eSeg->leftDir.y = 0; eSeg->data = enumX1;++m_expandSegmentNum;eSeg = &m_expandSegments[m_expandSegmentNum];eSeg->p1.x = mapGridNum.x * TileExtend - const18_; eSeg->p1.y = 0; eSeg->p2.x = mapGridNum.x * TileExtend - const18_;eSeg->p2.y = mapGridNum.y * TileExtend; eSeg->leftDir.x = -1; eSeg->leftDir.y = 0; eSeg->data = enumX1;++m_expandSegmentNum;eSeg = &m_expandSegments[m_expandSegmentNum];eSeg->p1.x = 0; eSeg->p1.y = const18_; eSeg->p2.x = mapGridNum.x * TileExtend; eSeg->p2.y = const18_; eSeg->leftDir.x = 0; eSeg->leftDir.y = 1; eSeg->data = enumX1;++m_expandSegmentNum;PartionExpandSegment();
}
void MiniGameRacingMotor::PartionExpandSegment()
{expandSegPartionX = ceil(mapGridNum.x * TileExtend / const20);expandSegPartionY = ceil(mapGridNum.y * TileExtend / const20);expandSegPartion = new std::vector<int>[expandSegPartionY*expandSegPartionX];for (int i = 0; i < m_expandSegmentNum; ++i){RoadSegment* eSeg = &m_expandSegments[i];int minX = eSeg->p1.x;if (eSeg->p2.x < minX){minX = eSeg->p2.x;} int minY = eSeg->p1.y;if (eSeg->p2.y < minY){minY = eSeg->p2.y;} int maxX = eSeg->p1.x;if (eSeg->p2.x > maxX){maxX = eSeg->p2.x;} int maxY = eSeg->p1.y;if (eSeg->p2.y > maxY){maxY = eSeg->p2.y;} minX = (minX / const20);minY = (minY / const20);maxX = (maxX / const20);maxY = (maxY / const20);minX = max(minX, 0);minY = max(minY, 0);maxX = min(maxX, expandSegPartionX - 1);maxY = min(maxY, expandSegPartionY - 1);for (int y = minY; y <= maxY; ++y){for (int x = minX; x <= maxX; ++x){(expandSegPartion[y*expandSegPartionX+x]).push_back(i);} } }
}void MiniGameRacingMotor::PartionRoadSegment()
{for (int i = 0; i < m_roadSegmentNum; ++i){RoadSegment* seg = &m_roadSegments[i];var minX = seg->p1.x;if (seg->p2.x < minX){minX = seg->p2.x;} var minY = seg->p1.y;if (seg->p2.y < minY){minY = seg->p2.y;} var maxX = seg->p1.x;if (seg->p2.x > maxX){maxX = seg->p2.x;} var maxY = seg->p1.y;if (seg->p2.y > maxY){maxY = seg->p2.y;} minX = floor(minX / const20_);minY = floor(minY / const20_);maxX = floor(maxX / const20_);maxY = floor(maxY / const20_);minX = max(minX, 0);minY = max(minY, 0);maxX = min(maxX, roadSegPartionX - 1);maxY = min(maxY, roadSegPartionY - 1);for (int y = minY; y <= maxY; ++y){for (int x = minX; x <= maxX; ++x){(roadSegPartion[y*roadSegPartionX+x]).push_back(i);} } }
}void MiniGameRacingMotor::InitRoadSegments()
{for (int y = 0; y < mapGridNum.y; ++y){for (int x = 0; x < mapGridNum.x; ++x){vec2 tt;tt.x = x * TileExtend;tt.y = y * TileExtend;int data = mapData[y*mapGridNum.x +x];std::vector<int>& kk = arrKK[data];vec2 dd,ff,pp,qq,m3,m4,m5,m6;for (int m = 0; m < kk.size(); m = m + 5){dd.x = kk[m + 0] + tt.x;dd.y = kk[m + 1] + tt.y;ff.x = kk[m + 2] + tt.x;ff.y = kk[m + 3] + tt.y;vec2 leftDir = LeftDir(ff - dd);pp = dd + leftDir * const4;qq = ff + leftDir * const4;for (int n = 0; n < kk.size(); n = n + 5){if (m != n){m3.x = kk[n + 0] + tt.x;m3.y = kk[n + 1] + tt.y;m4.x = kk[n + 2] + tt.x;m4.y = kk[n + 3] + tt.y;leftDir = LeftDir(m4 - m3);m5 = m3 + leftDir * const4;m6 = m4 + leftDir * const4;if (IsEqual(dd, m4) == true){pp = (m6 + pp) * 0.5;} if (IsEqual(ff, m3) == true){qq = (m5 + qq) * 0.5;} } } int dir[] = {-1, 0, -1, -1, 0, -1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1};for (int i = 0; i < 16; i = i + 2){int nx = x + dir[i + 0];int ny = y + dir[i + 1];if (nx >= 0 && nx < mapGridNum.x && ny >= 0 && ny < mapGridNum.y){data = mapData[ny*mapGridNum.x+nx];std::vector<int>& _loc3 = arrKK[data];var _loc17 = nx * TileExtend;var _loc18 = ny * TileExtend;for (int k = 0; k < _loc3.size(); k = k + 5){m3.x = _loc3[k + 0] + _loc17;m3.y = _loc3[k + 1] + _loc18;m4.x = _loc3[k + 2] + _loc17;m4.y = _loc3[k + 3] + _loc18;leftDir = LeftDir(m4 - m3);m5 = m3 + leftDir * const4;m6 = m4 + leftDir * const4;if (IsEqual(dd, m4) == true){pp = (m6 + pp) * 0.5;} if (IsEqual(ff, m3) == true){qq = (m5 + qq) * 0.5;} } } } leftDir = LeftDir(qq - pp);RoadSegment* seg = &m_roadSegments[m_roadSegmentNum];seg->p1.x = pp.x; seg->p1.y = pp.y; seg->p2.x = qq.x; seg->p2.y = qq.y; seg->leftDir.x = leftDir[0]; seg->leftDir.y = leftDir[1]; seg->data = kk[m + 4];++m_roadSegmentNum;}} } RoadSegment* seg = &m_roadSegments[m_roadSegmentNum];seg->p1.x = const4; seg->p1.y = mapGridNum.y * TileExtend; seg->p2.x = const4; seg->p2.y = 0;seg->leftDir.x = 1; seg->leftDir.y = 0; seg->data = enumX1;++m_roadSegmentNum;seg = &m_roadSegments[m_roadSegmentNum];seg->p1.x = mapGridNum.x * TileExtend - const4;seg->p1.y = 0; seg->p2.x = mapGridNum.x * TileExtend - const4; seg->p2.y = mapGridNum.y * TileExtend;seg->leftDir.x = -1; seg->leftDir.y = 0;seg->data = enumX1;++m_roadSegmentNum;seg = &m_roadSegments[m_roadSegmentNum];seg->p1.x = 0; seg->p1.y = const4; seg->p2.x = /*q0a05 **/ TileExtend; seg->p2.y = const4;seg->leftDir.x = 0;seg->leftDir.y = 1; seg->data = enumX1;++m_roadSegmentNum;roadSegPartionX = ceil(mapGridNum.x * TileExtend / const20_);roadSegPartionY = ceil(mapGridNum.y * TileExtend / const20_);roadSegPartion = new std::vector<int>[roadSegPartionX*roadSegPartionY];PartionRoadSegment();
}bool MiniGameRacingMotor::CollideSegment(const vec2& p1,const vec2& p2, RoadSegment* seg,vec2& res)
{//p1 from  p2 tovec2 dif1 = p1 - seg->p1;var dot = seg->leftDir.Dot(dif1);if (dot < 0){return false;} vec2 difSeg = seg->p2 - seg->p1;vec2 difMov = p2 - p1;var c12 = difSeg.Cross(dif1);var c23 = difMov.Cross(difSeg);var c13 = difMov.Cross(dif1);if (c23 == 0) //[p1 p2] 平行  [seg->p1 seg->p2] {return false;} var _loc10 = c12 / c23;var _loc11 = c13 / c23;if (_loc10 < 0 || _loc10 > 1){return false;} if (_loc11 < 0 || _loc11 > 1){return false;} vec2 dif2 = p2 - seg->p1;dot = seg->leftDir.Dot(dif2) - 0.1f;res = p2 - seg->leftDir * dot;return true;
}bool MiniGameRacingMotor::CollideRoad(const vec2& p1,const vec2& p2_,Contact& res)
{vec2 p2 = p2_;var minX = p1.x;if (p2.x < minX){minX = p2.x;} var minY = p1.y;if (p2.y < minY){minY = p2.y;} var maxX = p1.x;if (p2.x > maxX){maxX = p2.x;} var maxY = p1.y;if (p2.y > maxY){maxY = p2.y;} var _loc23 = maxX - minX;var _loc21 = maxY - minY;var _loc22 = max(_loc23, _loc21);var _loc20 = _loc22 * 0.5 + 1;minX -= _loc20;maxX += _loc20;minY -= _loc20;maxY += _loc20;minX = floor(minX / const20_);minY = floor(minY / const20_);maxX = floor(maxX / const20_);maxY = floor(maxY / const20_);if (maxX < 0){return false;} if (maxY < 0){return false;} if (minX >= roadSegPartionX){return false;} if (minY >= roadSegPartionY){return false;} minX = max(minX, 0);minY = max(minY, 0);maxX = min(maxX, roadSegPartionX - 1);maxY = min(maxY, roadSegPartionY - 1);RoadSegment* seg = NULL;bool find = false;while (find == false){find = true;for (int y = minY; y <= maxY; ++y){for (int x = minX; x <= maxX; ++x){std::vector<int>& item = roadSegPartion[y*roadSegPartionX+x];int num = item.size();for (int i = 0; i < num; ++i){vec2 _loc2;RoadSegment* segit = &m_roadSegments[item[i]];if (CollideSegment(p1, p2,segit ,_loc2)){find = false;p2 = _loc2;seg = segit;} } } } } if (seg == NULL){return false;}else{res.point = p2;res.normal = seg->leftDir;res.data = seg->data;return true;}
}bool MiniGameRacingMotor::CollideExpand(const vec2& p1,const vec2& p2_,Contact& res)
{vec2 p2 = p2_;int minX = p1.x;if (p2.x < minX){minX = p2.x;} int minY = p1.y;if (p2.y < minY){minY = p2.y;} int maxX = p1.x;if (p2.x > maxX){maxX = p2.x;} int maxY = p1.y;if (p2.y > maxY){maxY = p2.y;} int extendX = maxX - minX;int extendY = maxY - minY;int _loc22 = max(extendX, extendY);var radius = _loc22 * 0.5f + 1;minX = minX - radius;maxX = maxX + radius;minY = minY - radius;maxY = maxY + radius;minX = (minX / const20);minY = (minY / const20);maxX = (maxX / const20);maxY = (maxY / const20);if (maxX < 0){return false;} if (maxY < 0){return false;} if (minX >= expandSegPartionX){return false;} if (minY >= expandSegPartionY){return false;} minX = max(minX, 0);minY = max(minY, 0);maxX = min(maxX, expandSegPartionX - 1);maxY = min(maxY, expandSegPartionY - 1);RoadSegment* eSeg = NULL;bool find = false;while (find == false){find = true;for (int y = minY; y <= maxY; ++y){for (int x = minX; x <= maxX; ++x){std::vector<int>& item = expandSegPartion[y*expandSegPartionX+x];int num = item.size();for (int n = 0; n < num; ++n){vec2 _loc2;RoadSegment* segit = &m_expandSegments[item[n]];if (CollideSegment(p1, p2, segit,_loc2)){find = false;p2 = _loc2;eSeg = segit;} } } } } if (eSeg == NULL){return false;}else{res.point = p2;res.normal = eSeg->leftDir;res.data = eSeg->data;return true;}
}bool MiniGameRacingMotor::IsEqual(const vec2& p1,const vec2& p2)
{if (abs(p1.x - p2.x) > 1){return false;} if (abs(p1.y - p2.y) > 1){return false;} return true;
}vec2 LeftDir(const vec2& dir_)
{vec2 dir = dir_;dir.Normalize();return vec2(-dir.y, dir.x);
}vec2 Rotate(const vec2& dir,float ang)
{var cosR = cos(ang);var sinR = sin(ang);vec2 newPos;newPos.x = dir.x * cosR - dir.y * sinR;newPos.y = dir.x * sinR + dir.y * cosR;return newPos;
}

2D横版摩托游戏源码相关推荐

  1. unity3d游戏2d横版射击游戏完整项目源码分享

    unity3d游戏2d横版射击游戏完整项目源码分享 免费下载地址: 链接:https://pan.baidu.com/s/1YwhEy7DeKIHFU8pBLdJFPg 提取码:3wnx 复制这段内容 ...

  2. Unity学习笔记3 简易2D横版RPG游戏制作(三)

    这一篇本来应该是在上一篇后面直接补进去的.不过因为排版的问题.所以我就另开一篇来整理了,好了,废话不多说,马上整理: 十八.关卡的锁定与解锁 前面我们已经解决了在游戏开始时可以选择关卡的问题,接下来我 ...

  3. Unity 4 3 制作一个2D横版射击游戏 2

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 在上一篇 ...

  4. HTML5高度还原复古24层魔塔网页版小游戏源码

    简介: HTML5高度还原复古24层魔塔网页版小游戏源码 网盘下载地址: http://kekewl.cc/OFfi6keX7OS0 图片:

  5. 《游戏学习》| 水果忍者HTML5网页版在线游戏 | 源码分析

    游戏介绍 这是一款由百度JS小组提供的HTML5版切水果游戏,这款基于HTML5实现的网页版切水果游戏虽然和原版的切水果游戏相比仍有美中不足之处,但也算有声有色,画面效果也十分炫目华丽. 游戏截图 主 ...

  6. 【180720】坦克大战电脑版小游戏源码

    本源码是一个坦克大战电脑版小游戏源码,基于C#开发,可进行单人和双人游戏,但是事件有一个控制,可自行修改. 主要功能: 1.单人和双人两种游戏模式,但双人模式控制按键需要自行修改 2.进入游戏后,键盘 ...

  7. Unity 4.3 制作一个2D横版射击游戏(2)

    在上一篇<Unity 4.3 制作一个2D横版射击游戏>时,已经完成一个基本的射击游戏了.在这一篇将继续完善. 1.视差卷轴效果 为了达到这种视差卷轴的效果,可以让背景层以不同的速度进行移 ...

  8. Unity 4 3 制作一个2D横版射击游戏

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 这是一个 ...

  9. Unity 4.3 制作一个2D横版射击游戏

    这是一个横版射击游戏. 教程来自: http://pixelnest.io/tutorials/2d-game-unity/   中文版教程: http://www.litpo.com/categor ...

最新文章

  1. Page与Loaded
  2. 零基础学python需要多久-Python要学习多久能入门?精通需要多久?
  3. 怎么在代码中打开、关闭屏幕旋转
  4. DCMTK:OFStandard中“转换为标记”代码的测试程序
  5. 奇虎360大战腾讯QQ 高潮迭起用户受伤
  6. Java Swing专栏订阅须知《必读》
  7. 以太网帧格式、最少字节介绍(arp)
  8. 有点牛论坛小程序v3.0.16源码
  9. 训练AI太辛苦?OpenAI新方法:不如让AI之间互教吧
  10. 读取properties配置文件的方法
  11. java读取某一行_java 读取指定某一行的文本
  12. 统计自然语言处理第二版 下载
  13. Java新特性(一 · JDK1.5)
  14. 索尼6400夜景测试 镜头索尼18-55
  15. 解析|拼多多爆红背后值得借鉴的思路
  16. vc2010串口通信(使用mscomm控件)
  17. HFSS激励类型----电流源激励
  18. echarts实现中国地图各省背景根据数值大小变化的方法
  19. 物理学的困惑: 个体与交互
  20. iPhone4S安装Linux系统,Absinthe 2.0.4 官网Windows/Mac/Linux原版下载—iPhone4S和iPad2完美越狱工具...

热门文章

  1. UI仿应用宝app下载页面源码
  2. linux 查询挂载信息,linux 查询挂载信息
  3. 使用系统自带计算器进行二进制运算
  4. Serial Programming HOWTO
  5. flink GROUPING SETS多维度聚合、设置Table state 到期时间
  6. Django 学习 之ORM简介与单表操作
  7. 中国式家长——旅行者困境
  8. Deepin20.6直接运行exe文件
  9. 【题解】Comet OJ 夏季欢乐赛(2019)A 完全k叉树⭐⭐ 【思维】
  10. Android手机屏幕不清晰,4大参数如何影响屏幕显示清晰度