Для управления сложными взаимодействиями, такими как несколько фаз боя с разными состояниями монстра, лучший подход — использовать шаблон проектирования "Состояние" (State Pattern). 3 |3 M: o) o! F% b0 F+ S5 U
9 U2 T- D, D. L* m. ?
Этот шаблон позволяет разделить логику поведения объекта на разные состояния и управлять ими более гибко, избегая перегрузки основного класса монстра.1 a! f& W5 o; ]% c# S' @6 B! W
& k2 J' a5 n) e, [, h2 x
Шаг 1: Создание интерфейса для состояний монстраПервый шаг — создать интерфейс, который будет представлять разные состояния монстра. Этот интерфейс определяет метод, который будет вызываться в зависимости от текущего состояния.
( O+ M3 Y: y/ ~' {# ]4 Z8 d4 X$ d, T
- // Пакет для состояний монстра* ]* j) W g3 \: @; a( Y* y
- package org.l2jmobius.gameserver.model.actor.state;, [2 `: a* c* X/ T
4 i" W* |$ S% l- // Интерфейс, представляющий состояния монстра- _ _6 B; M9 x4 E6 E2 K
- public interface MonsterState {
3 V0 n3 B l2 ]9 Z5 s% B! a5 a, p4 S - void handleState(Monster monster);0 D o1 j" i2 d) ^5 N5 \7 g! B7 D
- }7 S. D+ B7 N# X2 W( c
Скопировать код ! W R7 R8 r+ \4 C
Шаг 2: Реализация различных состоянийТеперь создадим классы для каждого состояния: например, InitialState, AggressiveState и FinalState. 7 G3 o9 c+ }# S% a& ~- o. }) `- f! q
5 o9 O3 a! w& [( dЭти состояния будут реализовывать интерфейс MonsterState и определять поведение монстра на разных этапах боя.
+ \5 w# ]# `( V: i
: z2 A" W3 d% aКласс для начального состояния монстра:. X4 {8 r) |: X9 l w
- // Пакет org.l2jmobius.gameserver.model.actor.state6 ~7 r7 ]: g1 I0 Z7 }2 w
- package org.l2jmobius.gameserver.model.actor.state;
* j8 y' a% p, @$ E6 U, T3 } - ?* O! T1 V1 [* A+ r ~* R6 }
- import org.l2jmobius.gameserver.model.actor.Monster;
, A- g! J* c8 j& }3 W
4 i$ p( F! J3 a9 T- public class InitialState implements MonsterState {' K" @; e: h; [- L0 [
- @Override
% b8 Z+ m: L- _; a2 o1 f - public void handleState(Monster monster) {- F7 k" e5 W3 y
- // Начальная фаза боя# p- x+ o) f. A( M
- System.out.println(monster.getName() + " начинает бой с обычной атакой.");$ ]" @" s4 F) p3 W4 X
- }6 _/ z( C7 F$ M2 V0 E- C) Y
- }
8 w3 [1 {6 P! B2 U# p
Скопировать код Класс для агрессивного состояния монстра:1 ^) b/ G: m" B( Y
- // Пакет org.l2jmobius.gameserver.model.actor.state- k+ v9 Z$ b& O; ?0 L
- package org.l2jmobius.gameserver.model.actor.state;* ]9 {6 {: O9 N- d- B) }
: z0 Y$ v+ L. D% ~3 Z- import org.l2jmobius.gameserver.model.actor.Monster;& d* v: M+ z$ w5 a+ N5 W
- + W2 o- c1 E) X H
- public class AggressiveState implements MonsterState {) j$ }; `1 B; t! _' `0 m" w
- @Override- m& ^4 X; ^; @/ ~0 H: o
- public void handleState(Monster monster) {
( T' E" r& b. g - // Агрессивная фаза боя
Y* e+ E4 S; @& u. K" n. B7 Y - System.out.println(monster.getName() + " становится агрессивным! Атаки усиливаются.");
7 D, I& |/ g6 }4 ^- U2 Q - monster.setAttackPower(monster.getAttackPower() * 1.5); // Увеличиваем силу атаки
/ c/ ]- h# L8 N* u0 q1 l s2 ^$ I - }& d4 Z4 @. K" h' ~0 N. _+ i4 I
- }9 F& ^8 x M2 \" k9 B; ^
Скопировать код Класс для финального состояния монстра:! K0 D$ J% k. ^1 x# `$ e; g
- // Пакет org.l2jmobius.gameserver.model.actor.state* i0 H7 q0 V. N, O3 t
- package org.l2jmobius.gameserver.model.actor.state;
$ V, k( W& V3 e6 f4 G
. |" e4 n3 l- F- import org.l2jmobius.gameserver.model.actor.Monster;
6 N5 e# ~% g( h+ i7 N - / B4 ~4 X- h4 C/ W/ i4 g0 A
- public class FinalState implements MonsterState {5 k$ Z: ]$ p1 y0 w4 \
- @Override
" |5 b0 ?. W k3 a1 {0 \" A3 o6 A4 c# Z" S - public void handleState(Monster monster) {; _: j7 a! o; z9 s# @3 \
- // Финальная фаза боя' ~. p. U4 k# ^: y5 V: I
- System.out.println(monster.getName() + " готовится к финальной атаке!");
$ G t* w( L( |9 {0 i6 n - monster.setAttackPower(monster.getAttackPower() * 2); // Максимальная сила атаки1 B3 W( o0 w( A' @4 Q! `: ~
- }& @7 i+ f; @! E: H8 {' n0 R! i1 U
- } W0 V! U0 i# `+ M; U# w
Скопировать код + R( m8 X& ?0 D' Y2 m# r
Шаг 3: Изменение класса MonsterЧтобы монстр мог переключаться между состояниями, нам нужно обновить класс Monster. В этой сборке L2J_Mobius, классы для игровых объектов, таких как монстры, находятся в пакете org.l2jmobius.gameserver.model.actor.
. x6 Q) R0 E: V5 ]+ H- // Пакет org.l2jmobius.gameserver.model.actor" }3 c! ~( r6 V* F
- package org.l2jmobius.gameserver.model.actor;
) [$ d% S' ~* K
4 \+ `+ {" H% S' ?/ ]& \5 A- import org.l2jmobius.gameserver.model.actor.state.MonsterState;. _. t+ U- V1 Z2 N8 [
- import org.l2jmobius.gameserver.model.actor.state.InitialState;6 B. ]; |2 b/ q" D& t/ i2 m
* B; V* D/ d& \- public class Monster extends Creature {
1 |7 d/ A( D; M/ s - private String name;
! l( }0 X. R& u: \' f3 Z. z2 l5 \ - private double attackPower; j* y$ f* W) Q7 r5 X: A! ^0 p: b L
- private MonsterState state; // Текущее состояние монстра$ q& Q. {8 ?4 h, S4 N! A
- 9 a. [$ M5 B2 A/ [' g
- // Конструктор монстра
# H* e0 V6 Y! s- G9 n7 q - public Monster(String name, double attackPower) {
& J P8 r+ r" r9 U - this.name = name;' X6 u8 r# c3 [$ T
- this.attackPower = attackPower;
8 g I3 y0 h$ J) w - this.state = new InitialState(); // Устанавливаем начальное состояние
% z. h0 O0 m, q* h. G - }
) `2 k1 p1 t3 G$ ^3 ?7 C - / ]# T2 Q' Z! N6 V" c
- // Метод для смены состояния
/ G" @7 i4 ^5 E. l: b( V7 Q - public void setState(MonsterState newState) {
c1 V# A4 W* J% r6 F/ D - this.state = newState;
( e% z3 \, P7 J/ N0 z& V - }/ u8 |% k4 h3 R3 C& z. {9 N% L* P
! J4 L! b5 T6 ^+ D- // Выполнение действий на основе текущего состояния9 g/ a& j% A+ S" r$ o- ?; h- i( X
- public void executeState() {( @- G/ z; \: f
- state.handleState(this);
' U) ]4 G% N1 H/ ^2 ?7 t! h - }
8 z/ w( j2 U9 m3 K3 l3 F, U; S - + m, l* [- V9 D
- // Геттеры и сеттеры) H1 N% @7 x3 A! f
- public String getName() {: s7 P; ` S. E4 j4 U
- return name;1 n6 p4 u( |( }" {/ N6 }' ?& U
- }
( r- w+ H0 T+ M- p - 4 }; h6 v; @! \
- public double getAttackPower() {
* Y+ Q0 H+ k+ @7 y - return attackPower;+ ^$ C U, A( n0 h% _: A
- }1 o: l0 L9 W- i, a% e+ {
) O, ]! x0 L1 c& y0 D& W- public void setAttackPower(double attackPower) {" `0 \8 \6 W* p. H% Q3 [ k
- this.attackPower = attackPower;
4 g- w7 b. c& a4 x# c - }' Q/ H7 r$ W) _8 U
- }
9 ^3 |. N* P: J) U5 f
Скопировать код
1 o- e% S0 `+ [# V2 s/ e: rШаг 4: Симуляция боя с фазамиТеперь мы можем протестировать логику боя с переключением состояний монстра.
# p4 y Q7 Q2 ?; d3 t! Z: e5 a0 k1 X$ o: I/ r( d+ d
- // Пакет org.l2jmobius.gameserver.model.battle: T8 F- _( U* F; i, g
- package org.l2jmobius.gameserver.model.battle;
3 o; g a2 v' p4 {: s
+ ]! X8 X/ z0 ~+ a# b- import org.l2jmobius.gameserver.model.actor.Monster;
; q; D8 M+ h9 Q7 Q, g - import org.l2jmobius.gameserver.model.actor.state.AggressiveState;
, @! y) g: a# O9 }% V - import org.l2jmobius.gameserver.model.actor.state.FinalState;1 g8 b( \) v0 P
- * ~3 u0 o" f& s) z; s6 ?/ n1 I
- public class BattleSimulation {
w1 r; {' H2 E! Q/ A$ o! J - public static void main(String[] args) {
: D: i& \" z0 p) F4 Q9 Z2 G. G - // Создаем монстра с начальной атакой
( b! H7 |+ n4 U! x6 i5 n9 f( T - Monster monster = new Monster("Дракон", 100);
, Y- j1 t0 \; Q. d z
7 K( a' \. N+ ?! \" R: F* \- // Начальная фаза
: o* R$ N% I) G. c) a* f - monster.executeState();3 M; [8 `$ \ |( S+ K: o0 v
- 0 i( T3 c( [8 I n" Z
- // Переход в агрессивную фазу
1 c0 a9 P5 Q( b( y) ]5 l - monster.setState(new AggressiveState());) ?: ]& e4 O% i& F2 k& t- L+ a8 P
- monster.executeState();3 R! o3 m( L! t1 C' ^. D
- 0 Y" J# u$ r( O- i6 w
- // Финальная фаза
# c8 j+ i" d) s2 O1 J - monster.setState(new FinalState());. O- r+ U; ^: V$ m
- monster.executeState();, u6 f( T, l! i* C
- }: _# l3 \" f. i2 _8 }
- }
( F% m4 Y6 N; o' ?
Скопировать код
! _1 I0 u! }. t' M) Y, qКомментарии по структуре пакетов и классов:
3 m& P! v$ C' b0 o- Пакет org.l2jmobius.gameserver.model.actor: содержит основные игровые сущности, такие как Monster.
- Пакет org.l2jmobius.gameserver.model.actor.state: отвечает за реализацию состояний для объектов, таких как монстры.
- Пакет org.l2jmobius.gameserver.model.battle: может содержать примеры взаимодействий, такие как симуляция боевых сценариев.. ^( p, z1 }& V
ЗаключениеШаблон "Состояние" позволяет легко управлять фазами боя и не перегружать основной класс монстра. Это делает логику боевых сценариев более гибкой и масштабируемой. В будущем, если появятся новые фазы или состояния, их можно будет легко добавить, не изменяя основной код.
7 H+ ?5 D2 X# U2 OЕсли появятся дополнительные вопросы по реализации или структуре классов, буду рада помочь!' s' A, C4 d1 s$ o1 a
7 N9 ~: S& U: R9 O' O
( P! s* Y( n" ] [/ k% u' i) m! \5 {
4 F/ r: M- q5 ^% v+ d c
: E/ r! u/ P+ l" |: `/ ]- d1 L) L
! z: Q( w6 c0 c# |9 u; T1 ?/ V
9 I( k5 s% B) J) S% y+ o
4 @( @" R. E% T) L0 v* m4 {0 k4 m5 \+ i6 a" T9 f
# U4 m! }: h3 G6 n
! Y% O6 J! Q. f* s
! R. a2 }8 g( y1 g. a7 \- g9 M3 |% m* ~6 U9 u
- u8 `# F4 U& }( D9 Z% Q
% f3 q1 ~9 D r# ]6 \: N4 F
|