Для управления сложными взаимодействиями, такими как несколько фаз боя с разными состояниями монстра, лучший подход — использовать шаблон проектирования "Состояние" (State Pattern).
+ S' Q5 i& I0 M. s& j
0 k/ u+ K0 O k, e1 q5 aЭтот шаблон позволяет разделить логику поведения объекта на разные состояния и управлять ими более гибко, избегая перегрузки основного класса монстра. G3 A" a7 V, y
4 t. C1 u8 Q+ i2 d# _Шаг 1: Создание интерфейса для состояний монстраПервый шаг — создать интерфейс, который будет представлять разные состояния монстра. Этот интерфейс определяет метод, который будет вызываться в зависимости от текущего состояния.$ x8 |/ F6 t G: W
: A/ g0 J9 ^% }* N9 j/ Z5 |5 ~9 F- // Пакет для состояний монстра
" o% _4 |, j" v, V - package org.l2jmobius.gameserver.model.actor.state;
! h; [3 f7 x4 T* L4 ?
) n1 \8 b9 M3 J- e9 Z- // Интерфейс, представляющий состояния монстра
( [4 k. e9 b5 o/ [& X - public interface MonsterState {- ?% _& p7 `8 c: W4 S" O' y7 r
- void handleState(Monster monster);
5 B6 d( r3 F/ R7 ?$ X" o - }
5 e$ I9 X: m2 l; i3 ~
Скопировать код % c" W7 H6 c8 \# s
Шаг 2: Реализация различных состоянийТеперь создадим классы для каждого состояния: например, InitialState, AggressiveState и FinalState.
. o+ i" i+ c. P- B4 J
0 j- i7 ~& X9 |7 hЭти состояния будут реализовывать интерфейс MonsterState и определять поведение монстра на разных этапах боя.
4 l/ z2 v1 F" [+ W! @: B4 Q/ K+ D
, {' s9 h0 r) z7 U$ ]" }8 ZКласс для начального состояния монстра:
! g) t2 U4 u# S" U" O: D- // Пакет org.l2jmobius.gameserver.model.actor.state
$ b2 D1 _3 @6 K( E! o7 r - package org.l2jmobius.gameserver.model.actor.state;
7 P" | N. f5 z1 D- V% @ - # A) Z) t0 G) _* E7 k: a$ P: ?6 ~
- import org.l2jmobius.gameserver.model.actor.Monster;
+ o5 `' b; c1 a, Y Q, } - + `* U) ~5 f2 V) R& S
- public class InitialState implements MonsterState {
8 Z' t. y3 j; k9 p% @ ?$ y* D - @Override5 u) C' s4 A, |! n, H5 E: _. ^
- public void handleState(Monster monster) {
. V9 c% R4 H0 j* Y) v! K - // Начальная фаза боя
* q6 x5 Y0 B. M5 u* q# o1 d - System.out.println(monster.getName() + " начинает бой с обычной атакой.");* Z( P3 K& _/ m. Y4 \
- }* S6 B: A/ x! H1 G
- }
& A/ Q0 o& {% o. _+ G+ z/ l; d
Скопировать код Класс для агрессивного состояния монстра:
$ w/ h0 @4 i& Z! i! Q/ k+ k; w- // Пакет org.l2jmobius.gameserver.model.actor.state- r$ k. ^+ s' J
- package org.l2jmobius.gameserver.model.actor.state;4 w8 e: l" Z- b" {" o! t
1 F4 T3 N" u: ?4 u2 G& ?, a- import org.l2jmobius.gameserver.model.actor.Monster;) u4 d! Q6 [: _4 R
3 n( M6 h$ k2 M D5 B9 k9 p5 E- public class AggressiveState implements MonsterState {+ P- W# q( Q, W" o+ n5 Z
- @Override' C) W* o9 M/ ~7 v% U! a
- public void handleState(Monster monster) {- n' e) l9 B. e
- // Агрессивная фаза боя6 J8 W) o9 A3 _9 P0 M
- System.out.println(monster.getName() + " становится агрессивным! Атаки усиливаются.");3 }2 x9 Y0 c" @4 | ^6 \
- monster.setAttackPower(monster.getAttackPower() * 1.5); // Увеличиваем силу атаки# _9 X& E b' O0 O
- }
3 Q, d' T$ ~. Q& y6 d' v - }! z- e: w9 I9 N" s$ V0 q
Скопировать код Класс для финального состояния монстра:& X' X% b5 y g4 f. v' e, b2 M
- // Пакет org.l2jmobius.gameserver.model.actor.state3 K, e( N0 M7 X( s6 c" @$ }
- package org.l2jmobius.gameserver.model.actor.state;
+ M( a9 J, g) ~5 Z" ~9 d
. i. X+ g# G- p) c' T o- import org.l2jmobius.gameserver.model.actor.Monster;* d- @3 z7 T. j1 a* ?( r5 d$ i% b! s
- 9 ?) M' V1 \+ X9 O
- public class FinalState implements MonsterState {' u& i* d \% N) f0 K" Y
- @Override
& M! }( X3 A# c* e3 Z& y. Q - public void handleState(Monster monster) {
, T; _4 P( Q! X0 h - // Финальная фаза боя
- ^' R$ o3 i7 {, L; u* ] - System.out.println(monster.getName() + " готовится к финальной атаке!");1 ]" u! M" g$ I; W0 h6 T6 u$ n
- monster.setAttackPower(monster.getAttackPower() * 2); // Максимальная сила атаки# {$ |, B3 r% W
- }
/ O3 b+ [, O% C* b - }
% A; l1 i. [5 T
Скопировать код 6 B% `. v. {( O0 U0 S
Шаг 3: Изменение класса MonsterЧтобы монстр мог переключаться между состояниями, нам нужно обновить класс Monster. В этой сборке L2J_Mobius, классы для игровых объектов, таких как монстры, находятся в пакете org.l2jmobius.gameserver.model.actor.
$ b, I! X1 v# J0 K/ S" z- // Пакет org.l2jmobius.gameserver.model.actor9 {! t4 i3 F2 f3 r$ d* e5 ~
- package org.l2jmobius.gameserver.model.actor;, t; n! @! v* n, n: f8 Z
- 3 e. M8 h& R& K
- import org.l2jmobius.gameserver.model.actor.state.MonsterState;
, e! s7 D9 \ O - import org.l2jmobius.gameserver.model.actor.state.InitialState;
% `& R: ^- Y9 u5 i3 j
+ K2 P; y7 ]( q5 Y) a- public class Monster extends Creature {
+ C0 Q z$ ~& F; U - private String name; V U2 D1 O# ?& E: z# x5 n! Q9 w( a
- private double attackPower;
& e2 d: ^7 ~$ Q1 g8 i! p - private MonsterState state; // Текущее состояние монстра: R/ u6 v; ~+ |% h& \1 [! b+ a
% A- Z, P" i$ i1 r- // Конструктор монстра6 ], I/ {/ F+ v, r
- public Monster(String name, double attackPower) {/ H% E% {9 |8 Q7 ]: X1 a- \3 R
- this.name = name;
: I( p: E+ z! e J - this.attackPower = attackPower;
" d' V: D+ q6 ]. ~1 }/ ?, F" \ - this.state = new InitialState(); // Устанавливаем начальное состояние
0 j- X B0 M' l6 w# m% R' T& b4 E - }
6 R) y6 C' s7 d! H- s5 Q5 i
/ C. v+ J( G7 I2 I, u* p- // Метод для смены состояния
5 a: d; F k1 q: A - public void setState(MonsterState newState) {: E r. J3 Q2 V4 {8 `& ~
- this.state = newState;
h( a6 t2 u7 V - }" Z) B/ V" o; v/ p- _, }" e! j
- 5 s8 m4 S* J# l7 T7 b5 O6 I
- // Выполнение действий на основе текущего состояния
8 c' M+ T% ]! Q - public void executeState() {$ l) R. P: K3 A2 q, _+ k" S" e6 s
- state.handleState(this);
& i- |6 x4 n3 h V3 X1 M9 u, f - }) l9 b; Z! l! }) y
4 e, d, J! [2 s% N+ [- // Геттеры и сеттеры
: n4 `. t k" {3 s* Q$ g - public String getName() {
$ E8 d0 y2 u6 L8 y* B - return name;
# e: P& \7 j6 q) P. @; z2 \9 T9 y - }7 ~& {6 r* q* A8 R) z/ }! c
$ A0 \- c% y0 R4 F- public double getAttackPower() {
+ _, {! @: _8 H! h+ l - return attackPower;
0 E2 F" `# S; |) L6 i, b k - }
3 _4 B& Z/ h& L6 j g* @( H1 E
7 `, k: U( c. V- public void setAttackPower(double attackPower) {
$ v+ q% J5 c+ ` - this.attackPower = attackPower;
( Q8 G& V; ^6 x$ l - }0 Q4 X4 @" }+ m8 n6 a+ H
- }. h, a; C; {9 M3 Q H# o5 ^+ w
Скопировать код
5 j5 c, y, x( I% {: ~Шаг 4: Симуляция боя с фазамиТеперь мы можем протестировать логику боя с переключением состояний монстра.
# V" x, P+ y: b" C5 n0 |4 W }
: e( S! } ?" P0 J- // Пакет org.l2jmobius.gameserver.model.battle! Q% o5 \( @: {+ R; U* B/ I
- package org.l2jmobius.gameserver.model.battle;* |. L7 y# P% [+ Q1 q4 J
- . e1 |& {5 b9 c$ ?# }) s) _' `
- import org.l2jmobius.gameserver.model.actor.Monster;+ x# U8 X; G6 i3 z" Z X
- import org.l2jmobius.gameserver.model.actor.state.AggressiveState;' _4 ^9 D6 ]) u `
- import org.l2jmobius.gameserver.model.actor.state.FinalState;
. q G" L8 a: G: G9 }
1 {) _+ F: f+ j5 |/ R; N) z- public class BattleSimulation {5 p* P9 t# ^. J. i
- public static void main(String[] args) {: [# R" Z$ }. k) e$ |1 [* r
- // Создаем монстра с начальной атакой( N0 Q2 {- [' _" Z
- Monster monster = new Monster("Дракон", 100);
' T! C' {4 R0 p' K% P
1 B6 l% a0 W: \" [- K4 q# e- // Начальная фаза
" B+ ~! @( J$ R3 }- J) ]/ a - monster.executeState();
0 p B9 k1 F* k( C4 r2 _& }. \
( O$ P& Q& V0 {, Z- // Переход в агрессивную фазу
/ }+ a( K4 u5 h1 K - monster.setState(new AggressiveState());
1 { v) y0 p6 J! P - monster.executeState();" l' Y9 z- H+ V9 B+ C2 b9 @. |0 ^
- # n- `, q& [8 q( V
- // Финальная фаза" F. H8 [3 n, \ P
- monster.setState(new FinalState());
( o2 M8 Q) t6 d - monster.executeState();
, r7 K3 N1 F C" w p - }
/ Y: u; c* ?. P% m9 l$ ` - }
- D& y( V i1 y" f
Скопировать код 1 |4 S6 K% Q N1 P! a4 S- o2 I2 U# j
Комментарии по структуре пакетов и классов:! h+ Z( }4 h. H) C2 ~9 G
- Пакет org.l2jmobius.gameserver.model.actor: содержит основные игровые сущности, такие как Monster.
- Пакет org.l2jmobius.gameserver.model.actor.state: отвечает за реализацию состояний для объектов, таких как монстры.
- Пакет org.l2jmobius.gameserver.model.battle: может содержать примеры взаимодействий, такие как симуляция боевых сценариев.) k- @ F/ Z# D
ЗаключениеШаблон "Состояние" позволяет легко управлять фазами боя и не перегружать основной класс монстра. Это делает логику боевых сценариев более гибкой и масштабируемой. В будущем, если появятся новые фазы или состояния, их можно будет легко добавить, не изменяя основной код.
6 o- }2 Y2 a& EЕсли появятся дополнительные вопросы по реализации или структуре классов, буду рада помочь!
. c0 y9 [% S' k. x+ M& s; V& `3 b4 L/ O; u$ F
|# N4 y9 M+ g
+ U# ^0 V1 c q5 @) C- p! A' C5 W
" [# R" U( e8 `6 J! _- \2 p
: H, w7 N6 c2 w1 i8 j& @: _1 i; h; o% t
( |- p2 r7 p3 l# d
7 |; V! K: j/ ?+ C
1 ?/ h, ^# G; H* Z% ~7 g5 i3 c- g# l
" N) M: c- v4 W/ n2 A/ [6 y, ^$ U, X4 ?
, v' |7 T0 b8 p" ?# k8 P0 _1 z, K& _# C. }" f5 ~8 p
: s8 m! r/ b# ~4 v/ \
|