-
XNA Help (Once Again)
I have realised that when using XNA to draw graphics, If I add labels to the form then everything gets screwed up.
Basically what i wanted to do is have two labels:
First Label:
"10"
Second Label:
"Moves Left"
And as a block is used in my game, decrease the number 10 by 1.
Should I be using images and XNA to draw these as well or is there any other ways?
Thanks again for all the help :D
-
Re: XNA Help (Once Again)
You call it via a SpriteBatch object in your Render function:
Code:
mySpriteBatch.Draw(WriteText("My Text", New Font("Arial", 16, FontStyle.Bold), Brushes.White, New Bitmap(200, 75), myDevice), New Vector2(150, 50), Color.White)
The coordinates in your Vector2 are your X and Y coordinates. The Bitmap coordinates are the size of your text field. Adjust as needed.
Whatever your Device is goes into myDevice.
By the way, how's your game coming along? Making progress with the XNA? :)
-
Re: XNA Help (Once Again)
Ok cool ill give that a shot. When it comes to changing the number displayed would I use an integer variable instead of "My Text" and just modify the variable and convert it to a string when drawing it. Like this:
Code:
Public MoveCount as Integer = 10
Code:
mySpriteBatch.Draw(WriteText(CStr(MoveCount), New Font("Arial", 16, FontStyle.Bold), Brushes.White, New Bitmap(200, 75), myDevice), New Vector2(150, 50), Color.White)
-------------------------------------------------------------------------------------
Game is going good nearly finished the first level and the rest of the levels will just be a case of tweaking the level one code. I think i'm getting the hang of XNA just getting to grips with actually creating games as the only games i've created so far is one just using picture boxes which is just a maze game where you move an object through the maze using the mouse and the other being a tetris game using gdi+.
When games up and running will post it in demo forums :)
Thanks again for the help
-
Re: XNA Help (Once Again)
Another thing I was going to ask also is about making a menu. How do you draw graphics that can be clicked to execute code?
-
Re: XNA Help (Once Again)
You know, I haven't really explored mouse-sensitive regions in XNA. If there isn't anything built in, it would just be a matter of reading the mouse position when the user clicks and seeing if it's over any "menu items" and displaying the menus as normally via your render loop.
That render loop can get pretty darned complex. Lots of If-Thens sometimes to break it up.
-
Re: XNA Help (Once Again)
When I use the code you supplied i'm getting an error that says "Write Text is not declared
"
Any Suggestions?
-
Re: XNA Help (Once Again)
Aww dammit. Sorry, I just realized that was a local function I wrote:
Code:
Public Function WriteText(ByVal str As String, ByVal NewFont As Font, ByVal StringColour As Brush, ByRef [BitMap] As Bitmap, ByRef d As GraphicsDevice) As Texture2D
Using Graph As Graphics = System.Drawing.Graphics.FromImage(BitMap)
Graph.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit
Graph.DrawString(str, NewFont, StringColour, 0, 0)
End Using
Dim MemStream As System.IO.MemoryStream = New System.IO.MemoryStream
BitMap.Save(MemStream, System.Drawing.Imaging.ImageFormat.Png)
MemStream.Position = 0
Return Texture2D.FromFile(d, MemStream)
End Function
That combined with the sample above will do what you want it to. Drawing fonts is one of those oddball things that they only implemented easilly if you're using C#, where you can just add a font to your project and convert it to some form of "texture-font" and use it with a function.
-
Re: XNA Help (Once Again)
-
2 Attachment(s)
Re: XNA Help (Once Again)
I'm having some slight problems with my game. I have been through it using breakpoints and I just cant work out what's going wrong. I have have attached my project to this post. I don't expect you to take a look at it but have attached just in case you are up for it.
I have also attached an image. Basically the aim of the game is to get three of the same colour blocks in a row horizontally or vertically and clear all blocks with a set amount of moves. If I do it in the correct order it works fine but if i shoot the blocks as in the attached image its not picking up the win. Its just getting rid of the block you shoot and not the two above it. :confused:
-
Re: XNA Help (Once Again)
I'll take a look at your code when I get a free spot today.
-
Re: XNA Help (Once Again)
You have any luck with the code? I still can't work it out
-
Re: XNA Help (Once Again)
I have noticed while debugging this that when I shoot the last block in the above image the two blocks above's position in the array are set to nothing but are still being rendered to the screen. I can't really understand how its rendering them if there's nothing there.
It doesn't do this if I just shoot the blocks in the right order it gets rid of them?
-
Re: XNA Help (Once Again)
I did take a crack at your code, first by converting your Form to an actual Game object and moving your code over.
The biggest problem I see in your code is your arrays are divided between storing positional X/Y information for drawing and status X/Y information on a 10x15 grid. First thing I'd do (and when I started organizing your code, this helped a lot) was get rid of all your pixel locations of objects everywhere except the render loop. Your Block objects for example shouldn't have ANY positional or size information in them if you're using a grid. All they need is what color they are. All the game needs to know is "A Red Block is at position 1,2 on the game grid".
Here's the basics of hor your game should perform:
Logic routine: Only work with a grid of 10x15. Figure out what color block is in which cell. Your Shooter Block is handled here. When the player moves left, then move it left on the grid +1. When "shot", then do your figuring to find the first empty cell in it's column and move that Block to that position. It also checks to see if there's a removal condition (you got 3 or more in a row of the same color) and/or a game win/loss condition.
The Render Loop: This has one purpose, take the grid of 10x15 block colors, and draw them. This is the only place in your code that should worry about the blocks being 25x25, or the game board offset being 515 pixels left, etc... The purpose is simple, if I say there is a "Red Block at position 1,2 on the game grid", then it's job is to take a red block sprite, offset it A and B so it's not being drawn at the top-left corner of the screen, calculate it's real pixel X,Y position (A+X*25, B+Y*25) and draw it.
-
Re: XNA Help (Once Again)
Ok thanks a lot, do you by any chance have the project you have modified?
-
1 Attachment(s)
Re: XNA Help (Once Again)
Actually, I've done one better. I was bored so I completed it. It's fully functional with animation, level-loading system, key-repeat, checks for win condition, etc.
I'm attaching it here: Attachment 72346
Pick it apart and see what I did.
Personally, I'm not the happiest I could be with it, but just like you, I am still learning XNA. I like how I did some of the routines, especially the animation and keyboard input, but other parts of it I feel could be done more elegantly given time.
Anyways, I toss the ball back in your court to expand upon it and really make this little game of yours shine. You know where to find me if you got any more questions. :)
-
Re: XNA Help (Once Again)
Thanks a lot appreciate all the help. I've had a look through your project and the way your'e handling the block movements is far more effective that the way i was doing it so have implemented this into mine. I also like the way the levels are set up as it will be far quicker to create the text files than the way i was going about it.
There is some stuff i don't understand such as using a game object instead of the form and the use of gametime so think i will leave that at the moment and look for some tutorials on it at some point.
-
Re: XNA Help (Once Again)
Using GameTime is one of those oddball things when writing games that seems really weird at first but eventually you get used to. Basically, GameTime is a number that constantly counts upwards telling you how many milliseconds or whatnot have passed since you engaged the Game object. If you want to time things in a game, you simply mark the time when you want to start something like an animation, or a delay, and every time the game loop comes back around, check if it's XX milliseconds later than the time you marked.
Game programmers do this because it's massively more efficient than setting up a bunch of timers, which are resource hogs. Think of GameTime as a single permanent timer that you have to manually set and check for everything that you're doing. Thus, if you got 35 things on the screen animating at once, all you need to do is check a list of 35 start-times vs. the current time to time them all rather than a nightmare of 35 timers which are resource hogs.
The Game object is the ultimate in simplified game design. First off, the concept of any "game" is a program that runs in a loop and cycles that loop at least 30 times a second. Every cycle of that loop, it updates the screen. We don't need to do complex stuff like AI though in that render loop, so we got a secondary loop that handles that. The two loops work independent of each other.
The XNA Game object has these two loops in the Update() function (your logic loop) and the Draw() function (your render loop). The Update() function is called every second or so like a heartbeat. The Draw() function is called whenever it's needed to update the screen (like 60x a second). It has other features as well, but these two alone are worth using it since you can stack all your game logic in the update loop and all your graphics drawing in the render loop and not have to worry about timing or synchronization.
-
Re: XNA Help (Once Again)
Do you know for any tutorials on using game time? I'm a bit confused by what you have done in the project can't get my head around it.
-
Re: XNA Help (Once Again)
Not really I'm afraid. Basically, what I'm doing in the key-repeat thing is making a little lock-out class that holds the time when the original key was pressed and which key it was.
I'm doing something similar to control the animation and events.
I then stack any new lock-out classes to a list and check the list next pass to see if the new gametime is some amount greater than the original recorded value.
Gametime is just a number that climbs higher and higher as the game plays on. You use it however you feel fit. Your Update and Draw functions will always know what the current Gametime number is, and thus, you can compare it to a recorded value and get the difference between the two. Since Update and Draw are called several times a second, this is pretty beneficial.
-
Re: XNA Help (Once Again)
Ok cool all i basically wanted to do is have the delay before the blocks dissapear like you had on the one you modified but i don't really like using code if i know i dont understand it. If possible would you be able to add comments on the project just to the parts that control this delay so i can have another crack at understanding it.
Games almost finished now have one more level to come up with and just have to convert the form to a game object then but that's just a case of copying over the code so should be finished tommorow.
Thanks again for all the help
-
Re: XNA Help (Once Again)
This should explain things better.
Code:
Protected Overrides Sub Update(ByVal gameTime As Microsoft.Xna.Framework.GameTime)
'The Update function of a Game object is called once a second.
'frameNumber is used for timing. We count the time between frames.
frameNumber += 1
'Reset it to zero if it gets too big, don't want to blow max int.
If frameNumber = UInteger.MaxValue Then frameNumber = 0
'Read and process the keys.
'Get the current state of the keyboard. This gets all the keys pressed.
Dim pressed_Key() As Input.Keys = Input.Keyboard.GetState.GetPressedKeys
Dim k As Integer = 0
'Process all the keys it finds in the list of pressed keys. Looking back over this
'loop, I could have used For Each k As Key In pressed_Key, but this part came from
'an older game I wrote and I just copy-pasted it.
Do While (k < pressed_Key.Length)
'In the global section of this game object, we set up a dictionary that will
'contain lock-objects. Lockobjects are just simple dataholder objects that
'record the time when they were created and the framenumber they were created
'on. This next part will add a new lockobject to the dictionary if one doesn't
'already exist.
If Not key2KeyPress.ContainsKey(pressed_Key(k)) Then
key2KeyPress.Add(pressed_Key(k), New FrameLock(frameNumber))
End If
'Get the lockobject for the key we are looking at in the loop.
Dim pk As FrameLock = key2KeyPress(pressed_Key(k))
'First check to see if this is the NEXT run through Update() after I set a
'lockobject on a key. This is important for the delay effect because the ONLY time
'it's going to pick up keys that were updated LAST frame is if the key is still
'being held down.
If ((pk.frameLocked + 1) = frameNumber) Then
'If it is, add the elapsed time that has passed since the last Update()
'call to the recorded time in the lockobject.
pk.time += gameTime.ElapsedRealTime
'Set the lockobjects frame to the current one. This is so we can process this
'on the NEXT frame as well if the key is STILL held down!
pk.frameLocked = frameNumber
'Here's our delay. If the total time that has passed since the lockobject's
'setup is more than 400ms, then process the key press, otherwise, do nothing.
If (pk.time.Milliseconds > 400) Then
PressKey(pressed_Key(k))
End If
Else
'So what happens if this is on any other run through Update as the lockobject was
'created? We need to immediately process the keypress without delay! If this is a
'brand new lockobject created in that "If Not key2KeyPress..." line above, then this
'will be a case. If the key was let up, and then re-pressed down, then it's lockobject
'also won't have the last-frame recorded! It'll have some older one. Thus, I'm resetting
'that key's lockobject by resetting the objects time and frameLocked values.
pk.time = TimeSpan.Zero
pk.frameLocked = frameNumber
PressKey(pressed_Key(k))
End If
k += 1
Loop
'So, when I press a key for te very first time in my program, it makes a lockobject for that key and
'adds it to my key2KeyPress dictionary.
'It gets to the If statement. The current frame does not equal the lockedframe plus one, so, I skip
'to the Else clause and set my initial values and process the first Keypress.
'Next pass through Update(). I'm one frame higher. I hit the big If-Else statement again. This time
'I AM one frame higher than my last pass because I have the key held down, so it records the elapsed time
'and gets to that second If. Oh, the elapsed time has only been 143ms or something. It's not >400, do
'nothing.
'NEXT pass through Update(), key is still held down, it enters that first If case again because I reset the
'framenumber to the one from last pass. Go again. Add more time. Do the check... no, only 290ms passed...
'NEXT pass... 371ms, still do nothing
'NEXT pass... the user is STILL holding the key, but this time, the elapsed time is > 400! Process another
'keystroke!
'NEXT pass... key is STILL held down, and the time is > 400ms still. Another keystroke. At this point, the
'rapid-fire is turned on.
'NEXT pass... the key is no longer held down. It's not part of pressed_Key() so it's lockobject doesn't get touched.
'after maybe a few dozen more Update passes... the key is pressed again! It's framenumber recorded in the lockobject
'is old! It's frame 1400 and it's now on frame number 1480; that's 80 Updates later since it last processed
'that key. The If-Else statement jumps to the Else part and resets the lockobject for the current frame and
'processes that initial keystroke... and the cycle happens again.
-
Re: XNA Help (Once Again)
Cool, thanks a lot that clears it up.
I'm having a slight problem with this though and i'm not sure how to fix it.
When I complete a level, sometimes when the next level has loaded it's automatically shooting a block???
-
Re: XNA Help (Once Again)
Sorry have sorted problem now i didn't add mybase.update as the end.
Thanks
-
Re: XNA Help (Once Again)
I have one last question for you. Game is pretty much finished now but there's one more feature i wanted to add. When the blocks are cleared rather than have them just disapear I wanted them to flash maybe once or twice and then disapear but i'm not sure how to go about this.
-
Re: XNA Help (Once Again)
I haven't really followed this thread, but couldn't you just have an "illuminated" sprite and draw it over the previous sprite to create the flashing effect?
-
Re: XNA Help (Once Again)
So you basically mean have two different states for the texture and alternate between them to create the flashing effect?
-
Re: XNA Help (Once Again)
Correct. I am using a similar effect in a game I'm making where the player spins around and walks. You could use the game timer to control the speed of the flash before it disappears.
-
Re: XNA Help (Once Again)
Ok cool. my game is made up of blocks which are all held in a 2d array. Would i just change the textures for the specific blocks that will be flashing?
-
Re: XNA Help (Once Again)
That is essentially what I am proposing, yes.
-
Re: XNA Help (Once Again)
Ok i'm still getting confused with this. The part I can't grasp i's when to change the textures and how to get the time intervals
-
Re: XNA Help (Once Again)
Well I can't tell you too much without your code, but what you could do, is when a block is destroyed, grab the current game time.
Then, every 100ms or so after that make it flash until it disappears after 500ms or something.
-
Re: XNA Help (Once Again)
Ok I have attached project here if you wanna take a look. I am on the verge of giving up on this as everything I try to do just doesn't work for me
Project File
-
Re: XNA Help (Once Again)
You got the basics just fine. Love what you've done with it though.
I re-wrote your CheckWin functions to a single one that checks for a winning condition and flashs and removes the blocks. It could probably be split into two separate functions, one to check for a match, the other to do the actual flash/remove, but it works.
The vertical and horizontal had to be combined into one though because you can have composite-win situations.
Attached is a link to where you can download the project. After you replace the Microsoft.Xna library references (because I think I'm running an older version of XNA), everything should be apparent.
Revised Project File
-
Re: XNA Help (Once Again)
Ok thanks a lot have now added that. At the moment i have left it to jest check the horizontal and vertical wins as all the levels are set up to be completed with just these but if I make Block Smash 2 then that's a feature i can add.
Just gotta decide on what sound effects to use now, think the explosion is a bit to aggressive need to find some more arcade style effects.
Game should all be done tomorrow so will be posting on game demos. Will post link for you to check it out.
Thanks again for all the help
-
1 Attachment(s)
Re: XNA Help (Once Again)
Ok I knew I would have one last problem. I have published game and installed it. When running the game I get an error as shown in the below image. Any ideas?
-
Re: XNA Help (Once Again)
That's a generic unhandled exception error.
Does the game run at all?
-
Re: XNA Help (Once Again)
No it just brings that up and closes
-
Re: XNA Help (Once Again)
Do you think it is because i'm using vb express and the click once publishing method?
-
Re: XNA Help (Once Again)
Ah! Absolutely. You need to make sure the XNA runtime files are installed on the target machine. I don't think the pathetic excuse of an installer Click Once can handle this prerequisite.
Basically, from a clean-clean install, you need:
.NET Framework
XNA Redistributable
DirectX
Your Game
The Setup Projects in VS Pro can handle these with a large amount of prodding and poking, but I'd actually seriously look at something like Inno installer for XNA games. It's mega-powerful and it's free.
-
Re: XNA Help (Once Again)
Ok cool is there any tutorials you know of on how to use this software?
I also bumped into a slight problem with my game and can't figure it out. Basically when the level is completed before the next level is loaded it is detecting that all the moves have been used so is displaying the no moves left text. I have posted project if you wanna take a look.
Project
Sorry to trouble you again.