Для управления сложными взаимодействиями, такими как несколько фаз боя с разными состояниями монстра, лучший подход — использовать шаблон проектирования "Состояние" (State Pattern).
) Y- f# p; c( s: R. G4 f- A3 _0 A- n4 I6 H+ Q1 a) F1 O" d- R$ u
Этот шаблон позволяет разделить логику поведения объекта на разные состояния и управлять ими более гибко, избегая перегрузки основного класса монстра.
2 B F! D* }9 Q9 G8 G' W8 |5 z6 S# K' L* l4 m
Шаг 1: Создание интерфейса для состояний монстраПервый шаг — создать интерфейс, который будет представлять разные состояния монстра. Этот интерфейс определяет метод, который будет вызываться в зависимости от текущего состояния.
4 |+ A8 n3 u4 D3 J# Z7 j" B
* O0 \7 [2 n. Z! x% ]. X& G) w- // Пакет для состояний монстра$ K$ D" X! N! f$ u- f
- package org.l2jmobius.gameserver.model.actor.state;: j& t( N2 ^& P& t0 s& T
* Q" v) ?& w- d1 S$ ]9 k- // Интерфейс, представляющий состояния монстра/ Y+ i2 N6 e1 I8 Q( P) E2 J4 Y
- public interface MonsterState {# W7 B! w' x, ^" A0 G. M" J, }6 R4 v
- void handleState(Monster monster);
$ \$ [% I4 G. c. t$ I - }
6 o; `# s) |, x7 x
Скопировать код
' L: ^+ g# t6 V: `. Y# _Шаг 2: Реализация различных состоянийТеперь создадим классы для каждого состояния: например, InitialState, AggressiveState и FinalState. 0 W; @: i. H1 S2 E0 j2 |
) z1 ~5 _- o! X
Эти состояния будут реализовывать интерфейс MonsterState и определять поведение монстра на разных этапах боя.; D z2 g* G0 F9 G. _$ t
$ s! w j: ], c ^" W& c9 A! D
Класс для начального состояния монстра:5 j o. w( ]% N; Q) k/ J
- // Пакет org.l2jmobius.gameserver.model.actor.state1 }' d1 P& t8 K" c- W& j
- package org.l2jmobius.gameserver.model.actor.state;. _; F; X& E8 z) C
, [3 ? i- y( o- import org.l2jmobius.gameserver.model.actor.Monster;
9 g+ u1 O" `5 y - ' x+ c7 I0 s3 u
- public class InitialState implements MonsterState {
F0 n+ S' h9 z0 Z L - @Override
2 l4 v v; M* U/ _1 E3 h/ _! F0 \ - public void handleState(Monster monster) {
1 Q) v4 F8 K, y7 L- { B0 B/ K1 U! i - // Начальная фаза боя
- W. E0 f( w# Y: \: @% a3 P - System.out.println(monster.getName() + " начинает бой с обычной атакой.");
3 ]4 e3 Y# R6 p% R - }
" C, {; [' f- i) s5 G - }
6 v4 ]" Y: Q: z d- e; _
Скопировать код Класс для агрессивного состояния монстра: k( C9 Q5 K& H6 j
- // Пакет org.l2jmobius.gameserver.model.actor.state$ T" j- g/ A0 A& Q
- package org.l2jmobius.gameserver.model.actor.state;0 N! e5 T+ g* ~$ y s. R
z% T; j4 K, O- import org.l2jmobius.gameserver.model.actor.Monster;7 I( F2 t/ \" @; u9 }
( ~, o( N M; A- W8 o- public class AggressiveState implements MonsterState {7 [& A2 q- `8 D
- @Override
- U1 P, J/ V H+ ? - public void handleState(Monster monster) {
, }4 ^0 z% `, f* | R - // Агрессивная фаза боя
+ d; J0 n" ?+ n; J6 Q - System.out.println(monster.getName() + " становится агрессивным! Атаки усиливаются.");
7 W ], q7 ~6 ?5 u) ~4 p - monster.setAttackPower(monster.getAttackPower() * 1.5); // Увеличиваем силу атаки" X% A% u- d; J8 j6 e% Q
- }
* c. z3 G, h# j* E, u4 J - }+ z) Y: {- x; m: ?4 L+ o$ c
Скопировать код Класс для финального состояния монстра:
3 B% G# `: a4 @' ]- W5 V. Z- // Пакет org.l2jmobius.gameserver.model.actor.state
; l W& M+ o" d4 ^1 u9 h6 p3 D - package org.l2jmobius.gameserver.model.actor.state;* W* A8 W# i2 p+ I( N
- 2 n9 L( z1 ~2 t. e; O
- import org.l2jmobius.gameserver.model.actor.Monster;$ s: ^8 l+ t4 N& [# R
- ) d" ~$ [9 P- J: ` Z
- public class FinalState implements MonsterState {$ v" R6 i. n4 ~1 h C: ?$ ^
- @Override
# Y. V! U% r0 h0 J" _* A - public void handleState(Monster monster) {/ C# b8 w" s/ o$ V
- // Финальная фаза боя4 d8 N# E* v! q/ M5 I
- System.out.println(monster.getName() + " готовится к финальной атаке!");5 R( g5 c0 I2 v; B l; m
- monster.setAttackPower(monster.getAttackPower() * 2); // Максимальная сила атаки
/ Y/ Q9 S. [) \$ `& Q) X - }
2 |7 f6 h: a1 Y& i' L3 G& `! P - }) |- D& p! G" d6 |# D8 S3 T7 L+ j
Скопировать код
6 z; i4 J \" |: f- _% U0 HШаг 3: Изменение класса MonsterЧтобы монстр мог переключаться между состояниями, нам нужно обновить класс Monster. В этой сборке L2J_Mobius, классы для игровых объектов, таких как монстры, находятся в пакете org.l2jmobius.gameserver.model.actor.
) G' f' G; \2 \. ?. P: G- // Пакет org.l2jmobius.gameserver.model.actor$ F1 k- `4 @( F9 o( @4 v- i* Y
- package org.l2jmobius.gameserver.model.actor;5 }6 S, l- }+ ~: s7 U, B
% s; j' ]5 M; `. J% S- import org.l2jmobius.gameserver.model.actor.state.MonsterState;) f: q6 S. d8 u+ K
- import org.l2jmobius.gameserver.model.actor.state.InitialState;% C5 g* S7 @# Z" _' d9 L' i. |
p" Z; H& T4 p3 ~( }, s- public class Monster extends Creature {; r K! \* w* O6 g/ p
- private String name;
2 i6 \0 w! I# G" G* { a6 W8 m - private double attackPower;2 X% o5 e+ u+ C' ]1 |) h A6 r- w
- private MonsterState state; // Текущее состояние монстра/ {) h2 A5 M3 l* J( k
- " \$ J% i: T, [' l7 q
- // Конструктор монстра1 m0 U* L$ J* R2 C6 t0 r7 d% L
- public Monster(String name, double attackPower) {8 v% S! I9 \! O& f' a% i
- this.name = name;
6 G* D: B& m7 A9 p' _. g7 r( ^' l - this.attackPower = attackPower;. \- b% U$ o, k( q% A" O
- this.state = new InitialState(); // Устанавливаем начальное состояние' g5 c0 _" K# v/ o: i9 C: Y# M
- }' ~. q9 t2 ^+ M7 e+ a' m# H
4 [1 P+ F" b1 Y, x4 R0 q4 s- // Метод для смены состояния
0 a, s- N! ^. R' F+ u9 \/ ]0 p' ^ - public void setState(MonsterState newState) {
( W& V0 i. K, q& k0 o5 d" L - this.state = newState;# L- i. E, S4 u' E
- }
. A. f2 x" B0 M- A7 V
1 P* C. P. S9 e. V, ~' p- // Выполнение действий на основе текущего состояния
, x/ ?4 t) c8 I# G - public void executeState() {
1 M2 h, C- c$ ?$ n# J3 k h+ Q0 T! q - state.handleState(this); F# W/ W( V* p
- }
# S2 x0 e) R6 S' I2 R: W
7 l" b5 M' o: b- // Геттеры и сеттеры
' M$ q9 K4 d5 v5 r( [+ W1 I - public String getName() {* [- I& y4 d; A9 I$ P# c; k: Q
- return name;" J9 a9 R8 o( @; q3 T$ n4 R
- }
9 J0 R& }% e" _/ y, p( W
& z I* R$ y4 p' k1 d v- public double getAttackPower() {
0 R3 M# y+ o2 G; K - return attackPower;
5 [- ?" G" r2 [6 r - }! @4 a, n6 W S/ j# F
; ^- i, H' i5 I! h W$ m5 ~- public void setAttackPower(double attackPower) {
" ^7 ]! e9 j9 o' d4 v: M+ f - this.attackPower = attackPower;
5 c7 }. P$ r8 n - }" l) x p% p) h( x* z: z
- }
7 X* W* w0 F+ z! k
Скопировать код - w4 H" o6 U& k. Y: {4 w8 i
Шаг 4: Симуляция боя с фазамиТеперь мы можем протестировать логику боя с переключением состояний монстра.7 Y j3 {: t+ T, D/ p8 R6 N* f# N* e
" E4 z$ d6 \, m. T$ `3 B- // Пакет org.l2jmobius.gameserver.model.battle
9 \. D( ^6 Z, A - package org.l2jmobius.gameserver.model.battle;
- }5 X. S) o. q3 B. w" c - & x- e. }- C7 m1 a: h: C3 Q$ U
- import org.l2jmobius.gameserver.model.actor.Monster;2 u9 a( w! q4 Y9 ~8 Y7 y% B
- import org.l2jmobius.gameserver.model.actor.state.AggressiveState;2 K' }1 M* R1 E/ [9 J
- import org.l2jmobius.gameserver.model.actor.state.FinalState;' f5 O6 C& }- ~, f
- $ W- A) U7 I5 B2 a0 k' ^
- public class BattleSimulation {' P! i) w. H9 _4 r+ ]1 h! L9 c
- public static void main(String[] args) {* l2 [1 s+ U% _. ^" v" H6 t
- // Создаем монстра с начальной атакой3 D& r' _8 E& O$ e3 u; `
- Monster monster = new Monster("Дракон", 100);
0 O7 n- K8 O, M8 U - n* I: Y8 p( w) @% d' H1 S5 i. }
- // Начальная фаза
* S* p5 T+ m! [& s3 n - monster.executeState();4 ~4 `5 r$ R, v, b. ?& U
. l j5 u6 V' l: u- // Переход в агрессивную фазу
8 p* y" R( N, E. l/ n - monster.setState(new AggressiveState());2 A$ e C; J: S& k& q& E5 A3 R
- monster.executeState();
" x' Y! H4 [6 @
; V# q; E1 { Y& {* d- // Финальная фаза/ Z) u' z' I* c5 P4 m/ A
- monster.setState(new FinalState());
* ~- w, ^6 q8 _+ z - monster.executeState();
& \, P i( M8 `6 l! { - }% K7 q3 @8 i( q: e2 s4 W
- }
" C) w B, K8 D$ @0 N. V
Скопировать код
& T6 V" k n; ? t. r- ]Комментарии по структуре пакетов и классов:
' u9 `" d$ W2 y* q: r- Пакет org.l2jmobius.gameserver.model.actor: содержит основные игровые сущности, такие как Monster.
- Пакет org.l2jmobius.gameserver.model.actor.state: отвечает за реализацию состояний для объектов, таких как монстры.
- Пакет org.l2jmobius.gameserver.model.battle: может содержать примеры взаимодействий, такие как симуляция боевых сценариев.
$ S/ R) J- t/ Z1 W ЗаключениеШаблон "Состояние" позволяет легко управлять фазами боя и не перегружать основной класс монстра. Это делает логику боевых сценариев более гибкой и масштабируемой. В будущем, если появятся новые фазы или состояния, их можно будет легко добавить, не изменяя основной код.$ ?' Z: P5 o$ w0 r
Если появятся дополнительные вопросы по реализации или структуре классов, буду рада помочь!0 T$ `: U8 j1 L( [* f5 t" `5 r
& O. ^4 e0 o7 _1 p: a5 K6 N
- d$ m/ b: s4 t2 `
. f+ j- a. w q T
3 D( C% \ R, y, @+ A3 l' J# d: O
8 E/ {8 l4 A; h6 A) g3 t# V( n. y& V5 P
* C- S ^8 v' W. r; Y4 |; A
- N6 ?" G, _* S( T6 z9 T
" s+ t' x3 {+ M' q9 E5 m- t4 o$ [
: N' f* J0 U- D8 g9 s1 g. @" B& G' h1 `! O- K8 [6 m! g
- s3 _" e' W& o1 y6 W ^; p
# B% |/ v7 _( d" e" w1 T3 `' h6 l
3 b ], \! J( l |