Can not we initialize a Font for second time in VB.NET? - vb.net

I am making a 2D game in VB.NET. I use only one font object to draw strings on the form. This font is only needed in Game Menu. Therefore I dispose the font when it is not necessary and initialize it again when needed.
font_1 = New Font("Autobus Bold", 15.0)
When I use this font (font_1) to draw a string on the form, I get this error.
An unhandled exception of type 'System.ArgumentException' occurred in
System.Drawing.dll
Additional information: Parameter is not valid.
When I view the the font, it shows,
{Name = Reference to a non-shared member requires an object reference.
Size=15.0}
This error doesn't happen when the game menu is loaded for the first time (when font_1 is initialized for the first time). When the user plays the game, font is disposed. When user enters to Game Menu again, font is initialized again before it is used for drawing. When font is used for drawing a string on the window, this error happens.
It looks like error is only within the Font Family. I saw this question in few forums, but no one had given a solution. (This is my first question in a forum)
Edited : I removed the Font(font_1). But still I get the same error. Here is the code that draws the string.
Private Sub mcFramesHandler_TIMER_Tick(sender As Object, e As EventArgs) Handles mcFramesHandler_TIMER.Tick
gB.Clear(Color.Black)
gB.DrawImage(Background_IMG, 0, 0, 640, 480)
Select Case currentMode
Case GameMode.OnGame
If mcShoot_TIMER.Enabled Then gB.DrawImage(Bullet_IMG, Bullet_X, Bullet_Y, 20, 50)
If mcEneShoot_TIMER.Enabled Then gB.DrawImage(EneBullet_IMG, EneBullet_X, EneBullet_Y, 20, 50)
If Shooter_Lives Then gB.DrawImage(Shooter_IMG, Shooter_X, Bullet_Y_Def, 100, 105)
If mcMoveEnemy_TIMER.Enabled Then gB.DrawImage(Enemy_IMG, Enemy_X, 10, 100, 80)
If mcExplode_TMER.Enabled Then gB.DrawImage(Explotion_IMG, Explotion_X, Explotion_Y, 100, 80)
Case GameMode.Begining
gB.DrawString("Start", New Font("Autobus Bold", 15.0), textBrush(0), 110, 98) 'Error is generated in this line
gB.DrawString("Credits", New Font("Autobus Bold", 15.0), textBrush(1), 102, 158)
gB.DrawString("Exit", New Font("Autobus Bold", 15.0), textBrush(2), 114, 218)
End Select
Me.CreateGraphics.DrawImage(backbuffer, 0, 0, 640, 480)
End Sub
Here textBrudh(0) is a brush. gB is the Graphic object. gB successfully draws the background image before it draws the string. This happens only when Game Menu is displayed
Your support is really appreciated.

After you have finished to draw your things you need to dispose all objects around Graphics, not only the font but all (better with closure techniques like code below)
If you need a new instace of Graphics you can create this at the moment this is needed without using a Global object (when you work with Graphics).
Using gB As Graphics = Me.CreateGraphics
Using textBrush As Brush = Brushes.Black
Using font_1 As Font = New Font("Courier New", 15)
gB.DrawString("Start", font_1, textBrush, 400, 98)
'gB.DrawOtherthings()
'gB.DrawOtherthings()
'gB.DrawOtherthings()
'gB.DrawOtherthings()
'gB.DrawOtherthings()
'gB.DrawOtherthings()
'gB.DrawOtherthings()
'gB.DrawOtherthings()
'gB.DrawOtherthings()
End Using
End Using
End Using

Problem was with the brush (textBrush : an array of brush). When I dsipose each item in the array and re initialize, looks like something has happened to them (like they are not brushes anymore. See the error again. It says "Parameter is not valid"). So I just redim the array to 0.
Redim textBrush (0)
This clears previous items. Then I redim the array again initilizes each of them when needed.
Redim textBrush (2)
textBrush (0) = Brushes.Yellow
textBrush (1) = Brushes.Red
textBrush (2) = Brushes.Red
This array is used to change text color when up and down key is pressed.
I saw lot of people had mentioned this error in forums
{Name = Reference to a non-shared member requires an object reference. Size=15.0}
I don't what this name is, but it doesn't effect the programme. It is always like that in any Font.

Related

Drawing on an image before drawing on screen in XNA using VB.NET

I'm programming a game in XNA, using VB.NET. I want to create an intro to the game that zooms in/out the whole screen and scaling each image to accomplish this is cumbersome at best. I like to be able to draw a lot of .PNG's (or parts of them) onto a whole image, to then be able to manipulate (scale, turn etc) that whole image, before drawing it with the spriteBatch. The examples I can find use something like:
dim bitmap as New Bitmap
or
dim image as New Image
but these codes highlights the "Bitmap" or "Image" as red, and I cannot use them. I'd be thankful for any help on this issue!
SpriteBatch works with XNA Texture2D objects, whereas Bitmap and Image are System.Drawing types. They do not work together.
You can create a new RenderTarget2D, set it as active using GraphicsDevice.SetRenderTarget() and draw there using a SpriteBatch. You can then draw the stored render target to screen using a SpriteBatch, since render targets are a type of Texture2D.
So I've experimented with Petri Laarne's answer and finally come up with a workable code (most examples online are using C#, and doesn't explain the entire process). Trying to explain it here:
In Public Class Game1:
Private WithEvents graphics As GraphicsDeviceManager
Private WithEvents spriteBatch, spriteBatch2 As SpriteBatch
In Loadcontent:
Public render2 As RenderTarget2D
spriteBatch2 = New SpriteBatch(GraphicsDevice)
spriteBatch = New SpriteBatch(GraphicsDevice)
render2 = New RenderTarget2D(GraphicsDevice, 1024, 768)
In Draw:
spriteBatch2.GraphicsDevice.SetRenderTarget(render2)
GraphicsDevice.Clear(Color.Black)
srcRect = New Rectangle(440, 0, 440, 440) : destRect = New Rectangle(100, 335, 440, 440)
spriteBatch2.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend) : spriteBatch2.Draw(introNEWMirrorDecos, destRect, srcRect, Color.White) : spriteBatch2.End()
destRect = New Rectangle(300, 335, 440, 440)
spriteBatch2.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend) : spriteBatch2.Draw(introNEWMirrorDecos, destRect, srcRect, Color.White) : spriteBatch2.End()
spriteBatch2.GraphicsDevice.SetRenderTarget(Nothing)
GraphicsDevice.Clear(Color.Black)
destRect = New Rectangle(512, 384, 1024, 768) : srcRect = New Rectangle(0, 0, 1024, 768)
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend) : spriteBatch.Draw(render2, destRect, srcRect, Color.White, PI / 12, New Vector2(512, 384), SpriteEffects.None, 0) : spriteBatch.End()
This is an example code from the actual game that worked like it was intended: drawing 2 things on the alternate rendering image and then drawing them as one single image (in this case being able to rotate it by pi/12).
Any comments on how to do this differently or more efficient is appreciated, and thank's for the initial answer #Petri Laarne

How to Draw above a picture in VB.NET

I am building a 2D game where the user is a circle(:P) and the enemies are rectangles coming at him. However, my problem is that when I placed a very nice picture of space I found on the internet, the screen draws whatever it has to underneath this image. Everything works,I can still see my lives going down when something collides into me - except the fact it is all covered up by this picture.
In a nutshell, my question is: How Do I Draw everything ON Top of this - (I tried using the 'Send To Back' Command)
EDIT: The form draws everything through a timer, and the user controls his character through keys. This probably won't help - but if it does it's here.
Sorry folks didn't think you'd need the code. Here it is:
In the mybase.load procedure:
PicBackGround.Dock = DockStyle.Fill
PicBackGround is the picture box with the image.
In the paint procedure:
e.Graphics.Clear(Color.Black)
e.Graphics.FillEllipse(Brushes.Orange, Player)
'Projectiles
Dim i As Integer = 0
Do
If Current_Projectile(i).IsEmpty = False Then e.Graphics.FillRectangle(Brushes.Red, Current_Projectile(i))
i += 1
Loop Until i = UBound(Current_Projectile)
'Objects
i = 0
Do
If Objects(i).IsEmpty = False Then e.Graphics.FillRectangle(Brushes.Blue, Objects(i))
i += 1
Loop Until i = UBound(Objects)
Okay: Player is a rectangle declared right at the top, Dim Player As New Rectangle(0, 0, 50, 50);
There is then the array Objects, which stores all the data about the enemies coming at the player, Current_Projectiles is simply an array to store data about rectangles(bullets) that the player fires.
Anything else you want to know just let me know.
Yes, a control overlaps anything you draw on the form. A simple solution is to use the form's BackgroundImage property instead. Or draw the image yourself.

I've increased the size of image in picture box but now I want to take it back to its original size

I am working with vb.net and want to increase the size of image when the cursor is over that image, but the image should come back to its original size when the cursor leaves that image area.
I've used the following code to increase the size of image:
Private Sub PictureBox1_MouseHover(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.MouseHover
PictureBox1.Size = New Size(300, 250)
End Sub
I've used the default size class but, it gives some different dimensions.
Please guide me by the code that brings the image into its original size that I've been declared into the picture box properties.
You should probably be hooking in to the MouseEnter and MouseLeave events. Links for MSDN reference
Here's the code that will resize the PictureBox to the dimensions of the image:
PictureBox1.Size = PictureBox1.Image.Size
Assuming that the original size of the PictureBox was the image size, then that'll work just fine.
As kaveman suggested, MouseEnter and MouseLeave would be much better events to put the code in ;-)
In order to restore the custom size you've set it to, you'll need some code like this: (make sure its somewhere which won't go out of scope, like in the form, outside of methods)
You'll need a variable to store the original size:
Dim OriginalSize as Size
Then, before changing the size when the user moves the mouse over the image, store the size in the variable: (put this in the MouseEnter event)
OriginalSize = PictureBox1.Size
PictureBox1.Size = New Size(300, 250)
Restoring that size is a simple matter of putting that variable back into the picturebox size: (this goes in the MouseLeave event)
PictureBox1.Size = OriginalSize
=)

VB.NET custom user control graphics rotation

this is my first question on here.
I'm trying to build a dial control as a custom user control in VB.NET. I'm using VS2008.
so far I have managed to rotate image using graphics.rotatetransform . however, this rotate everything. Now I have a Bitmap for the dial which should stay stable and another Bitmap for the needle which I need to rotate.
so far i've tried this:
Dim gL As Graphics = Graphics.FromImage(bmpLongNeedle)
gL.TranslateTransform(bmpLongNeedle.Width / 2, bmpLongNeedle.Height * 0.74)
gL.RotateTransform(angleLongNeedle)
gL.TranslateTransform(-bmpLongNeedle.Width / 2, -bmpLongNeedle.Height * 0.74)
gL.DrawImage(bmpLongNeedle, 0, 0)
As I understand it, the image of the needle should be rotated at angle "angleLongNeedle" although i'm placing the rotated image at 0,0. However, the result is that the Needle doesn't get drawn on the control.
any pointers as to where I might be going wrong or something else I should be doing?
Thanks in advance
First of all, why do you allocate the Graphics object from a bitmap that you then proceed to draw onto the graphics? That doesn’t make sense.
Dim gL As Graphics = Graphics.FromImage(bmpLongNeedle)
' … '
gL.DrawImage(bmpLongNeedle, 0, 0)
What you probably want is a graphics context for the whole image. You then apply the transformations to it and finally draw the bmpLongNeedle image.
Secondly, your translations look inversed: in the first step, you need to move the image to the origin (0, 0); then you rotate it, and then move it back. So the transformation should look like this:
gL.TranslateTransform(-bmpLongNeedle.Width * 0.5, -bmpLongNeedle.Height * 0.5)
gL.RotateTransform(angleLongNeedle)
gL.TranslateTransform(bmpLongNeedle.Width * 0.5, bmpLongNeedle.Height * 0.5)
Notice the inversed order of the TranslateTransforms. Also, why did you translate by 0.74 times the height, instead of half?
oh the bitmap for needle has the pivot point at 0.74 * height.
may be I should have posted this before. but this is what i've done.
Public Class Altimeter
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Dim bmpBezel As New Bitmap("{path}\Altimeter_Background.bmp")
Dim bmpLongNeedle As New Bitmap("{path}\LongNeedle.bmp")
Dim rect2 As New Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width, e.ClipRectangle.Height)
'make transparent
bmpBezel.MakeTransparent(Color.Yellow)
bmpLongNeedle.MakeTransparent(Color.Yellow)
Dim angleLongNeedle As Single = (Altitude / 50) * 360
'draw bezel
e.Graphics.DrawImage(bmpBezel, rect2)
'rotate long needle
Dim gL As Graphics = Graphics.FromImage(bmpLongNeedle)
gL.TranslateTransform(bmpLongNeedle.Width / 2, bmpLongNeedle.Height * 0.74)
gL.RotateTransform(angleLongNeedle)
gL.TranslateTransform(-bmpLongNeedle.Width / 2, -bmpLongNeedle.Height * 0.74)
gL.DrawImage(bmpLongNeedle, 0, 0)
MyBase.OnPaint(e)
End Sub
i use e.graphics.drawimage to paint the whole image. i don't really understand what you said about having graphics object for all the images and then drawing the needle? do you have any pseudo code?
thanks

vb.net code to make a image transparent

I wish to make a bitmap image (.bmp) transparent using VB.NET code. Kindly help me.
I found the key was using the imageAttributes class. Basically set the color key to the color you are using to represent the transparent area, and use one of the drawImage calls that accepts an imageAttribute parameter...
Imports System.Drawing.Imaging
' and in a sub somewhere:
Private mImageAttributes As New ImageAttributes
mImageAttributes.SetColorKey(Color.FromArgb(0, 220, 20, 255),
Color.FromArgb(0, 220, 20, 255))
Dim imageRectangle As New Rectangle(pX, pY, pBitmap.Width, pBitmap.Height)
e.Graphics.DrawImage(pBitmap, imageRectangle, 0, 0, pBitmap.Width, pBitmap.Height,
GraphicsUnit.Pixel, mImageAttributes)
VS 2012
Dim watermark_bm2 As Bitmap = 'someimage(from file or global resource)
watermark_bm2.MakeTransparent()
This msdn article gives full details on how to do this
Here is another article, but code sample is in c#