#pragma once
#include <math.h>
#include "hge.h"
class CBall
{
public:
CBall();
CBall(float _x,float _y,float _speedX ,float _speedY,float _radius ,DWORD _color,float _density = 1.0f);
~CBall(){};
public:
bool IsCollision(CBall *ball,float dt); //碰撞检测
void CollisionWith(CBall *ball); //弹性正碰
void CollisionWith2(CBall *ball); //弹性斜碰
void SwapColor(CBall *ball); //好玩点,加个交换颜色
void MoveNext(float dt,float _width,float _height);
//由于程序不大,方便起见所有就都public了
public:
float x; //x轴坐标
float y; //y轴坐标
float speed_x; //x轴方向速度
float speed_y; //x轴方向速度
float radius; //球体半径
float density; //密度
float weight; //质量
DWORD color; //混合颜色
};
bool CBall::IsCollision(CBall *ball,float dt)
{
//计算的是下一刻的位置,以免发生粘连
float disX = (this->x+this->speed_x*dt)-(ball->x+ball->speed_x*dt);
float disY = (this->y+this->speed_y*dt)-(ball->y+ball->speed_y*dt);
float dis = sqrt(disX*disX+disY*disY);
//判断下一刻是否 发生碰撞
if(dis < this->radius+ball->radius)
return true;
return false;
}void CBall::CollisionWith2(CBall *ball)
{
//参考资料:
//http://www.cnblogs.com/kenkofox/archive/2011/09/06/2168944.html
//http://tina0152.blog.163.com/blog/static/119447958200910229109326/
//球心点
float x1 = this->x ;
float y1 = this->y ;
float x2 = ball->x ;
float y2 = ball->y ;
//碰撞处切平面向量t,及其法向量s
hgeVector s(x2-x1, y2-y1);
s.Normalize();//标准化矢量
hgeVector t(x2-x1, y2-y1);
t.Rotate(3.1415926f/2);
t.Normalize();
//速度向量
hgeVector v1(this->speed_x,this->speed_y);
hgeVector v2(ball->speed_x,ball->speed_y);
//先算v1(v1x, v1y)在s和t轴的投影值,分别设为v1s和v1t
//再算v2(v2x, v2y)在s和t轴的投影值,分别设为v2s和v2t:
float v1s = v1.Dot(&s);
float v1t = v1.Dot(&t);
float v2s = v2.Dot(&s);
float v2t = v2.Dot(&t);
//转换后于s向量上的弹性正碰撞。质量不等
//弹性正碰撞公式
//v1‘ = [ (m1-m2)*v1 + 2*m2*v2 ] / (m1+m2)
//v2‘ = [ (m2-m1)*v2 + 2*m1*v1 ] / (m1+m2)
float m1 = this->weight;
float m2 = ball->weight;
float temp_v1s = ((m1-m2)*v1s + 2*m2*v2s )/ (m1+m2);
v2s = ((m2-m1)*v2s + 2*m1*v1s )/ (m1+m2);
v1s = temp_v1s;
//首先求出v1t和v2t在t轴的向量v1t‘和v2t‘(将数值变为向量)
//再求出v1s‘和v2s‘在s轴的向量v1s‘和v2s‘(将数值变为向量)
hgeVector v1tVector = t*v1t;
hgeVector v1sVector = s*v1s;
hgeVector v2tVector = t*v2t;
hgeVector v2sVector = s*v2s;
//新速度矢量
hgeVector v1_new = v1tVector+v1sVector;
hgeVector v2_new = v2tVector+v2sVector;
//划分成x,y方向分量速度
this->speed_x = v1_new.x;
this->speed_y = v1_new.y;
ball->speed_x = v2_new.x;
ball->speed_y = v2_new.y;
}
void CBall::MoveNext(float dt,float _width,float _height)
{
float moveX = speed_x*dt;
float moveY = speed_y*dt;
//x方向边界
if (x+moveX<radius||x+moveX>_width-radius)
speed_x = -speed_x;
//Y方向边界
if(y+moveY<radius||y+moveY>_height-radius)
speed_y = -speed_y;
x+=speed_x*dt;
y+=speed_y*dt;
}
#include "hge.h"
#include "hgesprite.h"
#include "hgefont.h"
#include "hgeparticle.h"
#include "Ball.h"
#include "hgecommon.h"
//宏定义
#define WIND_WIDTH 800
#define WIND_HEIGHT 600
HGE *hge=0;
hgeFont *fnt;//字体
HEFFECT snd;//音频
HTEXTURE tex;//加载气泡纹理,即图片
hgeSprite *spr_ball;//气泡精灵
//函数声明
bool LoadRes();
bool InitData();
bool FrameFunc();//回调函数
bool RenderFunc();
//抽象对象Balls
CBall *balls[16];
//全局变量
int g_nBalls = 5;//小球的个数
bool g_bCollision = false;//判断一帧中是否有碰撞
DWORD g_alpha = 0xA0FFFFFF;//设置Alpha透明度,与操作
DWORD g_colors[16] = {g_alpha&0xFFFFFFFF/*纯白色*/,
g_alpha&0xFFFF0000/*红*/,g_alpha&0xFF00FF00/*绿*/,g_alpha&0xFF0000FF/*蓝*/,
g_alpha&0xFFFFFF00/*红绿*/,g_alpha&0xFFFF00FF/*红蓝*/,g_alpha&0xFF00FFFF/*绿蓝*/,
g_alpha&0xFF790000/*淡红*/,g_alpha&0xFF007900/*淡绿*/,g_alpha&0xFF000079/*淡蓝*/,
g_alpha&0xFFFF7900/*红淡绿*/,g_alpha&0xFFFF0079/*红淡蓝*/,
g_alpha&0xFF79FF00/*绿淡红*/,g_alpha&0xFF00FF79/*绿淡蓝*/,
g_alpha&0xFF7900FF/*蓝淡红*/,g_alpha&0xFF0079FF/*蓝淡绿*/};
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
hge = hgeCreate(HGE_VERSION);
hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
hge->System_SetState(HGE_TITLE, "Balls Collision");
hge->System_SetState(HGE_FPS, 100);
hge->System_SetState(HGE_WINDOWED, true);
hge->System_SetState(HGE_HIDEMOUSE,false);
hge->System_SetState(HGE_SCREENWIDTH, WIND_WIDTH);
hge->System_SetState(HGE_SCREENHEIGHT, WIND_HEIGHT);
hge->System_SetState(HGE_SCREENBPP, 32);
if(hge->System_Initiate())
{
//加载资源
if (!LoadRes()||!InitData())
{
//加载资源失败
hge->System_Shutdown();
hge->Release();
}
// Let‘s rock now!,进入消息循环
hge->System_Start();
// 直到任意回调函数返回true时,停止消息循环
delete fnt;
delete spr_ball;
hge->Texture_Free(tex);
hge->Effect_Free(snd);
}
// Clean up and shutdown
hge->System_Shutdown();
hge->Release();
return 0;
}
bool FrameFunc()
{
float dt=hge->Timer_GetDelta();
// Process keys
if (hge->Input_GetKeyState(HGEK_ESCAPE)) return true;
//碰撞检测
for (int i= 0;i<g_nBalls;i++)
{
for(int j = i+1;j<g_nBalls;j++)
{
if(balls[i]->IsCollision(balls[j],dt))
{
balls[i]->CollisionWith2(balls[j]);
balls[i]->SwapColor(balls[j]);
g_bCollision = true;
}
}
}
//撞击声音
if (g_bCollision)
{
hge->Effect_Play(snd);
g_bCollision = false;
}
//balls move
for (int i=0;i<g_nBalls;i++)
{
balls[i]->MoveNext(dt,WIND_WIDTH,WIND_HEIGHT);
}
return false;
}
bool RenderFunc()
{
// 开始绘图
hge->Gfx_BeginScene();
//以0X00000000颜色清屏
hge->Gfx_Clear(0);
//绘制
for (int i=0;i<g_nBalls;i++)
{
spr_ball->SetColor(balls[i]->color);
float temp_scale = 2*balls[i]->radius/spr_ball->GetWidth();
spr_ball->RenderEx(balls[i]->x,balls[i]->y,0,temp_scale,0);
//绘制方向线,与球速度有关,顶点位置为其以当前速度下一秒钟的位置
hge->Gfx_RenderLine(balls[i]->x,balls[i]->y,balls[i]->x+balls[i]->speed_x,balls[i]->y+balls[i]->speed_y,0xFFFF0000);
}
//fps
fnt->printf(5, 5, HGETEXT_LEFT, "FPS:%d (constant)\ndt:%.3f",hge->Timer_GetFPS(),hge->Timer_GetDelta());
//end
hge->Gfx_EndScene();
return false;
}
bool InitData()
{
for(int i=1;i<=g_nBalls;i++)
{
float temp_ratio = 16.0f/g_nBalls;
balls[i-1]= new CBall(150.f*(i%4+1), 100.f*(i/4+1),
80+i*5*temp_ratio, 70, 20+i*2*temp_ratio, g_colors[i%16]);
}
return true;
}
bool LoadRes()
{
fnt = new hgeFont("resource/font1.fnt");
tex = hge->Texture_Load("resource/ball.png");
snd=hge->Effect_Load("resource/Collision.wav");
spr_ball = new hgeSprite(tex,0,0,256,256);
spr_ball->SetHotSpot(spr_ball->GetWidth()/2,spr_ball->GetHeight()/2);
spr_ball->SetBlendMode(BLEND_COLORMUL|BLEND_ALPHABLEND|BLEND_NOZWRITE);
spr_ball->SetColor(0xA00000FF);
if(!fnt || !tex || !spr_ball || !snd)
return false;
return true;
}
C++多小球非对心弹性碰撞(HGE引擎),布布扣,bubuko.com
原文地址:http://blog.csdn.net/y85171642/article/details/25008091