Alternating Images
Alternating Images
Alternating Images
Alternating Images
Alternating Images
Alternating Images Alternating Images Alternating Images Alternating Images Alternating Images Alternating Images Alternating Images Alternating Images
Alternating Images Alternating Images
Alternating Images
Go Back  Xtreme Visual Basic Talk > > > Alternating Images


Reply
 
Thread Tools Display Modes
  #61  
Old 08-09-2011, 12:27 PM
passel's Avatar
passelAlternating Images passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default


Quote:
Originally Posted by AtmaWeapon View Post
... In structured programming languages without custom data types, you don't have classes. ...
I assume you don't really mean to use the phrase "structured programming languages" there.
Structured programming refers to a methodology, not a language, and the idea as a concept was generally considered to start in the late 60's.
Procedural programming, modular programming, and Object Oriented programming all fall under the umbrella of Structured programming.
Choosing not to use structures, or Types in the old VB vernacular, is another matter.
And yes, that can lead to the complications you've mentioned.
But not using a structure or user defined type is more likely to be a "mistake" of the programmer, not a restriction of the language, as I believe you would have to go back more than 30 years, to a BASIC interpreter like GW-BASIC, or other early Microsoft based BASICs, on the AppleIIs or Commodores, etc.. to find a BASIC that doesn't support User Defined Types.
The later interpreter, QBasic, that came with DOS and Windows machines up to Windows 95, had procedures (Subs and Functions, and Types) so allowed "Structured programming" if the programmer was disciplined.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #62  
Old 08-09-2011, 02:30 PM
AtmaWeapon's Avatar
AtmaWeaponAlternating Images AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

(All of this is a reply to passel but an aside for writing a Space Invaders game)

I suppose "procedural" fits what I was trying to describe more, but I always saw the types of languages like so:
  • Unstructured languages have GOTO and little else. Assembly and BASIC are among the unstructured languages.
  • Structured programming was indeed a concept, but languages adopted flow control, procedures/functions, and custom types. Visual Basic, Pascal, and C are among the structured languages.
  • OOP languages are structured languages that extend custom types with more features and typically treat *everything* as an object. VB .NET, C#, Java, and C++ are among the OOP languages.
There are four "pillars" of OOP. Abstraction can be achieved by unstructured languages through data protocols. Encapsulation can be achieved by structured languages through custom types. It's inheritance and polymorphism that set an object-oriented language apart from an "object-aware" language.

I agree a structured language without custom types is quite weak, but I needed one for my example. In a large system, no sane C programmer would have written the tedious card catalog system I wrote. Instead she'd make a struct and emulate an OO system. It's what MS did in the Windows API: CreateWindowEx() returns an HWND, and functions designed to do things with a window take an HWND as the parameter. Internally, creating the window involves the creation of a data structure stored in some internal collection, and the HWND is the key to that data structure. You can't directly see or modify the data structure (encapsulation!) unless you use a function. In OOP, those functions become part of the object and this takes the place of the HWND parameter.

In short, I knew that with structs in the language someone could point out the following snippets aren't very different:
Code:
hEntry dickensBook = CatalogFindFirstAuthor(hCatalog, "Dickens, Charles");
entrySetLocation(entry, "DI 402.31");
--
Dim dickensBook As Book = Catalog.FindByAuthor("Dickens, Charles").First()
dickensBook.Location = "DI 402.31"
All a matter of interpretation. But if I take structs out of C, I get the example I want.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #63  
Old 08-11-2011, 01:30 AM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

Checked MSDN to try get an example of a jagged array to see if I had the syntax wrong, according to Microsoft you can’t do a jagged array with VB or they don’t have a code example... http://msdn.microsoft.com/en-us/library/2s05feca.aspx

I tend to think they just don’t do a code example, because if I comment out everything after Image the error goes away.

Below without commenting it out I get ... error message: Explicit Initialization is not permitted for arrays declared with explicit bounds

Code:
    Private _alienImages(4)() As Image ‘= {{My.Resources.AlienType1A, My.Resources.AlienType1B, My.Resources.AlienType1C, My.Resources.AlienType1D}, _
                             {My.Resources.AlienType2A, My.Resources.AlienType2B, My.Resources.AlienType2C, My.Resources.AlienType2D}, {My.Resources.AlienType3A, My.Resources.AlienType3B, _ 
                              My.Resources.AlienType3C, My.Resources.AlienType3D}}
Or below if I take out the 4 out of the brackets I get a different error message: Value of type 2-dimensonal array of System.Drawing.Bitmap cannot be converted to 1-dimensional array of 1-dimensional array of System.Drawing.Image because System.Drawing.Bitmap is not derived from 1-dimensional array of System.Drawing.Image

Code:
    Private _alienImages()() As Image = {{My.Resources.AlienType1A, My.Resources.AlienType1B, My.Resources.AlienType1C, My.Resources.AlienType1D}, {My.Resources.AlienType2A, _
My.Resources.AlienType2B, My.Resources.AlienType2C, My.Resources.AlienType2D}, {My.Resources.AlienType3A, _
 My.Resources.AlienType3B, My.Resources.AlienType3C, My.Resources.AlienType3D}}
Below produces the error message: Value of type-1 dimensional array of System.Drawing.Image cannot be converted to System.Drawing.Image

Code:
    Private Function GetAlienImages(ByVal rowIndex As Integer) As Image
        Return _alienImages(rowIndex)
    End Function
Below produces the error message: Value of System.Drawing.Image cannot be converted to 1-dimensional array of System.Drawing.Image

Code:
    Private Sub CreateAliens()
        Dim alienIndex As Integer = 0
        For row As Integer = 0 To 4
            Dim yOffset As Integer = Alien.Height * row
            For column As Integer = 0 To 10
                Dim xOffset As Integer = Alien.Width * column
                Dim newAlien As New Alien(GetAlienImages(row))
                newAlien.Location = New Point(xOffset, yOffset)
                _aliens(alienIndex) = newAlien
                alienIndex += 1
            Next
        Next
    End Sub
I have attached the code I have so far to see if you can spot my error. Obviously since I can’t get rid of the errors (using a jagged array, I did with 2 dimensional array, but scrapped it to do it your way) I haven’t stepped through it to see what it does.

I had to change below values to suit the size of the Alien images.

Code:
    Public Const Width As Integer = 60
    Public Const Height As Integer = 40
Attached Files
File Type: zip SpaceInvadersV2.zip (37.7 KB, 2 views)

Last edited by passel; 08-11-2011 at 11:03 AM. Reason: Split Long code lines to hopefully make page not so wide
Reply With Quote
  #64  
Old 08-11-2011, 02:21 AM
Roger_Wgnr's Avatar
Roger_Wgnr Roger_Wgnr is offline
CodeASaurus Hex

Forum Leader
* Expert *
 
Join Date: Jul 2006
Location: San Antonio TX
Posts: 2,427
Default

VB Jagged Array Example
Code:
Class ArrayTest
	Private Shared Sub Main()
		' Declare the array of two elements:
		Dim arr As Integer()() = New Integer(1)() {}

		' Initialize the elements:
		arr(0) = New Integer(4) {1, 3, 5, 7, 9}
		arr(1) = New Integer(3) {2, 4, 6, 8}

		' Display the array elements:
		For i As Integer = 0 To arr.Length - 1
			System.Console.Write("Element({0}): ", i)

			For j As Integer = 0 To arr(i).Length - 1
				System.Console.Write("{0}{1}", arr(i)(j), If(j = (arr(i).Length - 1), "", " "))
			Next
			System.Console.WriteLine()
		Next
		' Keep the console window open in debug mode.
		System.Console.WriteLine("Press any key to exit.")
		System.Console.ReadKey()
	End Sub
