XNA Folder Hierarchy - file

Ok so I'm new to XNA and I am just trying to get an image to show on the screen. I believe I have added the Images to the content folder in the VS2010 program HOWEVER when I try to run the program I get an error saying File not found. So I am wondering what folder to have the image in to just be able to call the image file Tank.png.
the code is simple:
namespace Aceldama_Windows_Game
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Vector2 mPosition = new Vector2(0, 0);
Texture2D mSpriteTexture;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
mSpriteTexture = this.Content.Load<Texture2D>("Tank");
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.Draw(mSpriteTexture, mPosition, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
What folder should I put the image into to be able to call the file directly without having to put the full file path? Essentially the problem being is it seems as though no matter where i place the tank.png file (whether it is in the the file with the executable/c# files or in the content folder)

The XNA Content Pipeline takes the items that are referenced by your content project and transforms them into XNB files. The ContentManager then loads those XNB files.
So the first thing to check is if the XNB files are being created where you expect them in your output directory.
According to the code you have posted, with Content.RootDirectory = "Content" and Content.Load<Texture2D>("Tank"), assuming a Windows Debug build, it will be looking for the file:
bin/x86/Debug/Content/Tank.xnb
If you changed the content project output directory, you need to change the RootDirectory you set in code as well.

So I figured out what the problem was after searching the web endlessly;p it The code was fine the problem was I needed to create a reference to the content folder in the project. uploaded a pic of the solution explorer to show what I needed to do!
Under Content References I did not have the "Aceldama_windows_gameContent" Added. That needs to be there to reference the game content folder with the images in it!

Related

Creating and running WPF window in another thread

So I am working on a console project which should display a WPF window at some point where I can see the visual representation of my graph while it continues running through the algorithm.
I've come so far that I can create a Window and open it in another thread, but as soon as I call Dispatcher.Run() the Console gets blocked. My approach so far:
Step 1: Creating a thread which creates the Application and an SynchronizationContext for itself once run
Step 2: Calling the application's method (it's an inherited custom class which provides these methods) to create a window using a transportation class, using the sync-context of the thread. Expectation: It should create an instance of a Window owned by the separate UI thread.
Step 3: Calling the ShowWindow() method on the application using the sync-context of the thread, which shows the Window (does work) and then runs the Dispatcher. Because it's dispatched using the sync-context of the thread, it shouldn't lock the Console thread. It does, though.
Step 4: Using the Window's dispatcher to call the update methods for the graph.
Well, in my thoughts this should perfectly well work, but somehow the Dispatcher locks the Console thread and not the UI thread. Am I overlooking something here?
The custom Application:
internal sealed class CrossThreadApplication : Application
{
private SynchronizationContext _context;
///=================================================================================================
/// <summary> Constructor. </summary>
///
/// <param name="context"> The context. </param>
///=================================================================================================
public CrossThreadApplication(SynchronizationContext context)
{
if (context == null) throw new ArgumentNullException(nameof(context));
_context = context;
}
///=================================================================================================
/// <summary> Shows the window. </summary>
///
/// <exception cref="ArgumentNullException"> Thrown when one or more required arguments are
/// null. </exception>
///
/// <param name="window"> The window. </param>
///=================================================================================================
public void ShowWindow(Window window)
{
if (window == null) throw new ArgumentNullException(nameof(window));
_context.Send(state =>
{
((Window)state).Show();
System.Windows.Threading.Dispatcher.Run();
}, window);
}
///=================================================================================================
/// <summary> Creates a new object. </summary>
///
/// <param name="handle"> The creation handle for a Window. </param>
///
/// <returns> An object. </returns>
///=================================================================================================
public void Create(CreationHandle<Window> handle)
{
_context.Send(state =>
{
CreationHandle<Window> hnd = (CreationHandle<Window>) state;
hnd.Set(Activator.CreateInstance(hnd.CreationType));
}, handle);
}
}
The UIHost class which hosts the UI thread and interacts with the application
static UIHost()
{
HostThread = new Thread(Start);
HostThread.SetApartmentState(ApartmentState.STA);
HostThread.Name = "UI Thread";
CreationEvent = new ManualResetEvent(false);
HostThread.Start(CreationEvent);
}
private static void Start(object o)
{
ManualResetEvent ev = (ManualResetEvent) o;
SynchronizationContext context = new SynchronizationContext();
SynchronizationContext.SetSynchronizationContext(context);
_application = new CrossThreadApplication(context);
ev.Set();
_application.Run();
}
///=================================================================================================
/// <summary> Executes the user interface operation. </summary>
///
/// <param name="windowType"> The window type. </param>
/// <param name="reset"> The reset. </param>
///
/// <returns> An object. </returns>
///=================================================================================================
internal static object RunUI(Type windowType, ManualResetEvent reset)
{
CreationEvent.WaitOne();
CreationHandle<Window> handle = new CreationHandle<Window>();
_application.Create(handle);
_application.ShowWindow(handle.Get());
reset.Set();
return handle.Get();
}
The issue occurs in CrossThreadApplication.ShowWindow() at *.Dispatcher.Run();.
Why is this so? How can I get this working? It has to be possible somehow.

WPF Best way of displaying a busy indicator when dynamically creating a page

I have a WPF application that runs as an XBAP in a browser. On a few pages all the controls are dynamically created depending on what the user selects. Because of this it can look like the application is not doing anything until all the controls are loaded. I'd like to have some sort of busy indicator displayed before hand to show the user that the controls are loading, it doesn't have to be animated although would be nice if it did. I've looked into the telerik busy indicator but this doesn't work as it's really for getting data for a single control and doesn't show until the controls are loaded which defeats the purpose.
I was thinking of displaying an overlay, or something similar, first, containing a loading logo, then load the page behind this and hide the overlay when the controls have loaded. I was wondering if this was the best way of going about this or if there's a better way?
Note: I haven't tried this in a XBAP browser app, but it works in WPF Apps without any problems!
I use a DispatcherTimer to show an hourglass when necessary, and abstract this code to a static class.
public static class UiServices
{
/// <summary>
/// A value indicating whether the UI is currently busy
/// </summary>
private static bool IsBusy;
/// <summary>
/// Sets the busystate as busy.
/// </summary>
public static void SetBusyState()
{
SetBusyState(true);
}
/// <summary>
/// Sets the busystate to busy or not busy.
/// </summary>
/// <param name="busy">if set to <c>true</c> the application is now busy.</param>
private static void SetBusyState(bool busy)
{
if (busy != IsBusy)
{
IsBusy = busy;
Mouse.OverrideCursor = busy ? Cursors.Wait : null;
if (IsBusy)
{
new DispatcherTimer(TimeSpan.FromSeconds(0), DispatcherPriority.ApplicationIdle, dispatcherTimer_Tick, Application.Current.Dispatcher);
}
}
}
/// <summary>
/// Handles the Tick event of the dispatcherTimer control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private static void dispatcherTimer_Tick(object sender, EventArgs e)
{
var dispatcherTimer = sender as DispatcherTimer;
if (dispatcherTimer != null)
{
SetBusyState(false);
dispatcherTimer.Stop();
}
}
}
You would use it like this:
void DoSomething()
{
UiServices.SetBusyState();
// Do your thing
}
Hope this helps!

MVVM multiple Dialogs headache

I am using caliburn micro. My problem is how to manage dialogs.
The biggest problem is that because when not using window your code doesnt stop and wait.
So i did something like this.
public void ShowDialog(IScreen dialogModel, Action<object> callback = null)
{
ActivateItem(dialogModel);
if (callback != null)
dialogModel.Deactivated += delegate { callback(dialogModel); };
}
This has lots of problem.For example in case i want to show dialog A and then at callback i want to show dialog B under certain cases there comes a problem.I have to write an extra function for DoSomething in order not to duplicate.And i loose all the other local variables..The problem is bigger when more levels are required..
showDialog(A, (cb)=>{
if(...) {
showDialog(B,(cb2)=>{
DoSomething();
});
}
else{
DoSomething();
}
});
Also because i wanted to show one dialog at a time i extended Collection.OneActive . But this had problem too. In deactivate event callback i couldnt close all if i wanted to! Because it keeps in memory the next reference after Deactivated is triggered and even if you clear it it comes again..
How about using a class to track state information as you move between dialogs, rather than nesting closures as shown in your original example?
I think you're on the right track, but it seems like you have two problems:
The amount of nesting that you're doing is not good for code clarity.
You need a better way to capture local variables and state information between dialogs.
To solve the first problem, I'd recommend breaking apart your logic into different methods. Every time a dialog is deactivated, you could have a method to handle the logic that should be executed afterward.
To solve the second problem, you might try creating a class that is responsible for storing the information that you want to pass between dialogs. An instance of this class could be passed in as an argument into each method that is to be executed upon dialog deactivation.
Here's how you could accomplish this:
Conductor Class
public class DialogTestsViewModel : Conductor<object>.Collection.OneActive
{
/// <summary>
/// Shows a dialog and executes its callback if necessary.
/// </summary>
/// <param name="dialogModel">The dialog view model to be shown.</param>
/// <param name="callback">The callback to be executed when dialog is closed.</param>
public void ShowDialog(IScreen dialogModel, Action callback = null)
{
// Show the dialog.
ActivateItem(dialogModel);
// If there is a callback, call it when dialog is closed / deactivated.
if (callback == null) return;
dialogModel.Deactivated += (sender, args) => callback();
}
/// <summary>
/// This method kicks off the dialog chain.
/// </summary>
public void ShowFirstDialog()
{
// Create a new context. This will hold state information
// as it is passed between dialogs.
var context = new TestDialogContext();
// Create the first dialog's view model.
var viewModel = new FirstDialogViewModel();
// Show the first dialog.
ShowDialog(viewModel, () => OnFirstDialogDeactivated(viewModel, context));
}
/// <summary>
/// Logic to be executed when the first dialog is closed.
/// </summary>
/// <param name="viewModel">The first dialog's view model.</param>
/// <param name="context">The state information.</param>
private void OnFirstDialogDeactivated(FirstDialogViewModel viewModel, TestDialogContext context)
{
// Check the view model here and store state information inside the context.
if (viewModel.SomethingIsChecked)
{
context.ShouldShowSecondDialog = true;
}
// Use information in the view model or the context to decide if we should show the next dialog.
// You could also make a decision about which dialog to show next here.
if (context.ShouldShowSecondDialog)
{
var secondDialog = new SecondDialogViewModel();
ShowDialog(secondDialog, () => OnSecondDialogDeactivated(context));
}
}
/// <summary>
/// Logic to be executed when the second dialog is closed.
/// </summary>
/// <param name="context">The state information.</param>
private void OnSecondDialogDeactivated(TestDialogContext context)
{
// Do more stuff.
}
}
Dialog Context Class
Here is where you would store the state information that needed to be passed between dialogs. I've only included one property here as an example, but you could put a lot of info here.
/// <summary>
/// State information to be passed between dialogs.
/// </summary>
public class TestDialogContext
{
public bool ShouldShowSecondDialog { get; set; }
}

How to re-style WPF application when using lower resolution screen

I am developng a WPF application which will be used on a couple of different PC types. The first type is more of a development machine with dual hi-res monitors; the second is a hand-held touch screen about 800x600.
Using the MVVM pattern, I have developed some different Views which display more or less information depending on the chosen mode. In general, the layout scales well enough.
I also have some dialog boxes but at the moment these are optimised for the hi-res mode. Unfortunately the buttons appear very small on the touch screen and are difficult to hit reliably.
I was wondering how to restyle the dialogs dynamically. I would like to have one application setting which sets the screen type and thereby control styles. So for example, if the screen is a touch screen then all buttons and menus will have a larger default size.
Are Themes the way to go? If so, can someone point me at a good tutorial? (not just using existing themes but also creating them)
In the interest of changing styles, I do the following:
Create a style sheet for each type of theme I want.
Set all style references throughout my project to DynamicResource instead of "StaticResource".
Use manipulation of ResourceDictionaries.
In this example, I have themes for High, Medium, and Low quality. My style sheets paths are:
/Assets/Styles/GlobalStylesLow.xaml
/Assets/Styles/GlobalStylesMed.xaml
/Assets/Styles/GlobalStylesHigh.xaml
The code for the manipulation works like this:
/// <summary>
/// Level of graphics quality enum.
/// </summary>
public enum GraphicsQuality
{
/// <summary>
/// Low
/// </summary>
Low = 0,
/// <summary>
/// Medium
/// </summary>
Medium = 1,
/// <summary>
/// High
/// </summary>
High = 2
}
/// <summary>
/// Sets the Application Resource Dictionaries based on selection.
/// </summary>
/// <param name="quality">The quality.</param>
/// <param name="onRedraw">The on redraw.</param>
public static void UpdateStyles(
Enums.GraphicsQuality quality = Enums.GraphicsQuality.High, Action onRedraw = null)
{
// Reset resource dictionaries
Application.Current.Resources.MergedDictionaries.Clear();
// Base style path
const string basePath = "/<project_base>;component/Assets/Styles";
// Evaluate global quality
switch (quality)
{
case Enums.GraphicsQuality.High:
LoadStyle(basePath + "/GlobalStylesHigh.xaml");
break;
case Enums.GraphicsQuality.Medium:
LoadStyle(basePath + "/GlobalStylesMed.xaml");
break;
case Enums.GraphicsQuality.Low:
LoadStyle(basePath + "/GlobalStylesLow.xaml");
break;
}
// Redraw
if (onRedraw != null)
{
onRedraw();
}
}
/// <summary>
/// Loads a specific style by Uri.
/// </summary>
/// <param name="stylePath">The style path.</param>
private static void LoadStyle(string stylePath)
{
var dic = new ResourceDictionary
{
Source = new Uri(stylePath, UriKind.Relative)
};
Application.Current.Resources.MergedDictionaries.Add(dic);
}
When the condition exists to change your StyleSheet, call UpdateStyles.
Note:
The onRedraw parameter is simply a final action to perform after updating the style. In some cases, you may want to pass
this.InvalidateVisual
from the UI if you are having issues with the UI properly updating.

'System.Windows.Application' cannot run multiple times

This error ocurr when I call System.Application.Run(); in a WPF application. There is no other call to method Run(). Someone did see this?
Why would you need to call Run() manually? The framework does it for you if you have an Application derived object usually defined in a file called App.xaml.
If you go in your obj directory you'll find the auto generated file for the application object (file is called App.g.cs) and it has something similar to:
/// <summary>
/// App
/// </summary>
public partial class App : System.Windows.Application {
/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public void InitializeComponent() {
#line 4 "..\..\App.xaml"
this.StartupUri = new System.Uri("Window1.xaml", System.UriKind.Relative);
#line default
#line hidden
}
/// <summary>
/// Application Entry Point.
/// </summary>
[System.STAThreadAttribute()]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static void Main() {
gridsh.App app = new gridsh.App();
app.InitializeComponent();
app.Run();
}
}
Notice it defines a static main which has the call to Run.
No, if you didn't include another call to Run, maybe try deleting the file and recreating it...

Resources