当前位置:网站首页>State mode design procedure: Heroes in the game can rest, defend, attack normally and attack skills according to different physical strength values.
State mode design procedure: Heroes in the game can rest, defend, attack normally and attack skills according to different physical strength values.
2022-07-06 00:18:00 【newlw】
One . Application scenarios and case descriptions
We often play games in our spare time to relax our body and mind , relieve stress . In many games, heroes have different physical strength values , You can make different actions to face the enemy .
Heroes can rest 、 defense 、 Common attack 、 Skill attack . The physical strength value consumed or recovered is different , for example :
- rest : Restore physical strength to the maximum , There is no need to rest when the physical strength is the maximum ;
- defense : Consume 10 Some physical strength , You can't defend without physical strength ;
- Common attack : Consume 15 Some physical strength , You can't attack normally without physical strength ;
- Skill attack : Consume 20 Some physical strength , You can't attack skills without physical strength ;
Two . Case analysis and problem solving
If we write these operation logic in the same class —— The method of being a hero in the hero class , There will be the following problems :
- Later, if the operation logic ( Such as the change of physical strength value consumed ) If there is any change, you need to modify the whole hero class ;
- If you want to add operations later ( Such as increasing magic attack ) You need to modify the whole hero class ;
- Only a lot of if—else if—else, The code is not easy to maintain , Poor readability ;
So I decided to use state mode to solve this problem . The advantages of state mode in this scenario :
- Using a class to encapsulate a state of an object ( operation ), It's easy to add new States ( operation );
- In state mode , Environmental Science (Context)—— Heroes (Hero) You don't have to have a lot of conditional statements in . Environmental Science (Context) The state of the instance becomes clearer 、 Easy to understand ;
- Using state mode allows user programs to easily switch environments (Context)—— Heroes (Hero) Status of the instance ( operation );
- Using state mode doesn't make the environment (Context)—— Heroes (Hero) Internal state inconsistency occurs in the instance of ;
- When the state object has no instance variables , Environmental Science (Context)—— Heroes (Hero) Each instance of can share a state object ;
I abstract the operation of heroes into states , The four operations correspond to four different specific states :
- RestState( Resting state )
- DefenseState( Defensive state )
- NormalAttackState( Normal attack status )
- SkillAttackState( Skill attack status )
3、 ... and . Description of each role and UML Icon
Role description :
- Environmental Science (Context):Hero class
- Abstract state (State):State abstract class
- Specific state (Concrete State):RestState、DefenseState、NormalAttackState and SkillAttackState class
UML chart :
Four . Running effect
- Generated apk
- Icon after installation
Running results
Take a rest :
Defend :
Common attack :
Skill attack :
5、 ... and . Program complete source code
1. Environmental Science (CONTEXT)
In this design , The environmental role is Hero class , The code is as follows :
Hero.java
package com.yuebanquan.statepattern;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import pl.droidsonroids.gif.GifImageView;
public class Hero extends AppCompatActivity implements View.OnClickListener {
State state; // current state
State lastState; // Last state
private State restState; // Resting state
private State defenseState; // Defensive state
private State normalAttackState; // Normal attack status
private State skillAttackState; // Skill attack status
private int MP; // Hero's physical strength
int MAXMP = 100; // Maximum physical strength
int MINMP = 0; // Minimum physical strength
// Declare the components of the interface
TextView t_MP;
TextView t_state;
Button b_rest;
Button b_defense;
Button b_normalAttack;
Button b_skillAttack;
GifImageView doingGif;
// Make a statement Toast
ToastShow toast = new ToastShow(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init(MAXMP);
}
/*************
* initialization Hero
*************/
public void init(int MP) {
this.MP = MP;
// Initialize various states
restState = new RestState(this);
defenseState = new DefenseState(this);
normalAttackState = new NormalAttackState(this);
skillAttackState = new SkillAttackState(this);
// Heroes default to rest
state = restState;
lastState = restState;
// Binding interface components
t_MP = (TextView) findViewById(R.id.t_MP);
t_state = (TextView) findViewById(R.id.t_state);
b_rest = (Button) findViewById(R.id.b_rest);
b_defense = (Button) findViewById(R.id.b_defense);
b_normalAttack = (Button) findViewById(R.id.b_normalAttack);
b_skillAttack = (Button) findViewById(R.id.b_skillAttack);
doingGif = (GifImageView) findViewById(R.id.doingGif);
http://www.biyezuopin.vip
// Set listeners for a few buttons
b_rest.setOnClickListener(this);
b_defense.setOnClickListener(this);
b_normalAttack.setOnClickListener(this);
b_skillAttack.setOnClickListener(this);
}
// Monitor
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.b_rest:
setLastState(getState());
setState(getRestState());
state.toDo();
break;
case R.id.b_defense:
setLastState(getState());
setState(getDefenseState());
state.toDo();
break;
case R.id.b_normalAttack:
setLastState(getState());
setState(getNormalAttackState());
state.toDo();
break;
case R.id.b_skillAttack:
setLastState(getState());
setState(getSkillAttackState());
state.toDo();
break;
}
}
void midToast(String str, int showTime) {
Toast toast = Toast.makeText(Hero.this, str, showTime);
TextView v = (TextView) toast.getView().findViewById(android.R.id.message);
toast.show();
}
// Various getter and setter
public int getMP() {
return MP;
}
public void setMP(int MP) {
this.MP = MP;http://www.biyezuopin.vip
t_MP.setText(String.valueOf(getMP()));
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
public State getLastState() {
return lastState;
}
public void setLastState(State lastState) {
this.lastState = lastState;
}
public State getRestState() {
return restState;
}
public State getDefenseState() {
return defenseState;
}
public State getNormalAttackState() {
return normalAttackState;
}
public State getSkillAttackState() {
return skillAttackState;
}
}
2. Abstract state (STATE)
For this question , Abstract state (State) yes State abstract class , The code is as follows :
State.java
package com.yuebanquan.statepattern;
public abstract class State {
public abstract void toDo();
}
3. Specific state (Concrete State)
For this question , share 4 Specific status roles , Namely RestState、DefenseState、NormalAttackState and SkillAttackState class , The code is as follows :
RestState.java
package com.yuebanquan.statepattern;
import android.widget.Toast;
public class RestState extends State {
Hero hero;
RestState(Hero hero) {
this.hero = hero;
}
public void toDo() {
if (hero.getMP() == hero.MAXMP) { // Physical strength is full
//hero.midToast(" Physical strength is full , No need to rest ", Toast.LENGTH_SHORT);
hero.toast.toastShow(" Physical strength is full , No need to rest ");
hero.setState(hero.getLastState());
}
else { // Enter a resting state
hero.setMP(hero.MAXMP); // Physical strength is set to the maximum 100
hero.setState(hero.getRestState());
hero.t_state.setText(" Resting state ");
hero.doingGif.setImageResource(R.drawable.rest);
//hero.midToast(" Take a rest , Physical strength has reached the upper limit ", Toast.LENGTH_SHORT);
hero.toast.toastShow(" Take a rest , Physical strength has reached the upper limit ");
}
}
}
DefenseState.java
package com.yuebanquan.statepattern;
import android.widget.Toast;
public class DefenseState extends State {
Hero hero;
DefenseState(Hero hero) {
this.hero = hero;
}
public void toDo() {
if (hero.getMP() < (hero.MINMP + 10)) { // Physical strength is not enough
//hero.midToast(" Physical strength is not enough , No defense ", Toast.LENGTH_SHORT);
hero.toast.toastShow(" Physical strength is not enough , No defense ");
hero.setState(hero.getLastState());
} http://www.biyezuopin.vip
else { // Enter a defensive state
hero.setMP(hero.getMP() - 10); // Defense physical strength -10
hero.setState(hero.getDefenseState());
hero.t_state.setText(" Defensive state ");
hero.doingGif.setImageResource(R.drawable.defense);
//hero.midToast(" Defend , Physical strength -10", Toast.LENGTH_SHORT);
hero.toast.toastShow(" Defend , Physical strength -10");
}
}
}
NormalAttackState.java
package com.yuebanquan.statepattern;
import android.widget.Toast;
public class NormalAttackState extends State {
Hero hero;
NormalAttackState(Hero hero) {
this.hero = hero;
}
public void toDo() {
if (hero.getMP() < (hero.MINMP + 15)) { // Physical strength is not enough
//hero.midToast(" Physical strength is not enough , Cannot attack normally ", Toast.LENGTH_SHORT);
hero.toast.toastShow(" Physical strength is not enough , Cannot attack normally ");
hero.setState(hero.getLastState());
} else { // Enter the normal attack state
hero.setMP(hero.getMP() - 15); // Normal attack stamina -15
hero.setState(hero.getNormalAttackState());
hero.t_state.setText(" Normal attack status ");
hero.doingGif.setImageResource(R.drawable.normal_attack);
//hero.midToast(" Launch a normal attack , Physical strength -15", Toast.LENGTH_SHORT);
hero.toast.toastShow(" Launch a normal attack , Physical strength -15");
}
}
}
SkillAttackState.java
package com.yuebanquan.statepattern;
import android.widget.Toast;
public class SkillAttackState extends State {
Hero hero;
SkillAttackState(Hero hero) {
this.hero = hero;
}
public void toDo() {
if (hero.getMP() < (hero.MINMP + 20)) { // Physical strength is not enough
//hero.midToast(" Physical strength is not enough , Unable to attack skills ", Toast.LENGTH_SHORT);
hero.toast.toastShow(" Physical strength is not enough , Unable to attack skills ");
hero.setState(hero.getLastState());
}
else { // Enter the skill attack state
hero.setMP(hero.getMP() - 20); // Skill attack physical strength -20
hero.setState(hero.getSkillAttackState());
hero.t_state.setText(" Skill attack status ");
hero.doingGif.setImageResource(R.drawable.skill_attack);
//hero.midToast(" Launch skill attack , Physical strength -20", Toast.LENGTH_SHORT);
hero.toast.toastShow(" Launch skill attack , Physical strength -20");
}
}
}
4. Other categories
Expand one ToastShow Class to solve Android Self contained Toast Show delay issues , The code is as follows :
Toast.java
package com.yuebanquan.statepattern;
import android.content.Context;
import android.widget.Toast;
public class ToastShow {
private Context context; // Prompt information in this window
private Toast toast = null; // It is used to judge whether there is Toast perform
public ToastShow(Context context) {
this.context = context;
}
public void toastShow(String text) {
if(toast == null)
{
toast = Toast.makeText(context, text, Toast.LENGTH_SHORT); // Normal execution
}
else {
toast.setText(text); // Used to overwrite the prompt information that has not disappeared before
}
toast.show();
}
}
5. Android Layout file for
The layout file is located in app/src/main/res/layout, The code is as follows :
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Hero">
<!-- placeholder -->
<TextView
android:layout_width="match_parent"
android:layout_height="100dp" />
<!-- Hero name -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" Hero name :"
android:textSize="30sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" Moon Spring "
android:textSize="30sp"/>
</LinearLayout>
<!-- Physical strength -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" Physical strength :"
android:textSize="30sp"/>
<TextView
android:id="@+id/t_MP"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="100"
android:textSize="30sp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="/100"
android:textSize="30sp"/>
</LinearLayout>
<!-- state -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" state :"
android:textSize="30sp"/>
<TextView
android:id="@+id/t_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" Resting state "
android:textSize="30sp"/>
</LinearLayout>
<!--<!– placeholder –>-->
<!--<TextView-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="100dp" />-->
<pl.droidsonroids.gif.GifImageView
android:id="@+id/doingGif"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:src="@drawable/rest"/>
<Button
android:id="@+id/b_rest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text=" Take a rest "
android:textSize="30sp" />
<Button
android:id="@+id/b_defense"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text=" Defend "
android:textSize="30sp"/>
<Button
android:id="@+id/b_normalAttack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text=" Common attack "
android:textSize="30sp"/>
<Button
android:id="@+id/b_skillAttack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text=" Skill attack "
android:textSize="30sp"/>
</LinearLayout>
6. Android Program declaration file
The program declaration file is located at app/src/, The code is as follows :
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yuebanquan.statepattern">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".Hero">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
7. Android Of build.gradle
Position in app/, Specify the generated apk Name and introduced module , The code is as follows :
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.yuebanquan.statepattern"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
android.applicationVariants.all {
variant ->
variant.outputs.all {
// Specify generated here apk file name
outputFileName = " Big homework ( The state pattern ).apk"
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support:support-vector-drawable:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
// Show GifView modular
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.7'
}
边栏推荐
- FFT 学习笔记(自认为详细)
- Configuring OSPF load sharing for Huawei devices
- MySql——CRUD
- 【GYM 102832H】【模板】Combination Lock(二分图博弈)
- OS i/o devices and device controllers
- MySql——CRUD
- Huawei equipment is configured with OSPF and BFD linkage
- Detailed explanation of APP functions of door-to-door appointment service
- Global and Chinese markets of universal milling machines 2022-2028: Research Report on technology, participants, trends, market size and share
- Mathematical model Lotka Volterra
猜你喜欢
OS i/o devices and device controllers
The difference of time zone and the time library of go language
Notepad++ regular expression replacement string
Key structure of ffmpeg - avformatcontext
FFT learning notes (I think it is detailed)
Permission problem: source bash_ profile permission denied
权限问题:source .bash_profile permission denied
Wechat applet -- wxml template syntax (with notes)
Mathematical model Lotka Volterra
wx.getLocation(Object object)申请方法,最新版
随机推荐
MySQL functions
[designmode] Decorator Pattern
[Chongqing Guangdong education] Chongqing Engineering Vocational and Technical College
OS i/o devices and device controllers
[designmode] adapter pattern
关于结构体所占内存大小知识
What are the functions of Yunna fixed assets management system?
Senparc. Weixin. Sample. MP source code analysis
剖面测量之提取剖面数据
如何解决ecology9.0执行导入流程流程产生的问题
Global and Chinese market of valve institutions 2022-2028: Research Report on technology, participants, trends, market size and share
【luogu P3295】萌萌哒(并查集)(倍增)
多线程与高并发(8)—— 从CountDownLatch总结AQS共享锁(三周年打卡)
Browser local storage
云呐|固定资产管理系统主要操作流程有哪些
Global and Chinese markets for pressure and temperature sensors 2022-2028: Research Report on technology, participants, trends, market size and share
Problems encountered in the database
[Luogu cf487e] tours (square tree) (tree chain dissection) (line segment tree)
Hudi of data Lake (2): Hudi compilation
单商户V4.4,初心未变,实力依旧!