Для управления сложными взаимодействиями, такими как несколько фаз боя с разными состояниями монстра, лучший подход — использовать шаблон проектирования "Состояние" (State Pattern). 6 { ~! R' I# t! @
# ~9 G, O3 v" y! K' T) U: }/ _
Этот шаблон позволяет разделить логику поведения объекта на разные состояния и управлять ими более гибко, избегая перегрузки основного класса монстра.; N% [0 L8 L. P/ c3 e' r$ O( a
. `% _& W5 P9 CШаг 1: Создание интерфейса для состояний монстраПервый шаг — создать интерфейс, который будет представлять разные состояния монстра. Этот интерфейс определяет метод, который будет вызываться в зависимости от текущего состояния.; t, D g$ ~7 s9 p1 c
Q: h% {2 Y! q8 q" z6 _5 W
- // Пакет для состояний монстра
: Q, m5 e; [( [/ ?+ w - package org.l2jmobius.gameserver.model.actor.state;9 {5 O* ^ u" v. u i6 @ ]- |
4 S7 b8 w5 L9 U1 X( D, m- // Интерфейс, представляющий состояния монстра
$ n% u3 {; b( e, C - public interface MonsterState {; c7 Q+ I9 ~: ~6 V- H5 U6 h
- void handleState(Monster monster);
4 ]& \8 x$ z/ O$ y6 Q" T - }
8 ?) h# u" j" c* Q( l
Скопировать код
1 r# c1 S8 J# u+ S1 D, u' s; I% dШаг 2: Реализация различных состоянийТеперь создадим классы для каждого состояния: например, InitialState, AggressiveState и FinalState. * V& j3 E1 x) M0 D* p; D; }
4 w1 |/ |" } N, DЭти состояния будут реализовывать интерфейс MonsterState и определять поведение монстра на разных этапах боя.) g" k& `: P; I+ s! N
& N) P9 u: h- b6 h# R
Класс для начального состояния монстра:
3 }9 o+ j8 T' R4 F' V( W$ d# L9 L- // Пакет org.l2jmobius.gameserver.model.actor.state
n) O$ t/ T3 t' G/ w - package org.l2jmobius.gameserver.model.actor.state;" N/ U, \: T2 u/ ]+ E/ D' \. [% H$ X+ W
1 J% m- j+ o# i- import org.l2jmobius.gameserver.model.actor.Monster;. \1 Y# L' } r" J
8 t- |: \0 d) N+ P4 B' [9 n! U- t- public class InitialState implements MonsterState {
f2 G- [( L/ ~" S( g - @Override5 d+ P. J) {6 _) w8 w, ?
- public void handleState(Monster monster) {
( \3 \8 q/ P0 `1 f4 ]- a3 O - // Начальная фаза боя
0 ?3 k2 y# V+ C/ W% f5 a - System.out.println(monster.getName() + " начинает бой с обычной атакой.");
7 N8 J- |, v& C - }3 v, p$ G/ i, x
- }
0 U3 M' i" E) k/ j+ K
Скопировать код Класс для агрессивного состояния монстра:
( h ^7 ^% E% d) u$ K- // Пакет org.l2jmobius.gameserver.model.actor.state; O& j- {+ S3 K+ l Z: |( h
- package org.l2jmobius.gameserver.model.actor.state;+ U, @/ |5 G. U+ N/ |5 r: _0 c
8 E* T$ S1 G8 F6 H# V+ f- import org.l2jmobius.gameserver.model.actor.Monster;$ T) u {' V J% f; e1 }
- 6 w8 e9 E: Y' ?( I, t s
- public class AggressiveState implements MonsterState {
& H- K% e G9 W! ^ - @Override" }9 d/ Q% k+ z" G! k
- public void handleState(Monster monster) {5 ~4 v9 i5 c6 T) T* a" ~9 f/ O7 n
- // Агрессивная фаза боя8 s4 E! X) w* Q6 v# @. m K
- System.out.println(monster.getName() + " становится агрессивным! Атаки усиливаются.");! Z% o- p, ^, a+ m5 X7 ?
- monster.setAttackPower(monster.getAttackPower() * 1.5); // Увеличиваем силу атаки
0 s9 D" }) d) m! }; O - }
2 ~7 ~7 @* U& Y - }
) t* z2 |* d' _2 W+ T
Скопировать код Класс для финального состояния монстра:9 p! }9 d) N0 b- T- y# D i
- // Пакет org.l2jmobius.gameserver.model.actor.state
; _$ ?$ y$ p0 g9 ?1 ^( k* \7 b; ^ - package org.l2jmobius.gameserver.model.actor.state;/ z8 o8 m- t! M& d/ O
4 _4 j- e" o% H- f6 t% e- import org.l2jmobius.gameserver.model.actor.Monster;
5 l$ `1 T$ Q2 ~
0 t9 z" h' q# M# ?: x- public class FinalState implements MonsterState {
6 M2 ]: B% J! S2 I$ a% a - @Override
6 E! [( }2 |2 ~+ h% q1 c; X3 N7 u - public void handleState(Monster monster) {4 k! U, U6 h: B9 K( j! L
- // Финальная фаза боя5 x: ]& V# b: z
- System.out.println(monster.getName() + " готовится к финальной атаке!");7 I9 y% T( Y# K( A' C# G2 M7 g
- monster.setAttackPower(monster.getAttackPower() * 2); // Максимальная сила атаки. Y6 a# p% s7 R6 W6 }& m
- }* m- I5 e, T- B& T0 J* y
- }/ T, N& o- b/ A/ }: o: N
Скопировать код
z6 O! H2 s; HШаг 3: Изменение класса MonsterЧтобы монстр мог переключаться между состояниями, нам нужно обновить класс Monster. В этой сборке L2J_Mobius, классы для игровых объектов, таких как монстры, находятся в пакете org.l2jmobius.gameserver.model.actor.5 M* u" l, R! K
- // Пакет org.l2jmobius.gameserver.model.actor/ G8 ?. J& s9 \0 U$ y
- package org.l2jmobius.gameserver.model.actor;1 j) }/ w& p: h% ?5 l7 G
! {" W T/ L! G& ?, P) o# @- import org.l2jmobius.gameserver.model.actor.state.MonsterState;/ ]& r2 q6 B/ b1 A
- import org.l2jmobius.gameserver.model.actor.state.InitialState;6 @4 |0 B$ d2 }
- ; B A8 }" d, A: [4 z+ o0 x
- public class Monster extends Creature {
7 P9 M5 M6 o( ^9 L. v8 N3 P - private String name;' x' X; B7 K1 d0 {! `; K" P
- private double attackPower;. A# U& a4 A. w2 W
- private MonsterState state; // Текущее состояние монстра
, ?, R+ r0 y' i, ?6 H. [" d - 6 }" c2 ^# d" l% F* ~* v* G
- // Конструктор монстра5 q# g' u9 @# z' |: r7 G/ `
- public Monster(String name, double attackPower) {
; A) z. {8 a0 j- [1 ~ - this.name = name;6 Y' ^3 e7 M, p
- this.attackPower = attackPower;
6 H( j3 ]% B! m" l( H - this.state = new InitialState(); // Устанавливаем начальное состояние8 S, e% f% k) X
- }
# ?0 L6 g$ @' F1 d - - H& J* A+ ]* i; o+ t( x
- // Метод для смены состояния
7 W+ C7 F' n d - public void setState(MonsterState newState) {
# G2 r6 J9 E+ N! t - this.state = newState;
5 M4 H6 K4 q7 G. t0 d - }' W6 Q' O! a" W$ t
2 I# W& E N$ p! U1 n- // Выполнение действий на основе текущего состояния" n, N6 G T) O6 m/ j4 a# O
- public void executeState() {- G$ _! O5 P# R# h4 n8 Y9 h
- state.handleState(this);; |! [* ]' G8 m: ?! Y9 J
- }
/ G" x3 Y m9 ^$ r: r2 e
! m- H; Y4 _, G1 e( U x. j- // Геттеры и сеттеры, \1 ?4 n/ e3 K5 C
- public String getName() {
- I; V( _' O; d, J; y - return name;
$ S* ~: t \% F - }
A( [" F; M( D0 O6 T - / f% T0 y9 ~2 |, M& ]/ T
- public double getAttackPower() {
" P, k% }2 a R& s - return attackPower;
) H+ \! A4 Y/ o2 s7 `* K/ c - }$ H7 C' T, M& E% V+ h4 b0 d3 ~8 h
- 0 d! s( V: h) @0 y* z$ u1 V
- public void setAttackPower(double attackPower) {
( G7 ?8 W7 n/ L$ o - this.attackPower = attackPower;
5 R7 D# y0 T7 E. O9 Y/ H - }
. Q/ G! P1 d* _0 ^$ P - }! D' _2 u Z2 `
Скопировать код / e0 d: z: h0 ~& K5 V
Шаг 4: Симуляция боя с фазамиТеперь мы можем протестировать логику боя с переключением состояний монстра.
5 K$ i! r# N& [- u
: ^- K& Z I9 \( C$ m t- // Пакет org.l2jmobius.gameserver.model.battle
P% L; Y8 d/ r* [; f! G1 J( c - package org.l2jmobius.gameserver.model.battle;
: a. _/ g6 v% L- f& R3 K
: a. u a% e9 C M# M, i/ s9 J- import org.l2jmobius.gameserver.model.actor.Monster;& @9 {+ N0 ~5 r$ g
- import org.l2jmobius.gameserver.model.actor.state.AggressiveState;
! I# h" Y5 W$ u - import org.l2jmobius.gameserver.model.actor.state.FinalState;# x7 t" i/ Y/ k
- . C1 T5 T! J" @4 i w5 q6 U
- public class BattleSimulation {, Q' u9 l @% t1 Y, E) o j
- public static void main(String[] args) {
5 O0 H- Y0 G! P, {% k8 ~. U" ]* B, y" K - // Создаем монстра с начальной атакой
" A, G9 O! F3 h( v" \. Y1 W - Monster monster = new Monster("Дракон", 100);
+ @3 Y; B9 A8 s7 s0 K6 c
3 g1 D1 S8 b" Z6 W3 `# w' m- // Начальная фаза" I. _: V2 [9 _: E$ W+ Z4 S X
- monster.executeState();
7 V. F/ g2 @& V - + \9 ^: s2 p* w6 r" G' A6 f# K2 ^
- // Переход в агрессивную фазу
: Y- x5 s/ X! k# R4 _ - monster.setState(new AggressiveState());* E" S, e& y( J- ^/ n/ _
- monster.executeState();
9 v7 I6 z' l3 t* U( t3 w - * |5 g% b5 n0 W/ P8 l
- // Финальная фаза
d. Y2 @& M+ n8 f. ~5 K: F' ^' R - monster.setState(new FinalState());0 V& a/ N1 t! T9 u# o8 f
- monster.executeState();. W9 [8 v- h5 a- L9 b" T
- }
( N. H9 w2 x8 N: a+ e. o1 q/ D - }
- J$ N5 C! H9 F6 @
Скопировать код 5 j) S' x, c: C: l* m
Комментарии по структуре пакетов и классов:
2 y7 L- R2 c2 ~ }6 Z* ]- Пакет org.l2jmobius.gameserver.model.actor: содержит основные игровые сущности, такие как Monster.
- Пакет org.l2jmobius.gameserver.model.actor.state: отвечает за реализацию состояний для объектов, таких как монстры.
- Пакет org.l2jmobius.gameserver.model.battle: может содержать примеры взаимодействий, такие как симуляция боевых сценариев.9 F( k! m" H/ {$ E9 [- \
ЗаключениеШаблон "Состояние" позволяет легко управлять фазами боя и не перегружать основной класс монстра. Это делает логику боевых сценариев более гибкой и масштабируемой. В будущем, если появятся новые фазы или состояния, их можно будет легко добавить, не изменяя основной код.
5 F1 @9 X: e- e: sЕсли появятся дополнительные вопросы по реализации или структуре классов, буду рада помочь!
" ~/ m% S& O: d0 c
8 R8 ]0 m, o( p3 y. f8 v! {7 z2 A7 s2 a/ {: D# f& U% _, I% g
6 z2 i! J$ x9 \ l
: {4 H5 d. d9 L( q j0 a
$ A! Y4 T: Q5 G4 y( {& z' f% `) Q5 A8 z
- Z1 j. [. c% H5 @
! b# q; l9 G" ~) d' @/ e
3 ~! l4 K+ V/ _1 U4 M9 u
6 E* ~( s- g, j5 x
' R" u8 H: C6 {, _: i( p0 x8 T p
' @ H+ _) Z9 V& c7 w: Y* f# d- m, l3 r
4 p! V- E. O# @
|