文字小游戏(DoomsdayGame)

前言:从零开始一点一点做一个属于自己的文字冒险小游戏!虽然现在连javaSE都没有学完,但是会用自己的“毕生所学”先做出一个大体的框架出来,再用之后的知识能力逐步完善升级。例如数据库存档、前端界面等等。未完待续。。。

Doomsday Game

一、基本构思

  1. 在弹窗中开启游戏
  2. 游戏主界面加载完成后弹窗提示玩家输入姓名并保存
  3. 共设置三个场景,玩家不同选择将导致不同结果。前两个为剧情场景,最后一个为战斗关卡,出现随机战斗力的敌人或boss。
  4. 战斗胜利则弹出彩蛋窗口,玩家死亡则弹出死亡提示窗口

遇到的问题:

  1. Player与Enemy有抽象父类Role,我想要Enemy也为抽象父类,有两个子类Max和min继承它。我想要的是Player构造的时候初始默认hp为100,mp为50,Max初始默认hp为150,mp为100,min初始默认hp为20,mp为10,怎么写代码中的构造方法?完整的构造一定要写么?应该没要求吧,有默认构造就行了

    // 如果你需要设置玩家的名字,并且使用默认的生命值和魔法值 public Player(String name) { super(name, 100, 50, false); }这样不就好了!

  2. 要不要写角色、敌人、武器等的接口?接口在此能有什么应用场景?

  3. 游戏一环套一环是不是要写无数个for与if循环好麻烦?

    可以使用状态机的设计模式。使用状态模式或命令模式来更好地管理状态转换和用户输入。那么还有哪些合适的很好的设计模式?

设计模式是软件工程中常用的解决特定问题的模板。在你的游戏中,我们可以使用状态模式来管理不同场景(状态)之间的转换,以及命令模式来封装玩家的操作。

二、初级代码

2.1 APP启动类

1
2
3
4
5
6
7
8
9
10
//APP启动类
public class APP {
//程序启动入口
public static void main(String[] args) {
//登录与注册界面之后完善
//new LoginJFrame();
//开启主界面
new GameJFrame();
}
}

2.2 GameJFrame窗口类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
//GameJFrame窗口类
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;//监听事件接口
import java.awt.event.ActionEvent;

