Для управления сложными взаимодействиями, такими как несколько фаз боя с разными состояниями монстра, лучший подход — использовать шаблон проектирования "Состояние" (State Pattern).
' {- B% M. \" i2 q! ?) }1 A/ M- o! o9 h8 F) ?4 {& V# _* f- s
Этот шаблон позволяет разделить логику поведения объекта на разные состояния и управлять ими более гибко, избегая перегрузки основного класса монстра.
4 [9 E. C, e/ q- J/ }4 T$ N5 k! N, ~
Шаг 1: Создание интерфейса для состояний монстраПервый шаг — создать интерфейс, который будет представлять разные состояния монстра. Этот интерфейс определяет метод, который будет вызываться в зависимости от текущего состояния.! \5 z5 {) [# n* v, O; {4 y
# s; ^$ ^; V: l6 B% h' q
- // Пакет для состояний монстра! c" @9 S" W; n: d
- package org.l2jmobius.gameserver.model.actor.state;6 I( K3 W* y6 e2 S' V! {
- . t3 ]0 R4 P( S7 W3 {
- // Интерфейс, представляющий состояния монстра: F5 T8 m' Q8 {3 n# ?1 ~7 u
- public interface MonsterState {( }! o1 p9 m. \: N, h7 o8 e
- void handleState(Monster monster);/ r5 c$ p8 ~2 O$ X
- }
9 Y% h' B6 V0 {4 H
Скопировать код
/ }- } g5 ]/ V$ O3 lШаг 2: Реализация различных состоянийТеперь создадим классы для каждого состояния: например, InitialState, AggressiveState и FinalState. $ R% V/ {7 S, ]- e( t& P& P
0 O8 H5 g9 k" {4 e' i, u' N4 rЭти состояния будут реализовывать интерфейс MonsterState и определять поведение монстра на разных этапах боя.: Q3 {0 V1 q1 D0 Q) D
, u# p& W9 t% A1 c) P
Класс для начального состояния монстра:9 q7 ]; Z8 a- F8 H0 s0 b! O! Z
- // Пакет org.l2jmobius.gameserver.model.actor.state
/ y0 Y& R) X7 R9 y# E. n. P1 W - package org.l2jmobius.gameserver.model.actor.state;. D! X p3 q- q) r
! Q6 a8 s, g! V+ k: e- import org.l2jmobius.gameserver.model.actor.Monster;# e: n) c5 E! ?, s$ i& f8 `1 D
- 9 n/ l/ T; r( ] ]7 C+ i8 |5 W2 {' e
- public class InitialState implements MonsterState {' { z$ g, \/ S$ T
- @Override
, o8 N' Z8 T' p" ^ - public void handleState(Monster monster) {1 a3 G2 M6 S! @
- // Начальная фаза боя
! P1 R2 Q9 @8 [/ }' L9 `. @% u - System.out.println(monster.getName() + " начинает бой с обычной атакой.");5 Q$ t' A3 r( r, H* ` P
- }
4 j) F; S0 ~6 n - }
9 j! U4 Q+ G0 ]
Скопировать код Класс для агрессивного состояния монстра:% w" h) j2 L, }: o
- // Пакет org.l2jmobius.gameserver.model.actor.state- Z! k( ~! M! p. b
- package org.l2jmobius.gameserver.model.actor.state;7 X3 {8 `+ w! a$ D; n( I7 ?
9 X$ Z* `7 P' A* H4 _3 T2 j- import org.l2jmobius.gameserver.model.actor.Monster;
! ~8 ]! e) G' ^; Z - 7 b/ r' v' |/ e H+ S/ P
- public class AggressiveState implements MonsterState {
% B- H" |& f/ z( V - @Override
$ r1 D1 { B3 _+ A - public void handleState(Monster monster) {
' B# }# x! A% R- t9 c) U - // Агрессивная фаза боя4 w9 i P' {9 }# P
- System.out.println(monster.getName() + " становится агрессивным! Атаки усиливаются.");5 g+ [9 S% z: q, b0 k
- monster.setAttackPower(monster.getAttackPower() * 1.5); // Увеличиваем силу атаки7 ^2 r9 N8 j, o
- }
8 |, k" u: Y# u0 b" i$ ] - }
. b, c |* A0 r! Y# l! c
Скопировать код Класс для финального состояния монстра:8 E3 G; b) n/ Z, |4 d& V
- // Пакет org.l2jmobius.gameserver.model.actor.state* ?8 A6 |9 e7 w0 L
- package org.l2jmobius.gameserver.model.actor.state;
! z- k- l7 a9 z- H C& { - : F# N5 R) N2 O5 f0 G( w+ Y$ j
- import org.l2jmobius.gameserver.model.actor.Monster;
1 [# g3 S% Q9 s - / m6 F" V8 d* K
- public class FinalState implements MonsterState {0 o) C6 u! I- G1 K, f
- @Override3 x S0 z( S$ r5 H8 U4 Z
- public void handleState(Monster monster) {: H' f, c$ y! y1 [, D( @+ N
- // Финальная фаза боя) T X0 i# g7 d3 J6 Q4 @: }
- System.out.println(monster.getName() + " готовится к финальной атаке!");1 t# L2 f! i3 c
- monster.setAttackPower(monster.getAttackPower() * 2); // Максимальная сила атаки
: o8 I; |1 j6 X5 W: ~ - }
# v, `% j" \. D - }
4 o: ^& G3 L# c
Скопировать код 0 _3 u5 Q) ?6 ]5 u
Шаг 3: Изменение класса MonsterЧтобы монстр мог переключаться между состояниями, нам нужно обновить класс Monster. В этой сборке L2J_Mobius, классы для игровых объектов, таких как монстры, находятся в пакете org.l2jmobius.gameserver.model.actor.
3 y( {/ g; Z6 x2 Y+ h- U- // Пакет org.l2jmobius.gameserver.model.actor% W2 _- X3 e. f3 N7 l2 }6 t* A
- package org.l2jmobius.gameserver.model.actor;
0 j+ `/ ^' L: `; j3 F9 K
( L) v- b! F" Z6 ^* b0 ~- import org.l2jmobius.gameserver.model.actor.state.MonsterState;
' {. e8 I% C1 n# U! O. v5 s3 s' |3 p - import org.l2jmobius.gameserver.model.actor.state.InitialState;
1 @8 ?8 M6 u, l' B% |( g; _3 M - 3 f5 ^* v; Z4 Y B R: y
- public class Monster extends Creature {! }! ]( Y) w' L! D" Q, G
- private String name;
# }- I* w' s7 g! E - private double attackPower;% o2 m* p" m; R0 G! D% `+ v s& q
- private MonsterState state; // Текущее состояние монстра B4 |# O0 f; i! `: V6 X
# U' Y+ w: l' _0 @* o: @, @3 t2 l- // Конструктор монстра
: Y8 ]7 P1 P/ b c7 C3 X - public Monster(String name, double attackPower) {$ m! K) P* H8 K$ C! Z6 E- k
- this.name = name;
( W+ Z" W8 s2 w: H - this.attackPower = attackPower;- E. V% S0 g6 Y0 g
- this.state = new InitialState(); // Устанавливаем начальное состояние* f% S9 T: K0 z' p7 D
- }8 e* q/ ` B. n; b: w
- 9 `: F! @3 J* _5 @
- // Метод для смены состояния
+ _1 w. D! x0 ]1 z t - public void setState(MonsterState newState) {
4 z* x* r2 C* M0 a - this.state = newState;" U* _4 _7 t% S9 F2 F
- }
& K) J1 c8 _/ U
- j% p+ ]- s% P% ?0 M- // Выполнение действий на основе текущего состояния
5 [8 D# V) A: R Q2 ? - public void executeState() {# V7 F9 i3 \$ k" G7 a
- state.handleState(this);. V/ C3 O$ ^# }, T6 h! v
- }
: r; I d! X8 V5 _- p, A - ( ^1 ]( p( S' [ {: g
- // Геттеры и сеттеры
+ }2 j& y. f v$ c6 R% z4 t3 o - public String getName() {
+ ~( Y! W o& @5 @, K# u# Q - return name;
' B# @5 h! M9 W* _7 w - }
7 i4 V8 K2 _5 X. j
. A- c9 B' |$ H- v. l- public double getAttackPower() {+ n- _2 F4 _6 E4 j( _
- return attackPower;
X, n; W4 ~' d2 k2 s1 J0 B - }
: E' j' X! R" _, m0 }! l - 7 M1 s: p- K& \7 k
- public void setAttackPower(double attackPower) {: y& O% s1 i, I/ b
- this.attackPower = attackPower;
f7 c! J/ e( \6 b9 d- x- P - } ^; Q' Q0 }( X1 ^+ ~, t
- }
+ g4 t [. `% X q
Скопировать код ) W* F8 ~5 Y/ ^, K# v7 Q
Шаг 4: Симуляция боя с фазамиТеперь мы можем протестировать логику боя с переключением состояний монстра.
0 r- B8 y3 \( B( J, k
& s- w+ b" |8 X. \5 U3 l! F+ Q0 o: _- // Пакет org.l2jmobius.gameserver.model.battle
7 F' U( ~; Y: Q6 }# o# G - package org.l2jmobius.gameserver.model.battle;
8 l3 I/ x" }4 ]3 W( w - . H+ |- l4 n/ z0 f1 b
- import org.l2jmobius.gameserver.model.actor.Monster;
+ R4 P v8 H; |: T' L1 ^ - import org.l2jmobius.gameserver.model.actor.state.AggressiveState;' C# D8 y9 d4 L4 J4 b; m
- import org.l2jmobius.gameserver.model.actor.state.FinalState;3 ?5 T" z! g0 }3 B! @
. q. F& R1 ^/ f- public class BattleSimulation {
* V5 a' t L: n Y6 s& M% @ - public static void main(String[] args) {
- x1 i$ T% k. H' w0 C# } - // Создаем монстра с начальной атакой
5 v1 T/ ~# @ G" I7 j& F - Monster monster = new Monster("Дракон", 100);- F E9 t' E. N9 m' ~2 g
- 5 G/ S- k8 ~9 A, v/ A7 h2 M
- // Начальная фаза& T& v" M% Y. |* _1 M1 @
- monster.executeState();
, s9 W+ C& A1 ^3 ?6 U
( h' q+ M2 V" Z$ g [" Q! Y- // Переход в агрессивную фазу' J6 ~+ Q6 [: d, o
- monster.setState(new AggressiveState());
+ G+ O4 z9 x7 {* ]$ g1 W9 a9 t - monster.executeState();
3 w0 ~6 L) ]. m9 W& p - / A. N9 u) e2 e# x( L
- // Финальная фаза
8 Z" F& P7 n8 t, d - monster.setState(new FinalState());6 `" H( v* T% {
- monster.executeState();
4 e+ h2 A8 T! k# V- X8 p' a - }
. r/ q* F4 Z0 @9 i% F2 M; O1 z - }4 W: m8 p( j8 l/ p0 M8 c9 V3 e
Скопировать код
' }2 I4 [% G1 }- y6 ^# Q4 r ^Комментарии по структуре пакетов и классов:( d2 m9 S( j$ @2 C
- Пакет org.l2jmobius.gameserver.model.actor: содержит основные игровые сущности, такие как Monster.
- Пакет org.l2jmobius.gameserver.model.actor.state: отвечает за реализацию состояний для объектов, таких как монстры.
- Пакет org.l2jmobius.gameserver.model.battle: может содержать примеры взаимодействий, такие как симуляция боевых сценариев.. Z; H; \6 u* l3 G1 e, K
ЗаключениеШаблон "Состояние" позволяет легко управлять фазами боя и не перегружать основной класс монстра. Это делает логику боевых сценариев более гибкой и масштабируемой. В будущем, если появятся новые фазы или состояния, их можно будет легко добавить, не изменяя основной код.; N! F* |- B, a, h
Если появятся дополнительные вопросы по реализации или структуре классов, буду рада помочь!
* E# B( Z P y( d4 ^; l( r" f0 @9 F" d, E9 I1 Z3 A
6 \; }5 t; p; \$ }0 ]' u6 M# i
/ A/ i7 k2 H* ]$ |, Z
* N: J7 X1 V# o+ o9 X0 O. \! C
3 o; A2 v0 S- U; }7 y# S! H
. G4 y0 X( x' {! ]6 w
+ {& y) U. U$ k. K# K& S' K5 ^) [3 i
( D8 X! {5 j% o3 h0 [! g
1 A: _1 n$ U! F8 w% t4 p+ G+ d
( o! ]4 {$ y& m$ I5 d- K9 _; d+ \+ h4 B; S2 v
4 I5 s6 @1 E% z
6 w/ O! H$ h0 }( G& d/ N' m6 ]6 s
|