2013-09-06 4 views
2

Я делаю своего рода «хак» или «мод» для Minecraft. Он удалит блоки вокруг вас и продвинется вперед, удалит больше, движется вперед и т. Д. Через некоторое время он переместится в сторону и вернется назад. Это, как мир медленно удаляя себя: DЕсть ли более эффективный способ написания этого кода?

if(Camb.nuker){ 
    whenToStop++; 
    byte byte0 = 3; 
    if(whenToStop < 60){ 
     mc.thePlayer.setPosition(posX, posY, posZ-1.5); 
    } 
    if(whenToStop > 60 && whenToStop < 65){ 
     mc.thePlayer.setPosition(posX-1.2, posY, posZ); 
    } 
    if(whenToStop > 65 && whenToStop < 124){ 
     mc.thePlayer.setPosition(posX, posY, posZ+1.5); 
    } 
    if(whenToStop > 124 && whenToStop < 129){ 
     mc.thePlayer.setPosition(posX-1.2, posY, posZ); 
    } 
    if(whenToStop > 129 && whenToStop < 188){ 
     mc.thePlayer.setPosition(posX, posY, posZ-1.5); 
    } 
    if(whenToStop > 188 && whenToStop < 193){ 
     mc.thePlayer.setPosition(posX-1.2, posY, posZ); 
    } 
    if(whenToStop > 193 && whenToStop < 252){ 
     mc.thePlayer.setPosition(posX, posY, posZ+1.5); 
    } 
    if(whenToStop > 252 && whenToStop < 257){ 
     mc.thePlayer.setPosition(posX-1.2, posY, posZ); 
    } 
    if(whenToStop > 257 && whenToStop < 316){ 
     mc.thePlayer.setPosition(posX, posY, posZ-1.5); 
    } 
    if(whenToStop > 316 && whenToStop < 321){ 
     mc.thePlayer.setPosition(posX-1.2, posY, posZ); 
    } 
    if(whenToStop > 321 && whenToStop < 376){ 
     mc.thePlayer.setPosition(posX, posY, posZ+1.5); 
    } 

    for(int k = byte0; k > -byte0; k--) 
    { 
     for(int i1 = byte0; i1 > -byte0; i1--) 
     { 
      for(int j1 = byte0; j1 > -byte0; j1--) 
      { 
       double d1 = mc.thePlayer.posX + (double)k; 
       double d3 = mc.thePlayer.posY + (double)i1; 
       double d5 = mc.thePlayer.posZ + (double)j1; 
       int k1 = (int)d1; 
       int l1 = (int)d3; 
       int i2 = (int)d5; 
       int j2 = mc.theWorld.getBlockId(k1, l1, i2); 
       Block block = Block.blocksList[j2]; 
       if(block != null){ 
        ((EntityClientPlayerMP)mc.thePlayer).sendQueue.addToSendQueue(new Packet14BlockDig(0, k1, l1, i2, 1)); 
        ((EntityClientPlayerMP)mc.thePlayer).sendQueue.addToSendQueue(new Packet14BlockDig(2, k1, l1, i2, 1)); 
       } 
      } 
     } 
    } 
} 
if(Camb.nuker==false){ 
    whenToStop = 0; 
} 

Вы в основном должны сосредоточиться на кусок кода под которой я объявляю байт. Остальная часть кода перебирает блоки и разбивает их, ничего особенного.

Итак, как бы я сделал этот кусок кода более эффективным? Я думаю о создании функции, но я не слишком осведомлен о создании функций, как бы я сделал что-то подобное? Например, я бы использовал код имя функции (количество строк для разрыва);

Спасибо, Брэд

+0

'void functionname (int numberOfRowsToBreak) {/ * implementation * /}' – gparyani

+4

Вместо нескольких 'if', вы должны использовать' if (condition) {} else if (condition) {} ' – araknoid

+0

@gparyani Я бы просто вставить все if's в это? Благодаря! – Brad

ответ

-1

в случае, если вы не знаете, несколько если() {} делает компилятор проверить их в обратном порядке, он проверяет последний, если тогда, если перед ним, то один перед ним, то так на

в отличие, если() {} еще если() {}

если еще делает компилятор проверить их в письменном порядке, первый один в коде является первым один проверил

любой Кстати, это какой-то переформатированный Код

// in your Camb class if possible 
//... 
private boolean nuker = false; 
// more code that changes the nuker variable 
public static boolean isNuker(){ 
    return nuker; 
} 


// in this class 
if(Camb.isNuker()){ 
     whenToStop++; 
     byte byte0 = 3; 
     checkWhenToStop(whenToStop) 
     checkBytes(byte0) 
}else{ 
    whenToStop = 0; 
} 