public class GameJFrame extends JFrame implements ActionListener {
//File file = new File("src\\Text01");
//文本框项 创建JTextArea
JTextArea textArea = new JTextArea();//行列数而非像素
//菜单项
JMenuItem replayItem = new JMenuItem("重新游戏");
//JMenuItem reLoginItem = new JMenuItem("重新登录");
JMenuItem accountItem = new JMenuItem("作者微信");
//按钮项
JButton attackButton = new JButton("攻击对方");
JButton pickupButton = new JButton("捡起装备");
JButton checkPlayerButton = new JButton("查看属性");
JButton advanceButton = new JButton("前进");
JButton retreatButton = new JButton("后退");

//(构造函数)初始化游戏主界面
public GameJFrame() {
//初始化界面设置
initJFrame();
//初始化滚动文本框
initScrollPane();
//初始化菜单栏
initJMenuBar();
//初始化按钮选项
initButtons();
//进入游戏主逻辑
GameLogic();
//显示界面(必须放最后)
this.setVisible(true);
}

//初始化界面设置
private void initJFrame() {
//界面宽高
this.setSize(800, 800);
this.setTitle("Doomsday Game v1.0");
//设置界面居中
this.setLocationRelativeTo(null);
//设置关闭模式(点击x即可关闭进程)
this.setDefaultCloseOperation(3);
//为界面添加监听事件
//this.addKeyListener(this);??
//设置布局管理器
setLayout(new BorderLayout());
}

//初始化滚动文本框
private void initScrollPane() {
//创建滚动面板并添加文本区域
JScrollPane scrollPane = new JScrollPane(textArea);
//将滚动面板添加到JFrame并放在中间
add(scrollPane, BorderLayout.CENTER);
//创建文本区域
Font font = new Font("楷体", Font.BOLD, 40);//设置字体
textArea.setFont(font);
textArea.setBackground(Color.black);//背景颜色
textArea.setForeground(Color.white);//字体颜色
textArea.setLineWrap(true);//自动换行
textArea.setWrapStyleWord(true);
textArea.setEditable(false);//文本区不可编辑
textArea.append("欢迎来到末日世界游戏!\n请输入您的玩家身份并记得随时查看属性:\n");
}

//初始化按钮选项
private void initButtons() {
//创建一个面板来放置按钮
JPanel buttonPanel = new JPanel(new GridLayout(1, 5, 10, 10));
Dimension buttonSize = new Dimension(160, 50);
//为按钮增加动作监听器
attackButton.addActionListener(this);
pickupButton.addActionListener(this);
checkPlayerButton.addActionListener(this);
advanceButton.addActionListener(this);
retreatButton.addActionListener(this);
//将按钮添加到面板
buttonPanel.add(attackButton);
buttonPanel.add(pickupButton);
buttonPanel.add(checkPlayerButton);
buttonPanel.add(advanceButton);
buttonPanel.add(retreatButton);
//面板置底
add(buttonPanel, BorderLayout.SOUTH);
}

//初始化菜单项
private void initJMenuBar() {
//创建整个菜单对象
JMenuBar jMenuBar = new JMenuBar();
//创建菜单上面两个选项
JMenu fonctionJMenu = new JMenu("功能");
JMenu aboutJMenu = new JMenu("关于作者");
//将每个选项下的条目添加到选项中
fonctionJMenu.add(replayItem);
//fonctionJMenu.add(reLoginItem);
aboutJMenu.add(accountItem);
//给条目绑定事件
replayItem.addActionListener(this);
//reLoginItem.addActionListener(this);
accountItem.addActionListener(this);
//将选项添加进菜单中
jMenuBar.add(fonctionJMenu);
jMenuBar.add(aboutJMenu);
//给界面设置菜单
this.setJMenuBar(jMenuBar);
}

//游戏逻辑
int Scene = 1;
Player player = new Player("吴");

private void GameLogic() {
switch (Scene) {
case 1:
//进入场景一
textArea.append("你突然醒来,发现自己身处浓浓的迷雾中\n你尝试询问这是何处,但没有任何回答\n待迷雾渐渐散去,你却惊恐地发现自己的面前是深不见底的悬崖\n");
break;
case 2:
//进入场景二
textArea.append("你转身一看,是一只胖胖的黄色小猫\n");
break;
case 3:
//进入场景三
textArea.append("肉泥渐渐融入地里,很快长出了几朵纯白的花\n");
break;
}
}

@Override
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (Scene == 1) {
if (obj == attackButton) {
textArea.append("你朝空中挥了一拳\n不过毫无疑问,这是浪费体力的愚蠢行为\n");
} else if (obj == pickupButton) {
textArea.append("你往地上摸去,只摸到了几块石头\n");
} else if (obj == checkPlayerButton) {
textArea.append(player.toString());
} else if (obj == advanceButton) {
textArea.append("你前进了一步,然后愚蠢地掉入了悬崖\n");
player.Die();
} else if (obj == retreatButton) {
textArea.append("你后退了一步,却被背后突然发出的声响吓了一跳\n");
Scene = 2;
GameLogic();
}
} else if (Scene == 2) {
if (obj == attackButton) {
textArea.append("你极度戒备,立即摸起一块石头\n将小猫砸成了肉泥\n");
Scene=3;
GameLogic();
} else if (obj == pickupButton) {
textArea.append("你往地上摸去,只摸到了几块石头\n");
} else if (obj == checkPlayerButton) {
textArea.append(player.toString());
} else if (obj == advanceButton) {
textArea.append("你向前走了一步想要看看小猫\n但是小猫的头颅突然裂开,钻出了几条触手将你撕裂\n并吞入口中\n");
player.Die();
} else if (obj == retreatButton) {
textArea.append("你后退了一步,然后愚蠢地掉入了悬崖\n");
player.Die();
}
}
else if (Scene == 3) {
if (obj == attackButton) {
textArea.append("你朝空中挥了一拳\n不过毫无疑问,这是浪费体力的愚蠢行为\n");
} else if (obj == pickupButton) {
textArea.append("你往地上摸去,只摸到了几块石头\n");
} else if (obj == checkPlayerButton) {
textArea.append(player.toString());
} else if (obj == advanceButton) {
textArea.append("你慢慢摸索着向前走,迷雾又渐渐加重,将你包裹入其中\n你感受到前所未有的未知恐惧\n");
} else if (obj == retreatButton) {
textArea.append("你后退了几步,茫然而又恐惧地蹲了下去,抱紧双臂\n");
}
}
}
}

