побитовая обработка Java

Вот очень простой пример, который может помочь вам начать. Вам нужно будет добавить ссылку на две сборки, чтобы это работало.

Шаг 1. В Solution Explorer щелкните правой кнопкой мыши по References и выберите PresentationCore и WindowsBase, чтобы добавить эти ссылки в ваш проект.

Шаг 2. Добавьте Timer к вашей форме и установите свойства следующим образом (Name) = timer, Interval = 16. На вкладке событий установите обработчик события Tick на timer_Tick (двойной щелчок сделает это автоматически.

Шаг 3. Вот код для формы.

[ 1117] Вы также должны добавить обработчик событий для события Load в Форме, здесь этот обработчик называется Form1_Load .Код также предполагает, что у вас есть элемент управления picPlayer в форме, вероятно, элемент управления PictureBox в вашем случае .

using System;
using System.Windows.Forms;
using System.Windows.Input;

namespace MovePlayerDemo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            timer.Enabled = true;
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            if (Keyboard.IsKeyDown(Key.W))
            {
                picPlayer.Top -= 5;
            }

            if (Keyboard.IsKeyDown(Key.S))
            {
                picPlayer.Top += 5;
            }
        }
    }
}

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

10
задан jbu 16 August 2016 в 18:59
поделиться

5 ответов

Кто бы ни думал, что байты должны быть подписаны, когда Java был изобретен, должен быть вынут и разбит влажной палкой сельдерея, пока они не кричат :-)

Можно сделать то, что Вы хотите путем кастинга до интервала и обеспечения, чтобы Вы никогда не смещали 1 в главный бит, что-то вроде этого:

byte x = -1;
int x2 = ((int)x) & 0xff;
for(int i = 0; i < 8; i++)
{
    x2 = (x2 >>> 1);
    System.out.println("X: " + x2);
}

Ваша конкретная проблема состоит в том, потому что>>> бросает до интервала, чтобы сделать сдвиг, затем Вы бросаете его назад к байту, как показано сюда:

byte x = -1;
int x2 = ((int)x) & 0xff;
int x3;
int x4 = x2;
for(int i = 0; i < 8; i++)
{
    x2 = (x2 >>> 1);
    System.out.println("X2: " + x2);
    x3 = (x >>> 1);
    x = (byte)x3;
    x4 = (x4 >>> 1);
    System.out.println("X: " + x3 + " " + x + " " + x4);
}

Какие выводы:

X2: 127
X: 2147483647 -1 127
X2: 63
X: 2147483647 -1 63
X2: 31
X: 2147483647 -1 31
X2: 15
X: 2147483647 -1 15
X2: 7
X: 2147483647 -1 7
X2: 3
X: 2147483647 -1 3
X2: 1
X: 2147483647 -1 1
X2: 0
X: 2147483647 -1 0

Можно ясно видеть, что x и x3 не работают (даже при том, что x3 смещается правильно, бросание его назад к байту в x устанавливает его на-1 снова). x4 работает отлично.

27
ответ дан 3 December 2019 в 14:18
поделиться

Помните что:

  • операнды битовых операций всегда продвигаются, по крайней мере, на интервал!
  • броски всегда включают расширение знака.

Таким образом, когда Вы делаете (x>>> n), даже при том, что Вы определили x как байт в целях сдвига, он будет сначала преобразован в интервал. Если преобразовываемый байт будет отрицателен, то все "дополнительные биты" (так, крайние левые 24 бита получающегося интервала) добавленный для создания его до интервала будут установлены на 1. Или помещенный иначе, если исходный байт был-1, вещь, Вы на самом деле смещаетесь,-1 как интервал, т.е. 32-разрядное число со всем набором на 32 бита к 1. Смещение этого права 1-8 местами все еще приведет к нижней части 8 битов весь набор к 1, следовательно когда Вы вспомните байт, Вы заканчиваете с байтом со всем набором на 8 битов к 1, или другими словами, значение байта-1.

5
ответ дан 3 December 2019 в 14:18
поделиться

Я не знаю, почему это не работает, но простой способ очистить главный бит к и с (двоичными) 0111111:

x = (byte) (x >>> 1) & 0x7F;
0
ответ дан 3 December 2019 в 14:18
поделиться

Я не уверен в этом. Но, мое предположение - это

x >>> 1 

продвинут на интервал от байта, потому что литерал "1" является интервалом. Затем то, что Вы наблюдаете, имеет смысл.

3
ответ дан 3 December 2019 в 14:18
поделиться

Проблема, как уже говорилось ранее (давным-давно), в том, что x преобразуется в int (расширенный по знаку) перед выполнением сдвига.
Преобразование «бит в бит» должно помочь:

byte x = -1;
for(int i = 0; i < 8; i++)
{
    x = (byte) ((x & 0xFF) >>> 1);
    System.out.println("X: " + x);
}
0
ответ дан 3 December 2019 в 14:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: