X operations(XOPS)に非常に近いFPSゲームを制作・リメイクし、成果物をオープンソースとして公開することを目的としたプロジェクトです。
| Revision | 139 (tree) |
|---|---|
| Time | 2016-08-13 22:38:53 |
| Author | |
人とマップのあたり判定を改善。人が立てない斜面への処理を改良。
| @@ -68,7 +68,7 @@ | ||
| 68 | 68 | #define HUMAN_MAPCOLLISION_R 5.0f //!< 人とマップの当たり判定 半径 |
| 69 | 69 | #define HUMAN_MAPCOLLISION_HEIGTH 10.2f //!< 人とマップの当たり判定 高さ(注:腰程度) |
| 70 | 70 | #define HUMAN_MAPCOLLISION_SLOPEANGLE DegreeToRadian(50) //!< 人とマップの当たり判定 登れない斜面の角度 |
| 71 | -#define HUMAN_MAPCOLLISION_SLOPEFORCE 1.0f //!< 人とマップの当たり判定 登れない斜面が人を押し出す力 | |
| 71 | +#define HUMAN_MAPCOLLISION_SLOPEFORCEANGLE DegreeToRadian(22.62f) //!< 人とマップの当たり判定 登れない斜面が人を押し出す角度 | |
| 72 | 72 | #define HUMAN_DEADLINE -100.0f //!< 人が死亡するY座標(デッドライン) |
| 73 | 73 | #define HUMAN_DEADADDRY DegreeToRadian(0.75f) //!< 死体の倒れる加速度 |
| 74 | 74 |
| @@ -1284,6 +1284,8 @@ | ||
| 1284 | 1284 | float Dist; |
| 1285 | 1285 | float FallDistance; |
| 1286 | 1286 | float offset; |
| 1287 | + float move_x2 = move_x; | |
| 1288 | + float move_z2 = move_z; | |
| 1287 | 1289 | |
| 1288 | 1290 | //足元ギリギリは当たり判定から除外する |
| 1289 | 1291 | offset = 0.1f; |
| @@ -1335,9 +1337,20 @@ | ||
| 1335 | 1337 | //地面と認めない (ジャンプ対策) |
| 1336 | 1338 | move_y_flag = true; |
| 1337 | 1339 | |
| 1340 | + float angvx = atan2(bdata.material[face].vz, bdata.material[face].vx); | |
| 1341 | + float angvy = acos(bdata.material[face].vy); | |
| 1342 | + | |
| 1343 | + //押し出す力の決定 | |
| 1344 | + //y = -0.6*x*x + 1.9*x - 0.2 | |
| 1345 | + float force = -0.6f*angvy*angvy + 1.9f*angvy - 0.2f; | |
| 1346 | + | |
| 1338 | 1347 | //押し出す |
| 1339 | - move_x += bdata.material[face].vx * HUMAN_MAPCOLLISION_SLOPEFORCE; | |
| 1340 | - move_z += bdata.material[face].vz * HUMAN_MAPCOLLISION_SLOPEFORCE; | |
| 1348 | + move_x = cos(angvx) * cos(HUMAN_MAPCOLLISION_SLOPEFORCEANGLE) * force; | |
| 1349 | + move_y = sin(HUMAN_MAPCOLLISION_SLOPEFORCEANGLE) * force; | |
| 1350 | + move_z = sin(angvx) * cos(HUMAN_MAPCOLLISION_SLOPEFORCEANGLE) * force; | |
| 1351 | + | |
| 1352 | + move_x2 = move_x; | |
| 1353 | + move_z2 = move_z; | |
| 1341 | 1354 | } |
| 1342 | 1355 | else{ |
| 1343 | 1356 | move_y_flag = false; |
| @@ -1359,9 +1372,9 @@ | ||
| 1359 | 1372 | // 水平方向のあたり判定(移動) |
| 1360 | 1373 | //-------------------------------------------------- |
| 1361 | 1374 | |
| 1362 | - if( (move_x*move_x + move_z*move_z) ){ | |
| 1375 | + if( (move_x2*move_x2 + move_z2*move_z2) ){ | |
| 1363 | 1376 | int surface; |
| 1364 | - float ang = atan2(move_z, move_x); | |
| 1377 | + float ang = atan2(move_z2, move_x2); | |
| 1365 | 1378 | float newpos_x, newpos_y, newpos_z; |
| 1366 | 1379 | |
| 1367 | 1380 | //腰付近を当たり判定 |
| @@ -1379,18 +1392,18 @@ | ||
| 1379 | 1392 | if( surface != -1 ){ |
| 1380 | 1393 | //HUMAN_MAPCOLLISION_R 分の先を調べる |
| 1381 | 1394 | if( CollD->CheckBlockInside(i, pos_x + cos(ang)*HUMAN_MAPCOLLISION_R, pos_y + HUMAN_MAPCOLLISION_HEIGTH, pos_z + sin(ang)*HUMAN_MAPCOLLISION_R, true, NULL) == true ){ |
| 1382 | - CollD->ScratchVector(i, surface, move_x, vy, move_z, &move_x, &vy, &move_z); | |
| 1395 | + CollD->ScratchVector(i, surface, move_x2, vy, move_z2, &move_x2, &vy, &move_z2); | |
| 1383 | 1396 | } |
| 1384 | 1397 | |
| 1385 | 1398 | //左右90度づつを調べる |
| 1386 | 1399 | if( CollD->CheckBlockInside(i, pos_x + cos(ang + (float)M_PI/2)*HUMAN_MAPCOLLISION_R, pos_y + HUMAN_MAPCOLLISION_HEIGTH, pos_z + sin(ang + (float)M_PI/2)*HUMAN_MAPCOLLISION_R, true, NULL) == true ){ |
| 1387 | 1400 | if( CollD->CheckPolygonFrontRx(i, surface, ang) == true ){ //進行方向に対して表向きなら〜 |
| 1388 | - CollD->ScratchVector(i, surface, move_x, vy, move_z, &move_x, &vy, &move_z); | |
| 1401 | + CollD->ScratchVector(i, surface, move_x2, vy, move_z2, &move_x2, &vy, &move_z2); | |
| 1389 | 1402 | } |
| 1390 | 1403 | } |
| 1391 | 1404 | if( CollD->CheckBlockInside(i, pos_x + cos(ang - (float)M_PI/2)*HUMAN_MAPCOLLISION_R, pos_y + HUMAN_MAPCOLLISION_HEIGTH, pos_z + sin(ang - (float)M_PI/2)*HUMAN_MAPCOLLISION_R, true, NULL) == true ){ |
| 1392 | 1405 | if( CollD->CheckPolygonFrontRx(i, surface, ang) == true ){ //進行方向に対して表向きなら〜 |
| 1393 | - CollD->ScratchVector(i, surface, move_x, vy, move_z, &move_x, &vy, &move_z); | |
| 1406 | + CollD->ScratchVector(i, surface, move_x2, vy, move_z2, &move_x2, &vy, &move_z2); | |
| 1394 | 1407 | } |
| 1395 | 1408 | } |
| 1396 | 1409 | } |
| @@ -1398,8 +1411,8 @@ | ||
| 1398 | 1411 | } |
| 1399 | 1412 | |
| 1400 | 1413 | //進行方向を示すベクトルを算出 |
| 1401 | - vx = move_x; | |
| 1402 | - vz = move_z; | |
| 1414 | + vx = move_x2; | |
| 1415 | + vz = move_z2; | |
| 1403 | 1416 | speed = sqrt(vx*vx + vz*vz); |
| 1404 | 1417 | if( speed > 0.0f ){ |
| 1405 | 1418 | vx = vx / speed; |
| @@ -1409,7 +1422,7 @@ | ||
| 1409 | 1422 | //頭を当たり判定 |
| 1410 | 1423 | if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y + HUMAN_HEIGTH, pos_z, vx, 0, vz, NULL, NULL, &Dist, speed) == true ){ |
| 1411 | 1424 | CollD->CheckALLBlockIntersectRay(pos_x, pos_y + FallDistance + HUMAN_HEIGTH, pos_z, vx, 0, vz, &id, &face, &Dist, speed); |
| 1412 | - CollD->ScratchVector(id, face, move_x, vy, move_z, &move_x, &vy, &move_z); | |
| 1425 | + CollD->ScratchVector(id, face, move_x2, vy, move_z2, &move_x2, &vy, &move_z2); | |
| 1413 | 1426 | } |
| 1414 | 1427 | |
| 1415 | 1428 | //足元がブロックに埋まっていなければ |
| @@ -1416,8 +1429,8 @@ | ||
| 1416 | 1429 | if( CollD->CheckALLBlockInside(pos_x, pos_y + offset, pos_z) == false ){ |
| 1417 | 1430 | |
| 1418 | 1431 | //進行方向を示すベクトルを算出 |
| 1419 | - vx = move_x; | |
| 1420 | - vz = move_z; | |
| 1432 | + vx = move_x2; | |
| 1433 | + vz = move_z2; | |
| 1421 | 1434 | speed = sqrt(vx*vx + vz*vz); |
| 1422 | 1435 | if( speed > 0.0f ){ |
| 1423 | 1436 | vx = vx / speed; |
| @@ -1440,7 +1453,7 @@ | ||
| 1440 | 1453 | } |
| 1441 | 1454 | |
| 1442 | 1455 | //足元を当たり判定 |
| 1443 | - CollD->ScratchVector(id, face, move_x, vy, move_z, &move_x, &vy, &move_z); | |
| 1456 | + CollD->ScratchVector(id, face, move_x2, vy, move_z2, &move_x2, &vy, &move_z2); | |
| 1444 | 1457 | } |
| 1445 | 1458 | else{ //水平〜斜面なら |
| 1446 | 1459 | //地面と認めない (ジャンプ対策) |
| @@ -1447,9 +1460,9 @@ | ||
| 1447 | 1460 | move_y_flag = true; |
| 1448 | 1461 | |
| 1449 | 1462 | //移動先の位置を計算 |
| 1450 | - newpos_x = pos_x + move_x; | |
| 1463 | + newpos_x = pos_x + move_x2; | |
| 1451 | 1464 | newpos_y = pos_y + FallDistance; |
| 1452 | - newpos_z = pos_z + move_z; | |
| 1465 | + newpos_z = pos_z + move_z2; | |
| 1453 | 1466 | |
| 1454 | 1467 | //移動先の高さを調べる |
| 1455 | 1468 | if( CollD->CheckALLBlockInside(newpos_x, newpos_y + HUMAN_HEIGTH, newpos_z) == false ){ |
| @@ -1464,7 +1477,9 @@ | ||
| 1464 | 1477 | FallDistance = height; |
| 1465 | 1478 | } |
| 1466 | 1479 | |
| 1480 | + //move_x2 = 0.0f; | |
| 1467 | 1481 | move_y = 0.0f; |
| 1482 | + //move_z2 = 0.0f; | |
| 1468 | 1483 | } |
| 1469 | 1484 | } |
| 1470 | 1485 | } |
| @@ -1472,9 +1487,9 @@ | ||
| 1472 | 1487 | } |
| 1473 | 1488 | |
| 1474 | 1489 | //移動先の位置を計算 |
| 1475 | - newpos_x = pos_x + move_x; | |
| 1490 | + newpos_x = pos_x + move_x2; | |
| 1476 | 1491 | newpos_y = pos_y + FallDistance; |
| 1477 | - newpos_z = pos_z + move_z; | |
| 1492 | + newpos_z = pos_z + move_z2; | |
| 1478 | 1493 | |
| 1479 | 1494 | //全身を改めて確認 |
| 1480 | 1495 | if( |
| @@ -1482,16 +1497,15 @@ | ||
| 1482 | 1497 | (CollD->CheckALLBlockIntersectRay(newpos_x, newpos_y + offset, newpos_z, 0, 1, 0, NULL, NULL, &Dist, HUMAN_HEIGTH - offset - 1.0f) == true) |
| 1483 | 1498 | ){ |
| 1484 | 1499 | //めり込むなら移動しない |
| 1485 | - move_x = 0.0f; | |
| 1486 | - move_z = 0.0f; | |
| 1500 | + move_x2 = 0.0f; | |
| 1501 | + move_z2 = 0.0f; | |
| 1487 | 1502 | inside = true; |
| 1488 | 1503 | } |
| 1489 | 1504 | } |
| 1490 | 1505 | |
| 1491 | - *nowmove_x = move_x; | |
| 1492 | - *nowmove_z = move_z; | |
| 1493 | - | |
| 1494 | 1506 | *FallDist = FallDistance; |
| 1507 | + *nowmove_x = move_x2; | |
| 1508 | + *nowmove_z = move_z2; | |
| 1495 | 1509 | return inside; |
| 1496 | 1510 | } |
| 1497 | 1511 |