0

I've placed a bunch of elements on a WPF canvas within an ItemsControl + datatemplate. They all have X and Y coordinates. They also move around. I loop through the elements and I add or minus a certain amount from their X and/or Y coordinate(s).

Sounded easy enough to pull of. It kinda works. Problem is that every element seems to have a different idea of what Y means.

If the elements touch the sides of the canvas, they should bounce back. It works for all sides except for the bottom side. I've defined the bottom at Y 400 so they should never pass this. They all seem to have a different idea of what Y 400 means.

This means that they all bounce back at a different moment from the bottom. my canvas

 <Canvas x:Name="Canvas" Background="LightGray" Grid.Row="0" Grid.Column="0" Width="800" Height="600">
            <ItemsControl x:Name="SpaceObjectsIC"
                          ItemsSource="{Binding SpaceObjects, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Ellipse Fill="{Binding Color, Converter={StaticResource ColorConverter}}"
                                 Height="{Binding Radius}" Width="{Binding Radius}" Tag="{Binding Name}"
                                 ClipToBounds="True">
                            <Ellipse.RenderTransform>
                                <TranslateTransform X="{Binding X}" Y="{Binding Y}" />
                            </Ellipse.RenderTransform>
                        </Ellipse>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Canvas>

This is the move method thats part of the spaceobject class. Every element on the canvas uses this method to move + check if they hit the side of the canvas. For some of the elements the 400 which I defined as the bottom of the canvas works. For most it doesn't.

X and Y are decimal coordinates of the element. _vx and _vy are the amount that they move in either an X or Y direction. Both decimal. Used to be float and I also tried double, but none of them changed the outcome.

public void Move()
        {
            X += _vx;
            Y += _vy;

            int newRad = (int) Radius;

            // leftside canvas
            if (X < -10 + newRad)
            {
                _vx = Math.Abs(_vx);
                Color = Color.Brown;
            }

            // rightside canvas
            if (X > 770 - newRad)
            {
                _vx = -Vx;
                Color = Color.Blue;
            }

            // topside canvas
            if (Y < 0 + newRad)
            {
                _vy = Math.Abs(_vy);
                Color = Color.Pink;
            }

            // bottomside canvas
           if (Y > 400 - newRad)
            {
                _vy = -_vy;
                Color = Color.Orange;
            }
        }

If more code is needed let me know, but there is not much more code than this. Only thing I did before this was creating the elements. Just a bunch of decimals that had to be set.

In this picture you see tree point. On the left as8, and on the right as20 and as21. On the right hand side of the screen you can see the X and the Y of these elements (x on top, Y below).

As you can see as8 is right between as20 and as21, so it's Y coordinate should be between 300 and 312. However, it's way higher!

space data

Full xaml

<Page x:Class="Flat_space.View.Pages.Space.Space"
      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:Flat_space.View.Pages.Space"
      xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
      xmlns:converters="clr-namespace:Flat_space.Converters"
      mc:Ignorable="d"
      Title="Space"
      DataContext="{Binding Space, Source={StaticResource Locator}}">

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding LoadSpaceCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>

    <Page.Resources>
        <converters:ColorConverter x:Key="ColorConverter" />
        <converters:BoolToEnabledConverter x:Key="BoolToEnabledConverter" />
    </Page.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="7*" />
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="2*" />
            <ColumnDefinition Width="5*" />
            <ColumnDefinition Width="2*" />
        </Grid.ColumnDefinitions>

        <Canvas x:Name="Canvas" Background="LightGray" Grid.Row="0" Grid.Column="0" Width="800" Height="600">
            <ItemsControl x:Name="SpaceObjectsIC"
                          ItemsSource="{Binding SpaceObjects, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Ellipse Fill="{Binding Color, Converter={StaticResource ColorConverter}}"
                                 Height="{Binding Radius}" Width="{Binding Radius}" Tag="{Binding Name}"
                                 ClipToBounds="True">
                            <Ellipse.RenderTransform>
                                <TranslateTransform X="{Binding X}" Y="{Binding Y}" />
                            </Ellipse.RenderTransform>
                        </Ellipse>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Canvas>

        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Grid.ColumnSpan="3"
                    Grid.Column="0"
                    Orientation="Vertical">
            <TextBlock Foreground="Green" Text="{Binding SimulationState, NotifyOnSourceUpdated=True}" />
            <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Grid.ColumnSpan="3"
                        Orientation="Horizontal">
                <Button Command="{Binding BackToMainMenuCommand}" Margin="0,0,5,0">Back To Main Menu</Button>
                <Button>Back 5 Seconds</Button>
                <Button x:Name="StartButton" Command="{Binding StartCommand}" Margin="5,0,5,0">Start</Button>
                <Button x:Name="StopButton" Command="{Binding StopCommand}" Margin="5,0,5,0">Stop</Button>
                <Button>Forward 5 Seconds</Button>
                <Button Command="{Binding SpaceDetailsCommand}">Data details</Button>
            </StackPanel>
        </StackPanel>
    </Grid>
</Page>
InfoSpunge
  • 49
  • 8
  • Seems to me like you are not taking into account that your circles have different radii. – Freggar Sep 28 '20 at 13:31
  • The whole logic of bouncing is 2 checks for X and Y bounds where you have to [invert](https://stackoverflow.com/q/9765317/1997232) corresponding delta. Ok, you are using different colors, not sure why. – Sinatr Sep 28 '20 at 13:36
  • `_vx = -Vx;` - looks like a typo. It's probably bad idea to ask for help and do not show real code. – Sinatr Sep 28 '20 at 13:41
  • @Sinatr not a typo. – InfoSpunge Sep 28 '20 at 13:50
  • @Sinatr the different colors were just for debugging. The inverting works but that's not the problem. It's WHEN it inverts. – InfoSpunge Sep 28 '20 at 13:51
  • @Freggar I am taking it into account. I forgot to add this to the post but 'newRad' represents the radius. Also, there's a lot of smaller dots with the same radius that all bounce back at different moments. – InfoSpunge Sep 28 '20 at 13:51
  • 2
    Please set the `ItemsPanel` to actually use a `Canvas`, else your items will get put into a `StackPanel` which will lead to some weird effects. See here: https://learn.microsoft.com/de-de/dotnet/api/system.windows.controls.itemscontrol.itemspanel?view=netcore-3.1 Also consider using Canvas.Left and Canvas.Top properties instead of transforms – Ehssan Sep 28 '20 at 13:57
  • Then what is `Vx` ? Please see [mcve], you have to show complete enough code. Consider to present problem more clearly, e.g by recording gif (google screen to gif or something). – Sinatr Sep 28 '20 at 13:57
  • @Ehssan Your suggestion fixed my problem! Thanks man! How can I mark it as an answer? – InfoSpunge Sep 28 '20 at 14:20

0 Answers0