O'Reilly Forums: Chap 1 - Save The Humans - O'Reilly Forums

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Chap 1 - Save The Humans VS 2013 Pro- trouble with AddEnemy

#1 User is offline   ehilberg 

  • New Member
  • Pip
  • Group: Members
  • Posts: 2
  • Joined: 27-January 14

Posted 27 January 2014 - 06:09 PM

Hello,

I was chugging along creating the Save the Humans game, when I ran across an error when I went to run the game for the first time (p 35). This is the error that it gives me.


"An exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll but was not handled in user code

Additional information: 'maxValue' must be greater than zero."

c#
using Save_the_Humans.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.UI.Xaml.Media.Animation;

// The Basic Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234237

namespace Save_the_Humans
{
    /// <summary>
    /// A basic page that provides characteristics common to most applications.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        Random random = new Random();

        private NavigationHelper navigationHelper;
        private ObservableDictionary defaultViewModel = new ObservableDictionary();

        /// <summary>
        /// This can be changed to a strongly typed view model.
        /// </summary>
        public ObservableDictionary DefaultViewModel
        {
            get { return this.defaultViewModel; }
        }

        /// <summary>
        /// NavigationHelper is used on each page to aid in navigation and 
        /// process lifetime management
        /// </summary>
        public NavigationHelper NavigationHelper
        {
            get { return this.navigationHelper; }
        }


        public MainPage()
        {
            this.InitializeComponent();
            this.navigationHelper = new NavigationHelper(this);
            this.navigationHelper.LoadState += navigationHelper_LoadState;
            this.navigationHelper.SaveState += navigationHelper_SaveState;
        }

        /// <summary>
        /// Populates the page with content passed during navigation. Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        /// <param name="sender">
        /// The source of the event; typically <see cref="NavigationHelper"/>
        /// </param>
        /// <param name="e">Event data that provides both the navigation parameter passed to
        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested and
        /// a dictionary of state preserved by this page during an earlier
        /// session. The state will be null the first time a page is visited.</param>
        private void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
        {
        }

        /// <summary>
        /// Preserves state associated with this page in case the application is suspended or the
        /// page is discarded from the navigation cache.  Values must conform to the serialization
        /// requirements of <see cref="SuspensionManager.SessionState"/>.
        /// </summary>
        /// <param name="sender">The source of the event; typically <see cref="NavigationHelper"/></param>
        /// <param name="e">Event data that provides an empty dictionary to be populated with
        /// serializable state.</param>
        private void navigationHelper_SaveState(object sender, SaveStateEventArgs e)
        {
        }

        #region NavigationHelper registration

        /// The methods provided in this section are simply used to allow
        /// NavigationHelper to respond to the page's navigation methods.
        /// 
        /// Page specific logic should be placed in event handlers for the  
        /// <see cref="GridCS.Common.NavigationHelper.LoadState"/>
        /// and <see cref="GridCS.Common.NavigationHelper.SaveState"/>.
        /// The navigation parameter is available in the LoadState method 
        /// in addition to page state preserved during an earlier session.

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            navigationHelper.OnNavigatedTo(e);
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            navigationHelper.OnNavigatedFrom(e);
        }

        #endregion

        private void startButton_Click(object sender, RoutedEventArgs e)
        {
            AddEnemy();
        }

 private void AddEnemy()
        {
            ContentControl enemy = new ContentControl();
            enemy.Template = Resources["EnemyTemplate"] as ControlTemplate;
//the following three lines are what VS highlighted with the error message
            AnimateEnemy(enemy, 0, playArea.ActualWidth - 100, "(Canvas.Left)");
            AnimateEnemy(enemy, random.Next((int)playArea.ActualHeight - 100),
                random.Next((int)playArea.ActualHeight - 100), "(Canvas.Top)");
            playArea.Children.Add(enemy);
        }

        private void AnimateEnemy(ContentControl enemy, double from, double to, string propertyToAnimate)
        {
            Storyboard storyboard = new Storyboard() { AutoReverse = true, RepeatBehavior = RepeatBehavior.Forever };
            DoubleAnimation animation = new DoubleAnimation()
            {
                From = from,
                To = to,
                Duration = new Duration(TimeSpan.FromSeconds(random.Next(4, 6)))
            };
            Storyboard.SetTarget(animation, enemy);
            Storyboard.SetTargetProperty(animation, propertyToAnimate);
            storyboard.Children.Add(animation);
            storyboard.Begin();
        }
    }
}



