Yes, yes, I have an 'image' problem

Hi all, big time VB fan, longtime off it. Saw Xojo, thought, WOW, resurrection city BUT, I’ve encountered something on my first 2 days that is causing a massive stall.

  • I can’t seem to paint/draw/whatever to a ‘canvas’ unless I’m sitting inside it’s Paint event. Is this correct?

My history for kicks:- Making semi-complex dungeon crawlers in 2.5d with 1000’s of monsters doing their thing. Animations, spells, combat stabbing and such. So, during the many for-next loops I’m often throwing things onto the VB picturebox control, and then passing through many modules to thusly, throw more things into the picturebox. Once refreshed, that picturebox ended up as a fast, real-time game that was animated and ran ever-so-smoothly.

But after crawling through the forums and samples, it looks like the ‘similar’ function for external dumping/painting onto the canvas has been taken away. (Even by outside modules).

Am I perceiving this correctly or is their some sort of magic that I haven’t found yet?

Thank you for your time.

This is a feature of modern OS and not a bug. You need to structure everything in a way that you only use the paint event.

What is a picturebox?

Hi Beatrix.

Below are the settings of the picturebox in VB6. By calling it from anywhere, any module, you can place image files and imagelists, whilst manipulating said pictures too.

VisualBasic6Picturebox.PaintPicture SrcPictBox.Picture, destX, destY, [destWidth],
[destHeight], [srcX], [srcY2], [srcWidth], [srcHeight], [Opcode])

From: VB- PictureBox and Image Controls in Visual Basic 6

It seems reminiscent of the Canvas operators to me. So I thought it was going to be a similar process to call said function from inside a program module.

A picturebox sounds like a really good idea. I’m only drawing simple stuff like icons and the like. Xojo is really OO even when painting.

Define a picture and the canvas only needs to update the picture.

  • Schlepp the picture around so that different classes/modules/methods can work on the picture. The benefit is that you can inspect the picture (mostly) in the debugger.
  • Instead of the picture give the different classes/modules/methods the graphics property of the picture. This should be faster but you can’t inspect the graphics in the debugger.

Sorry, I’m not sure what OO means in context there. :slight_smile: (Good, bad, something else?)
Picturebox’s are what made VB amazing in a graphical sense.
You can throw layers of 2.5d terrain down, then trees, rocks, shrubs, walls, monsters and characters, refresh it and presto, instant single frame of animation. When moving your character, everything animates spectacularly well. BUT, only by processing that via many modules (& subroutines). It was incredibly smooth, to the point you could run maps 100,000x100,000 squares, and 10,000+ monsters(with AI). Pictureboxes are awesome, and inspired me learn as much as possible in VB6 in the first place.
The only thing I can think to do is handle all graphics outside the canvas paint.event by jamming all the images(as data numbers) into a matrix, then, finally, for-next looping inside the canvas paint.event (to display them). Which means I’m double processing and time bloating the CPU.
Passing graphics in matrices or via variables also sounds horrific to me, memory-wise, as the program deals with literally insane amounts of data on the fly.
Having the ability to call and slap anything down into a picturebox, from any part of the program is vital. If Xojo doesn’t do that, it’s a bit of a deal breaker for me in going further. :frowning:

Have you checked out the graphics and games examples that come with Xojo?

Create a ‘global’ picture object
Do all your drawing on that, in exactly the way you expect.

The canvas just needs to know when you are ready to display.
So after a recycle, call canvas.invalidate
In the Canvas paint() event, draw your picture to the canvas graphics using
g.drawpicture myalreadydrawnimage,0,0 , g.width, g.height, 0,0,g.width, g.height

…your image needs to be the same size as the canvas of course…

1 Like

I downloaded a few sample games that were listed from the forum, and anything I could find that had a canvas with image. No luck finding my solution yet.

Oh Jeff! Thanks! I’ll look into that. That sounds like a great thing. :smiley:

Xojo comes with a lot of examples:

