Вот очень простой пример, который может помочь вам начать. Вам нужно будет добавить ссылку на две сборки, чтобы это работало.
Шаг 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;
}
}
}
}
Это должно помочь вам начать. По сути, все, что происходит, это каждый тик таймера, когда вы проверяете состояние клавиатуры, а затем соответствующим образом обновляете игровые объекты. Обратите внимание, что есть более эффективные способы сделать это но пока это будет проще, и вам не нужно будет беспокоиться об обновлении элементов управления между потоками и т. д.
Кто бы ни думал, что байты должны быть подписаны, когда 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 работает отлично.
Помните что:
Таким образом, когда Вы делаете (x>>> n), даже при том, что Вы определили x как байт в целях сдвига, он будет сначала преобразован в интервал. Если преобразовываемый байт будет отрицателен, то все "дополнительные биты" (так, крайние левые 24 бита получающегося интервала) добавленный для создания его до интервала будут установлены на 1. Или помещенный иначе, если исходный байт был-1, вещь, Вы на самом деле смещаетесь,-1 как интервал, т.е. 32-разрядное число со всем набором на 32 бита к 1. Смещение этого права 1-8 местами все еще приведет к нижней части 8 битов весь набор к 1, следовательно когда Вы вспомните байт, Вы заканчиваете с байтом со всем набором на 8 битов к 1, или другими словами, значение байта-1.
Я не знаю, почему это не работает, но простой способ очистить главный бит к и с (двоичными) 0111111:
x = (byte) (x >>> 1) & 0x7F;
Я не уверен в этом. Но, мое предположение - это
x >>> 1
продвинут на интервал от байта, потому что литерал "1" является интервалом. Затем то, что Вы наблюдаете, имеет смысл.
Проблема, как уже говорилось ранее (давным-давно), в том, что x преобразуется в int (расширенный по знаку) перед выполнением сдвига.
Преобразование «бит в бит» должно помочь:
byte x = -1;
for(int i = 0; i < 8; i++)
{
x = (byte) ((x & 0xFF) >>> 1);
System.out.println("X: " + x);
}