Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
MingSnake_241120
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
SparkProjects
MingSnake_241120
Commits
05fee1ee
Commit
05fee1ee
authored
Nov 25, 2024
by
haiyoucuv
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
init
parent
2a62f6d9
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
27 additions
and
30 deletions
+27
-30
AISnake.ts
assets/Scripts/Scenes/MainGame/AISnake.ts
+26
-30
Player.ts
assets/Scripts/Scenes/MainGame/Player.ts
+1
-0
No files found.
assets/Scripts/Scenes/MainGame/AISnake.ts
View file @
05fee1ee
import
{
_decorator
,
math
,
v3
,
Vec3
,
Node
,
Collider2D
,
Contact2DType
,
PhysicsGroup
}
from
"cc"
;
import
{
_decorator
,
math
,
v3
,
Vec3
,
Node
,
Collider2D
,
Contact2DType
,
PhysicsGroup
,
Vec2
,
IVec2Like
,
v2
}
from
"cc"
;
import
{
Snake
}
from
"./Snake"
;
import
{
Snake
}
from
"./Snake"
;
import
{
DirectionType
}
from
"./Common/Enums"
;
import
{
DirectionType
}
from
"./Common/Enums"
;
import
{
Global
}
from
"./Global"
;
import
{
Global
}
from
"./Global"
;
...
@@ -26,14 +26,14 @@ export class AISnake extends Snake {
...
@@ -26,14 +26,14 @@ export class AISnake extends Snake {
private
currentState
:
AIState
=
AIState
.
WANDERING
;
private
currentState
:
AIState
=
AIState
.
WANDERING
;
private
behaviorTimer
:
number
=
0
;
private
behaviorTimer
:
number
=
0
;
private
targetFood
:
Vec
3
=
null
;
private
targetFood
:
Vec
2
=
null
;
private
targetSnake
:
Snake
=
null
;
private
targetSnake
:
Snake
=
null
;
private
escapeTarget
:
Snake
=
null
;
private
escapeTarget
:
Snake
=
null
;
private
readonly
BASE_VIEW_DISTANCE
=
300
;
private
readonly
BASE_VIEW_DISTANCE
=
300
;
private
readonly
INTERCEPT_DISTANCE
=
350
;
// 降低拦截距离
private
readonly
INTERCEPT_DISTANCE
=
350
;
// 降低拦截距离
private
readonly
PREDICTION_TIME
=
1.2
;
// 增加预测时间
private
readonly
PREDICTION_TIME
=
1.2
;
// 增加预测时间
private
readonly
ESCAPE_BOUNDARY
=
1
50
;
// 增加边界安全距离
private
readonly
ESCAPE_BOUNDARY
=
2
50
;
// 增加边界安全距离
private
readonly
SAFE_MARGIN
=
3.0
;
// 增加安全边际
private
readonly
SAFE_MARGIN
=
3.0
;
// 增加安全边际
private
readonly
COLLISION_CHECK_DISTANCE
=
500
;
// 增加碰撞检测距离
private
readonly
COLLISION_CHECK_DISTANCE
=
500
;
// 增加碰撞检测距离
private
readonly
ASSIST_DISTANCE
=
500
;
// 协助攻击的最大距离
private
readonly
ASSIST_DISTANCE
=
500
;
// 协助攻击的最大距离
...
@@ -173,7 +173,7 @@ export class AISnake extends Snake {
...
@@ -173,7 +173,7 @@ export class AISnake extends Snake {
this
.
currentState
=
state
;
this
.
currentState
=
state
;
switch
(
state
)
{
switch
(
state
)
{
case
AIState
.
HUNTING
:
case
AIState
.
HUNTING
:
this
.
targetFood
=
target
as
Vec
3
;
this
.
targetFood
=
target
as
Vec
2
;
break
;
break
;
case
AIState
.
INTERCEPTING
:
case
AIState
.
INTERCEPTING
:
this
.
targetSnake
=
target
as
Snake
;
this
.
targetSnake
=
target
as
Snake
;
...
@@ -227,7 +227,6 @@ export class AISnake extends Snake {
...
@@ -227,7 +227,6 @@ export class AISnake extends Snake {
}
}
const
playerPos
=
this
.
targetSnake
.
head
.
getPosition
();
const
playerPos
=
this
.
targetSnake
.
head
.
getPosition
();
const
partnerPos
=
this
.
assistTarget
.
head
.
getPosition
();
// 计算包围位置:在玩家和协助目标的另一侧
// 计算包围位置:在玩家和协助目标的另一侧
const
angle
=
this
.
calculateTargetAngle
(
playerPos
);
const
angle
=
this
.
calculateTargetAngle
(
playerPos
);
...
@@ -341,7 +340,7 @@ export class AISnake extends Snake {
...
@@ -341,7 +340,7 @@ export class AISnake extends Snake {
if
(
!
this
.
targetFood
)
return
;
if
(
!
this
.
targetFood
)
return
;
const
myPos
=
this
.
head
.
getPosition
();
const
myPos
=
this
.
head
.
getPosition
();
const
distance
=
Vec
3
.
distance
(
myPos
,
this
.
targetFood
);
const
distance
=
Vec
2
.
distance
(
myPos
as
IVec2Like
,
this
.
targetFood
);
const
targetAngle
=
this
.
calculateTargetAngle
(
this
.
targetFood
);
const
targetAngle
=
this
.
calculateTargetAngle
(
this
.
targetFood
);
const
angleDiff
=
Math
.
abs
(
this
.
head
.
angle
-
targetAngle
);
const
angleDiff
=
Math
.
abs
(
this
.
head
.
angle
-
targetAngle
);
...
@@ -387,10 +386,10 @@ export class AISnake extends Snake {
...
@@ -387,10 +386,10 @@ export class AISnake extends Snake {
}
}
// 寻找更好的替代角度
// 寻找更好的替代角度
private
findBetterAngleToFood
(
foodPos
:
Vec
3
):
number
|
null
{
private
findBetterAngleToFood
(
foodPos
:
Vec
2
):
number
|
null
{
const
myPos
=
this
.
head
.
getPosition
();
const
myPos
=
this
.
head
.
getPosition
();
const
directAngle
=
this
.
calculateTargetAngle
(
foodPos
);
const
directAngle
=
this
.
calculateTargetAngle
(
foodPos
);
const
currentDistance
=
Vec
3
.
distance
(
myPos
,
foodPos
);
const
currentDistance
=
Vec
2
.
distance
(
myPos
as
IVec2Like
,
foodPos
);
// 根据当前角度差决定搜索范围
// 根据当前角度差决定搜索范围
const
angleDiff
=
Math
.
abs
(
this
.
head
.
angle
-
directAngle
);
const
angleDiff
=
Math
.
abs
(
this
.
head
.
angle
-
directAngle
);
...
@@ -406,7 +405,7 @@ export class AISnake extends Snake {
...
@@ -406,7 +405,7 @@ export class AISnake extends Snake {
if
(
this
.
willHitOwnBody
(
testAngle
))
continue
;
if
(
this
.
willHitOwnBody
(
testAngle
))
continue
;
const
futurePos
=
this
.
predictFuturePosition
(
myPos
,
testAngle
,
this
.
radius
*
5
);
const
futurePos
=
this
.
predictFuturePosition
(
myPos
,
testAngle
,
this
.
radius
*
5
);
const
newDistance
=
Vec
3
.
distance
(
futurePos
,
foodPos
);
const
newDistance
=
Vec
2
.
distance
(
futurePos
as
IVec2Like
,
foodPos
);
// 计算路径改善程度
// 计算路径改善程度
const
improvement
=
currentDistance
-
newDistance
;
const
improvement
=
currentDistance
-
newDistance
;
...
@@ -429,7 +428,7 @@ export class AISnake extends Snake {
...
@@ -429,7 +428,7 @@ export class AISnake extends Snake {
// 检查与自己身体的碰撞
// 检查与自己身体的碰撞
for
(
const
bodyPart
of
this
.
bodyArr
)
{
for
(
const
bodyPart
of
this
.
bodyArr
)
{
const
bodyDistance
=
Vec
3
.
distance
(
futurePos
,
bodyPart
.
getPosition
()
);
const
bodyDistance
=
Vec
2
.
distance
(
futurePos
,
bodyPart
.
getPosition
()
as
IVec2Like
);
if
(
bodyDistance
<
this
.
radius
*
2.5
)
{
// 略大的碰撞检测范围
if
(
bodyDistance
<
this
.
radius
*
2.5
)
{
// 略大的碰撞检测范围
return
true
;
return
true
;
}
}
...
@@ -529,8 +528,8 @@ export class AISnake extends Snake {
...
@@ -529,8 +528,8 @@ export class AISnake extends Snake {
// 检查身体威胁
// 检查身体威胁
for
(
let
i
=
0
;
i
<
snake
.
bodyArr
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
snake
.
bodyArr
.
length
;
i
++
)
{
const
bodyPart
=
snake
.
bodyArr
[
i
];
const
bodyPart
=
snake
.
bodyArr
[
i
];
const
bodyDistance
=
Vec
3
.
distance
(
myPos
,
bodyPart
.
getPosition
());
const
bodyDistance
=
Vec
2
.
distance
(
myPos
,
bodyPart
.
getPosition
());
const
futureDist
=
Vec
3
.
distance
(
myFuturePos
,
bodyPart
.
getPosition
()
);
const
futureDist
=
Vec
2
.
distance
(
myFuturePos
,
bodyPart
.
getPosition
()
as
IVec2Like
);
const
bodyAngle
=
this
.
calculateTargetAngle
(
bodyPart
.
getPosition
());
const
bodyAngle
=
this
.
calculateTargetAngle
(
bodyPart
.
getPosition
());
const
angleDiff
=
Math
.
abs
(
this
.
head
.
angle
-
bodyAngle
);
const
angleDiff
=
Math
.
abs
(
this
.
head
.
angle
-
bodyAngle
);
...
@@ -569,11 +568,8 @@ export class AISnake extends Snake {
...
@@ -569,11 +568,8 @@ export class AISnake extends Snake {
}
:
null
;
}
:
null
;
}
}
private
predictFuturePosition
(
currentPos
:
Vec3
,
angle
:
number
,
speed
:
number
):
Vec3
{
private
predictFuturePosition
(
currentPos
:
IVec2Like
,
angle
:
number
,
speed
:
number
):
IVec2Like
{
const
radian
=
angle
*
Math
.
PI
/
180
;
return
Vec2
.
add
(
v2
(),
currentPos
,
this
.
getVelocity
().
multiplyScalar
(
speed
));
const
futureX
=
currentPos
.
x
+
Math
.
cos
(
radian
)
*
speed
;
const
futureY
=
currentPos
.
y
+
Math
.
sin
(
radian
)
*
speed
;
return
v3
(
futureX
,
futureY
,
0
);
}
}
private
executeEscaping
()
{
private
executeEscaping
()
{
...
@@ -689,7 +685,7 @@ export class AISnake extends Snake {
...
@@ -689,7 +685,7 @@ export class AISnake extends Snake {
let
safety
=
100
;
let
safety
=
100
;
// 检查与威胁的距离
// 检查与威胁的距离
const
threatDistance
=
Vec
3
.
distance
(
futurePos
,
threat
.
head
.
getPosition
());
const
threatDistance
=
Vec
2
.
distance
(
futurePos
as
IVec2Like
,
threat
.
head
.
getPosition
());
safety
+=
threatDistance
;
safety
+=
threatDistance
;
// 检查边界距离
// 检查边界距离
...
@@ -702,7 +698,7 @@ export class AISnake extends Snake {
...
@@ -702,7 +698,7 @@ export class AISnake extends Snake {
.
filter
(
snake
=>
snake
&&
snake
!==
this
&&
snake
!==
threat
&&
snake
.
isLife
);
.
filter
(
snake
=>
snake
&&
snake
!==
this
&&
snake
!==
threat
&&
snake
.
isLife
);
for
(
const
snake
of
allSnakes
)
{
for
(
const
snake
of
allSnakes
)
{
const
distance
=
Vec
3
.
distance
(
futurePos
,
snake
.
head
.
getPosition
()
);
const
distance
=
Vec
2
.
distance
(
futurePos
,
snake
.
head
.
getPosition
()
as
IVec2Like
);
if
(
distance
<
this
.
COLLISION_CHECK_DISTANCE
)
{
if
(
distance
<
this
.
COLLISION_CHECK_DISTANCE
)
{
safety
-=
(
this
.
COLLISION_CHECK_DISTANCE
-
distance
);
safety
-=
(
this
.
COLLISION_CHECK_DISTANCE
-
distance
);
}
}
...
@@ -719,7 +715,7 @@ export class AISnake extends Snake {
...
@@ -719,7 +715,7 @@ export class AISnake extends Snake {
}
}
// 获取到边界的距离
// 获取到边界的距离
private
getDistanceToBoundary
(
position
:
Vec3
):
number
{
private
getDistanceToBoundary
(
position
:
IVec2Like
):
number
{
const
mapWidth
=
Global
.
MAP_WIDTH
;
const
mapWidth
=
Global
.
MAP_WIDTH
;
const
mapHeight
=
Global
.
MAP_HEIGHT
;
const
mapHeight
=
Global
.
MAP_HEIGHT
;
...
@@ -791,7 +787,7 @@ export class AISnake extends Snake {
...
@@ -791,7 +787,7 @@ export class AISnake extends Snake {
}
}
}
}
private
findNearestFood
():
Vec
3
|
null
{
private
findNearestFood
():
Vec
2
|
null
{
const
myPos
=
this
.
head
.
getPosition
();
const
myPos
=
this
.
head
.
getPosition
();
let
nearestFood
=
null
;
let
nearestFood
=
null
;
let
minDistance
=
this
.
difficultyParams
.
viewDistance
;
let
minDistance
=
this
.
difficultyParams
.
viewDistance
;
...
@@ -858,7 +854,7 @@ export class AISnake extends Snake {
...
@@ -858,7 +854,7 @@ export class AISnake extends Snake {
}
}
// 寻找替代食物
// 寻找替代食物
private
findAlternativeFood
(
foods
:
Node
[],
myPos
:
Vec3
,
viewDistance
:
number
,
competitors
:
Snake
[]):
Vec
3
|
null
{
private
findAlternativeFood
(
foods
:
Node
[],
myPos
:
Vec3
,
viewDistance
:
number
,
competitors
:
Snake
[]):
Vec
2
|
null
{
let
bestAlternative
=
null
;
let
bestAlternative
=
null
;
let
bestScore
=
-
1
;
let
bestScore
=
-
1
;
...
@@ -982,7 +978,7 @@ export class AISnake extends Snake {
...
@@ -982,7 +978,7 @@ export class AISnake extends Snake {
return
nearestThreat
;
return
nearestThreat
;
}
}
private
calculateEscapeAngle
(
threatPos
:
Vec3
):
number
{
private
calculateEscapeAngle
(
threatPos
:
IVec2Like
):
number
{
const
myPos
=
this
.
head
.
getPosition
();
const
myPos
=
this
.
head
.
getPosition
();
return
math
.
toDegree
(
Math
.
atan2
(
return
math
.
toDegree
(
Math
.
atan2
(
myPos
.
y
-
threatPos
.
y
,
myPos
.
y
-
threatPos
.
y
,
...
@@ -990,7 +986,7 @@ export class AISnake extends Snake {
...
@@ -990,7 +986,7 @@ export class AISnake extends Snake {
));
));
}
}
private
calculateTargetAngle
(
targetPos
:
Vec3
):
number
{
private
calculateTargetAngle
(
targetPos
:
IVec2Like
):
number
{
const
myPos
=
this
.
head
.
getPosition
();
const
myPos
=
this
.
head
.
getPosition
();
return
math
.
toDegree
(
Math
.
atan2
(
return
math
.
toDegree
(
Math
.
atan2
(
targetPos
.
y
-
myPos
.
y
,
targetPos
.
y
-
myPos
.
y
,
...
@@ -1002,6 +998,7 @@ export class AISnake extends Snake {
...
@@ -1002,6 +998,7 @@ export class AISnake extends Snake {
const
currentAngle
=
this
.
head
.
angle
;
const
currentAngle
=
this
.
head
.
angle
;
let
angleDiff
=
targetAngle
-
currentAngle
;
let
angleDiff
=
targetAngle
-
currentAngle
;
// angleDiff %= 360;
// 标准化角度差到 -180 到 180 度范围
// 标准化角度差到 -180 到 180 度范围
while
(
angleDiff
>
180
)
angleDiff
-=
360
;
while
(
angleDiff
>
180
)
angleDiff
-=
360
;
while
(
angleDiff
<
-
180
)
angleDiff
+=
360
;
while
(
angleDiff
<
-
180
)
angleDiff
+=
360
;
...
@@ -1018,16 +1015,15 @@ export class AISnake extends Snake {
...
@@ -1018,16 +1015,15 @@ export class AISnake extends Snake {
);
);
}
}
private
predictTargetPosition
(
target
:
Snake
):
Vec
3
{
private
predictTargetPosition
(
target
:
Snake
):
Vec
2
{
const
targetPos
=
target
.
head
.
getPosition
();
const
targetPos
=
target
.
head
.
getPosition
();
const
targetAngle
=
target
.
head
.
angle
;
const
targetSpeed
=
target
.
isFast
?
target
.
speed
*
2
:
target
.
speed
;
const
targetSpeed
=
target
.
isFast
?
target
.
speed
*
2
:
target
.
speed
;
const
radian
=
targetAngle
*
Math
.
PI
/
180
;
return
target
.
getVelocity
()
const
predictX
=
targetPos
.
x
+
Math
.
cos
(
radian
)
*
targetSpeed
*
this
.
PREDICTION_TIME
*
this
.
difficultyParams
.
predictionAccuracy
;
.
add2f
(
targetPos
.
x
,
targetPos
.
y
)
const
predictY
=
targetPos
.
y
+
Math
.
sin
(
radian
)
*
targetSpeed
*
this
.
PREDICTION_TIME
*
this
.
difficultyParams
.
predictionAccuracy
;
.
multiplyScalar
(
targetSpeed
*
this
.
PREDICTION_TIME
*
this
.
difficultyParams
.
predictionAccuracy
)
;
return
v3
(
predictX
,
predictY
,
0
);
//
return v3(predictX, predictY, 0);
}
}
setDifficulty
(
level
:
number
)
{
setDifficulty
(
level
:
number
)
{
...
...
assets/Scripts/Scenes/MainGame/Player.ts
View file @
05fee1ee
...
@@ -52,6 +52,7 @@ export class Player extends Snake {
...
@@ -52,6 +52,7 @@ export class Player extends Snake {
death
()
{
death
()
{
super
.
death
();
super
.
death
();
this
.
length
=
0
;
// 发送游戏结束事件
// 发送游戏结束事件
director
.
emit
(
Events
.
setGameState
,
GameState
.
OVER
);
director
.
emit
(
Events
.
setGameState
,
GameState
.
OVER
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment