School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become an Expert!

Join 307,116 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 2,008 people online right now. Registration is fast and FREE... Join Now!




XNA C# problem

 

XNA C# problem, Not sure of the cause, don't know where to start looking for a sol

Leora

26 Oct, 2009 - 08:59 AM
Post #1

New D.I.C Head
*

Joined: 19 Sep, 2009
Posts: 2


My Contributions
Hi, bit of a newbie to these forums, so apologies if I do something wrong. :x I've tried searching all over for a solution, but as I'm not sure what's causing my problem I don't really know what to look for!
I'm a student, and I'm used to java, this is the first class we've used C# or any type of programming with graphics and stuff (normally we're just in a linux console, so it's all text based), so I've been sort of learning as I go (so my code's probably pretty terrible). I'm also a bit sleep deprived, so sorry if I'm making no sense! tongue.gif

Anyway, I'm currently making a prototype, the purpose is to test a conversation. The player is given two options, chooses one and gets a response. (If we continued and put it in our theoretical game, it'd give different options based on a certain condition, and certain responses would effect that condition... there'd also be more than one choice made and response given.

So, my problem: the choices are displayed on screen (I'll refer to this as the first lot of text), I press one of the buttons to make a choice, the text blinks briefly (changes to the response, too quickly to see it properly) and returns back to the first lot of text.
Before this, I had the response showing up on top of the first lot of text (they were both on the screen at the same time. Before that I had included the code to effect the condition that changes the available choices, and pressing a button to make a choice made it keep choosing the same choice until the value associated with the available choices got high enough to change them, all in a matter of seconds. I think I figured out how to fix this, but I had to take out the code effecting the condition and gave me new problems.

Anyway, here's my code:
Main class:

CODE

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Prototype
{  
    public class Main : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        SpriteFont font;
        Texture2D background;
        Rectangle mainFrame;
        talk talk;
        Vector2 fontPos;

        public Main()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        { base.Initialize(); }

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            background = Content.Load<Texture2D>("background");
            mainFrame = new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);
            talk = new talk(this);
            font = Content.Load<SpriteFont>("Miramo");
            fontPos = new Vector2(GraphicsDevice.Viewport.Width / 8, GraphicsDevice.Viewport.Height - 100);
        }

        
        protected override void UnloadContent(){ }

        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            //talk.Update(gameTime);
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            talk.HandleInput();
            GraphicsDevice.Clear(Color.Black);
            spriteBatch.Begin();
            spriteBatch.Draw(background, mainFrame, Color.White);
            DrawText();
            spriteBatch.End();          
            base.Draw(gameTime);
        }

        protected void DrawText()
        {
            string toDraw = talk.getOutput();
            Vector2 fontOrigin = font.MeasureString(talk.getGreeting()) / 2;
            spriteBatch.DrawString(font, toDraw, fontPos, Color.White, 0, fontOrigin, 1.0f, SpriteEffects.None, 0.5f);
            
        }}}

'Talk' class:
CODE

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace Prototype
{
    public class talk : Microsoft.Xna.Framework.GameComponent
    {      
        //placeholders for conversation choices and responses
        string C1 = "1. <Choice 1>";
        string C2 = "2. <Choice 2>";
        string C3 = "1. <Choice 3>";
        string C4 = "2. <Choice 4>";
        string C5 = "1. <Choice 5>";
        string C6 = "2. <Choice 6>";
        string R1 = "<Response 1>";
        string R2 = "<Response 2>";
        string R3 = "<Response 3>";
        string R4 = "<Response 4>";
        string R5 = "<Response 5>";
        string R6 = "<Response 6>";
        string greet = "<Greeting>";

        int stress = 0;  //for testing, normally wont be a hardcoded number

        string output;
        
        bool choiceMade = false; //to stop the seemingly constant loop of input

        KeyboardState oldState;

        public talk(Main game) : base(game)
        { }

        public override void Initialize()
        {
            base.Initialize();
            oldState = Keyboard.GetState();
        }

        public override void Update(GameTime gameTime)
        {
            HandleInput();//gameTime);  Commented out the gameTime to see if it helped... it didn't, left it out anyway
            
            base.Update(gameTime);
        }

        public void HandleInput()//GameTime gameTime)   //also tried just calling HandleInput from the main
                                                                                  //class...   didn't help
        {
            
            KeyboardState keyState = Keyboard.GetState();
            keyState = Keyboard.GetState(PlayerIndex.One);

            if (stress >= 0 && stress <= 45)
            {
                output = greet + "\n" + C1 + "\n" + C2;
                if (keyState.IsKeyDown(Keys.D1))
                {
                    if (!oldState.IsKeyDown(Keys.D1))
                    {
                        output = R1;
                        choiceMade = true;
                        oldState = keyState;
                    }
                }
                else if (keyState.IsKeyDown(Keys.D2))
                {
                    if (!oldState.IsKeyDown(Keys.D2))
                    {
                        output = R2;
                        choiceMade = true;
                        //stress += 5;
                        oldState = keyState;
                    }
                }      
            }
            else if (stress > 45 && stress <= 75)
            {
                output = greet + "\n" + C3 + "\n" + C4;
                if (keyState.IsKeyDown(Keys.D1))
                {
                    output = R3;
                    choiceMade = true;
                    //stress += 3;
                }
                else if (keyState.IsKeyDown(Keys.D2))
                {
                    output = R4;
                    choiceMade = true;
                    //stress += 10;
                }
            }
            else
            {
                output = greet + "\n" + C5 + "\n" + C6;
                if (keyState.IsKeyDown(Keys.D1))
                {
                    output = R5;
                    choiceMade = true;
                    //stress += 20;
                    //if (stress >= 100)
                    //{
                    //    //code for stress max event would go here
                    //}
                }
                else if (keyState.IsKeyDown(Keys.D2))
                {
                    output = R6;
                    choiceMade = true;
                    //stress += 10;
                    //if (stress >= 100)
                    //{
                    //    //as above
                    //}
                }
            }                          
        }

        public string getOutput()
        {
            return output;
        }

        public string getGreeting()
        {
            return greet;
        }

        public bool getChoiceMade()
        {
            return choiceMade;
        }}}


