?? race_canvas3d.java
字號:
// for now, simply set speed to 0
carSpeedValue = 0;
UpdateSpeedVect();
}
}
catch (Exception e) {
System.out.println("moveObjects(): update road err: "+e);
}
}
private void UpdateSpeedVect()
{
// car is rotating around Z axis, so move in local car coordinated
// has to be transformed into move in world coordinates.
// take negative Y positions
float x = 0, y = 0;
float v = (float)KDegreeFactor*(float)(myCar.getSpinAngleY());
int angle = (int)v;
x = carSpeedValue*sinTab[angle];
y = (-carSpeedValue)*cosTab[angle];
carSpeedVect.x = (int)x;
carSpeedVect.y = (int)y;
}
private Vector3D triPos = new Vector3D(0,0,0);
// sets which direction (on the road) car is moving - wheather it moves
// forward (growing map index) or it moves back (goes back to 0 in map table)
// function makes sence as long as car is going on a road.
private void updateCarMoveDirection(boolean aUpdateSpeed)
{
if(aUpdateSpeed)
UpdateSpeedVect();
if( !mIsMulti && carSpeedValue == 0 )
return;
myCar.getLocation(aCarPosVect);
int dotProd;
road.getRoadVect(triPos, aCarPosVect);
dotProd = triPos.innerProduct(carSpeedVect);
// dotProd = 0, the angle between road is 90 or 180 degrees;
// for 90 degrees it might be sometimes better to use it as forward
if(dotProd > 0)
carMoveForward = true;
else
carMoveForward = false;
if( mIsMulti && aUpdateSpeed )
{
app.updateCarRemoteSpeedAndPos(aCarPosVect,
myCar.getSpinAngleY(),
carSpeedVect);
mAvatarUpdateStep = 0;
}
}
// iterates through all road unit's elements to find if there is collision
boolean isCarCollidesWithRoadSides()
{
int carPosX = myCar.getPosX();
int carPosY = myCar.getPosY();
RoadUnit unit;
for( int i=0; i<road.getRoadCount(); ++i )
{
unit = road.getUnit(i);
if( carDidSideColision(carPosX, carPosY, unit) ) {
unit = null;
return true;
}
}
unit = null;
return false;
}
// check if there is collision between car and particular road unit
Vector3D mCarBefore = new Vector3D(0,0,0);
Vector3D mCarAfter = new Vector3D(0,0,0);
int mDistBefore, mDistAfter;
private boolean carDidSideColision(int aCarX, int aCarY, RoadUnit aUnit)
{
// get vectors from one points belonging to the wall to the car position
// at the current moment
mCarBefore.set(aUnit.pointB.x - aCarX, aUnit.pointB.y - aCarY, 0);
// after moving with move vector
mCarAfter.set( aUnit.pointB.x - (aCarX + carSpeedVect.x),
aUnit.pointB.y - (aCarY + carSpeedVect.y), 0);
// get dot product of these vectors with wall normal vector
mDistBefore = mCarBefore.innerProduct(aUnit.sideNorm);
mDistAfter = mCarAfter.innerProduct(aUnit.sideNorm);
// if sign is different -> vectors are on the other sides of wall (or on if 0)
if( mDistBefore >= 0 && mDistAfter <= 0 ||
mDistBefore <= 0 && mDistAfter >= 0 )
{
// check if car goes in opposite direction to unit direction vector
// scalar product between vectors is > 0, angle is: -90<angle<90 degrees
if( carSpeedVect.innerProduct(aUnit.sideNorm) > 0 )
return false;
// scale variables (normal vector uses 1 as 4096)
int carSpeedX_s = carSpeedVect.x*4096;
int carSpeedY_s = carSpeedVect.y*4096;
// get reversed vector to what the car wants be moved this turn
Vector3D moveVect_s = new Vector3D(-carSpeedX_s, -carSpeedY_s, 0);
int divisor_s = moveVect_s.innerProduct(aUnit.sideNorm);
// if move is paraller to wall plane -> no possible colision
if( divisor_s == 0 )
return false;
// calculate the collision point, scale some variables first
int carX_s = aCarX*4096;
int carY_s = aCarY*4096;
// calculate vector from colision point to car position point
Vector3D distVect_s = new Vector3D(carX_s - aUnit.pointE.x*4096,
carY_s - aUnit.pointE.y*4096, 0);
// calculate fracture of speed vector that car moves to collision with wall
float speedPart = (float)distVect_s.innerProduct(aUnit.sideNorm) /
(float)divisor_s;
// collision point: car position point moved with calculated part of speed vector
Vector3D colPoint = new Vector3D((carX_s+(int)(speedPart*carSpeedX_s))/4096,
(carY_s+(int)(speedPart*carSpeedY_s))/4096,
0);
// check if collision point is placed inside wall's borders
if( isCollisionInsideWall(colPoint, aUnit.pointB, aUnit.pointE) )
{
doCarColisionResponce(aUnit.side.getSpinAngleZ());
colPoint = null;
return true;
}
else {
colPoint = null;
return false;
}
}
return false;
}
// does responce to car's collision with road unit
private void doCarColisionResponce(int aWallAng)
{
// As a responce to car colision, car gets rotated and speed is decreased.
// Angle is taken from relation between orientation of wall and car movement.
int carAng = myCar.getSpinAngleY() - 2048;
if(carAng == -2048)
carAng = 2048;
int wallAng = -(aWallAng - 1024);
int diff = carAng + wallAng;
if( diff < -4096 )
diff = wallAng - carAng;
if( diff < -1024 && diff < 0 )
diff = 2048 + diff;
if(diff > 2048)
diff = carAng - wallAng;
if( diff > 1024 )
diff = diff - 1024;
// Bounce of the wall.
// I set bounce angle with part of the angle car hit the wall,
// just so it is not an "ideal - (2*diff)" colision and "some energy get's lost".
// This could depend on the speed (i.e. the faster car goes, the more energy
// gets lost on bang - car gets damaged)
myCar.rotate(0, -(diff+diff/4), 0);
// decrease speed value
carSpeedValue = (carSpeedValue / 4);
// update speed vector and car move direction with smaller speed value
updateCarMoveDirection(true);
}
// check if collision point (car-road unit) is inside road unit's borders
private boolean isCollisionInsideWall(Vector3D aTested, Vector3D aPointOne, Vector3D aPointTwo)
{
if( aPointOne.x > aPointTwo.x ) {
if( aPointTwo.x <= aTested.x && aTested.x <= aPointOne.x) {
if( aPointOne.y > aPointTwo.y ) {
if( aPointTwo.y <= aTested.y && aTested.y <= aPointOne.y) {
return true;
}
else
return false;
}
else {
if( aPointOne.y <= aTested.y && aTested.y <= aPointTwo.y) {
return true;
}
else
return false;
}
}
}
else {
if( aPointOne.x <= aTested.x && aTested.x <= aPointTwo.x) {
if( aPointOne.y > aPointTwo.y ) {
if( aPointTwo.y <= aTested.y && aTested.y <= aPointOne.y) {
return true;
}
else
return false;
}
else {
if( aPointOne.y <= aTested.y && aTested.y <= aPointTwo.y ) {
return true;
}
else
return false;
}
}
}
return false;
}
public void updateAvatar( int aPosX, int aPosY, int aRY, int aVx, int aVy )
{
awatarCar.setPositionAndAngle(aPosX, aPosY, aRY);
awatarSpeedVect.x = aVx;
awatarSpeedVect.y = aVy;
// assume awatar moved once while message was sent/received
awatarCar.move(aVx, aVy);
}
private void moveAvatar()
{
awatarCar.move(awatarSpeedVect.x, awatarSpeedVect.y);
// update car's direction periodically, to prevent bad direction used
++mAvatarUpdateStep;
if(mAvatarUpdateStep > 10) {
myCar.getLocation(aCarPosVect);
app.updateCarRemoteSpeedAndPos(aCarPosVect, myCar.getSpinAngleY(), carSpeedVect);
mAvatarUpdateStep = 0;
}
}
private boolean isCarCollisionWithAvatar()
{
if(carSpeedVect.x == 0 && awatarSpeedVect.x == 0 &&
carSpeedVect.y == 0 && awatarSpeedVect.y == 0)
return false;
int distX, distY, distance;
distX = (myCar.move.m03+carSpeedVect.x) - (awatarCar.move.m03+awatarSpeedVect.x);
distY = (myCar.move.m13+carSpeedVect.y) - (awatarCar.move.m13+awatarSpeedVect.y);
distance = distX*distX + distY*distY;
// distance between cars is smaller than their combined radius: we have collision
if (distance <= mCarTwiceRadSqare )
return true;
return false;
}
// when collision signal is received, this function handles it.
public void updateOnColisionSignal(int aPosX, int aPosY, int aRY, int aVx, int aVy)
{
System.out.println("received signal, is in updateOnColisionSignal");
// update out view on awatar's speed and position
awatarCar.setPositionAndAngle(aPosX, aPosY, aRY);
awatarSpeedVect.x = aVx;
awatarSpeedVect.y = aVy;
mAvatarUpdateStep = 0;
// If moveObjects() function is processing, let it finish.
while(true)
{
if(!mMovingFunctionPending)
break;
}
// check if there really was collision between cars,
// assume my car moved once since message was sent by other party
myCar.move(-carSpeedVect.x, -carSpeedVect.y );
moveWorldCam(carSpeedVect.x, -carSpeedVect.y, 0); // camera folows the car
if( isCarCollisionWithAvatar() )
{
// do some collision responce
carAvatarColisionResponce();
// Send responce to awatar: car's current position and speed.
// Tell also awatar its new speed vector after colision.
myCar.getLocation(aCarPosVect);
app.sendColisionBetweenCarsConfirmed(aCarPosVect,
myCar.getSpinAngleY(),
carSpeedVect,
awatarSpeedVect);
System.out.println("updateOnColisionSignal send confirmed");
}
else
{
myCar.move(carSpeedVect.x, carSpeedVect.y );
moveWorldCam(-carSpeedVect.x, carSpeedVect.y, 0); // camera folows the car
// if there was no collision, simply send car's valid parameters
myCar.getLocation(aCarPosVect);
app.sendColisionBetweenCarsNone(aCarPosVect, myCar.getSpinAngleY(), carSpeedVect);
System.out.println("updateOnColisionSignal send none");
}
}
// 1st message that can be received after we've send signal collision message
public void updateColisionConfirmed(Vector3D aAvatarPos, int aAwRY,
Vector3D aAvatarSpeed, Vector3D aCarSpeed)
{
System.out.println("recived colision CONFIRMATION");
// update car's speed vector after collision with the value received from other party
carSpeedVect.set(aCarSpeed);
carSpeedValue = (int)Math.sqrt( (carSpeedVect.x*carSpeedVect.x) +
(carSpeedVect.y*carSpeedVect.y) );
updateCarMoveDirection(false);
// update avatar's position and speed
awatarCar.setPositionAndAngle(aAvatarPos.x, aAvatarPos.y, aAwRY);
awatarSpeedVect.set(aAvatarSpeed);
mAvatarUpdateStep = 0;
repaint();
}
// 2nd message that can be received after we've send signal collision message
public void updateColisionNone(Vector3D aAvatarPos, int aAwRY, Vector3D aAvatarSpeed)
{
System.out.println("recived colision NONE");
awatarCar.setPositionAndAngle(aAvatarPos.x, aAvatarPos.y, aAwRY);
awatarSpeedVect.set(aAvatarSpeed);
mAvatarUpdateStep = 0;
repaint();
}
// as a colision responce do simple swap of speeds between car and awatar
private void carAvatarColisionResponce()
{
int tmpX = carSpeedVect.x;
int tmpY = carSpeedVect.y;
carSpeedVect.x = awatarSpeedVect.x;
carSpeedVect.y = awatarSpeedVect.y;
awatarSpeedVect.x = tmpX;
awatarSpeedVect.y = tmpY;
carSpeedValue = (int)Math.sqrt( (carSpeedVect.x*carSpeedVect.x) +
updateCarMoveDirection(false);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -