我有一批sprite(纹理OpenGL ES 2.0 Quads),我循环移动。这是我的代码的简化版本:
//'sprite' & other values have been are assumed to exist for the purpose of the question
public void moveQuadBatch(){
//Loop for as many sprites as there are to draw
for (loop = 0; loop < sprite.number; loop++){
moveQuadNumber(loop); //this method will move the sprite that corresponds to the number loops so we can move through the entire batch and move each individual sprite
}
}
现在,对于某些批次,有一个倒数计时器,或其他一些条件(并没有其他条件,如上所述)。因此,我为这些对象创建了一个类似的方法:
public void moveQuadBatchWithCheck(){
//Loop for as many sprites as there are to draw
for (loop = 0; loop < sprite.number; loop++){
//Only do this if the particular sprite's countdown/delay counter has reached 0 (counting down from another method not seen here)
if (sprite.delay[loop]<0){
moveQuadNumber(loop); //this method will move the sprite that corresponds to the number loops so we can move through the entire batch and move each individual sprite
}
}
}
然而,由于存在大量代码重复,我对此并不完全满意。而不是有这两种方法是否有任何方法我可以使用第一个,并以某种方式“滑流”附加检查到for循环?或者以其他方式减少我在这里的重复?这是一个简单的例子,还有其他一些,目前我有多种方法都非常相似。
修改
如上所述,上述内容有所简化。我可以有一些for循环检查另一个值(例如延迟除外),有些可以检查2个条件。
答案 0 :(得分:3)
public void moveQuadBatch(bool checkDelay) {
for (loop = 0; loop < sprite.number; loop++){
if (!checkDelay || sprite.delay[loop] < 0) {
moveQuadNumber(loop);
}
}
}
现在moveQuadBatch(false)
是您的第一个功能,moveQuadBatch(true)
是您的第二个功能。
至于“插入额外的代码”,你基本上是在谈论功能。在Python中,一种优雅的方法是将函数传入和卸载所有逻辑到函数,例如:
def moveQuadBatch(predicate=None):
for loop, sprite in enumerate(self.sprites):
if not predicate or predicate(loop, sprite):
self.moveQuadNumber(loop)
然后你会这样使用它:
inst.moveQuadBatch()
inst.moveQuadBatch(lambda loop, sprite: sprite.delay[loop] < 0)
inst.moveQuadBatch(lambda loop, sprite: sprite.doesItBlend(loop))
你可以用Java做同样的事情,但不是很整齐:你必须定义一个谓词类及其实例。这就是B.J. Smegma所倡导的方法。
public interface QuadBatchPredicate {
public boolean shouldMove(int loop, Sprite sprite);
}
你的功能如下:
public void moveQuadBatch(QuadBatchPredicate pred) {
for (loop = 0; loop < sprite.number; loop++){
if (pred == null || pred(loop, sprite)) {
moveQuadNumber(loop);
}
}
}
public void moveQuadBatch() {
moveQuadBatch(null);
}
然后您可以使用匿名类来定义谓词:
moveQuadBatch();
moveQuadBatch(new QuadBatchPredicate() {
public boolean shouldMove(int loop, Sprite sprite) {
return sprite.delay[loop] < 0;
}
});
moveQuadBatch(new QuadBatchPredicate() {
public boolean shouldMove(int loop, Sprite sprite) {
return sprite.doesItBlend();
}
});
比Python解决方案有点琐碎,但它得到了重点。现在,您可以通过在线定义谓词来“插入代码”,使其成为您想要的任何内容。另外,你可以保存经常使用的,所以你不要在整个地方重复它们:
QuadBatchPredicate checkBlends = new QuadBatchPredicate() {
public boolean shouldMove(int loop, Sprite sprite) {
return sprite.doesItBlend();
}
};
答案 1 :(得分:2)
创建一个界面:
public interface MyInteface {
void do_something(int loop);
}
根据您的需要制作该界面的不同实现,例如
public class MyInterfaceImpl {
public void do_something(int loop) {
if (!checkDelay || sprite.delay[loop] < 0) {
moveQuadNumber(loop);
}
}
然后你的方法看起来很简单:
public void moveQuadBatch(MyInterface interface) {
for (int loop = 0; loop < sprite.number; loop++){
interface.do_something(loop)
}
}
答案 2 :(得分:1)
你可以为你的精灵添加“效果”。
public class Sprite {
private boolean active = true;
private ArrayList<Effect> effects = new ArrayList<>();
public void update(int time) {
for(Effect e: effects) {
e.update(this, time);
}
}
public void addEffect(Effect effect) {
effects.add(effect);
}
public void setActive(boolean active) {
this.active = active;
}
}
public interface Effect {
void update(Sprite sprite, int time);
}
public class Delay implements Effect {
private int delay;
public Delay(int delay) {
this.delay = delay;
}
public void update(Sprite sprite, int time) {
delay -= time;
if(delay > 0) sprite.setActive(false);
else sprite.setActive(true);
}
}
答案 3 :(得分:0)
我会为延迟检查创建一个单独的方法,并改变你的方法,如下所示:
public void moveQuadBatchWithCheck(bool check){
for (loop = 0; loop < sprite.number; loop++){
if(check){
if (sprite.delay[loop]<0){
moveQuadNumber(loop);
}
}
else{
moveQuadNumber(loop);
}
}
然后当你想用true检查调用方法时 在参数。
不确定这是否是您正在寻找的,但我希望它有所帮助。