2.3 Role类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import javax.swing.*;
import java.util.*;

public abstract class Role {
Random r = new Random();
private String name;
private int hp;//红条
private int mp;//蓝条
private boolean isDeath;

public Role() {
}

public Role(String name, int hp, int mp, boolean isDeath) {
this.name = name;
this.hp = hp;
this.mp = mp;
this.isDeath = isDeath;
}

//展示角色属性
public abstract void showRole();
//死亡
public void Die() {
this.hp = 0;
isDeath = true;
System.out.println(getName() + "已死亡");
JOptionPane.showMessageDialog(null, getName() + "已死亡");
System.exit(0);
}

//攻击
public int Attack() {
int attack = r.nextInt(10) + 1;
setMp(getMp() - attack);
System.out.println(getName() + "发出了伤害为" + attack + "点的攻击,消耗体力" + attack + "点");
return attack;
}

//被伤害
public void Harm(int harm) {
setHp(getHp() - harm);
System.out.println(getName() + "受到了伤害为" + harm + "点的攻击,生命损耗" + harm + "点");
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getHp() {
return hp;
}

public void setHp(int hp) {
this.hp = hp;
}

public int getMp() {
return mp;
}

public void setMp(int mp) {
this.mp = mp;
}

public boolean isIsDeath() {
return isDeath;
}

public void setIsDeath(boolean isDeath) {
this.isDeath = isDeath;
}
}

2.4 Player类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class Player extends Role {
private Weapon weapon;//装备

public Player(String name) {
super(name, 100, 50, false);
this.weapon = null; // 默认无武器
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
String name = this.getName();
sb.append(name + "的生命: " + this.getHp() + "\n");
sb.append(name + "的体力: " + this.getMp() + "\n");
if (this.weapon != null) //注意检查
sb.append(name + "的装备: " + this.getWeapon().getName()+"\n");
else
sb.append(name + "的装备: 无"+"\n");
return sb.toString();
}

//捡起装备
public void pickUpWeapon(String weaponName) {
System.out.println(getName() + "捡起了" + weaponName);
}

//前进
public void Ahead() {
System.out.println(getName() + "向前走了一步");
}

//后退
public void Back() {
System.out.println(getName() + "向后退了一步");
}

//确认
public void forSure() {
System.out.println(getName() + "点击了确认");
}

public Weapon getWeapon() {
return weapon;
}

public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}

@Override
public void showRole() {
System.out.println(toString());
}
}

2.5 Weapon类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class Weapon {
private String name;
private int harm;
private Player player;

public Weapon() {
}

public Weapon(String name, int harm, Player player) {
this.name = name;
this.harm = harm;
this.player = player;
}

public void showWeapon() {
String name = this.getName();
System.out.println(name + "的攻击力: " + this.getHarm());
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getHarm() {
return harm;
}

public void setHarm(int harm) {
this.harm = harm;
}

public Player getPlayer() {
return player;
}

public void setPlayer(Player player) {
this.player = player;
}
}

2.6 Enemy类