java - 分离游戏逻辑和UI
问题描述
这是一个只有三个视图的简单游戏:一个 TextView 和两个按钮(红色和绿色按钮)。
玩家应该按下与 TextView 背景颜色相同颜色的按钮。如果 TextView 背景颜色是红色,那么玩家应该按下红色按钮。
假设有三种不同的播放模式: 常规:您可以玩一整天。时间限制:您只有 3 秒的时间来回答。计时赛:在 30 秒内尽可能多地回答正确。
所有模式共享相同的布局 (xml)。
方法 newGame() 和 newRound() 的行为会根据玩家选择的模式而有所不同。
“常规”可以有 2 种状态:正在播放 = 呈现颜色并且程序正在等待用户输入给 - 错误 - 答案 = 玩家按下了错误的按钮。现在该按钮已禁用。玩家必须按下正确的按钮才能继续(新回合)。
“Timelimit”总是从 3 倒数到 0。当用户按下按钮时,计时器总是重新启动,如果计时器达到 0,则触发 newRound。
“计时赛”将从 30 倒计时到 0,但在其他方面将像“常规”游戏一样工作。
所有三种模式共享一些公共变量,例如:boolean isRed;//知道TextView是否是红色的。
这将如何根据活动和课程进行组织/结构化?
下面是一些实际的代码:
活动主.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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"
tools:context=".MainActivity">
<Button
android:id="@+id/btn_red"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Normal game"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Timer game"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_red"
app:layout_constraintVertical_bias="0.041" />
</android.support.constraint.ConstraintLayout>
活动播放.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp"
tools:context=".PlayActivity">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<TextView
android:id="@+id/txt_colorbox"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="40dp"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="3"
android:orientation="horizontal"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<Button
android:id="@+id/btn_red"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:layout_weight="1"
android:text="" />
<Button
android:id="@+id/btn_green"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:layout_weight="1"
android:text="" />
</LinearLayout>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="4"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp">
</LinearLayout>
</LinearLayout>
</LinearLayout>
MainActivity.java:
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements
View.OnClickListener {
Button btn_normal;
Button btn_timer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_normal = findViewById(R.id.btn_red);
btn_timer = findViewById(R.id.btn_timer);
btn_normal.setOnClickListener(this);
btn_timer.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Intent intent = new Intent(this, PlayActivity.class);
if (v == btn_normal) {
intent.putExtra("GAME_MODE", "regular");
} else if (v == btn_timer) {
intent.putExtra("GAME_MODE", "timelimit");
}
startActivity(intent);
}
}
PlayActivity.java:
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class PlayActivity extends AppCompatActivity implements View.OnClickListener {
static Button btn_red;
static Button btn_green;
static TextView txt_colorbox;
Game game;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play);
txt_colorbox = findViewById(R.id.txt_colorbox);
btn_red = findViewById(R.id.btn_red);
btn_green = findViewById(R.id.btn_green);
btn_red.setOnClickListener(this);
btn_green.setOnClickListener(this);
String gameMode = getIntent().getStringExtra("GAME_MODE");
if (gameMode.equals("regular")) {
game = new RegularGame();
} else if (gameMode.equals("timelimit")) {
game = new TimelimitGame();
}
else if (gameMode.equals("timetrial")) {
game = new TimetrialGame();
}
game.newGame();
game.newRound();
}
@Override
public void onClick(View v) {
if (v == btn_red) {
System.out.println("pressed Red");
} else if (v == btn_green) {
System.out.println("pressed Green");
}
}
}
游戏.java:
public abstract class Game {
boolean isRed;
public void newGame() {
}
public void newRound() {
}
}
常规游戏.java
public class RegularGame extends Game {
@Override
public void newGame() {
System.out.println("New game: regular mode");
}
@Override
public void newRound() {
System.out.println("New Round");
}
}
TimelimitGame.java:
public class TimelimitGame extends Game {
@Override
public void newGame() {
System.out.println("New game: timelimit mode");
}
@Override
public void newRound() {
System.out.println("New Round");
}
}
TimetrialGame.java:
public class TimetrialGame extends Game {
@Override
public void newGame() {
System.out.println("New game: timer mode");
}
@Override
public void newRound() {
System.out.println("New Round");
}
}
我是否应该在 Game() 构造函数中提供上下文/活动。这样我就可以以这种方式访问 TextView 和 Buttons 还是应该 updateUI 驻留在 PlayActivity 中但从 Game 类中收集信息?
解决方案
推荐阅读
- wordpress - 几个永久链接 wordpress 的自定义模板页面
- mongodb - 使用 mongodb 聚合框架计算数组中的项目出现次数
- python - 不断收到关闭弹出窗口的错误
- powershell - 在 PowerShell 脚本中使用秘密变量的正确方法
- google-apps-script - 从单元格值调用函数,然后运行函数
- kframework - 在 K 语言中添加冒号
- python - 尽可能将整数列表分解为最大和的块
- vb.net - RS-232 不稳定行为
- .net-core - 要成为真正的 .Net Core,它是 .Net 标准 - 对吗?
- c# - 如何修改此 LINQ 查询以对分组进行重复数据删除?