public void checkWhenToStop(int whenToStop){ 
    if(whenToStop < 60){ 
     mc.thePlayer.setPosition(posX, posY, posZ-1.5); 
    } 
    if(whenToStop > 60 && whenToStop < 65){ 
     mc.thePlayer.setPosition(posX-1.2, posY, posZ); 
    } 
    if(whenToStop > 65 && whenToStop < 124){ 
     mc.thePlayer.setPosition(posX, posY, posZ+1.5); 
    } 
    if(whenToStop > 124 && whenToStop < 129){ 
     mc.thePlayer.setPosition(posX-1.2, posY, posZ); 
    } 
    if(whenToStop > 129 && whenToStop < 188){ 
     mc.thePlayer.setPosition(posX, posY, posZ-1.5); 
    } 
    if(whenToStop > 188 && whenToStop < 193){ 
     mc.thePlayer.setPosition(posX-1.2, posY, posZ); 
    } 
    if(whenToStop > 193 && whenToStop < 252){ 
     mc.thePlayer.setPosition(posX, posY, posZ+1.5); 
    } 
    if(whenToStop > 252 && whenToStop < 257){ 
     mc.thePlayer.setPosition(posX-1.2, posY, posZ); 
    } 
    if(whenToStop > 257 && whenToStop < 316){ 
     mc.thePlayer.setPosition(posX, posY, posZ-1.5); 
    } 
    if(whenToStop > 316 && whenToStop < 321){ 
     mc.thePlayer.setPosition(posX-1.2, posY, posZ); 
    } 
    if(whenToStop > 321 && whenToStop < 376){ 
     mc.thePlayer.setPosition(posX, posY, posZ+1.5); 
    } 
} 

public void checkBytes(byte byte0){ 
     for(int k = byte0; k > -byte0; k--){ 
      for(int i1 = byte0; i1 > -byte0; i1--){ 
       for(int j1 = byte0; j1 > -byte0; j1--){ 
        double d1 = mc.thePlayer.posX + (double)k; 
        double d3 = mc.thePlayer.posY + (double)i1; 
        double d5 = mc.thePlayer.posZ + (double)j1; 
        int k1 = (int)d1; 
        int l1 = (int)d3; 
        int i2 = (int)d5; 
        int j2 = mc.theWorld.getBlockId(k1, l1, i2); 
        Block block = Block.blocksList[j2]; 
        if(block != null){ 
         ((EntityClientPlayerMP)mc.thePlayer).sendQueue.addToSendQueue(new Packet14BlockDig(0, k1, l1, i2, 1)); 
         ((EntityClientPlayerMP)mc.thePlayer).sendQueue.addToSendQueue(new Packet14BlockDig(2, k1, l1, i2, 1)); 
        } 
       } 
      } 

     } 
} 
+0

вы даже можете заставить свои методы возвращать логическое значение (true или false), если вы хотите остановиться в середине –

+0

Не хотите ли вы сделать его 'if() {} elseif() {} elseif() { } ... ', поскольку они никогда не будут соответствовать более чем одному, и поэтому приложение не будет проверять каждое условие без необходимости, но только до того, которое применяется. – JRomero

+0

Я бы переименовал checkWhenToStop для перемещения(). –

5

Первый удар на, если может быть блок что-то вроде:

double dx = 0, dy = 0, dz = 0; 
whenToStop++; 
if (whenToStop < 60) { 
    dz = -1.5; 
} else if (whenToStop < 65) { 
    dx = -1.2; 
} else if (whenToStop < 124) { 
    dz = +1.5; 
} else if (whenToStop < 129) { 
    dx = -1.2; 
} else if (whenToStop < 188) { 
    dz = -1.5; 
} else if (whenToStop < 193) { 
    dx = -1.2; 
} else if (whenToStop < 252) { 
    dz = +1.5; 
} else if (whenToStop < 257) { 
    dx = -1.2; 
} else if (whenToStop < 316) { 
    dz = -1.5; 
} else if (whenToStop < 321) { 
    dx = -1.2; 
} else if (whenToStop < 376) { 
    dz = +1.5; 
} 
setPosition(posX + dx, posY + dy, posZ + dz); 

но что поднимает вопрос , что происходит, когда значение в точности равно сказать 60? Является ли этот эффект умышленным?

Теперь в этой форме вы можете использовать некоторую форму массива для точек разделения.

class D { 
    final int p; 
    final double x; 
    final double y; 
    final double z; 

    public D(int p, double x, double y, double z) { 
    this.p = p; 
    this.x = x; 
    this.y = y; 
    this.z = z; 
    } 
} 

D[] d = { 
    new D(60,  0, 0, -1.5), 
    new D(65, -1.2, 0, 0), 
    new D(124, 0, 0, +1.5), 
    new D(129, -1.2, 0, 0), 
    new D(188, 0, 0, -1.5), 
    new D(193, -1.2, 0, 0), 
    new D(252, 0, 0, +1.5), 
    new D(257, -1.2, 0, 0), 
    new D(316, 0, 0, -1.5), 
    new D(321, -1.2, 0, 0), 
    new D(376, 0, 0, +1.5), 
}; 

... 
    whenToStop++; 
    D delta = null; 
    for (int i = 0; i < d.length && whenToStop < d[i].p; i++) { 
    delta = d[i]; 
    } 
    if (delta != null) { 
    setPosition(posX + delta.x, posY + delta.y, posZ + delta.z); 
    } 