Anyone have any idea what's causing my problem? I've been leading towards something to do with Update/game time, but I don't really get how it works (they didn't actually bother teaching us XNA properly... gave us step by step instructions to make a (pretty bad) space invaders clone, then told us to make our own original games. And this is a first year subject! tongue.gif
Anyway, help would be appreciated! Even if you just tell me what to start looking for... I'm completely stuck!

Thanks smile.gif


User is offlineProfile CardPM
+Quote Post


SixOfEleven

RE: XNA C# Problem

26 Oct, 2009 - 04:33 PM
Post #2

lives.ToCode();
Group Icon

Joined: 18 Oct, 2008
Posts: 3,066



Thanked: 170 times
Dream Kudos: 775
Expert In: C, C#, XNA, Game Programming, Programming Concepts

My Contributions
Since you are using a GameComponent I would suggest doing one of two things. Add talk to the list of GameComponents or call the Update method of talk instead of the HandleInput method. You should never call a method that will update an object in the Draw method, always do it in the Update method.

CODE

Compents.Add(talk);


or

CODE

        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            talk.Update(gameTime);
            base.Update(gameTime);
        }


What you are trying to do here is manage the state of a game. State management can be a complicated topic in a game. You could handle the state in the Update method of the Talk class.

In your Update method in the Talk class you could use the choiceMade variable and a TimeSpan variable to control how long the response will stay on the screen. You could try something like this.

CODE

TimeSpan nextResponse = TimeSpan.Zero; // Class level variable

        public override void Update(GameTime gameTime)
        {
            if (!choiceMade)
                HandleInput();
            else if (choiceMade && nextResponse < TimeSpan.FromSeconds(2))
            {
                nextResponse += gameTime.ElapsedGameTime;
            }
            else
            {
                choiceMade = false;
                nextResponse = TimeSpan.Zero;
            }
          
            base.Update(gameTime);
        }


Basically what that does is if a choice has not been made it asks the player for input. If a choice has been made and less than 2 seconds have elapsed since the choice was made it increments the time since a response was made. Finally if a choice has been made and more than 2 seconds have elapsed it says that you can move on to making a new choice and set the time of the last response back to 0 seconds. Now, in the else clause you could call a method that would take the last response and ask a new question based on the response. Hope that helps a little.
User is offlineProfile CardPM
+Quote Post

Leora

RE: XNA C# Problem

26 Oct, 2009 - 04:58 PM
Post #3

New D.I.C Head
*

Joined: 19 Sep, 2009
Posts: 2


My Contributions
Thanks. I thought it might have something to do with timing, but I had no idea how to test it, or what to do about it (we really weren't taught much of anything at all, and our textbooks are only about game design & development, not coding). That's why I tried moving the call to talk into the draw method instead of the update method... It made no difference, I just didn't remember to move it back. tongue.gif
As this is just a prototype, I'm only testing making one choice and getting a response, so the response pretty much just needs to stay on the screen until you close the window... I'll try fiddling, see what happens (and what you posted will be really handy if we have the time to actually do this properly!).

Thanks again! smile.gif

Edit: Woo! Thank you so much! All it took was putting the if (!choiceMade) statement in the update method of talk... and it works! Always simple, stupid things like that that get me, every time!
Thank you so much! smile.gif



This post has been edited by Leora: 26 Oct, 2009 - 05:37 PM
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic

Time is now: 11/21/09 01:24PM

Live Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month