1 Like

It means “object oriented”. Xojo is a very object-oriented language.

I’d guess Beatrix is implying you could recreate the picture box class as a custom Xojo control and give it the behavior you expect.

This allows you to “solve the problem once” and then reuse your PictureBox class across multiple windows in multiple projects.

1 Like

Ah, thanks Anthony. Interesting! :slightly_smiling_face:

Not really. That limitation is just the way Xojo decided to do things.

:thinking: It is a shame that many resources about drawing no longer exists.

Anyway, in Xojo look for the examples and open the “ObjectsInCanvas” to get an idea of the drawing and interaction.

Also maybe what you look for is like the drawing in thread example, a constant frame rate with the content drawn as fast as posible.

Be aware that drawing is not really the strongest point of xojo, at least not in windows.

You sould make some benchmarks before spending a lot of time and discovering that it doesnt run as smooth as you need.

Hi Ivan,
Yes, stress testing the canvas is the first thing I’ll do. Then the map handling size. :japanese_ogre:

Generally speaking, it’s a good advice to ALWAYS Subclass any Xojo Object. Then you use your Subclassed Object instead of the “native” one and if you need to make changes to it’s behaviour or if you need to extend it’s abillitys, your changes will automatically be effective across all instances of your Subclass in your Project.

Just wondering if anyone can help with going a bit further. My testing is going a bit awry on this one.
I’m testing both a local and global variable picture object.
Local works fine, Global variable ‘error’ says it has no instance of ‘Graphics’

Working
Image_H.Graphics.Drawpicture Image1,60,60 'Local variable Image_H
Not working
Image_Holder.Graphics.DrawPicture Image1,80,80 'Global variable Image_Holder

Image_Holder was made by: Module, Properties, Name “Image_Holder”, Type “Picture”, Scope “Global”

Is there something extra I need to add or do to make a global picture work?

Did you create an instance of the Global Object with f.e. Dim Image_Holder As New NameOfGlobalClass?
Or did you add it as a Property to a Window f.e. and did you then do a Image_Holder = New NameOfGlobalClass?

In any case, you need to create a new instance of your global class. :slight_smile:

HI Sascha, sorry, I seem to be having massive difficulty. Probably due to the ‘VB6 for life’ attitude of mine. I find it hard to get around this new concept of not writing everything into a module ‘textbox’ and having it work straight up.
I manged to get the instance creation of the Image_H (Local variable) working in the canvas paint section easily enough, for a test.
However, I’m not sure where, or how to instance the global variable. My attempts to do so, so far, have all failed. I think I understand that, defining a new global variable (in a module) means I then have to make a new global variable by pointing to that module defined one, is that correct? But where in the app, or code or function do I do that so it stays global?

No. :slight_smile:

You can look at the global variable/object/class like a Blueprint.
You can create a local copy/instance of your global blueprint f.e. in a Method or Action of an Object in a Window, by writing:
Dim x As New GlobalBlueprint
Then you would have an Object with a local Scope, which is an Object based on the Properties of your global class (or blueprint).
But you can also create a new Object in a Module and point the “Super” to your class and so create an Object with a global Scope.

To make sure we speak about the same things:
I’d first start by adding a new empty Class within your project (maybe within a “Folder” in your project.
The super of this new Call would be set to be a “Canvas”.
Then i’d add to this new Class all the Properties, Methods and so on, that i need for your own Picture Class.
This new Class of a Picture Object can then be used across your Project like any other Class (like a Canvas f.e.).

:slight_smile:

In your Window Add a Property

OffScreen As Picture

In your Button:

Dim OffScreen As New Picture(Canvas1.Width, Canvas1.Height)

Then use

OffScreen.Graphics.DrawString “My nice Offscreen Picture”

In Canvas1.Paint Event:

If OffScreen <> Nil Then
g.DrawPicture OffScreen,0,0
End If

You get the idea (errors can arise, I typed that in the web page).

1 Like