当前位置:网站首页>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'
}
边栏推荐
- 第16章 OAuth2AuthorizationRequestRedirectWebFilter源码解析
- Global and Chinese markets for hinged watertight doors 2022-2028: Research Report on technology, participants, trends, market size and share
- 传输层协议------UDP协议
- Doppler effect (Doppler shift)
- Key structure of ffmpeg - avformatcontext
- Choose to pay tribute to the spirit behind continuous struggle -- Dialogue will values [Issue 4]
- Go learning --- structure to map[string]interface{}
- [gym 102832h] [template] combination lock (bipartite game)
- 云呐|公司固定资产管理系统有哪些?
- Wechat applet -- wxml template syntax (with notes)
猜你喜欢
18. (ArcGIS API for JS) ArcGIS API for JS point collection (sketchviewmodel)
Tools to improve work efficiency: the idea of SQL batch generation tools
Problem solving win10 quickly open ipynb file
多线程与高并发(8)—— 从CountDownLatch总结AQS共享锁(三周年打卡)
Permission problem: source bash_ profile permission denied
Key structure of ffmpeg - avformatcontext
Mysql - CRUD
Detailed explanation of APP functions of door-to-door appointment service
Room cannot create an SQLite connection to verify the queries
Key structure of ffmpeg - avframe
随机推荐
行列式学习笔记(一)
DEJA_VU3D - Cesium功能集 之 055-国内外各厂商地图服务地址汇总说明
NSSA area where OSPF is configured for Huawei equipment
Atcoder beginer contest 258 [competition record]
Notepad++ regular expression replacement string
【DesignMode】组合模式(composite mode)
Zhuan: in the future, such an organization can withstand the risks
[gym 102832h] [template] combination lock (bipartite game)
Detailed explanation of APP functions of door-to-door appointment service
Teach you to run uni app with simulator on hbuilderx, conscience teaching!!!
"14th five year plan": emphasis on the promotion of electronic contracts, electronic signatures and other applications
Search (DFS and BFS)
Shardingsphere source code analysis
Configuring OSPF GR features for Huawei devices
Determinant learning notes (I)
What are Yunna's fixed asset management systems?
Global and Chinese markets of universal milling machines 2022-2028: Research Report on technology, participants, trends, market size and share
软件测试工程师必会的银行存款业务,你了解多少?
云呐|固定资产管理系统功能包括哪些?
FFMPEG关键结构体——AVFormatContext