End Class
' Output:
'    Element(0): 1 3 5 7 9
'    Element(1): 2 4 6 8
'
__________________
Code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. ~Martin Golding
The user is a peripheral that types when you issue a read request. ~Peter Williams
MSDN Visual Basic .NET General FAQ
Reply With Quote
  #65  
Old 08-11-2011, 02:55 AM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

That may work but AtmaWeapon says his code works without modification...

You are declaring the array seperately to populating it. If I put a comment after "array", basically just declaring the array, that part works.. the problem comes in passing the array parameters and that is when I get an error message.

Code:
		' Declare the array of two elements:
		Dim arr As Integer()() = New Integer(1)() {}

		' Initialize the elements:
		arr(0) = New Integer(4) {1, 3, 5, 7, 9}
		arr(1) = New Integer(3) {2, 4, 6, 8}
Reply With Quote
  #66  
Old 08-11-2011, 03:13 AM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

Either of these two seem to work ok and get rid of one of the error messages but they are both seperate

Code:
    Private _alienImages(2)() As Image
or
Code:
    Private _alienImages As Image()() = New Image(2)() {}
Code:
Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        _alienImages(0) = New Image(3) {My.Resources.AlienType1A, My.Resources.AlienType1B, My.Resources.AlienType1C, My.Resources.AlienType1D}
        _alienImages(1) = New Image(3) {My.Resources.AlienType2A, My.Resources.AlienType2B, My.Resources.AlienType2C, My.Resources.AlienType2D}
        _alienImages(2) = New Image(3) {My.Resources.AlienType3A, My.Resources.AlienType3B, My.Resources.AlienType3C, My.Resources.AlienType3D}

End Sub
Edit:

Got rid of the other two error messages, I had left off the Image array brackets () after Image. Only the parrameter error to solve now.

Code:
   Private Function GetAlienImages(ByVal rowIndex As Integer) As Image()
Edit:

Got a result to screen :O)

but I needed to make one slight modification... Because there are 5 rows and only 3 Alien types I had to duplicate Alien 2 & 3...

Also need to sort out the spacing between the Aliens like my first version of the game but that should be relatively easy.

Code:
    Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        _alienImages(0) = New Image(3) {My.Resources.AlienType1A, My.Resources.AlienType1B, My.Resources.AlienType1C, My.Resources.AlienType1D}
        _alienImages(1) = New Image(3) {My.Resources.AlienType2A, My.Resources.AlienType2B, My.Resources.AlienType2C, My.Resources.AlienType2D}
        _alienImages(2) = New Image(3) {My.Resources.AlienType2A, My.Resources.AlienType2B, My.Resources.AlienType2C, My.Resources.AlienType2D}
        _alienImages(3) = New Image(3) {My.Resources.AlienType3A, My.Resources.AlienType3B, My.Resources.AlienType3C, My.Resources.AlienType3D}
        _alienImages(4) = New Image(3) {My.Resources.AlienType3A, My.Resources.AlienType3B, My.Resources.AlienType3C, My.Resources.AlienType3D}
        CreateAliens()
    End Sub
Edit:

Now the whole ()() works, everything is starting to fall into place, and now I see how the frames come into play. They provide an index of the image array for each of the image arrays.

Last edited by CodeCruncher; 08-11-2011 at 04:01 AM.
Reply With Quote
  #67  
Old 08-11-2011, 07:11 AM
passel's Avatar
passelAlternating Images passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

Technically, you are just loading those images to be transfered to your alien class instances, so you wouldn't have to load them more than once.
You could change your CreateAliens sub to refence _alienImages(1) if the row was 2 and _alienImages(2) for rows 3 and 4.

