如何将这些代码分解为遵循单一责任原则?尽管我理解了SOLID principles,并且阅读了很多资料,特别是Bob叔叔关于SOLID principles的文章,但不幸的是,我无法将以下代码分成两个不同的类来遵循单一责任原则。我将非常感谢StackOverflow的帮助
/**是唯一充分利用实体超类的子类(没有其他类需要在基于瓦片的地图中移动)。包含与玩家关联的所有游戏。**/
package com.neet.DiamondHunter.Entity;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import com.neet.DiamondHunter.Manager.Content;
import com.neet.DiamondHunter.Manager.JukeBox;
import com.neet.DiamondHunter.TileMap.TileMap;
public class Player extends Entity {
// sprites
private BufferedImage[] downSprites;
private BufferedImage[] leftSprites;
private BufferedImage[] rightSprites;
private BufferedImage[] upSprites;
private BufferedImage[] downBoatSprites;
private BufferedImage[] leftBoatSprites;
private BufferedImage[] rightBoatSprites;
private BufferedImage[] upBoatSprites;
// animation
private final int DOWN = 0;
private final int LEFT = 1;
private final int RIGHT = 2;
private final int UP = 3;
private final int DOWNBOAT = 4;
private final int LEFTBOAT = 5;
private final int RIGHTBOAT = 6;
private final int UPBOAT = 7;
// gameplay
private int numDiamonds;
private int totalDiamonds;
private boolean hasBoat;
private boolean hasAxe;
private boolean onWater;
private long ticks;
// player status
private int healthPoints;
private boolean invincible;
private boolean powerUp;
private boolean speedUp;
public Player(TileMap tm) {
super(tm);
width = 16;
height = 16;
cwidth = 12;
cheight = 12;
moveSpeed = 2;
numDiamonds = 0;
downSprites = Content.PLAYER[0];
leftSprites = Content.PLAYER[1];
rightSprites = Content.PLAYER[2];
upSprites = Content.PLAYER[3];
downBoatSprites = Content.PLAYER[4];
leftBoatSprites = Content.PLAYER[5];
rightBoatSprites = Content.PLAYER[6];
upBoatSprites = Content.PLAYER[7];
animation.setFrames(downSprites);
animation.setDelay(10);
}
private void setAnimation(int i, BufferedImage[] bi, int d) {
setAnimation(i, bi, d, false);
}
private void setAnimation(int i, BufferedImage[] bi, int d, boolean slowMotion) {
currentAnimation = i;
animation.setFrames(bi);
animation.setDelay(d);
slowMotion = true;
}
public void collectedDiamond() { numDiamonds++; }
public int numDiamonds() { return numDiamonds; }
public int getTotalDiamonds() { return totalDiamonds; }
public void setTotalDiamonds(int i) { totalDiamonds = i; }
public int getx() { return x; }
public int gety() { return y; }
public int getRow() { return rowTile; }
public int getCol() { return colTile; }
public void gotBoat() { hasBoat = true; tileMap.replace(22, 4); }
public void gotAxe() { hasAxe = true; }
public boolean hasBoat() { return hasBoat; }
public boolean hasAxe() { return hasAxe; }
public int getHealthPoints() { return healthPoints; }
// Used to update time.
public long getTicks() { return ticks; }
// Keyboard input. Moves the player.
public void setDown() {
super.setDown();
}
public void setLeft() {
super.setLeft();
}
public void setRight() {
super.setRight();
}
public void setUp() {
super.setUp();
}
// Keyboard input.
// If Player has axe, dead trees in front
// of the Player will be chopped down.
public void setAction() {
final boolean pressUPKEY = currentAnimation == UP && tileMap.getIndex(rowTile - 1, colTile) == 21;
final boolean pressDOWNKEY = currentAnimation == DOWN && tileMap.getIndex(rowTile + 1, colTile) == 21;
final boolean pressLEFTKEY = currentAnimation == LEFT && tileMap.getIndex(rowTile, colTile - 1) == 21;
final boolean pressRIGHTKEY = currentAnimation == RIGHT && tileMap.getIndex(rowTile, colTile + 1) == 21;
if(hasAxe) {
if(pressUPKEY) {
tileMap.setTile(rowTile - 1, colTile, 1);
}
if(pressDOWNKEY) {
tileMap.setTile(rowTile + 1, colTile, 1);
}
if(pressLEFTKEY) {
tileMap.setTile(rowTile, colTile - 1, 1);
}
if(pressRIGHTKEY) {
tileMap.setTile(rowTile, colTile + 1, 1);
}
JukeBox.play("tilechange");
}
}
public void update() {
ticks++;
boolean current = onWater;
onWater = CheckIfOnWater();
//if going from land to water
if(!current && onWater){
JukeBox.play("splash");
}
// set animation
setAnimationDown();
setAnimationLeft();
setAnimationRight();
setAnimationUp();
// update position
super.update();
}
public void setAnimationUp() {
if(up) {
if(onWater && currentAnimation != UPBOAT) {
setAnimation(UPBOAT, upBoatSprites, 10);
}
else if(!onWater && currentAnimation != UP) {
setAnimation(UP, upSprites, 10);
}
}
}
public void setAnimationRight() {
if(right) {
if(onWater && currentAnimation != RIGHTBOAT) {
setAnimation(RIGHTBOAT, rightBoatSprites, 10);
}
else if(!onWater && currentAnimation != RIGHT) {
setAnimation(RIGHT, rightSprites, 10);
}
}
}
public void setAnimationLeft() {
if(left) {
if(onWater && currentAnimation != LEFTBOAT) {
setAnimation(LEFTBOAT, leftBoatSprites, 10);
}
else if(!onWater && currentAnimation != LEFT) {
setAnimation(LEFT, leftSprites, 10);
}
}
}
public void setAnimationDown() {
if(down) {
if(onWater && currentAnimation != DOWNBOAT) {
setAnimation(DOWNBOAT, downBoatSprites, 10);
}
else if(!onWater && currentAnimation != DOWN) {
setAnimation(DOWN, downSprites, 10);
}
}
}
public boolean CheckIfOnWater(){
int index = tileMap.getIndex(ydest / tileSize, xdest / tileSize);
if(index == 4) {
return true;
}
else {
return false;
}
}
// Draw Player.
public void draw(Graphics2D g)
{
super.draw(g);
}
}发布于 2016-11-14 18:23:04
尝试在模型视图控制器样式中实现您的组件,例如,移动所有与更新yourapp.view包中的视图相关的代码,并将当前类播放器的代码移动到一个新类中,例如,GameBoard或GameView或诸如此类,其中该类的单一响应是更新在游戏板屏幕中绘制动画/图像等的模型表示。另一个类,例如,PlayerMovement和move,所有与de键盘事件相关的代码,目前在你的Player类中,这个类的响应性是捕捉让玩家移动的键。
移动所有与游戏命令和期望相关的代码,并移动到另一个包yourapp.controller或动作或任何东西,并创建新的类,例如PlayerController,GameController或任何东西,其中该类的单一响应性是接收玩家更新游戏模型状态的请求,寻址命令并告诉模型类将被更新,并告诉de view类,每次模型改变时获得新的模型状态;例如,当玩家在游戏板中有一个新的位置时,或者一些missil或一些角色死亡的位置等。
例如,将您的模型类放在其他包(例如yourapp.character或actors或其他任何包)中,并移动与创建新类的模型状态相关的代码,这些新类表示游戏角色或角色,或者定义游戏的行为或角色的活动元素。例如,玩家或一艘船或一门大炮等。这个类他们的责任只是定义游戏角色及其特征和行为,例如在游戏板中的位置,他们的武器,他们的力量,是活的还是死的等等,以及其他需要在游戏中扮演的角色的信息。
尝试在第二阶段识别并应用GoF模式,这可以帮助您重构代码,使其更加符合可靠的原则。
发布于 2016-11-15 06:39:27
关于SRP的另一种思考是每个单元应该有一个单一的更改原因。
以你的课程为例,将来可能会改变它的原因是什么:
其中的每一个你都组织了字段,所以你自己发现了它们。现在,只需更进一步,为每个类创建类。这样,您就可以在不接触影响游戏的代码的情况下更改动画。这一点:
example)
替换精灵组件来重新设置游戏的皮肤
https://stackoverflow.com/questions/40580693
复制相似问题