我正在创建一个基于平铺的回合制游戏,您可以在命令下使用多个单位,并使用鼠标点击控制它们(有点像国际象棋,但有更多的机制)。它们都是使用Java Graphics(g.drawImage或g.draw(shape))绘制的。用户每次单击鼠标都应执行某项任务,具体取决于之前的鼠标点击。
例如:要攻击敌方单位,必须先单击自己的单位,然后单击敌方单位。或者如果你点击你自己的单位,但他已经攻击了,那么你随后点击敌方单位不应该引起攻击。
游戏使用勾选/渲染系统,其中所有用户输入都以tick方法处理(每秒多次调用),然后使用渲染方法(也称为每秒多次)绘制到屏幕上
我解决这个问题的方法是使用很多不同的变量和if语句太多。我不会粘贴整个代码,因为它很长,但它的处理鼠标点击部分已被附加到下面。
一旦tick方法达到某一目的,它将调用" checkwhattoshow"比这更长的方法,但它会给渲染方法指示画在屏幕上。
代码对我想要的东西起了一半作用,但是我主要问的是,是否有一种更有效的方法,而不是制作过多的if语句和变量,以处理鼠标点击的序列,因为这似乎不必要和低效。
//class variables
private boolean unitclickedon; //if a friendly unit is selected
private int xTile, yTile;
private int onlyonce; //helps me perform a block of code only once
private int prevxTile, prevyTile;
private int speed; //distance the unit can move
private int maxRange; //how far the unit can attack
private Tile tile, newTile;
private Unit unit;
@Override
public void tick() {
//every time the left mouse button is clicked
if (handler.getMouseManager().buttonJustPressed(MouseEvent.BUTTON1)) {
//keep track of the tile you're clicking on
xTile = handler.getPosition().getCoordX();
yTile = handler.getPosition().getCoordY();
//if clicking outside of map do nothing
if (xTile > handler.getMap().getWidth() - 2
|| xTile < 1
|| yTile < 1
|| yTile > handler.getMap().getHeight() - 2) {
return;
}
//if you click on a unit
if (handler.getMap().getTileAt(xTile, yTile).getUnit() != null) {
//save the tile and unit info
tile = handler.getMap().getTileAt(xTile, yTile);
unit = tile.getUnit();
speed = unit.getSpeed();
maxRange = unit.getMaxRange();
//if nothing is currently selected at all
//select the unit and exit this method.
if (onlyonce++ == 0) {
unitclickedon = true;
prevxTile = xTile;
prevyTile = yTile;
//check what should render to the screen
checkWhatToShow();
return;
}
//if you've clicked on the same tile twice unselect the unit and reset
if (prevxTile == xTile && prevyTile == yTile) {
unitclickedon = false;
onlyonce = 0;
} else { // you're clicking on another unit
Unit prevUnit = handler.getMap().getUnit(prevxTile, prevyTile);
if (prevUnit.getOwner() == unit.getOwner()) { //selecting another one of your units
unitclickedon = true;
//check what should render to the screen
checkWhatToShow();
} else { //clicking an enemy unit
if (validAttack(prevxTile, xTile, prevyTile, yTile, maxRange + speed)) { //attack
System.out.println("attacking unit!");
unitclickedon = false;
prevUnit.setHasAttacked(true);
return;
} else { //cant attack
unitclickedon = false;
checkWhatToShow();
}
}
}
} else { //if you're not clicking on a unit
if (unitclickedon) { //you're attempting to move a unit
if (validMove(prevxTile, xTile, prevyTile, yTile, speed)) { //move the unit if its legal
tile = handler.getMap().getTileAt(prevxTile, prevyTile);
unit = tile.getUnit();
if (!unit.isActive() || unit.hasMoved()) {
unitclickedon = false;
return;
} else { //move the unit
newTile = handler.getMap().getTileAt(xTile, yTile);
tile.removeUnit();
newTile.addUnit(unit);
unit.setHasMoved(true);
unitclickedon = false;
onlyonce = 0;
}
} else { //dont move the unit because you're clicking outside of its range
unitclickedon = false;
onlyonce = 0;
}
} else { //you're not doing anything unit related
unitclickedon = false;
onlyonce = 0;
}
}
//record your last click
prevxTile = xTile;
prevyTile = yTile;
}
}
简短版本: 试图解决使大型版本更高效的问题:
if (first mouse click does x1)
if (second mouse click does y)
third mouse click does z
if (second mouse click was y2)
third mouse click z2
if (first mouse click does x2)
bla bla bla
然后获得最终结果并将其渲染到屏幕上
感谢和抱歉,如果它没有意义:c
答案 0 :(得分:0)
**你可以类似于:
List<Rule> rules = .... ; // your n rules initialized here somehow
for(Rule r : rules) {
if(r.condition()) {
r.action();
}
}**