|
Post by Smurftra on Apr 12, 2005 15:01:38 GMT
Ok, lets say as a first project to play around with this library, i would make Tetris.
Each figure is a group of 4 blocks.
Lets say i have an image with: 7 24x24 Blocks of 7 dff colors.
Then i have an array of (20,10) which represents (y,x) of my game board, and are loaded with values from 1 to 7 representing the color to draw (0 being no color)
now i loop through my array, and want to print the correct block image.
What is the spritecandy instruction to just print an image from another (layer)?. I mean, i dont want to create a pointer on that image, just blit it.
Now, what if i want each of my 200 tiles to be animated, on different speed/frame, but using again the same image ressource? I do not want each object to load the image.
Now what if my board is dynamic in size?
I dont have internet home so i dont have clear examples with me, i'll try to have some by tomorrow.
thanks,
Smurftra
|
|
|
Post by Jake on Apr 12, 2005 19:45:52 GMT
I don't understand your ideas fully, but I know Tetris and there are several approaches how you can do this with Spritecandy.
First, remember that SpriteCandy is 3D and that you can use VertexColor to get different colors for the same shape with this technique. So all you need is a texture with all your block-shapes (or just a single block, if you form your shapes with code). Color them all white (or grayshaded), then use HUD_SetVertexColor to color them.
Second, creating a large number of objects from the same texture (=from the same layer) will not use much memory. By adding an object with HUD_CreateImage, only 4 Vertices (2 Triangles) are created, so no extra memory is needed for the graphics. Try to keep layers and layerimages (textures) low, but don't worry about a lot of "images".
Unless you're using 1000+ (Hud-)Images, you should not run into any speed or memory-issues.
Hope that helps a bit
Jake
|
|
|
Post by Smurftra on Apr 12, 2005 21:08:49 GMT
cool this did help, but is not quite what i had in mind.
I used tetris as an example, but i'll try to explain another way: (my native language is not english, so this is kinda hard)
I'm used to think in object-oriented, so i think of all my items in games as objects.
Lets take warcraft as an example. (I think its fair to say anyone here knows what it is).
In warcraft, i have several units of the same type.
I would create an array of object Units. (in blitz3d, i figure we can only use Types)
Each of these units have a property class, all those of the same class (Ex: Fighter) use the same graphic.
Now, each of them is also animated, but is not at the same frame of animation.
So if have:
Type Unit X Y Alive Image END Type
FOR I = 0 TO MaxUnits Units.Unit\Image = HUD_CreateImage(Texture,...) NEXT
ok, now i have my units set up, and i want to draw them if they are alive
FOR I = 0 TO MaxUnits IF Units.Unit\Alive = 1 THEN ...(what do i insert here)? END IF NEXT
i dont know if its clear.. i'm gonna try another approache:
I want my Image variable to point to the texture, but now draw anything unless i specify it in the loop.
Smurftra
|
|
tonyg
Junior Member
Posts: 73
|
Post by tonyg on Apr 12, 2005 21:39:21 GMT
Each HUD_CreateImage creates a unique 'Object' (in this case an image) type instance pointing to your resource image using the clipping information you supply in HUD_CreateImage. Each can be referenced seperately so, in your type, you can loop through using HUD_PositionObject with it's own animation frame count and speed. The only problem I can see, which I'm looking at now, is that changing the original resource texture will change the image for each instance. Hope I've understood and it helps. <edited> If you are using HUD_AnimateImage then it points to this unique object type instance. <edit> If it helps... Create an image called anim1.png size 64*256 containing four 64*64 coloured rectangles (I put a text '1','2','3','4' in each rectangle to show the animation)...
Graphics3D 640,480 SetBuffer BackBuffer() Include "../sprite candy.bb" Type UNIT Field X Field Y Field IMAGE End Type cam% = CreateCamera() hud1% = HUD_Create(cam) resource1% = HUD_LoadImageResource ("anim1.png",4) imagelayer% = HUD_CreateLayer(hud1,resource1) units.unit = New unit units\x = 100 units\y = 100 units\image = HUD_CreateImage(imagelayer,0,0,0,0,64,64) HUD_AnimateImage units\image,0,0,4,4,"NORMAL",0,1000 units.unit = New unit units\x = 200 units\y = 100 units\image = HUD_CreateImage(imagelayer,0,0,0,0,64,64) HUD_AnimateImage units\image,0,0,4,4,"PENDULUM",0,2000 ;image1% = HUD_CreateImage(imagelayer,0,0,0,0,64,64) ;IMAGE2% = HUD_CreateImage(imagelayer,0,0,0,0,64,64) ;HUD_AnimateImage image1,0,0,4,4,"NORMAL",0 While Not KeyHit(1) For all.unit = Each unit HUD_PositionObject all\image,all\x,all\y Next HUD_Update UpdateWorld RenderWorld Flip Wend End
<edit (another).> Sorry the line formatting has disappeared and for lack of comments. I've used HUD_AnimateImage but the same should be true if you use manual animation.
|
|
|
Post by Smurftra on Apr 13, 2005 0:08:27 GMT
ok ok, exactly what i wanted, but it brings a questions(sorry, it'll be the last one i swear)
When i do this: units\image = HUD_CreateImage(imagelayer,0,0,0,0,64,64)
if i do it again to reposition the unit on another image (it has been upgraded a knight lets say), will sprite candy remove from memory the first animation (units\image, not the actual layer itself), even tho i have nothing pointing to it, or do i have to remove it myself?
With that, i think i can figure out the rest pretty quickly, thanks again in advance, you guys been kind to help me out like that
Smurftra
|
|
|
Post by Jake on Apr 13, 2005 5:04:09 GMT
if i do it again to reposition the unit on another image (it has been upgraded a knight lets say), will sprite candy remove from memory the first animation (units\image, not the actual layer itself), even tho i have nothing pointing to it, or do i have to remove it myself? Smurftra No, it creates a new object and its up to you to remove the old one. But have a look at HUD_SetImageClip and HUD_MoveImageClip. These functions alter the texture-position used by an Hud-Object.
|
|
tonyg
Junior Member
Posts: 73
|
Post by tonyg on Apr 13, 2005 9:11:16 GMT
I'd be tempted to add...
if image<>0 HUD_RemoveObject(Image)
before each HUD_CreateImage. Alternatively you could create your own myHUD_CreateImage function...
Graphics3D 640, 480, 0, 2 : SetBuffer BackBuffer() : SeedRnd=MilliSecs() Include "../sprite candy.bb" Cam = CreateCamera() HUD% = HUD_Create (Cam) Resource1% = HUD_LoadImageResource ("Media/image1.png",4) ; <-- BLACK BECOMES TRANSPARENT ImageLayer1% = HUD_CreateLayer(HUD, Resource1) While Not KeyDown(1) Image1% = my_HUD_CreateImage (ImageLayer1, 0,0, 0,372, 96, 95, "CENTER","BOTTOM-30",0,image1) HUD_Update : RenderWorld Text 0,0,HUD_GetStats$() Flip 0 Wend
HUD_RemoveAll True : End Function my_hud_createimage(LayerID, x%, y%, clipx=0, clipy=0, clipw=0, cliph=0, xAlign$="", yAlign$="", zorder%=0,newimage=0) If newimage <> 0 HUD_RemoveObject(newimage) imagedone=HUD_CreateImage(layerid,x,y,clipx,clipy,clipw,cliph,xalign$,yalign$,zorder) Return imagedone End Function
or, unofficially, change the spritecandy.bb file after taking a backup. <edit> I change SpriteCandy.bb to...
Function HUD_CreateImage% (LayerID, x%, y%, clip_x#=0, clip_y#=0, clip_w#=0, clip_h#=0, xAlign$="", yAlign$="", zorder%=0,image=0)
and, just before the 'Create an Image Object' comment...
If image<>0 HUD_RemoveObject(image) ; CREATE AN IMAGE OBJECT
It doesn't affect performance at all and is *quicker* if you intend to create lots of images with the same handle.
|
|
|
Post by Smurftra on Apr 13, 2005 13:38:18 GMT
thank you both, very helpfull and exactly what i wanted to know!
|
|
|
Post by Smurftra on Apr 16, 2005 20:53:01 GMT
Ok, last one i swear!
Is there a way to draw an image without keeping a pointer?
Like just blitting it to the back buffer?
Lets say i got an image: image%, and i want to draw it 4 times at 4 different spots. I dont want to create 4 images and keep pointers on each of them, i want something like:
Blit_Image image%, x, y Blit_Image image%, x+50, y+50 Blit_Image image%, x-50, y-50
then i want to flip.
If i do:
i=hud_CreateImage(...) HUD_RemoveObject I i=hud_CreateImage(...) HUD_RemoveObject I
then nothing is drawn.
thanks,
Smurf
|
|
tonyg
Junior Member
Posts: 73
|
Post by tonyg on Apr 16, 2005 21:54:14 GMT
I don't fully understand what it is you're trying to do. However, you might want to use HUD_CreateCopy, display each image and then remove them Something like...
While Not KeyDown(1) If image3 HUD_RemoveObject(image3) image3 = HUD_CreateCopy(image2) HUD_PositionObject Image2,MouseX(),MouseY() HUD_PositionObject Image3,MouseX()+30,MouseY()+30
|
|
|
Post by Smurftra on Apr 16, 2005 22:34:35 GMT
thats not what i'm looking for. I do not want to create an image3 object.
i just want to draw image1 at mroe than 1 place, without creating objects for each draw.
lets say i wanted a 5x5 led display (just an example), of 3 colors (yellow, red and green). I have a bitmap that has the 3 leds drawn, i load it as layer1.
now, i fill by 5x5 grid with 1 or 2 or 3 (1=yellow, 2=red, 3=green)
then i want to do something like for i=1 to 5 for j=1 to 5 ;here i want to draw the correct led x=HUD_CreateImage(layer1,i,j,Led(i,j),0,1,1) ;so i set my image to the led(i,j) color to start reading it at where that led is drawn
next next
but i've tried this and it seems to keep creating images, slowing it down exponentially every iteration.
I would just like it drawn to the backbuffer than forget it, not keep it loading, but if i add a line:
HUD_RemoveObject x
right after the createimage, it just doesnt draw the image
edit: the led display is only an example, i do not want to draw pixels but rather 32x32 sprites
|
|
|
Post by Xpressive on Apr 17, 2005 5:54:59 GMT
I am not sure if this is what you asked, so let me know if this info won't help you:
There is no need to save the handle of a created image object. You can just create images like this:
HUD_CreateImage... (without using a variable to save the handle)
It will be drawn to the screen (as soon as you use HUD_Update) and remain there until you delete it. Of course you can't delete an image directly without a saved handle, but that's no problem: simply clear the layer where the image has been placed and it will be removed.
|
|
tonyg
Junior Member
Posts: 73
|
Post by tonyg on Apr 17, 2005 7:52:19 GMT
Hmmm, how would you draw a tilemap where the same image is used in multiple locations (i.e. grass tile)? Would we have to createimage for each tile with individual handles?
|
|
|
Post by Jake on Apr 17, 2005 20:36:02 GMT
Remember that SpriteCandy is 3D and the way, how this works today.
(In Blitz) you have to render Triangles (build up by 3 Vertices). Images in SpriteCandy are build of 2 Triangles (build by 4 Vertices) that represent a texture-area. This is known as a Quad.
You could fill the screen with a single big quad and change the texture on the fly, but don't do this (it's to slow). Instead use the method TonyG described.
Hope I could help you understand 3D-Rendering in blitz.
|
|
|
Post by Smurftra on Apr 19, 2005 13:38:31 GMT
I think i don't get it.
If the image stays in memory, and i have to flush the layer to remove it, that means i have to reload the layer at each iteration?
That Tile example is a good one. Lets say i have a lyer containing 4 tiles, then i have an array of (20,20), set to numbers between 1 and 4, and i want to draw the correct image (1 or 2 or 3 or 4) at position x*32, Y*32
so,
Function DrawBackground()
for x = 1 to 20 for y = 1 to 20 HUD_CreateImage (Layer, x*32,y*32, x*32, 0, 32, 32) next x next y
End Function
now, if i could simply have a 'Draw Image' function instead of create image, i mean, i do not want to flush my layer because i will still need it at the next iteration of my DrawBackGround function. I do not want to keep a pointer on each image, as it is useless to me.
When i think about it, the CreateImage function is more a CreateSprite function. I'm sure SpriteCandy uses an internal function for blitting the said sprite on the backbuffer. I guess thats the function i would need. Isn't that how it's done in 2d gaming for the last 20 years? hehe.
Edit:
I want to add that the (20,20) object changes every iteration, so i do not want to 'keep it until i remove it'. I either want to draw it on the fly and then autodelete it (but if i do delete it, it doesnt show when i use HUD_Update). So maybe some HUD_UpdateObject() function to just draw a particular object, so i could do:
WHILE NOT KeyHit(1) UpdateObjects ;moves the objects, sets up the 20,20 grid) DrawBackGround ;draws only the grid HUD_Update WEND
Function DrawBackground()
for x = 1 to 20 for y = 1 to 20 Image = HUD_CreateImage (Layer, x*32,y*32, x*32, 0, 32, 32) Hud_DrawObject Image next x next y
HUD_RemoveObject Image
End Function
thx,
Smurf
|
|