0

Пишу игру в двух проектах: первый - меню(по сути основной), второй - экспериментальный(работа со спрайтами, движением и т.д.). Как только второй проект я посчитал уже законченным, то есть все, что я хотел реализовать - получилось, решил перенести код в первый. Но начав переписывать код связанный с движением, начались неполадки: создал Rectangle, который по сути является персонажем, которым ты играешь, после привязал KeyUp и KeyDown к кнопкам(код см. ниже), чтобы персонаж "двигался" при нажатии, но если установить KeyUp и KeyDown на кнопки "W" "A" "S" "D", то он не двигается, а если на стрелочки, то движение будет происходить, но отрывками, а после и вовсе кнопка будто зажимается и он продолжает свое движение уже за пределами карты. Сначала думал, что проблема в флагах, но ничего не нашел. После подумал о том, что второй проект я писал в главном окне, а первый(который с меню), у меня реализован с помощью пользовательского элемента управления, которые являются "окнами" меню, как и собственно "окном" с игрой, из этого вывел то, что фокус стоит на прошлом пользовательском элементе(они у меня работают по принципу Visible: нажал кнопку, и окно видно, нажал другую). Сам путь до игры состоит из: Главное меню(главное окно)->Подготовка к игре(пользовательский элемент)->Игра(еще один пользовательский элемент)

Game.XAML

<UserControl x:Class="TLC.Game"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:TLC"
             mc:Ignorable="d" 
             d:DesignHeight="1080" d:DesignWidth="1920">
    <Canvas Name="MyCanvas" KeyDown="KeyIsDown" KeyUp="KeyIsUp">
        <Canvas.Background>
            <ImageBrush ImageSource="/fone.png"/>
        </Canvas.Background>
        <Button x:Name="BackToMenu" Width="100" Height="100" Click="BackToMenu_Click" BorderBrush="{x:Null}" Foreground="{x:Null}">
            <Button.Background>
                <ImageBrush ImageSource="/free-icon-left-arrow-10559345.png"/>
            </Button.Background>
        </Button>
        <Label Name="TimerLabel" Content="0" FontFamily="Magma" FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center" Canvas.Left="750" Canvas.Top="5" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ></Label>
        <Rectangle x:Name="who" Width="100" Height="150" Canvas.Left="415" Canvas.Top="286" HorizontalAlignment="Left" VerticalAlignment="Top" Fill="White" Stroke="#FF006CFF" Focusable="True"></Rectangle>
        <Rectangle Name="ground" Width="1930" Height="300" Canvas.Top="695" VerticalAlignment="Top" HorizontalAlignment="Center"/>
        <Rectangle Name="tower" Width="100" Height="100"></Rectangle>
    </Canvas>
</UserControl>

Game.XAML.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace TLC { public abstract class Object { public int health { get; set; } public Object() { } public Object(int health) { this.health = health; } } class Player : Object { public int speed { get; set; } public int damage { get; set; } public int force { get; set; } public bool attack { get; set; } public bool goLeft { get; set; } public bool goRight { get; set; } public bool isJump { get; set; } public Player() { } public Player(int health, int speed, int damage, bool attack, bool goLeft, bool goRight, bool isJump, int force) : base(health) { this.speed = speed; this.damage = damage; this.attack = attack; this.goLeft = goLeft; this.goRight = goRight; this.isJump = isJump; this.force = force; } } class Enemy : Object { public int speed { get; set; } public int damage { get; set; } public bool attack { get; set; } public bool goLeft { get; set; } public Enemy() { } public Enemy(int health, int speed, int damage, bool attack, bool goLeft) : base(health) { this.speed = speed; this.damage = damage; this.attack = attack; this.goLeft = goLeft; } } class Tower : Object { public Tower() { } public Tower(int health) : base(health) {

    }
}

public partial class Game : UserControl
{
    DispatcherTimer gameTimer = new DispatcherTimer();

    Rect playerhitbox;
    Rect Groundhitbox;
    Rect towerhitbox;

    Player Mainplayer = new Player();
    Tower MainTower = new Tower(100);

    public Game()
    {
        InitializeComponent();
        MyCanvas.Focus();
        gameTimer.Tick += GameTimerEvent;
        gameTimer.Interval = TimeSpan.FromMilliseconds(20);
        StartGame();
        Mainplayer.speed = 10;
    }
    public void GameTimerEvent(object sender, EventArgs e)
    {
        //Canvas.SetTop(player, Canvas.GetTop(player) + Mainplayer.speed);
        if (Mainplayer.goLeft == true &amp;&amp; Canvas.GetLeft(who) &gt; 5)
        {
            Canvas.SetLeft(who, Canvas.GetLeft(who) - Mainplayer.speed);
        }
        if (Mainplayer.goRight == true &amp;&amp; Canvas.GetLeft(who) + (who.Width + 20) &lt; 1920)
        {
            Canvas.SetLeft(who, Canvas.GetLeft(who) + Mainplayer.speed);
        }

        playerhitbox = new Rect(Canvas.GetLeft(who), Canvas.GetTop(who), who.Width, who.Height);
        Groundhitbox = new Rect(Canvas.GetLeft(ground), Canvas.GetTop(ground), ground.Width, ground.Height);

        if (playerhitbox.IntersectsWith(Groundhitbox))
        {
            Canvas.SetTop(who, Canvas.GetTop(ground) - who.Height);
        }
    }
    private void KeyIsDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Left)
        {
            Mainplayer.goLeft = true;
        }
        if (e.Key == Key.Right)
        {
            Mainplayer.goRight = true;
        }
    }

    private void KeyIsUp(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Left)
        {
            Mainplayer.goLeft = false;
        }
        if (e.Key == Key.Right)
        {
            Mainplayer.goRight = false;
        }
    }
    private void BackToMenu_Click(object sender, RoutedEventArgs e)
    {
        Visibility = Visibility.Collapsed;
    }
    public void StartGame()
    {
        Canvas.SetLeft(who, 110);
        gameTimer.Start();
    }
}

}

citn
  • 3
  • 2
  • 1
    Вдруг полезно будет, пример управления: https://ru.stackoverflow.com/a/1222168/373567 скачайте, поиграйте. Кнопки считывать надо на уровне окна, либо очень жестко контролировать фокус. – aepot Nov 16 '23 at 00:14

0 Answers0