Для управления сложными взаимодействиями, такими как несколько фаз боя с разными состояниями монстра, лучший подход — использовать шаблон проектирования "Состояние" (State Pattern). 0 E' N# ?5 t( W( u7 G/ t
) R1 }& a( p& e e* _# i" t, I
Этот шаблон позволяет разделить логику поведения объекта на разные состояния и управлять ими более гибко, избегая перегрузки основного класса монстра., A9 G. D+ Q9 `& c
+ D) S0 Q4 s9 M2 X X; `
Шаг 1: Создание интерфейса для состояний монстраПервый шаг — создать интерфейс, который будет представлять разные состояния монстра. Этот интерфейс определяет метод, который будет вызываться в зависимости от текущего состояния.
7 B" o# m R1 d1 G8 e. H* s. a/ U
4 {. v- }& v; d5 X2 v- // Пакет для состояний монстра
, N6 ?2 O9 Y5 f# @, T$ `5 n7 ~ - package org.l2jmobius.gameserver.model.actor.state;, y( j1 _9 i4 u+ w: X& e
- $ h! P' M- a& c' ]
- // Интерфейс, представляющий состояния монстра% @ h9 L o4 @6 M4 @
- public interface MonsterState {
- s2 z+ b5 R) _' Z6 M3 {: c6 } - void handleState(Monster monster);
) B6 M# k% A- l+ u- N - }; f& u, z0 ?1 D' {
Скопировать код
2 u6 J+ ^8 S# ZШаг 2: Реализация различных состоянийТеперь создадим классы для каждого состояния: например, InitialState, AggressiveState и FinalState.
6 u1 {. X. ^. ^5 V4 D) B; |1 d" M6 ~: r
Эти состояния будут реализовывать интерфейс MonsterState и определять поведение монстра на разных этапах боя.- C8 G l0 Q0 u4 {4 K
2 q3 J% F" |% T m2 B9 I" V7 nКласс для начального состояния монстра:
9 |' N& L9 V4 b3 J- // Пакет org.l2jmobius.gameserver.model.actor.state' u7 |8 b$ |: f$ U6 ]* w6 r# R: y
- package org.l2jmobius.gameserver.model.actor.state;5 X2 c# p h* g5 d
8 \2 S- l4 Q* f( ]- import org.l2jmobius.gameserver.model.actor.Monster;
, w' o6 ]; o R1 }, Z$ v* ?* M7 ^1 X/ D
3 L; k& ?; Z: F& t+ [- public class InitialState implements MonsterState {
0 Y! c3 \3 V6 L" O0 G7 T - @Override
: b+ K1 e# d# Y$ T8 K/ t' c% J - public void handleState(Monster monster) {1 c2 I: r, ^% N# x8 L: Y$ F' ?& z0 F
- // Начальная фаза боя
0 d! l% J* x7 h+ B! X - System.out.println(monster.getName() + " начинает бой с обычной атакой.");1 [7 g2 P) ~; N( [* i
- }4 l* K# W$ P) |9 a
- }
* |) F. Y7 v2 g9 I8 G( d
Скопировать код Класс для агрессивного состояния монстра:
( }( W) \- q9 ~* s1 X6 L- // Пакет org.l2jmobius.gameserver.model.actor.state
7 @' L9 O5 N. \- y - package org.l2jmobius.gameserver.model.actor.state;) d8 @* d% i k- r$ i$ P/ h+ l
- c1 s- o/ L( U+ S% R- H6 V
- import org.l2jmobius.gameserver.model.actor.Monster;* h: L# X! j0 J0 Y
- . D$ ] r. ?( h2 h" S/ ~# R9 [
- public class AggressiveState implements MonsterState {
% _2 ]$ L8 n" t6 ] - @Override
- R7 i( Z, b( F* t - public void handleState(Monster monster) {! T* @) m9 r" y8 Z& Q- f
- // Агрессивная фаза боя4 c9 ^6 l8 W) b$ E, H( |4 i0 Q
- System.out.println(monster.getName() + " становится агрессивным! Атаки усиливаются.");
$ l( u# P- Z" K+ l0 a - monster.setAttackPower(monster.getAttackPower() * 1.5); // Увеличиваем силу атаки7 D6 d; z( n f2 g
- }( W2 {( [# c/ y* C- V! b
- }' G, t( u+ ]+ A) c$ h, s
Скопировать код Класс для финального состояния монстра:
% J" ~8 [& Z1 V3 d& K6 R& F; t: h: M- // Пакет org.l2jmobius.gameserver.model.actor.state
" }2 Q' n8 a& Z7 D - package org.l2jmobius.gameserver.model.actor.state;
8 X% q- r3 x1 t* q/ F) W
8 l# T1 \ G4 s% E; P/ N( O8 D- import org.l2jmobius.gameserver.model.actor.Monster;
1 @7 M% r$ v' l+ y$ y - S. U9 P' v( U; h4 b
- public class FinalState implements MonsterState {$ T0 X, Y5 }& A& |; r( x, f
- @Override
4 n3 d% X! e' t& Y* ]5 K - public void handleState(Monster monster) {
- D6 Z' e& O5 ~7 P - // Финальная фаза боя
8 m2 [; ]& L2 n% b3 { - System.out.println(monster.getName() + " готовится к финальной атаке!");
- k& H0 W$ [; n! A - monster.setAttackPower(monster.getAttackPower() * 2); // Максимальная сила атаки
5 e0 F% z! @5 h - }" d* _+ o3 E1 S9 o# l
- }% }$ S% D0 A3 o$ `9 q: I+ f
Скопировать код . E, w3 U8 I4 q. D% @
Шаг 3: Изменение класса MonsterЧтобы монстр мог переключаться между состояниями, нам нужно обновить класс Monster. В этой сборке L2J_Mobius, классы для игровых объектов, таких как монстры, находятся в пакете org.l2jmobius.gameserver.model.actor.
* ]" b" c% W' z# H& x$ u- // Пакет org.l2jmobius.gameserver.model.actor
, |4 G$ I9 s8 v - package org.l2jmobius.gameserver.model.actor;
+ P' n# e- a/ _- S
, l0 \% j* j9 S7 B5 |8 G0 ?) i I- import org.l2jmobius.gameserver.model.actor.state.MonsterState;6 f/ I- g7 {1 f$ X- X0 T
- import org.l2jmobius.gameserver.model.actor.state.InitialState;7 R5 R7 \2 K& v; N* W+ r
- 9 l( l- {6 ] k8 d; \
- public class Monster extends Creature {
5 g( c) z8 p( z" s - private String name;
4 x3 T0 ]# p' W7 F - private double attackPower;
3 U) Z7 x% H/ @ - private MonsterState state; // Текущее состояние монстра
8 o4 S" M- d! o1 U# A! h
9 l* _1 c8 Z. z5 Z- // Конструктор монстра
# V- b4 O4 q% Q5 d) g2 S - public Monster(String name, double attackPower) {( o0 t/ c( J6 A) ]0 `" q0 z
- this.name = name;6 ?' ^( f8 L3 ]0 h5 v- T2 p
- this.attackPower = attackPower; @5 H% y3 p0 F
- this.state = new InitialState(); // Устанавливаем начальное состояние
; h4 m- p3 A$ m: k2 c+ p0 n - }
4 J' w% E' m, s) ?+ r: g0 W - 1 M* ^6 b5 G! t8 v2 d
- // Метод для смены состояния
: f8 B y) t3 K A) W - public void setState(MonsterState newState) {5 {5 S% ]. a7 [5 |
- this.state = newState;
" v& x* K" Z/ W3 R/ p9 _$ [& K - }
, q" g! n% [- l" M - $ n! {" i# U% b/ _
- // Выполнение действий на основе текущего состояния+ \% h7 q8 V1 b
- public void executeState() {: _5 }! w* \! x2 ?! ~( d
- state.handleState(this);
: x) w; o5 @2 r3 P - }
/ y; t" _# z; [ s3 ~# |- | - ; L: M7 x1 B, f
- // Геттеры и сеттеры
* k$ `1 S! W# {1 X. m5 n - public String getName() {
( D: m, B+ p6 q7 n - return name;7 Z5 E8 c S5 }
- }. G$ e6 M j' Y. S2 V1 |( y+ ?2 Z
7 E5 k" A% w+ R5 ~& b, E5 o" N- public double getAttackPower() {3 |+ \7 P3 n# o; E
- return attackPower;
' V) f8 y5 ^" @" }5 I, }1 _ - }
, R) B C2 q. c; o8 L
. G. y( C/ u8 R: x9 u1 Y2 j X" d- public void setAttackPower(double attackPower) {4 J1 c$ H0 Q9 V: r8 w$ ^
- this.attackPower = attackPower;9 R0 R- P9 d; n$ e
- }
" Z \7 E! o0 R2 P - }
6 j7 N2 p. s& l ?
Скопировать код
' c( b/ p/ \! j) g, vШаг 4: Симуляция боя с фазамиТеперь мы можем протестировать логику боя с переключением состояний монстра.8 P9 F! u4 |7 @* D. Y% |
9 a% S# s+ t0 f9 T; T% F/ I
- // Пакет org.l2jmobius.gameserver.model.battle$ t* ^$ _+ o# M) T6 M' o+ \0 a
- package org.l2jmobius.gameserver.model.battle;
- t4 S+ W/ j5 H3 b$ ]
. o/ S8 r( e- x9 J9 G3 I- import org.l2jmobius.gameserver.model.actor.Monster;7 N' h. h' T5 F$ V
- import org.l2jmobius.gameserver.model.actor.state.AggressiveState;5 P6 }( {- o- i
- import org.l2jmobius.gameserver.model.actor.state.FinalState;
8 R% V) f9 I8 V! M) S: z) y8 Z. K - / p6 E' Q- G% `0 d8 v
- public class BattleSimulation {$ n$ p6 c. n( k% S) o' a- R
- public static void main(String[] args) {$ o; [2 t# u, i; A% H
- // Создаем монстра с начальной атакой8 A U c8 \, b7 n% X) F% x, c2 K
- Monster monster = new Monster("Дракон", 100);9 _8 T3 K% ~$ o" u2 |0 }
- + c) O" |1 H9 T! {! \3 f
- // Начальная фаза1 M7 O; b7 J3 [5 o3 S7 u1 t& R0 d
- monster.executeState();5 X8 h6 W- m/ D" s0 u6 Q% M
9 t; c0 i0 J, N- // Переход в агрессивную фазу
% J; {+ Q5 ]9 ` - monster.setState(new AggressiveState());4 C' I" K# R% m, H
- monster.executeState();
! b; X: M; @- j6 q* ~; t; w @% b" P - : `2 a' O5 O. p8 o
- // Финальная фаза
- r* ^/ E/ l7 E1 U& l- Y - monster.setState(new FinalState());
" `3 r. ]! {$ n A5 @4 g$ J - monster.executeState(); ^. \! Z- ?$ X( E6 A8 e
- }$ e/ H8 i: v p, i
- }$ J+ H* ?( C9 }4 j
Скопировать код
\, s9 c% ?9 y8 ?% u yКомментарии по структуре пакетов и классов:
! E8 P/ t1 x! I' s- Пакет org.l2jmobius.gameserver.model.actor: содержит основные игровые сущности, такие как Monster.
- Пакет org.l2jmobius.gameserver.model.actor.state: отвечает за реализацию состояний для объектов, таких как монстры.
- Пакет org.l2jmobius.gameserver.model.battle: может содержать примеры взаимодействий, такие как симуляция боевых сценариев.! Z$ ]5 X) v3 E4 v, q5 `! X! u
ЗаключениеШаблон "Состояние" позволяет легко управлять фазами боя и не перегружать основной класс монстра. Это делает логику боевых сценариев более гибкой и масштабируемой. В будущем, если появятся новые фазы или состояния, их можно будет легко добавить, не изменяя основной код.
" k' s* S% Z2 B5 n z# kЕсли появятся дополнительные вопросы по реализации или структуре классов, буду рада помочь! l3 G$ m. e, P4 f0 ?, z- r
! p2 e$ z8 M9 r* I0 `
$ g ~2 n. i! q
1 y& }' w1 ]' g N/ c* i8 J$ F5 Q
& c5 C1 L' C2 }* }! C& A1 x" q7 ~/ i& S# w2 H- l
, p) E+ G! e$ p( a3 o( ^. L5 X
, E2 j; Q9 L0 k$ J* X
3 }- [+ ]/ {# ^+ g! E$ U1 o) C9 Y" y
: }! f' p5 r i* E( M, A; {' E6 F+ S' t
7 W+ a! V: ~0 \) y! \6 ~- T! i: ?# I/ E- }! w) h
+ ~- a/ G! r2 w/ E+ k G* c
|