使用 KeyDown 事件 UWP 在 canvas 上平滑元素运动
Smooth element motion on canvas with KeyDown event UWP
我正在尝试创建一种宇宙飞船游戏,您可以在其中使用箭头键控制图像(显然是宇宙飞船)来移动 UP/DOWN/R/L。
为此,我使用了 CoreWindow.KeyDown 事件。
其实还可以,就是动作不够流畅。
每次我按下其中一个箭头键时,图像就会出现:
1. 向那个方向移动一步
2. 冻结,大约半秒(甚至更短)
3. 然后继续无障碍地移动。
(A "step" 是一个 'int' 变量,它包含多个像素,比如 20 个)。
当然,那是没办法运行一场比赛。当我按下其中一个箭头键时,我希望船立即平稳移动,没有 "Half a second" 延迟。
这是我的代码:
public sealed partial class MainPage : Page
{
double playerYAxisPosition;
double playerXAxisPosition;
int steps = 20;
bool upMovement;
bool downMovement;
bool rightMovement;
bool leftMovement;
public MainPage()
{
this.InitializeComponent();
Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
Window.Current.CoreWindow.KeyUp += CoreWindow_KeyUp;
}
// Recognizes the KeyDown press and sets the relevant booleans to "true"
private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args) {
playerYPosition = (double) playerShip.GetValue(Canvas.TopProperty);
playerXPosition = (double) playerShip.GetValue(Canvas.LeftProperty);
if (args.VirtualKey == Windows.System.VirtualKey.Up) {
upMovement = true;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Down) {
downMovement = true;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Left) {
leftMovement = true;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Right) {
rightMovement = true;
}
movePlayer();
}
// recognizes the KeyUp event and sets the relevant booleans to "false"
private void CoreWindow_KeyUp(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args) {
if (args.VirtualKey == Windows.System.VirtualKey.Up) {
upMovement = false;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Down) {
downMovement = false;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Left) {
leftMovement = false;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Right) {
rightMovement = false;
}
}
// Calls the movement Methods of the relevant direction
private void movePlayer() {
if (upMovement) {
moveUp();
}
if (downMovement) {
moveDown();
}
if (rightMovement) {
moveRight();
}
if (leftMovement) {
moveLeft();
}
}
private void moveUp() {
playerShip.SetValue(Canvas.TopProperty, playerYPosition - stepsToMove);
}
private void moveDown() {
playerShip.SetValue(Canvas.TopProperty, playerYPosition + stepsToMove);
}
private void moveRight() {
playerShip.SetValue(Canvas.LeftProperty, playerXPosition + stepsToMove);
}
private void moveLeft() {
playerShip.SetValue(Canvas.LeftProperty, playerXPosition - stepsToMove);
}
顺便说一句,我创建了一些专用的布尔值,这些布尔值将在每个 KeyDown 事件上设置为 'true' 或 'false',而不是直接使用 KeyDown 事件,因为这种分离允许元素(船图像)也沿对角线移动,而直接使用 "args.VirtualKey == Windows.System.VirtualKey.SomeArrowKey" 由于某种原因不允许它。
感谢您的帮助。
如果你想创建一个游戏,你应该在你的游戏循环中移动 playerShip
。您可以使用 DispatcherTimer or register CompositionTarget.Rendering 事件来创建游戏循环。
Windows.UI.Xaml.Media.CompositionTarget.Rendering += CompositionTarget_Rendering;
更改 CoreWindow_KeyDown
事件处理程序如下:
private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
{
if (args.VirtualKey == Windows.System.VirtualKey.Up)
{
upMovement = true;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Down)
{
downMovement = true;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Left)
{
leftMovement = true;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Right)
{
rightMovement = true;
}
}
接下来,在 CompositionTarget.Rendering
事件处理程序中移动你的飞船。
private void CompositionTarget_Rendering(object sender, object e)
{
playerYPosition = (double)playerShip.GetValue(Canvas.TopProperty);
playerXPosition = (double)playerShip.GetValue(Canvas.LeftProperty);
movePlayer();
}
我正在尝试创建一种宇宙飞船游戏,您可以在其中使用箭头键控制图像(显然是宇宙飞船)来移动 UP/DOWN/R/L。 为此,我使用了 CoreWindow.KeyDown 事件。
其实还可以,就是动作不够流畅。 每次我按下其中一个箭头键时,图像就会出现: 1. 向那个方向移动一步 2. 冻结,大约半秒(甚至更短) 3. 然后继续无障碍地移动。 (A "step" 是一个 'int' 变量,它包含多个像素,比如 20 个)。
当然,那是没办法运行一场比赛。当我按下其中一个箭头键时,我希望船立即平稳移动,没有 "Half a second" 延迟。 这是我的代码:
public sealed partial class MainPage : Page
{
double playerYAxisPosition;
double playerXAxisPosition;
int steps = 20;
bool upMovement;
bool downMovement;
bool rightMovement;
bool leftMovement;
public MainPage()
{
this.InitializeComponent();
Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
Window.Current.CoreWindow.KeyUp += CoreWindow_KeyUp;
}
// Recognizes the KeyDown press and sets the relevant booleans to "true"
private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args) {
playerYPosition = (double) playerShip.GetValue(Canvas.TopProperty);
playerXPosition = (double) playerShip.GetValue(Canvas.LeftProperty);
if (args.VirtualKey == Windows.System.VirtualKey.Up) {
upMovement = true;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Down) {
downMovement = true;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Left) {
leftMovement = true;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Right) {
rightMovement = true;
}
movePlayer();
}
// recognizes the KeyUp event and sets the relevant booleans to "false"
private void CoreWindow_KeyUp(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args) {
if (args.VirtualKey == Windows.System.VirtualKey.Up) {
upMovement = false;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Down) {
downMovement = false;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Left) {
leftMovement = false;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Right) {
rightMovement = false;
}
}
// Calls the movement Methods of the relevant direction
private void movePlayer() {
if (upMovement) {
moveUp();
}
if (downMovement) {
moveDown();
}
if (rightMovement) {
moveRight();
}
if (leftMovement) {
moveLeft();
}
}
private void moveUp() {
playerShip.SetValue(Canvas.TopProperty, playerYPosition - stepsToMove);
}
private void moveDown() {
playerShip.SetValue(Canvas.TopProperty, playerYPosition + stepsToMove);
}
private void moveRight() {
playerShip.SetValue(Canvas.LeftProperty, playerXPosition + stepsToMove);
}
private void moveLeft() {
playerShip.SetValue(Canvas.LeftProperty, playerXPosition - stepsToMove);
}
顺便说一句,我创建了一些专用的布尔值,这些布尔值将在每个 KeyDown 事件上设置为 'true' 或 'false',而不是直接使用 KeyDown 事件,因为这种分离允许元素(船图像)也沿对角线移动,而直接使用 "args.VirtualKey == Windows.System.VirtualKey.SomeArrowKey" 由于某种原因不允许它。
感谢您的帮助。
如果你想创建一个游戏,你应该在你的游戏循环中移动 playerShip
。您可以使用 DispatcherTimer or register CompositionTarget.Rendering 事件来创建游戏循环。
Windows.UI.Xaml.Media.CompositionTarget.Rendering += CompositionTarget_Rendering;
更改 CoreWindow_KeyDown
事件处理程序如下:
private void CoreWindow_KeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs args)
{
if (args.VirtualKey == Windows.System.VirtualKey.Up)
{
upMovement = true;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Down)
{
downMovement = true;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Left)
{
leftMovement = true;
}
else if (args.VirtualKey == Windows.System.VirtualKey.Right)
{
rightMovement = true;
}
}
接下来,在 CompositionTarget.Rendering
事件处理程序中移动你的飞船。
private void CompositionTarget_Rendering(object sender, object e)
{
playerYPosition = (double)playerShip.GetValue(Canvas.TopProperty);
playerXPosition = (double)playerShip.GetValue(Canvas.LeftProperty);
movePlayer();
}