But since images are reference types, you could reuse the arrays in the code you have and be a little more efficient without a lot of change.
Code:
    Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        _alienImages(0) = New Image(3) {My.Resources.AlienType1A, My.Resources.AlienType1B, My.Resources.AlienType1C, My.Resources.AlienType1D}
        _alienImages(1) = New Image(3) {My.Resources.AlienType2A, My.Resources.AlienType2B, My.Resources.AlienType2C, My.Resources.AlienType2D}
        _alienImages(2) = _alienImages(1)
        _alienImages(3) = New Image(3) {My.Resources.AlienType3A, My.Resources.AlienType3B, My.Resources.AlienType3C, My.Resources.AlienType3D}
        _alienImages(4) = _alienImages(3)
        CreateAliens()
    End Sub
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #68  
Old 08-11-2011, 09:29 AM
AtmaWeapon's Avatar
AtmaWeaponAlternating Images AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

The documentation you linked doesn't mention VB because it's in the C# Programming Guide. Would you expect to find information about proper care of kittens in a book about puppies? If you look at the arrays article in the Visual Basic programming guide you will find less information, but it does discuss jagged arrays.

To tell the truth, I don't know everything about VB .NET. 9 times out of 10 I have to go read documentation. From your end, there's no perceivable difference if I have everything memorized or if I have to look it up, so I look smart either way. If you want to look like you know the answer to everything, learn how to recognize when you don't know what's going on and how to find documentation to resolve the knowledge gap.

