Для управления сложными взаимодействиями, такими как несколько фаз боя с разными состояниями монстра, лучший подход — использовать шаблон проектирования "Состояние" (State Pattern).
9 i% Q0 c# S/ g: F" r$ j* f6 Q8 ~- r/ _7 B% x( d
Этот шаблон позволяет разделить логику поведения объекта на разные состояния и управлять ими более гибко, избегая перегрузки основного класса монстра.+ h9 `% I9 \5 L% z1 ]
' @% {/ w/ m; w5 _( |# }Шаг 1: Создание интерфейса для состояний монстраПервый шаг — создать интерфейс, который будет представлять разные состояния монстра. Этот интерфейс определяет метод, который будет вызываться в зависимости от текущего состояния.
* d; }1 u7 ~7 f8 g4 q8 f' _/ R1 u0 A6 K; N( S; ?
- // Пакет для состояний монстра
2 g9 P+ X" @7 k3 A9 ? - package org.l2jmobius.gameserver.model.actor.state;4 K. k/ |' F' ?
, ^' t! w$ _ j* A0 D. [- // Интерфейс, представляющий состояния монстра9 m; \: @+ f! e6 R6 v( \
- public interface MonsterState {
1 I& a2 k G) j5 e - void handleState(Monster monster);) ?( g- e7 z. c* }0 [4 P: `
- }: }( B) A6 O) z1 F" i
Скопировать код
1 ^( i+ D7 i4 F! I+ A, b; @; X. \Шаг 2: Реализация различных состоянийТеперь создадим классы для каждого состояния: например, InitialState, AggressiveState и FinalState. 8 B* |. {/ C- j9 \6 A6 [& x
" @2 p) }+ ^5 {& v: m
Эти состояния будут реализовывать интерфейс MonsterState и определять поведение монстра на разных этапах боя.
. q! v! P# @$ S8 A9 `4 o# D# }' d1 F* ^6 U/ i
Класс для начального состояния монстра:! c. j, L. ^" |5 o* O
- // Пакет org.l2jmobius.gameserver.model.actor.state
( [( i- R1 R/ _7 `+ @, a - package org.l2jmobius.gameserver.model.actor.state;6 Y2 H3 f5 I. x/ j+ U
0 N; \5 d0 G. O0 ^' O, l- import org.l2jmobius.gameserver.model.actor.Monster;
8 `& l. a( P% P8 d! [4 L' H/ d - 5 Y! A1 i. n8 z/ h( ?8 ~" y
- public class InitialState implements MonsterState {
/ d9 ?3 x* `1 `% F$ ?! c: t - @Override9 E2 ?4 n9 A0 p
- public void handleState(Monster monster) {' S/ Z& o4 }3 I% {8 K7 t
- // Начальная фаза боя- T" n1 X1 ~( m9 U9 ~ @0 j
- System.out.println(monster.getName() + " начинает бой с обычной атакой.");5 h& S o' I8 \1 A" r, m7 O/ J
- }4 K) `+ U2 }4 G0 T3 v* n
- }
* i1 l( X8 g* ?" V' X
Скопировать код Класс для агрессивного состояния монстра:
$ |/ K$ I. I4 l* Y9 P3 R7 Y+ h- // Пакет org.l2jmobius.gameserver.model.actor.state$ `0 c ]! O, j0 H5 [
- package org.l2jmobius.gameserver.model.actor.state;
4 w9 Z0 R) ~. B& {
* ]7 T3 S; O) N( o& q- import org.l2jmobius.gameserver.model.actor.Monster;; ^$ o. Y; U. |* ]; m3 x5 \
- 3 `! e5 Z+ D$ l5 d& v; n
- public class AggressiveState implements MonsterState { w. t9 C) w% A+ h$ ^
- @Override) X* }' I5 l, e# q; g g
- public void handleState(Monster monster) {: u* }# o7 f# Q0 N$ j6 f; F
- // Агрессивная фаза боя
5 Y( } m0 d) _; f - System.out.println(monster.getName() + " становится агрессивным! Атаки усиливаются.");
3 [! R! W) K* I A - monster.setAttackPower(monster.getAttackPower() * 1.5); // Увеличиваем силу атаки7 ~; d7 \$ d2 h7 I+ Z
- }8 X$ @" h; I5 g# i8 _
- }& r4 Y V" f" i/ b) M4 T
Скопировать код Класс для финального состояния монстра:
) {, ~2 i; v* s. A4 s- // Пакет org.l2jmobius.gameserver.model.actor.state
$ w( u9 c6 {, z% I' A- i9 Z - package org.l2jmobius.gameserver.model.actor.state;
! i( b, f/ R1 P( S
8 ~. b# O: N# b. g* C+ h- import org.l2jmobius.gameserver.model.actor.Monster;
% G _9 U: x1 D; S5 C/ F3 F
N) D% Y) J J: J; _& b- public class FinalState implements MonsterState {
+ k, p# q+ \* o/ B A1 `$ h - @Override o* O: ^. }1 i/ T5 B4 Y
- public void handleState(Monster monster) {1 n& T& m& x& I+ b; y8 Z; o% U
- // Финальная фаза боя
8 S# E7 M$ a o% O4 Z - System.out.println(monster.getName() + " готовится к финальной атаке!");: @( t+ y' r- M
- monster.setAttackPower(monster.getAttackPower() * 2); // Максимальная сила атаки
0 B/ A! ]9 H5 k- k6 }6 O7 d* D - }/ B0 }+ \7 E L3 Z8 D
- }( q/ r7 M, I' m# G! I
Скопировать код 1 a, q9 V8 p9 K& A, W5 q0 k
Шаг 3: Изменение класса MonsterЧтобы монстр мог переключаться между состояниями, нам нужно обновить класс Monster. В этой сборке L2J_Mobius, классы для игровых объектов, таких как монстры, находятся в пакете org.l2jmobius.gameserver.model.actor., r# M9 d9 H2 n% j
- // Пакет org.l2jmobius.gameserver.model.actor
$ S. w [% b6 k% k( |2 O. c - package org.l2jmobius.gameserver.model.actor; c+ n% ?' @, g, P7 q
- 6 ^) E6 M& O9 Z* V+ F
- import org.l2jmobius.gameserver.model.actor.state.MonsterState;
% }' U- f8 _( j. g* | - import org.l2jmobius.gameserver.model.actor.state.InitialState;
5 v' R' V7 i* `6 l, @5 F - ) w! ^) J8 ?. c, Q' u6 R1 K* }. i
- public class Monster extends Creature {. @$ Y1 g& v- C6 }! }2 F* _) @
- private String name;
$ `; v0 `* f2 I4 T5 w# d - private double attackPower;& N5 G. }. q% |8 h- ^, ]
- private MonsterState state; // Текущее состояние монстра& v2 e. i0 t: k: u4 }- m/ M4 }
& E8 T% Z/ P* U V- // Конструктор монстра
& m! H0 E5 Z' M; H; T - public Monster(String name, double attackPower) {
$ S* M8 p; a! L - this.name = name;8 [3 Z2 D! x+ Y% g) i5 o, j6 ~
- this.attackPower = attackPower;$ L- C) J* A4 e( m
- this.state = new InitialState(); // Устанавливаем начальное состояние
8 E9 I2 }6 D* f* w& A3 H9 p - }
5 X8 @: A! B# _- l1 i - - Q; ^- t ~- {8 Q) L* i
- // Метод для смены состояния( q$ c" Z* ^( i# t- U2 g5 P7 e1 {
- public void setState(MonsterState newState) {
# Y+ ~# z6 C$ L - this.state = newState;
, V, S- D8 T" P/ d - }6 K: J' E$ f/ ?" i, J, K" o4 C$ b2 ]8 T
- ) N" b" N! M( X( W* ~7 a
- // Выполнение действий на основе текущего состояния* h1 ]* d( _0 h# u- x* G
- public void executeState() {2 x1 A/ |- Z( ]/ p6 y
- state.handleState(this);) Z- w/ U+ @( [! D, k6 w
- }
+ [5 H6 S( C+ ]% Y4 _ - $ b3 a. G' c0 _4 g
- // Геттеры и сеттеры
3 @3 l( b, X q9 |4 r - public String getName() {1 w9 R6 \* S y2 x( Q
- return name;
8 S% y h# _4 m9 M3 L g - }
& ?1 n" I! y# ~2 Q( m: X, Y7 [/ R - 2 O& y2 ^' u' c4 w2 H) X1 v' A
- public double getAttackPower() {0 q* n2 ~# M2 q& ?8 j
- return attackPower;5 O8 o, h9 F( U6 G
- }" D/ o9 B+ m( Z3 D4 \
- # v1 C" {+ K3 g( K# m, j* d; R- \
- public void setAttackPower(double attackPower) {+ P0 B/ @! Z$ W! d& L' u
- this.attackPower = attackPower;
5 I$ i( Y* ?& b8 y. ? - }
3 b# @1 n: R" i Z - }
& a4 G- E. p/ R$ V+ T2 T0 Q
Скопировать код
1 r) L7 O9 x5 Z2 @Шаг 4: Симуляция боя с фазамиТеперь мы можем протестировать логику боя с переключением состояний монстра.
v a6 r0 c% X# t1 b _% u) P. G4 X1 W2 l8 v
- // Пакет org.l2jmobius.gameserver.model.battle
8 J# E# W8 w* W - package org.l2jmobius.gameserver.model.battle; ^; \# X5 w: u" F1 k4 T& ?
- 9 ~' W( t* E0 D8 P" g, n; _
- import org.l2jmobius.gameserver.model.actor.Monster;
: I. H H d, ~* s5 x - import org.l2jmobius.gameserver.model.actor.state.AggressiveState;
/ _, s( w/ W3 w" G - import org.l2jmobius.gameserver.model.actor.state.FinalState;
6 H; z4 X4 K9 {+ C, {# ~9 n9 ? - , M" y, v* ?$ ^, d& N9 R
- public class BattleSimulation {+ v5 i9 D% y9 I* w/ W4 h
- public static void main(String[] args) {) ~. L- I7 ] {5 P! H& U6 U: r
- // Создаем монстра с начальной атакой; w1 R! ^+ P k( v; p8 ?
- Monster monster = new Monster("Дракон", 100);+ f L: f; f6 O p
- 9 ^0 x; P' B$ {
- // Начальная фаза
$ s* E1 j& b7 V2 [ - monster.executeState();
2 _) E- n7 a1 B4 j2 K4 ?( d - ( U9 m/ Z% \. L( Q4 E6 o
- // Переход в агрессивную фазу6 Z' E4 V& ~, O& I. z
- monster.setState(new AggressiveState());
; j4 w( t# u: F8 ] K/ y* z - monster.executeState();, H7 Q! M3 b1 v R# q* z; z
- 7 d$ b% `# |/ O( e
- // Финальная фаза; w x6 H: r7 p% f, l
- monster.setState(new FinalState());* e8 ~; e4 M& P+ |
- monster.executeState();2 A) c+ l8 E2 h
- }
% p/ I) m8 M0 \) V - }
: T4 f( |* n$ J4 d4 n
Скопировать код 4 @+ Y) u" h8 B, a3 |; T
Комментарии по структуре пакетов и классов:" X7 [& K6 D2 _/ \! `, Z( O
- Пакет org.l2jmobius.gameserver.model.actor: содержит основные игровые сущности, такие как Monster.
- Пакет org.l2jmobius.gameserver.model.actor.state: отвечает за реализацию состояний для объектов, таких как монстры.
- Пакет org.l2jmobius.gameserver.model.battle: может содержать примеры взаимодействий, такие как симуляция боевых сценариев.
8 \0 F, e+ F: m+ [1 J- a0 P ЗаключениеШаблон "Состояние" позволяет легко управлять фазами боя и не перегружать основной класс монстра. Это делает логику боевых сценариев более гибкой и масштабируемой. В будущем, если появятся новые фазы или состояния, их можно будет легко добавить, не изменяя основной код." E2 c7 \" h1 N: S- E! j4 k
Если появятся дополнительные вопросы по реализации или структуре классов, буду рада помочь!
7 A5 p9 U* c2 z! Q: Z5 o4 o6 t9 v/ y2 q$ j; T: j' O
& E" W3 J* Q2 C) y$ K7 P. q: @) D- N C' h3 @
. f4 J7 z x; p b4 Y3 c
9 s: |0 ^* z$ f1 S0 P
3 C& x k- ~ ~) f+ e
' h( Q, a( d& l0 G: `
5 R! F/ p, e @" W& ^6 U% N1 _2 G, ~8 J! E! {+ t6 e
4 O; V* f- X2 b$ C5 Q
% W* p- o0 u' B2 W0 w
2 h7 F8 u g3 S( k
: d7 G' X, G$ E O$ B6 P$ F! A8 `! f1 j
|