Для управления сложными взаимодействиями, такими как несколько фаз боя с разными состояниями монстра, лучший подход — использовать шаблон проектирования "Состояние" (State Pattern). ( G% O U6 v7 A% d2 u' h
& c( v0 C8 q; X& Y* z: b
Этот шаблон позволяет разделить логику поведения объекта на разные состояния и управлять ими более гибко, избегая перегрузки основного класса монстра.
2 `; B9 w8 ~8 H+ D! a& P8 q: z4 ^6 C7 l
Шаг 1: Создание интерфейса для состояний монстраПервый шаг — создать интерфейс, который будет представлять разные состояния монстра. Этот интерфейс определяет метод, который будет вызываться в зависимости от текущего состояния.6 F, F# a6 C g$ n
$ G$ n! c: i! X- // Пакет для состояний монстра7 \9 b7 I) m. S
- package org.l2jmobius.gameserver.model.actor.state;) x' \7 G7 d. q
: C2 u, w* z3 T- // Интерфейс, представляющий состояния монстра
: c& T6 i3 A9 C- M2 g - public interface MonsterState {" i- y J q# k: E4 X i
- void handleState(Monster monster);
, u! t, [7 ]9 d! E' T; a - }
. p" Y+ c: o: E1 C. K
Скопировать код 0 K! \, ~, ?% {; E
Шаг 2: Реализация различных состоянийТеперь создадим классы для каждого состояния: например, InitialState, AggressiveState и FinalState.
+ S+ Y4 {4 f$ o1 w4 _- P! `
, ^2 P7 G& _( Z8 i1 w) V7 n- uЭти состояния будут реализовывать интерфейс MonsterState и определять поведение монстра на разных этапах боя.
+ h5 l( V' g% }( N5 Q' ?/ L
6 E( a* B7 D6 ^7 v5 p2 m' lКласс для начального состояния монстра:5 Q4 _ w( ~6 Q' c: Y: O3 b
- // Пакет org.l2jmobius.gameserver.model.actor.state
/ ^" _- d; A8 O6 g6 R7 z - package org.l2jmobius.gameserver.model.actor.state;; V0 C% l' H8 X0 X2 ], E0 l
, L3 e; l; w. D/ C9 z; H. X- import org.l2jmobius.gameserver.model.actor.Monster;3 n5 m# ~0 P) ^( y: E: H; p6 t
, w; l4 w0 D% {! I- public class InitialState implements MonsterState {* k" p# N, [# Z
- @Override
6 j: g# O. e2 w1 s* i" { - public void handleState(Monster monster) {
1 h/ P- V+ z9 I - // Начальная фаза боя+ `4 L' ^* `' S. F' U( T
- System.out.println(monster.getName() + " начинает бой с обычной атакой.");7 {- h' e) L. ?2 W) X4 }+ l# ]
- }
* v* k6 j# s6 ^ - }2 O1 S+ B ~) K. g" j! h3 V
Скопировать код Класс для агрессивного состояния монстра:$ O$ A% G+ b7 q
- // Пакет org.l2jmobius.gameserver.model.actor.state
: J e( C9 g, G. F( u, E - package org.l2jmobius.gameserver.model.actor.state;
3 w7 k% t* |2 R; t* f - ' X; a9 [* N1 T+ S0 B
- import org.l2jmobius.gameserver.model.actor.Monster; N- S, G- \5 O h; n6 N
- 7 q+ Y3 B' B5 Q' T; u3 g! j7 ~
- public class AggressiveState implements MonsterState {- i( E) F( R, h! G* K7 I& t( @
- @Override
2 h/ i- `. T% C8 |; C" P - public void handleState(Monster monster) {
' @: c; H7 _* G5 W, o - // Агрессивная фаза боя) V5 ^ \% E7 `- w0 B$ R) f4 l) s
- System.out.println(monster.getName() + " становится агрессивным! Атаки усиливаются.");
, h, D5 Y7 z" \6 V) w5 T) Q# c - monster.setAttackPower(monster.getAttackPower() * 1.5); // Увеличиваем силу атаки
1 T" w/ G. d% R7 D - }
1 Q1 g* r5 {% g, ]" T2 N3 W' s0 v - }7 X1 @, b. ^7 h, D$ K
Скопировать код Класс для финального состояния монстра:
. \( s* y4 Q' w- // Пакет org.l2jmobius.gameserver.model.actor.state
( T+ i" s3 C, h: z3 I - package org.l2jmobius.gameserver.model.actor.state;
( h% h7 Q6 N$ ]5 @3 b
% ]: r8 l7 S" ? \* O- import org.l2jmobius.gameserver.model.actor.Monster;( d) k- }& ]; [( }
- % x1 c- ?* I& l U( L
- public class FinalState implements MonsterState {; ? T V6 z# a% K+ A7 y
- @Override9 z7 Z0 B& l7 G! {! k8 p# c
- public void handleState(Monster monster) {
, K! `1 I% c# f7 Y3 n* U" h- S - // Финальная фаза боя
) A, _) g" ] G x: E6 @* t - System.out.println(monster.getName() + " готовится к финальной атаке!");; I3 r' `% q7 O$ ~( ]7 s
- monster.setAttackPower(monster.getAttackPower() * 2); // Максимальная сила атаки
* s) I# J% F, m9 b3 R; @! a - }. U8 y; U7 F% z9 D) w
- }
7 I5 k& k c( |( L1 _. {* W
Скопировать код % _& z9 ~0 l, J( I, E) E" I
Шаг 3: Изменение класса MonsterЧтобы монстр мог переключаться между состояниями, нам нужно обновить класс Monster. В этой сборке L2J_Mobius, классы для игровых объектов, таких как монстры, находятся в пакете org.l2jmobius.gameserver.model.actor.; ^) O# m4 o: ~4 N* R# T# c- w
- // Пакет org.l2jmobius.gameserver.model.actor
8 V- U" `0 E5 s - package org.l2jmobius.gameserver.model.actor;
. L' M# \+ e. ]- \# \
& T- ~% R- v S- n% N9 p& G- import org.l2jmobius.gameserver.model.actor.state.MonsterState;
9 ]- E1 B5 \! n5 M* G! W - import org.l2jmobius.gameserver.model.actor.state.InitialState;
9 q. s# g( _7 p1 k
2 K8 ^! T' `+ j- public class Monster extends Creature {
' T3 J8 m# F" _0 H - private String name;
7 @4 V a$ p" k - private double attackPower;
. b9 C* Q, V6 G0 [; ~/ k - private MonsterState state; // Текущее состояние монстра
& a7 ?: D0 s3 X
3 t+ i/ y1 c. r/ _9 F8 v" p: T8 X3 l- // Конструктор монстра" H& `9 W, V5 N4 [
- public Monster(String name, double attackPower) {
& L# L% @* @, S L8 k9 T - this.name = name;
& ^" h6 Y5 `7 g1 h: g - this.attackPower = attackPower;
* L/ ^4 ]9 Y) b" C1 W. a7 b - this.state = new InitialState(); // Устанавливаем начальное состояние
' G) b4 R. ^5 s1 r- L, _ - }
' a( i2 [8 [) o y0 l: u8 Q' ^ - 7 d- K4 }, t) ~0 I7 G. x# V
- // Метод для смены состояния
2 z. E* g* C! c" f7 E1 j, C - public void setState(MonsterState newState) {
' O9 ?$ h! n" p. h& {9 M - this.state = newState;! b; I5 a" _- A! D) t' e- }8 d
- }+ i2 `6 p! Y8 |0 C
- - |$ L* t j, i$ s ?# @: y0 ^
- // Выполнение действий на основе текущего состояния" n5 b0 H# k; U% r
- public void executeState() {
) ?- d# v* ? I" [8 l - state.handleState(this);
7 {" `6 A) X$ C7 R, b* W0 b - }' j# e. r) F* n
6 v/ y" a& h2 p# \4 a" m; Z1 y8 d- // Геттеры и сеттеры/ I0 Z/ q2 h' i* z* s0 W: A% Z) p
- public String getName() {
: Z c9 e: \; y# t. B - return name;
* |& \2 V, V5 e8 ?7 Z+ ?* l - }1 b# i/ B8 E2 d3 B2 |
; R0 v& p8 A# G* T# J C$ r- public double getAttackPower() {
6 X! `! u8 P. z8 v1 o5 d - return attackPower;
& e! c$ M) _8 \: J' H& T1 ~2 C - }
1 r* w- t+ {" y% ^9 h4 r( D j
1 N0 H6 P" k# E8 j- Q' f: D- public void setAttackPower(double attackPower) {
4 j4 q8 c4 j- {) t! C3 ~ B! ~4 F! x - this.attackPower = attackPower;
% ~: j2 }4 w. O - }
4 l* X5 y( ~; d6 f% v" v* h" T - }+ a Z0 |% Y n3 W5 ^. Q
Скопировать код . j8 J" X. ^1 }. u
Шаг 4: Симуляция боя с фазамиТеперь мы можем протестировать логику боя с переключением состояний монстра.
8 s! S2 A' @1 l. f& T l7 Z+ C) m- U4 U d) e/ e4 h; @
- // Пакет org.l2jmobius.gameserver.model.battle
% t Q& T3 b; w: Y - package org.l2jmobius.gameserver.model.battle;
" T F6 v1 o( j
- [; A" {6 @- G* ^! R$ E- import org.l2jmobius.gameserver.model.actor.Monster; ^) T3 D6 q, B) q: n0 V
- import org.l2jmobius.gameserver.model.actor.state.AggressiveState;
" L( V# i7 m8 {- D& ^ - import org.l2jmobius.gameserver.model.actor.state.FinalState;" N. {) N+ c6 T3 s5 n* e
: {+ p7 V* x3 ~- public class BattleSimulation {
- p6 n$ N: x, l! v - public static void main(String[] args) {
4 _, e% @0 A% o0 }, V+ A! V# I - // Создаем монстра с начальной атакой
+ B. q+ p' L6 h- Q- X - Monster monster = new Monster("Дракон", 100);+ q Q! v8 ]. x) M8 Q; B: {
- % k5 ~' q. M' i; ^
- // Начальная фаза! v1 @$ u( G- c7 f- M
- monster.executeState(); N* O1 F" H$ P- ?
6 {+ I! h$ A [$ X4 N- // Переход в агрессивную фазу/ g" E+ ~- h$ ~+ p* u* y' R
- monster.setState(new AggressiveState());
3 b+ d9 s" }' | - monster.executeState();+ Q$ m! O; N6 ?
- 2 L9 @6 M0 |8 E+ [
- // Финальная фаза
4 g8 l4 r; G# r8 g$ ]0 x - monster.setState(new FinalState());# U+ W7 C& S5 G, C8 k( w/ ]
- monster.executeState();+ {) Z& D* z( [6 C! ~9 Q
- }$ a/ V; n: u' W ]) P7 C9 g' C! q
- }
; f/ I, h4 D2 k+ Z9 A; Y2 `
Скопировать код * ?8 S. h; j, \' ]3 K
Комментарии по структуре пакетов и классов:
0 t7 [# Z+ F8 c2 V' S- Пакет org.l2jmobius.gameserver.model.actor: содержит основные игровые сущности, такие как Monster.
- Пакет org.l2jmobius.gameserver.model.actor.state: отвечает за реализацию состояний для объектов, таких как монстры.
- Пакет org.l2jmobius.gameserver.model.battle: может содержать примеры взаимодействий, такие как симуляция боевых сценариев.
7 c2 B4 ?1 Z9 R1 y& T ЗаключениеШаблон "Состояние" позволяет легко управлять фазами боя и не перегружать основной класс монстра. Это делает логику боевых сценариев более гибкой и масштабируемой. В будущем, если появятся новые фазы или состояния, их можно будет легко добавить, не изменяя основной код.
2 P7 h$ H9 L* O7 N! f- ~- uЕсли появятся дополнительные вопросы по реализации или структуре классов, буду рада помочь!) S$ p) x' ?: j6 }. o0 G$ ?
7 U3 a3 j4 H+ G5 I
4 o" B* C% D, d2 [
" J% |! ~3 f: Y2 S$ q
+ \8 ? d: {! q7 Y$ E* p
- L. a8 ~& i0 Z7 f
, s: g) H2 `, n Z+ y! l
) e3 ^) j: i2 ?7 A, J: b$ W& t
, E2 F4 @1 H3 _- x! ~4 H$ k0 D* a5 E H7 c$ Y; N( M
' x l$ e" I" s4 ~; p: h1 D+ F5 _
8 L4 Z. F! J* M7 c
4 d& }& {3 @5 K2 k9 {1 T8 o# f5 N: U9 @ Q
: k/ Y' Y) ^/ w3 m( T |