Я бы сказал, что теперь вы там, где вам нужно.

+0

Мне понравилась ваша старая версия лучше, она была намного понятнее. Не все должно быть объектом. – mavroprovato

+0

@mavroprovato - меня тоже - но фундаменталисты потребуют вторую форму, и вы должны признать, что шаблон более ясен. – OldCurmudgeon

1

я подробно останавливаться на @ MadProgrammer-х внушения:

Создать структуру для хранения предела и дельт для каждого условия:

class Entry { 
    int upper_limit; 
    double delta_x; 
    double delta_y; 
    double delta_z; 
} 

Затем заполнить список структур с данными:

ArrayList<Entry> entries; 
entries.add(new Entry(60, 0., 0., -1.5)); 
entries.add(new Entry(65, -1.2, 0., 0.)); 
// Continue with the remaining entries. 

Затем передать список в функцию:

DoMove(List<Entry> entries, int when_to_stop, SomeClass mc, 
     double pos_x, double pos_y, double pos_z) { 

    for (Entry entry : entries) { 
    if (when_to_stop < entry.upper_limit) { 
     // move 
    } 
    } 
// Default case or error 
} 
+3

Это java, у нас нет структур :-) – mavroprovato

+0

Вместо этого используйте класс –

+0

Я лично предпочел бы использовать перечисление над классом –

0

Модифицированная версия кода OldCurmudgeons.Сделать это полную функцию (я предполагаю, что игрок имеет PlayerType):

void move(PlayerType player, int step) { 
    double dx = 0, dy = 0, dz = 0; 
    int cycle = step % 128; 
    if (cycle < 60) { 
     dz = -1.5; 
    } else if (cycle < 64) { 
     dx = -1.2; 
    } else if (cycle < 124) { 
     dz = +1.5; 
    } else { 
     dx = -1.2; 
    } 
    player.setPosition(player.posX + dx, player.posY + dy, player.posZ + dz); 

} 

И тогда ваша «основная программа» назвала бы это нравится:

final int LIMIT = 1000; // this will stop the movement 

if (Camb.nuker) { 
    move(mc.thePlayer, step++); 
    <your for loop> 
    if (step == LIMIT) 
    Camb.nuker = false; 
} else 
    step = 0; 

Теперь вы можете использовать этот indefinetely с таким большим значения для whenToStop, как вам нравится.

Я также думаю, что у вас были небольшие ошибки в индексах, поэтому я выпрямил его до цикла 64/128.

Редактировать: нет необходимости в «if» на последнем блоке.

Edit2: сделал это функция и «основная программа»

Edit3: whenToStop является параметром функции, не ++ для него внутри функции не требуется.

Редактирование 4: перед объявлением цикла отсутствует 'int'.

Редактировать5: 'игрок.' отсутствует в 'поз': s

Edit6: переименованные переменные и добавил LIMIT

+0

Я думаю, что сейчас я попробую код. Хотя я немного смущен. Например, как я могу сделать это «разбить строки» дважды? Или четыре раза? Спасибо – Brad

+0

Хм, я не совсем уверен, что вы имеете в виду: вы имеете в виду, что вы хотели бы пройти одни и те же позиции несколько раз? –

+0

Да, точно. То, как это работает, это разбить блоки в огромной строке, переместиться в сторону, развернуться и снова сломаться. – Brad

0

Loop можно переписать в виде:

public void checkBytes(byte byte0) { 
    double d1e = mc.thePlayer.posX - byte0; 
    double d3e = mc.thePlayer.posY - byte0; 
    double d5e = mc.thePlayer.posZ - byte0; 
    for(double d1 = mc.thePlayer.posX + byte0; d1 > d1e; d1 -= 1.0) { 
     for(double d3 = mc.thePlayer.posY + byte0; d3 > d3e; d3 -= 1.0) { 
      for(double d1 = mc.thePlayer.posZ + byte0; d5 > d5e; d5 -= 1.0) { 
       int k1 = (int)d1; 
       int l1 = (int)d3; 
       int i2 = (int)d5; 
       int j2 = mc.theWorld.getBlockId(k1, l1, i2); 
       Block block = Block.blocksList[j2]; 
       if(block != null){ 
        ((EntityClientPlayerMP)mc.thePlayer).sendQueue.addToSendQueue(new Packet14BlockDig(0, k1, l1, i2, 1)); 
        ((EntityClientPlayerMP)mc.thePlayer).sendQueue.addToSendQueue(new Packet14BlockDig(2, k1, l1, i2, 1)); 
       } 
      } 
     } 

    } 
} 

Это позволит сэкономить время для преобразования двойного < -> Int, и дважды уменьшайте количество добавлений: вместо пары «k--» и «d1 = mc.thePlayer.posX + k» - будет только «d1 - = 1.0».

Кроме того, если значения d1/d3/d5 всегда положительны (я не уверен в этом), вы можете определить эти значения как ints и удалить кастинг в k1/l1/i2.