XAML
<Page
    x:Name="pageRoot"
    x:Class="Save_the_Humans.MainPage"
    DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Save_the_Humans"
    xmlns:common="using:Save_the_Humans.Common"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" HorizontalAlignment="Center" VerticalAlignment="Center">

    <Page.Resources>
        <!-- TODO: Delete this line if the key AppName is declared in App.xaml -->
        <x:String x:Key="AppName">Save the Humans</x:String>
        <ControlTemplate x:Key="EnemyTemplate" TargetType="ContentControl">
            <Grid>
                <Ellipse Fill="#FFF12B2B" HorizontalAlignment="Center" Stroke="Black" VerticalAlignment="Center" Width="100" Height="100"/>

            </Grid>
        </ControlTemplate>
    </Page.Resources>

    <!--
        This grid acts as a root panel for the page that defines two rows:
        * Row 0 contains the back button and page title
        * Row 1 contains the rest of the page layout
    -->
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="160"/>
            <ColumnDefinition/>
            <ColumnDefinition Width="160"/>
        </Grid.ColumnDefinitions>
        <Grid.ChildrenTransitions>
            <TransitionCollection>
                <EntranceThemeTransition/>
            </TransitionCollection>
        </Grid.ChildrenTransitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="140"/>
            <RowDefinition/>
            <RowDefinition Height="160"/>
        </Grid.RowDefinitions>

        <!-- Back button and page title -->
        <Grid Grid.ColumnSpan="3">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="120"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Button x:Name="backButton" Margin="39,59,39,0" Command="{Binding NavigationHelper.GoBackCommand, ElementName=pageRoot}"
                        Style="{StaticResource NavigationBackButtonNormalStyle}"
                        VerticalAlignment="Top"
                        AutomationProperties.Name="Back"
                        AutomationProperties.AutomationId="BackButton"
                        AutomationProperties.ItemType="Navigation Button"/>
            <TextBlock x:Name="pageTitle" Text="{StaticResource AppName}" Style="{StaticResource HeaderTextBlockStyle}" Grid.Column="1" 
                        IsHitTestVisible="false" TextWrapping="NoWrap" VerticalAlignment="Bottom" Margin="0,0,30,40"/>
        </Grid>
        <Button x:Name="startButton" Content="Start!" HorizontalAlignment="Center" Margin="50,65,39,57" Grid.Row="2" VerticalAlignment="Center" Click="startButton_Click"/>
        <ProgressBar Grid.Column="1" Grid.Row="2" Height="20"/>
        <StackPanel Grid.Column="2" Orientation="Vertical" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBlock TextWrapping="Wrap" Text="Avoid These" RenderTransformOrigin="0.158,0.281" FontSize="22" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            <ContentControl Content="ContentControl" Template="{StaticResource EnemyTemplate}"/>
        </StackPanel>
        <Canvas x:Name="playArea" HorizontalAlignment="Center" Margin="486,198,0,0" Grid.Row="1" VerticalAlignment="Center" Grid.ColumnSpan="3">
            <Canvas.Background>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="Black" Offset="0"/>
                    <GradientStop Color="White" Offset="1"/>
                    <GradientStop Color="#FF742E2E"/>
                </LinearGradientBrush>
            </Canvas.Background>
            <StackPanel x:Name="human" Orientation="Vertical">
                <Ellipse Fill="White" Height="10" Width="10"/>
                <Rectangle Fill="White" Height="25" Width="10"/>
            </StackPanel>
        </Canvas>
        <TextBlock x:Name="gameOverText" Grid.Column="1" HorizontalAlignment="Left" Margin="282,178,0,0" Grid.Row="1" TextWrapping="Wrap" Text="Game Over" VerticalAlignment="Top" FontFamily="Arial Black" FontSize="100" FontWeight="Bold" FontStyle="Italic"/>
        <Rectangle x:Name="target" Grid.Column="1" HorizontalAlignment="Left" Height="50" Margin="186,333,0,0" Grid.Row="1" VerticalAlignment="Top" Width="50" RenderTransformOrigin="0.5,0.5">
            <Rectangle.RenderTransform>
                <CompositeTransform Rotation="45"/>
            </Rectangle.RenderTransform>
            <Rectangle.Fill>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="Black" Offset="0"/>
                    <GradientStop Color="White" Offset="1"/>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>
    </Grid>
</Page>


This post has been edited by ehilberg: 27 January 2014 - 06:30 PM

0

#2 User is offline   AndrewStellman 

  • Andrew Stellman
  • PipPipPipPipPipPipPipPipPipPipPip
  • Group: O'Reilly Author
  • Posts: 716
  • Joined: 08-October 08
  • Gender:Male
  • Location:Brooklyn, NY
  • Interests:Author of: "Head First C#", "Beautiful Teams", "Head First PMP", "Applied Software Project Management"

Posted 27 January 2014 - 07:02 PM

Another reader made a typo that caused that error -- I bet your code has the same typo: http://forums.oreill...attack-problem/

I hope this helps!
Andrew Stellman
Author, Head First C#
Building Better Software -- http://www.stellman-greene.com
0

#3 User is offline   ehilberg 

  • New Member
  • Pip
  • Group: Members
  • Posts: 2
  • Joined: 27-January 14

Posted 27 January 2014 - 07:36 PM

View PostAndrewStellman, on 27 January 2014 - 07:02 PM, said:

Another reader made a typo that caused that error -- I bet your code has the same typo: http://forums.oreill...attack-problem/

I hope this helps!




Thanks. I'm running VS 2013 (pro version), is that going to have any influence on whether or not the published source code will work?

The height and width auto-reset to 0 when I hit the auto button. If I set them to arbitrary values (e.g., 150), the area appears and the enemies appear with each hit of the start button.

What part of the code sets the initial height?
0

#4 User is offline   AndrewStellman 

  • Andrew Stellman
  • PipPipPipPipPipPipPipPipPipPipPip
  • Group: O'Reilly Author
  • Posts: 716
  • Joined: 08-October 08
  • Gender:Male
  • Location:Brooklyn, NY
  • Interests:Author of: "Head First C#", "Beautiful Teams", "Head First PMP", "Applied Software Project Management"

Posted 29 January 2014 - 05:35 AM

This part:

<Canvas x:Name="playArea" HorizontalAlignment="Center" Margin="486,198,0,0" Grid.Row="1" VerticalAlignment="Center" Grid.ColumnSpan="3">


Your corrected version has a Height property. Later in the book you'll learn a lot about how properties work in XAML, how to set their values, and how that affects objects in memory.
Andrew Stellman
Author, Head First C#
Building Better Software -- http://www.stellman-greene.com
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users