Java 其他对象行为的意外复制
我有一个很有趣的个人项目,我在一个盒子竞技场里移动一个“机器人”,如果他撞到墙上,游戏就结束了。它有一个自动行走模式,可以让他在竞技场中走动,而不用使用有限状态机撞到墙壁。竞技场使用字符串和Java Swing UI打印,所有内容都由Swing事件控制 我想让他开枪。由于bullet行为与robot行为非常相似,因此我创建了一个名为entity的超级类,该类具有所有类似的方法和属性(如位置坐标和方向),然后扩展了robot和bullet类 问题是:当我移动(更改机器人的位置属性)时,子弹的位置也会更改。 我的UI显示两个对象的当前位置,当我移动机器人时,子弹移动。当我按下射击按钮时,子弹的位置才被设定。“射击”按钮将子弹的位置设置为机器人,然后沿同一方向移动子弹,直到它击中盒子限制 当我开枪的时候,发生的事情和机器人的动作是一样的:当子弹移动时,机器人移动到,拿着子弹在墙上自杀 就像它们是同一个对象,但我很确定我使用的是正确的对象调用move方法 根据要求,我制作了以下MCVE版本: 实体超类Java 其他对象行为的意外复制,java,swing,object,attributes,Java,Swing,Object,Attributes,我有一个很有趣的个人项目,我在一个盒子竞技场里移动一个“机器人”,如果他撞到墙上,游戏就结束了。它有一个自动行走模式,可以让他在竞技场中走动,而不用使用有限状态机撞到墙壁。竞技场使用字符串和Java Swing UI打印,所有内容都由Swing事件控制 我想让他开枪。由于bullet行为与robot行为非常相似,因此我创建了一个名为entity的超级类,该类具有所有类似的方法和属性(如位置坐标和方向),然后扩展了robot和bullet类 问题是:当我移动(更改机器人的位置属性)时,子弹的位置也
public abstract class Entity {
protected int[] position = new int[2];
protected char direction;
public int getPosI() {
// System.out.println("i: " + position[0]);
return position[0];
}
public int getPosJ() {
// System.out.println("j: " + position[1]);
return position[1];
}
public int[] getPosition() {
return position;
}
public void setPosition(int[] position) {
this.position = position;
}
public char getDirection() {
return direction;
}
public void setDirection(char direction) {
this.direction = direction;
}
public boolean move() {
switch (direction) {
case 'u':
if (this.position[0] != 0) {
this.position[0]--;
return true;
} else
return false;
case 'r':
if (this.position[1] != 3) {
this.position[1]++;
return true;
} else
return false;
case 'd':
if (this.position[0] != 3) {
this.position[0]++;
return true;
} else
return false;
case 'l':
if (this.position[1] != 0) {
this.position[1]--;
return true;
} else
return false;
default:
return false;
}
}
}
机器人类
public class Robot extends Entity {
public Robot(int[] position) {
super();
this.position = position;
this.direction = 'u';
}
public void resetPos() {
this.position[0] = this.position[1] = 1;
}
}
子弹级
public class Bala extends Entity{
public Bala(int[] position, char direction) {
this.position = position;
this.direction = direction;
}
}
主类
public class Main {
private static final int[] start = new int[] { 1, 1 };
public static void main(String[] args) {
Robot robot = new Robot(start);
robot.setDirection('d');
Bala bala = new Bala(robot.getPosition(), robot.getDirection());
for (int i = 0; i < 3; i++) {
System.out.println("MOVING ONLY THE ROBOT...");
robot.move();
System.out.println("Robot position: "
+ String.valueOf(robot.getPosI()) + ", "
+ String.valueOf(robot.getPosJ()));
System.out.println("Bullet position: "
+ String.valueOf(bala.getPosI()) + ", "
+ String.valueOf(bala.getPosJ()));
}
System.out.println("but the bullet moves to!!!");
System.out.println("reseting position of robot and lets see what happens to bullet...");
robot.resetPos();
System.out.println("Robot position: "
+ String.valueOf(robot.getPosI()) + ", "
+ String.valueOf(robot.getPosJ()));
System.out.println("Bullet position: "
+ String.valueOf(bala.getPosI()) + ", "
+ String.valueOf(bala.getPosJ()));
System.out.println("bullet moves too...");
}
}
公共类主{
私有静态final int[]start=new int[]{1,1};
公共静态void main(字符串[]args){
机器人=新机器人(启动);
robot.setDirection('d');
Bala-Bala=新的Bala(robot.getPosition(),robot.getDirection());
对于(int i=0;i<3;i++){
System.out.println(“仅移动机器人…”);
机器人。移动();
System.out.println(“机器人位置:”
+String.valueOf(robot.getPosI())+“,”
+valueOf(robot.getPosJ());
System.out.println(“项目符号位置:”
+String.valueOf(bala.getPosI())+“,”
+valueOf(bala.getPosJ());
}
System.out.println(“但子弹移动到!!!”;
System.out.println(“重置机器人的位置,让我们看看子弹会发生什么…”);
robot.resetPos();
System.out.println(“机器人位置:”
+String.valueOf(robot.getPosI())+“,”
+valueOf(robot.getPosJ());
System.out.println(“项目符号位置:”
+String.valueOf(bala.getPosI())+“,”
+valueOf(bala.getPosJ());
System.out.println(“子弹也移动…”);
}
}
重要事项:当我使用R(重置)按钮移动机器人时,它也会移动子弹。这意味着即使a不使用移动方法,子弹也在移动强>
因此,作为一个直接的问题,
“robot对象正在将其位置属性的更改复制到子弹位置,反之亦然,如何停止此行为?”robot和Bala共享完全相同的int数组,这就是您的问题所在,罪过代码如下:
Bala bala = new Bala(robot.getPosition(), robot.getDirection());
一个可能的解决方案是让getPosition()
返回数组的副本,或者另一个解决方案是在构造函数中创建一个新数组来复制参数中的值
顺便说一句,您发布的代码非常接近MCVE标准,只需要做一些更改就可以更接近MCVE标准。值得一提的是,以下是我如何更改您的代码,使其成为MCVE并进行修复:
public class Main {
private static final int[] start = new int[] { 1, 1 };
public static void main(String[] args) {
Robot robot = new Robot(start);
robot.setDirection('d');
Bala bala = new Bala(robot.getPosition(), robot.getDirection());
for (int i = 0; i < 3; i++) {
System.out.println("MOVING ONLY THE ROBOT...");
robot.move();
System.out.println("Robot position: "
+ String.valueOf(robot.getPosI()) + ", "
+ String.valueOf(robot.getPosJ()));
System.out.println("Bullet position: "
+ String.valueOf(bala.getPosI()) + ", "
+ String.valueOf(bala.getPosJ()));
}
System.out.println("but the bullet moves to!!!");
System.out.println("reseting position of robot and lets see what happens to bullet...");
robot.resetPos();
System.out.println("Robot position: " + String.valueOf(robot.getPosI())
+ ", " + String.valueOf(robot.getPosJ()));
System.out.println("Bullet position: " + String.valueOf(bala.getPosI())
+ ", " + String.valueOf(bala.getPosJ()));
System.out.println("bullet moves too...");
}
}
abstract class Entity {
protected int[] position = new int[2];
protected char direction;
public Entity(int[] position) {
System.arraycopy(position, 0, this.position, 0, position.length);
}
public Entity(int[] position, char direction) {
this(position);
this.direction = direction;
}
public int getPosI() {
// System.out.println("i: " + position[0]);
return position[0];
}
public int getPosJ() {
// System.out.println("j: " + position[1]);
return position[1];
}
public int[] getPosition() {
return position;
}
public void setPosition(int[] position) {
this.position = position;
}
public char getDirection() {
return direction;
}
public void setDirection(char direction) {
this.direction = direction;
}
public boolean move() {
switch (direction) {
case 'u':
if (this.position[0] != 0) {
this.position[0]--;
return true;
} else
return false;
case 'r':
if (this.position[1] != 3) {
this.position[1]++;
return true;
} else
return false;
case 'd':
if (this.position[0] != 3) {
this.position[0]++;
return true;
} else
return false;
case 'l':
if (this.position[1] != 0) {
this.position[1]--;
return true;
} else
return false;
default:
return false;
}
}
}
class Robot extends Entity {
public Robot(int[] position) {
super(position, 'u');
}
public void resetPos() {
this.position[0] = this.position[1] = 1;
}
}
class Bala extends Entity {
public Bala(int[] position, char direction) {
super(position, direction);
}
}
公共类主{
私有静态final int[]start=new int[]{1,1};
公共静态void main(字符串[]args){
机器人=新机器人(启动);
robot.setDirection('d');
Bala-Bala=新的Bala(robot.getPosition(),robot.getDirection());
对于(int i=0;i<3;i++){
System.out.println(“仅移动机器人…”);
机器人。移动();
System.out.println(“机器人位置:”
+String.valueOf(robot.getPosI())+“,”
+valueOf(robot.getPosJ());
System.out.println(“项目符号位置:”
+String.valueOf(bala.getPosI())+“,”
+valueOf(bala.getPosJ());
}
System.out.println(“但子弹移动到!!!”;
System.out.println(“重置机器人的位置,让我们看看子弹会发生什么…”);
robot.resetPos();
System.out.println(“机器人位置:+String.valueOf(Robot.getPosI())
+“,”+String.valueOf(robot.getPosJ());
System.out.println(“项目符号位置:+String.valueOf(bala.getPosI())
+“,”+String.valueOf(bala.getPosJ());
System.out.println(“子弹也移动…”);
}
}
抽象类实体{
受保护的整数[]位置=新整数[2];
保护字符方向;
公共实体(内部[]职位){
System.arraycopy(位置,0,this.position,0,position.length);
}
公共实体(int[]位置,字符方向){
这个(职位),;
这个方向=方向;
}
公共int getPosI(){
//System.out.println(“i:+位置[0]);
返回位置[0];
}
公共int getPosJ(){
//System.out.println(“j:+位置[1]);
返回位置[1];
}
public int[]getPosition(){
返回位置;
}
公共无效设置位置(int[]位置){
这个位置=位置;
}
公共字符getDirection(){
返回方向;
}
公共无效设置方向(字符方向){
这个方向=方向;
}
公共布尔移动(){
开关(方向){
案例“u”:
如果(此位置[0]!=0){
此。位置[0]-;
返回true;
}否则
返回false;
案例“r”:
如果(此位置[1]!=3){
这个位置[1]+