Here's an example with the array initializer:
Code:
 Private _alienImages()() As Image = {{My.Resources.AlienType1A,...
The compiler complains that "1-dimensional array of Image" cannot be converted to "Image". This means the compiler sees Image() where it expects Image. Odd. It indicates a likely syntax error, but I don't see it in the code you posted.

STOP! That was a red flag. The compiler is telling me there is a syntax error, but when I look at the syntax I don't see a problem. Either the compiler is wrong or I am wrong. There have only been 2 times in my life where the compiler was wrong, so I must be wrong. I wrote that code based on C#'s syntax, but maybe it's different in VB. That's easy to test:
Code:
Dim ints()() As Integer = {{1, 2, 3}, {3, 4, 5}, {5, 6, 7}}
Huh. "Value of type '2-dimensional array of Integer' cannot be converted to '1-dimensional array of 1-dimensional array of Integer'..." So the compiler sees Integer(,) but knows it needs Integer()(). That's not what I want. So I have a look at the Visual Basic Arrays documentation.

I know I want jagged arrays, so I search for "jagged". Nothing on this page discusses initializing a jagged array inline, so I have a look at Array Dimensions in Visual Basic, which is linked from the paragraphs about jagged arrays. Dead end, but I do see a link to How To: Initialize Array Variables in Visual Basic in the sidebar. Paydirt comes under "To initialize a jagged array variable by using array literals":
Quote:
Nest object values inside braces ({}). Although you can also nest array literals that specify arrays of different lengths, in the case of a jagged array, make sure that that the nested array literals are enclosed in parentheses (()). The parentheses force the evaluation of the nested array literals, and the resulting arrays are used as the initial values of the jagged array. The following code example shows two examples of jagged array initialization.
Oh. VB sure does like parenthesis, doesn't it? Jagged array literals need parenthesis. So I test it out with my Integer()():
Code:
Dim ints()() As Integer = {({1, 2, 3}), ({3, 4, 5}), ({5, 6, 7})}
Success! I should have known VB wouldn't want to be as convenient or concise as C#.

passel's suggestion in #67 is pretty good as well; no need to have more than one reference to an image laying around. I *think* My.Resources caches values, but I wouldn't bet on it.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #69  
Old 08-11-2011, 05:16 PM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

Wasn’t trying to be smart in anyway shape or form, if a Microsoft VB example exists then I think it is fair to assume it would be under the VB tab on a Microsoft page that says Visual Studio 2010, even if the Jagged Array says C# in brackets, after all that is the point of them having different programming language tabs.

I know search is definitely not my forte; I would go as far as saying it is a weakness, and your deductive reasoning on how you arrived at your answer is fine, if someone has your advanced understanding of all of the different elements that make up the programming syntax.

I wouldn’t be looking under array literals to find an answer as I have barely heard of the word “literals” before. If you cast your mind back to the start of the thread, it was you who introduced me to using curly brackets {} instead of the usual parenthesis () which I was using for every VB situation.

So I am reasonably confident I would not have worked out {({ without your help.

Just as a side not you started your explanation with a different error message to the one I got.

You started with “1-dimensional array of image cannot be converted to Image” Vs the “Explicit initialization is not permitted for arrays declared with explicit bounds”

I applied your changes below and still got the same error message”

Code:
    Private _alienImages(4)() As Image = {({My.Resources.AlienType1A, My.Resources.AlienType1B, My.Resources.AlienType1C, My.Resources.AlienType1D}), _
                                          ({My.Resources.AlienType2A, My.Resources.AlienType2B, My.Resources.AlienType2C, My.Resources.AlienType2D}), _
                                          ({My.Resources.AlienType3A, My.Resources.AlienType3B, My.Resources.AlienType3C, My.Resources.AlienType3D})}
I then tried (2) to match the length of the array and no joy

Code:
Private _alienImages(2)() As Image
And then I removed it altogether and it worked, whilst it is slightly different to your original syntax it does allow the parameters to be feed in at time of creation, which is a win.

Code:
Private _alienImages()() As Image
Thanks for you suggestion passel but that was just a temporary fix to align the 3 rows of different aliens to the 5 rows of AtmaWeapons code. My preferred fix would be to load the 3 rows of aliens with no duplication and alter the load code to load row 1 to the first row of alien, rows 2 & 3 with the second row of aliens, and rows 4 & 5 with the thirds row of aliens.

When I drop a line I want to reverse the direction of the images i.e. image 1.2.3 then 3.2.1 (so the walking looks better), so I will need something a little fancier than what I am currently working with.

I actually feel pretty excited about my new found understanding of what AtmaWeapon was trying to say from the start, because I didn’t know what a jagged array was I went completely off track and went from (for the want of a better word) a 2 dimensional array to a single dimensional array, and then that completely mucked me up on the frames which provided the index for the aliens.

Because I was thinking one dimensionally, I couldn’t understand how AtmaWeapons frames integrated into the solutions. Also not having a very good understanding of how this was all encapsulated in the class, that made controlling it all the harder.

Thanks to AtmaWeapons persistent help I now understand encapsulating variables in a class so much better than when I began this game, and the frame index makes perfect sense now.

I will need to alter the frames though because essentially that is a forward counter, and I need it to count both ways depending on the position of the aliens (dropped a line), but that should be relatively easy.

I would like to go back to the TextureBrush now that I understand what is going on (I want to develop this skill for later games)... Should I be trying to load the images into a jagged array like this, or should I be painting directly from the Sprite sheet?
Reply With Quote
  #70  
Old 08-11-2011, 10:16 PM
passel's Avatar
passelAlternating Images passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

Whether you use a jagged array, or not, or individual images or a sprite sheet doesn't have any bearing on using a texture brush vs DrawImage or bitblt, or whatever other means there may be to transfer an image from one graphic to another.
I think I mentioned as a side wayback when we were playing with the texture brush, that you will save a line of code if you don't use a sprite sheet.
With a sprite sheet you have to create a New Texture Brush and set the bounds to the area of the sprite sheet your source image is coming from.
If you use a single image, whose size is already the size you want for your brush, you don't have to do that step.

That spinning cars demo create a new brush each pass to align it to the car angle we wanted. We then used that brush over and over to paint multiple images of the car.
So, it really didn't matter if you were drawing 8 cars or 80 cars, the number of times the brush had to be created didn't increase proportionally to the number of cars drawn. In fact, it actually decreased because with 8 cars you had to create the brush once for every 8 cars drawn. With 80 cars, you create the brush once for every 80 cars drawn.

Now, for further investigation, which I did a couple of weeks ago but didn't post, I expanded the spinning cars demo to allow selecting between:
Using DrawImage
Using Dynamic Brush Creation
Using a Brush Array
Using a Structure (similar to a class) that contained the brush and had a draw routine that "knew" how to paint a given instance of the car (passed the graphics context and position to the routine).
And finally, using unmanaged GDI BitBlt (using the full spritesheet including masks).

Ok, the Dynamic Brush Creation is the method we are using in the code posted in this thread.
Each time we go to draw the field of cars, we create the appropriate brush, draw the cars, then dispose the brush.

With the Brush Array method, I create an array of 96 texturebrushes at startup, initialize them with the appropriate textures from the spritesheet, then just use the appropriate texturebrush from the array, no creation or disposing of brushes every pass.

With the Structure, I created a structure that contains a TextureBrush, a width and height of the TextureBrush, an Initialization routine and a draw routine.
I create an array of 96 instances of the Structure, calling the init routine, passing the texture image to it, which is uses to initialize the brush and set the height and width properties.
Then in the car field drawing loop, I call the draw method of the appropriate structure instance, passing the Graphics handle and X,Y location and the method draws the appropriate size filled rectrangle using the embedded brush.

Lastly, I use the pInvoke capability to Declare the GDI BitBlt API call and implemented a routine to use BitBlt to draw the image.

What I found in the case of this particular demo, I couldn't really see a difference in the various TextureBrush methods in regards to Frames per Second.
When I used BitBlt, the FPS increased 10 to 30 percent depending on the number of cars drawn. The more cars drawn, the greater the difference.
But, it is a bit more complicated to implement, so most of the time, I think I would stick with textureBrush over BitBlt unless doing a lot of graphic work.

Now, another odd thing, and I haven't determined why, but the spinning car demo posted earlier definitely gives the impression that using TextureBrush is many times faster, on the order of 50x faster, than using DrawImage.
The program isn't that complicated, and the methods for both the use of DrawImage and TextureBrush seem to be realistic in the way they are used, yet there is a hugh difference in the draw speed.

So, Lord_Lazy, had a question about speeding up his FPS in the start of a game in another thread. So, I revisited that code, armed with this new knowledge, and looked at replacing DrawImage with TextureBrush and see a jump in FPS.
Depending on the resolution of the monitor, the game draws a differnent number of tiles, and on the machine I was testing the monitor was 1920x1200.
The game used DrawImage in three places, and drew a total number of tiles between 100 and 200 (only a few rows at the bottom of the screen, and the player and a couple of other tiles).
So, create brushes for the various type of tiles he has, change the three DrawImage calls to do FillRectangle with the brushes, and voila, those 100-200 tiles should be drawn much faster.
Well, to my disapointment, the FPS barely crept up.
I investigate some, commented out a lot of code so the game loop ran faster, got it down so it was mostly just redrawing the scene each loop, and yet still, switching between using DrawImage or TextureBrush made little difference. Using TextureBrushes was only a few frames per second faster.
I can't understand why. I haven't been able to get back to it.
Perhaps the bit depth of the bitmaps used make a difference.
The car demo uses bitmaps with a transparent background, I don't think Lord_Lazy's game does at this point, so maybe TextureBrushes are much faster than DrawImage, when transparency is involved.
At this point, I don't know.

Bottom line, if you follow AtmaWeapons method, and have the class return an image, you can easily use that with DrawImage, or change the code a little to create the brush and use FillRectangle. Switching from one to the other is not a big effort.

Although it doesn't seem to make a difference in speed, between different ways of using a TextureBrush, as long as you're using a TextureBrush, if I were doing this and going down AtmaWeapon's method of using a class, I would probably change the methodology a bit, and instead of storing the images in the class, I would create brushes from the images, and store the brushes in the class.
And while the current proposed class returns the appropriate image back to the drawing routine based on frame number, to be drawn by the event handler, I wouldn't have the class pass back the brush. Since the filled rectangle you draw needs to match the brush and that depends on the size of the image used to create the brush, and that can depend on the type of alien in the class, I think I would want that drawing knowledge encapsulated in the class as well. Since you are maintaining Alien location in your class, as long as your drawing surface coordinates match that coordinate system, you could pass the Graphics object and frame number to the Class and ask the alien to draw itself.

But, for now, rather than mix more options into your stew, just continue down AtmaWeapon's lead, because if you stray too far from the path, we may lose interest in trying to find where you went.
Just return the bitmap from the class, based on frame number, and draw it with DrawImage.
Once you have that working, if you want to create a brush from the returned image, that should be a minor change.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 08-11-2011 at 10:23 PM.
Reply With Quote
  #71  
Old 08-13-2011, 12:42 AM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

Thanks for the insight passel... I must have missed the point you made about the sprite sheet and individual images not having an effect on the type of draw method used, but I now see that is merely a different way of presenting an image to be used.

I would however still like to focus on and getting familiar with using the sprite sheet simply because down the track I want to do some work on a car game that uses different backgrounds, and that means I am far more likely to be using different sections of a larger image, so getting more familiar with sprite sheets much more sense (to me anyway).

Any chance you could upload your updated version of the car image comparison?
Reply With Quote
  #72  
Old 08-13-2011, 10:38 AM
AtmaWeapon's Avatar
AtmaWeaponAlternating Images AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

If you're really serious about writing games with VB .NET, Windows Forms is ultimately the wrong tool for the job. Look into XNA. It's an abstraction above DirectX and it was designed for writing games. WinForms was designed for writing applications like Quicken and Excel. The SpriteBatch class has full support for working with tiled sprite sheets.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #73  
Old 08-15-2011, 02:33 PM
passel's Avatar
passelAlternating Images passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

I'm somewhat hesitant to upload the updated version, since it contains multiple draw methods all in the same module, it might add to the confusion of what code goes with a given method.
Unfortunately, I don't want to take the time to break it into different files to make the lines clearer.
I also don't know if having a bitblt example is good or bad, since using GDI or other unmanaged API calls is anathema to many in the .Net community, even if it is faster than any GDI+ method.

As AtmaWeapon says, using XNA would be more appropriate since its purpose for being is game development, but I do find transitioning to XNA still a bit of a headache with VB.Net.
It should be easier with 2010 and beyond as I've heard that Microsoft's plan is to bring VB into parity with C# development where XNA is concerned.

I guess I'll let the chips fall where they may. I've added a lot of comments to the updated demo, so that will hopefully help to keep straight what items exist for what purposes in the code.

The new parts are a few radio buttons to select which draw method you want to use.
Instead of a single draw routine with an if condition in the loop to choose the drawing code, each draw method now is in its own subroutine.
Each routine is essentially a copy of the original, so most of the code is redundant, but any extraneous code that supports one method over the other is removed from the specific sub.
Earlier, in my last post, I said the BitBlt version was using the "full spritesheet, including masks".
But that is not quite true. That was true in the VB6 version of the BitBlt test.
What the .Net version does, is create two GDI compatible copies of the spritesheet.
The GDI+ spritesheet has a transparent background.
We call the spritesheet's GetHbitmap method to both create a GDI compatible bitmap and get a handle to that bitmap. The GetHbitmap method call also allows specifying the backcolor, so the transparent areas are filled with the backcolor, which we use to create the "Sprites on Black background" and "Sprites on White background" bitmaps that we use with the bitblt method.
You can't call GDI methods on a Graphics object when GDI+ is in control, neither can you call GDI+ methods on a Graphics object when GDI is in control.
I don't know what overhead is involved with transferring the Graphics object DC for use by GDI and then transferring it back to GDI+, but this code only transfers it once each frame, by calling GetHdc on the graphics object, before entering the loop to do all the bitblts, and then releases the DC back to the Graphics Object by calling the graphics objects ReleaseHdc.

I don't recommend you use the BitBlt method in your project, since it adds more complication and a different paradigm than you're currently using with GDI+.

As for using a Structure, added to test the begining of a method for a tile class, it is a minimal structure at this point. The complete structure is :
Code:
'
  Public Structure Tile_Type
    Private TileRect As Rectangle         'Holds the size of the tile, used in drawing
    Private Brush As TextureBrush         'Holds the TextureBrush used to paint the tile

    Public Sub Init(ByVal bmp As Bitmap)  'Pass the bitmap to be used for the TextureBrush
      TileRect.Width = bmp.Width          'Save the width
      TileRect.Height = bmp.Height        'and Height in a Rectangle Structure
      Brush = New TextureBrush(bmp)       'Create the TextureBrush that will paint with the bitmap
    End Sub

    Public Sub Draw(ByRef g As Graphics, ByVal X As Double, ByVal Y As Double)
      TileRect.X = X                     'Update the Rectangle location to 
      TileRect.Y = Y                     'the location passed.
      Brush.TranslateTransform(X, Y)     'Transform the brush to align with this location
      g.FillRectangle(Brush, TileRect)   'Paint the tile at the location using the brush
      Brush.ResetTransform()             'Reset the brush transform matrix back to the default identity matrix
    End Sub
  End Structure
As you can see, there are only two elements, a rectangle to hold the size of the sprite and used in drawing the sprite, and the brush used to draw the sprite.
In addition to the two elements, is an Init routine that is passed a bitmap containing a single sprite, which is used to initialize the rectangle structure and texturebrush,
and a Draw routine which will draw the sprite on a given Graphics object at a specified location.

The rest has been describe a bit in the last post, and is describe more fully in the comments in the code, so I won't continue here.
I've also added in the comments, that the speed increase noted in this code, may not translate to real-world usage, since normally, you wouldn't use the same brush repeatedly in a loop like our test does.
A different brush would most likely be used for each object drawn.
On the other hand, the Brush Array test, and the Structure test, both access a brush associated with the specific sprite, so in theory should reflect a real-world scenario.
The tests could be changed so that the sprite selected for each car drawn is sequenced so that a different brush is chosen for each car.
I would expect that to make a real difference for the method that has to create the brush dynamically, since it would be creating and disposing of the brush for each car, not for each field of cars.
But, that will be left as an exercise, if someone was so inclined.
Attached Files
File Type: zip SpriteSheetAnimation.zip (151.2 KB, 17 views)
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 08-15-2011 at 02:43 PM.
Reply With Quote
  #74  
Old 08-19-2011, 07:07 PM
CodeCruncher CodeCruncher is offline
Junior Contributor
 
Join Date: Jul 2006
Posts: 355
Default

AtmaWeapon: I have no false sense of one day becoming some great game programmer, my desire to understand graphics a little better is because I would like to see if I can do some development work on a legacy game that has been opened up to the public under the GPL and it is written in C++.

I am trying to understand the concepts in VB first, so when the time comes that I have enough spare time to learn C properly, I can try to at least understand what is written.

It is a very old game but one I got a great deal of pleasure playing, they have revamped it several times but it is still far from perfect, but because it is old (and simple?) it may be within my reaches of understanding it.

Here is a link to the source code for it. http://sourceforge.net/projects/streetrod3/ and http://www.streetrod3.com/sr3.php but if I was looking at a career in game programming I hear XNA seems to be one of the ways to go.

passel, thanks for uploading that, I just did a quick check without looking at any code and running 20*20 cars, the only paint method that doesn’t come to the party is ImageDraw which drops as low as 1-2 fps, where as all the other methods are around the 35 fps mark varying just a few frames a second.

I think since there is so little between the others it would probably be best to learn the easiest of them (but have an awareness of the others).

Thanks once again to all contributors for the assistance given, but I need to park my development on Space Invaders for the time being, as I have a fairly sizable work related project that needs to take priority, and can only be done outside of work hours, but needs to be done with some kind of pace. So I will pick this game back up once I have the work project under control.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Alternating Images
Alternating Images
Alternating Images Alternating Images
Alternating Images
Alternating Images
Alternating Images Alternating Images Alternating Images Alternating Images Alternating Images Alternating Images Alternating Images
Alternating Images
Alternating Images
 
Alternating Images
Alternating Images
 
-->