Computer Science Canada

Sprites - Is There Another Way?

Author:  Bacchus [ Fri Mar 18, 2005 10:31 am ]
Post subject:  Sprites - Is There Another Way?

Sprites - A Tutorial for a New Way


Ok, here we go... as you may know, or just found out and looking for a reason why, Sprites in Turing v4.x have been disabled. They won't work. There are however alternatives to the default Sprite module, such as DanSprite. DanSprite was made by Hacker Dan, an Admin and the Owner I believe of compsci.ca. As you may know if you've tried DanSprite is that it has some bugs... In fact it has quite a few bugs. Dan gives the explanation for this:
Hacker Dan wrote:
Ok the truth about dansprits is that in all hosntly they suck, i made them when i was very borad one night. But they are all that u have if u whont to use sprites in turing (well there may be one by another user on the forum i whould have to check). They work ok in some cases but b/c i whonted them to be useable by baick users i made it to simple and it caused some unforseen bugs.
I encountered these bugs in DanSprite when I tried to start a RPG of my own, and then went on a rampage to create a more bug-free solution. Well I came up with BacchusSprite (Don't you just love my originality?). BacchusSprite is very similar to DanSprite and infact I used DanSprite as a guide when I got stuck every now and then. One difference is that every problem I have encountered has been fixed and hopefully should now work almost flawlessly.

The Commands

BSprite.New(x,y:int,filename:string):int
The New function is used to assign a Sprite to an Integer variable so that it can then be refered back to and moved around with that variable. ie: like Pic.FileNew
BSprite.Move(x,y,spriteID:int)
The Move procedure is used to move the Sprite around the screen. It will move the Sprite from it previous location to the specified x and y
BSprite.Change(filename:string,spriteID:int)
The Change procedure is used to Change the existing Sprite to a new Picture.
BSprite.Free(spriteID:int)
The Free procedure is used to free a Sprite and to just save space. ie: like Pic.Free
BSprite.Update(spriteID:int)
The Update procedure is used to redraw the specified Sprite above others
BSprite.UpdateAll
The UpdateAll procedure is to completly redraw all Sprites, starts and the first created
BSprite.ColorBack(spriteID,color:int)
The ColorBack procedure is to set the Transparent Color of the Sprite, default setting is white (0)
BSprite.Mirror(spriteID:int)
The Mirror procedure is used to Mirror the Sprite; flip the Sprite Horizontally
BSprite.Flip(spriteID:int)
The Flip procedure is used to Flip the Sprite; flip the Sprite Vertically
BSprite.Rotate(spriteID,angle,rotatex,rotatex:int)
The Rotate procedure is used to rotate the Sprite to a desired angle, the Rotation point is specified by the rotatex and rotatey. ie:similar to Pic.Rotate
BSprite.Mode(spriteID:int,mode:int)
the Mode procedure is used to specify the desired Picture mode for the Sprite (use like a normal Picture, picCopy, picXor, picMerge), default setting is picMerge *Thxs Cervantes
BSprite.Height(spriteID:int):int
the Height function returns the value in Pixels that the Height of the Sprite is
BSprite.Width(spriteID:int):int
the Width function returns the value in Pixels that the Width of the Sprite is

Lastly, I have also included an example of BacchusSprite in the form of Zero (from Megaman) running around. Some may remember this as a .exe that I poasted before, there are bugs, and I probably sould have written it better. But it is only an Example.
Keys:
Left->Left Arror
Right->Right Arrow
Jump->Up Arrow (can jump twice)
Z-Sword-> c (can slice 3 times, buggy though)

Hope they Help you out with whatever you're doing.

-Bacchus


*For BSprite.tu file, use the one poasted by Cervantes after this post

Author:  Cervantes [ Sat Mar 19, 2005 8:45 am ]
Post subject: 

Nice Bacchus. Very well done. I have one minor improvement, though. Smile Instead of making mode a string, make it an int. That way, people can type in "picMerge" (withouth the "s) or "picCopy" or "picXor", just as they would for a normal picture. They don't have to get used to the new method. But, more importantly then that (which doesn't really matter) is you save yourself lines. Instead of having a if .. elsif .. elsif .. end if everytime you want to draw something (for the various modes) just do this:
code:

Pic.Draw (sprite (picID).pic, sprite (picID).x, sprite (picID).y, sprite (picID).mode)

sprite (picID).mode should be either 0, 1, or 2. 0 = picCopy. 1 = picXor. 2 = picMerge.
code:

put picMerge
put picCopy
put picXor


Thanks for the submission Bacchus! +50 BITS

Author:  Bacchus [ Sat Mar 19, 2005 11:53 am ]
Post subject: 

ic, i wasnt to sure about that b4 and i didnt test it as much, thxs

Author:  windowsall [ Thu Apr 14, 2005 7:31 pm ]
Post subject: 

Ok i got a question for you ummmm yeah which is better Bacchus Sprites or DanSprite i tried both and i like Bacchus but whats the difference?

Author:  Suigi [ Tue Apr 19, 2005 12:44 pm ]
Post subject: 

Ummm...I hate to be a nitpicker, but is there any chance you could repost the exemplar with Zero in it?
I could really use it to help me out.
Y'see, I'm trying to recreate the Special Stage from Sonic the Hedgehog 2 for a Grade 12 CompSci project...and right now it's stinking.
And if I could use BSprite and the accompanying example, I could make my project that much better.

Author:  Bacchus [ Tue Apr 19, 2005 7:37 pm ]
Post subject: 

oops srry i havent checked this in a bit lol. ok the difference between DanSprite and BacchusSprite (arnt i so original with that name Razz) is if you try having a sprite go outside the window. in DanSprite it will leave a bit left over. BacchusSprite also has a check for if you draw a Sprite over another, it will still get the background. then just a few other things that i cant remember lol mostly preference for me (some of DanSprites command typos bugged me and i liked shorter command names). sure ill try posting the example again (i may have to clear some space i need more then 2 mb Sad )

Author:  Mr. T [ Mon Jun 27, 2005 8:40 pm ]
Post subject:  Alex's Opinion

BSprite.ColorBack(spriteID,color:int) doesnt seem to change the pic's background colour.

Author:  [Gandalf] [ Mon Jun 27, 2005 8:42 pm ]
Post subject: 

I've never used BSprite, but it might just be treating the specified colour as the sprites background, not changing it.

Author:  Bacchus [ Mon Jun 27, 2005 10:47 pm ]
Post subject: 

Yes, thats correct. Its to set the trasperent color for the sprite.

Author:  Mr. T [ Mon Jun 27, 2005 11:08 pm ]
Post subject:  Alex's Opinion

Can u explain how to do collision detection with sprites?

Author:  Bacchus [ Mon Jun 27, 2005 11:40 pm ]
Post subject: 

Depends on how your doing your game. Side-camera View, Overhead-Camera View, etc.
For an overhead-camera view you would probably have tiles and a text file for the collision (accually I'm working on something like that atm)
For a side-camera view, you would most likely use x/y comparison.

Author:  Mr. T [ Mon Jun 27, 2005 11:50 pm ]
Post subject:  Alex's Opinion

is it a good idea (or even possible) to use whatdotcolour for this kind of collision?

Author:  Bacchus [ Wed Jun 29, 2005 6:17 am ]
Post subject: 

It probably won't be that good of an idea to use whatdotcolor with sprites because most sprites are pictures with many different colors in them. There is a way of collision detection where you draw the color of everything before the main view and use that to detect the collision, but that would makes your program go slower and in my oppinion is unnecissary because I belive that x/y comparison would work better.

Author:  [Gandalf] [ Thu Jun 30, 2005 1:16 am ]
Post subject: 

But I would warn you against using x/y comparison. It's really painful if you have a lot of obstacles. It could maybe work for a snake game, but something like a basic mario style game would require a lot of defining. One alternative way is just doing it using a grid system. Make small boxes if you need them, but its a pretty good way.

Author:  maiku [ Sat Oct 21, 2006 3:14 pm ]
Post subject:  Huh?

Ok, I know this topic is more than a year old and I probably won't get a reply, but I need help Sad

It doesn't work for me...

It draws the first sprites but then when i try to move them it pops up the BSprite.tu code window and displays the error of Process "sprite_draw": Pic was freed.

sprite_draw is the name of the process I have it looks like this:
code:

process sprite_draw
 BSprite.UpdateAll
end sprite_draw


I don't know why this happens... I don't have it set to free the pic, and when i do, it does the same thing. I've tried re-writing my code about 4 different ways and it still doesnt want to work. Any help? please

Author:  Cervantes [ Sat Oct 21, 2006 6:02 pm ]
Post subject:  Re: Huh?

maiku wrote:
I've tried re-writing my code about 4 different ways and it still doesnt want to work.

Did one of those attempts involve writing the code without using processes? That'd be my guess.

If that turns out to be the problem, I'd like to raise a big "told you so" to all those people who use processes when they should know better.

Author:  maiku [ Sun Oct 22, 2006 9:35 am ]
Post subject:  !

Eh!?

I never thought about not using processes... I shall try it and post my results

Author:  Cervantes [ Sun Oct 22, 2006 9:55 am ]
Post subject: 

Never thought about not using processes? You should avoid them at all costs. Read why.

Author:  bruized [ Wed Nov 01, 2006 8:48 pm ]
Post subject: 

Sorry for the lateness, but I was just wondering (and having a little problem). I tried using BSprites and it works but for some reason the white in the picture is not transparent. As an example take the example (oh so confusing Laughing ) and change the background colour to black(or anything other than white). You can see all the (or at least a lot) white pixels. Anyway to get rid of this?

Author:  maiku [ Wed Nov 01, 2006 8:52 pm ]
Post subject:  yes!

yes, there is!!!

its a problem with the picture format. when ur editting the picture in paint save it as a 24 colour bit map and when ur editing, fill the entire background with bright pink first, then change it all to white.

Author:  bruized [ Wed Nov 01, 2006 8:58 pm ]
Post subject: 

Yeah, I get that it has to do with the pixels not being all pure white. But when I actually tried to do this with a few of my pictures it would show the picture just fine with transparency but as soon as I stuck it in a loop with BSprite.Change to change the picture for a blinking effect it just showed the whole entire white background.

I'll see if I can fix this some how in my program.

Author:  CodeMonkey2000 [ Thu Nov 30, 2006 8:51 pm ]
Post subject: 

two procedures that feel are useful, newpic and save.
you can use these to create sprites from a sprite tree, and then save them

code:
fcn NewPic (x, y : int, px1, py1, px2, py2 : int) : int
        var spriteNum : int
        if upper (unused) > 0 then
            spriteNum := unused (1)
            for removeElement : 1 .. upper (unused) - 1
                unused (removeElement) := unused (removeElement + 1)
            end for
            new unused, upper (unused) - 1
        else
            new sprite, upper (sprite) + 1
            spriteNum := upper (sprite)
            assert spriteNum <= MaxSprite %If error then over Max amount of Sprites
        end if
        sprite (spriteNum).pic := Pic.New (px1, py1, px2, py2)
        assert sprite (spriteNum).pic > 0 %if error, could not find pic
        sprite (spriteNum).x := x
        sprite (spriteNum).y := y
        sprite (spriteNum).transClr := 0 %default color of transparent color
        sprite (spriteNum).mode := picMerge %Default Merge
        sprite (spriteNum).background := Pic.New (0, 0, 0, 0)
        Pic.SetTransparentColor (sprite (spriteNum).pic, sprite (spriteNum).transClr)
        Pic.Draw (sprite (spriteNum).pic, sprite (spriteNum).x, sprite (spriteNum).y, picMerge)
        result spriteNum
    end NewPic

    proc save (picID : int, name : string)
        assert sprite (picID).pic > 0 %if error, could not find pic
        Pic.Save (sprite (picID).pic, name)
    end save

Author:  Nigrev [ Fri Dec 01, 2006 9:39 pm ]
Post subject: 

How do you return the value of the filename for thew sprite?

Author:  CodeMonkey2000 [ Mon Jan 29, 2007 9:00 pm ]
Post subject:  Re: Sprites - Is There Another Way?

I found an error. This:
Turing:
for test_back : 1 .. upper (sprite)
            if test_back ~= picID then
                if sprite (test_back).pic ~= 0 then
                    if (x >= sprite (test_back).x & x <= sprite (test_back).x + Width (test_back))|
                            (x1 >= sprite (test_back).x & x1 <= sprite (test_back).x + Width (test_back)) then
                        if (y >= sprite (test_back).y & y <= sprite (test_back).y + Height (test_back))|
                                (y1 >= sprite (test_back).y & y1 <= sprite (test_back).y + Height (test_back)) then
                            drawBack (test_back)
                            new redraw, upper (redraw) + 1
                            redraw (upper (redraw)) := test_back
                        end if
                    elsif (sprite (test_back).x >= x & sprite (test_back).x <= x1)|
                            (sprite (test_back).x + Width (test_back) >= x &
                            sprite (test_back).x + Width (test_back) <= x1) then
                        if (sprite (test_back).y >= y & sprite (test_back).y <= y1)|
                                (sprite (test_back).y + Height (test_back) >= y &
                                sprite (test_back).y + Height (test_back) <= y1) then
                            drawBack (test_back)
                            new redraw, upper (redraw) + 1
                            redraw (upper (redraw)) := test_back
                        end if
                    end if
                end if
            end if
        end for

should be:
Turing:
for test_back : 1 .. upper (sprite)
            if test_back ~= picID then
                if sprite (test_back).pic ~= 0 then
                    if (x >= sprite (test_back).x & x <= sprite (test_back).x + Width (test_back))|
                            (x1 >= sprite (test_back).x & x1 <= sprite (test_back).x + Width (test_back)) then
                        if (y >= sprite (test_back).y & y <= sprite (test_back).y + Height (test_back))|
                                (y1 >= sprite (test_back).y & y1 <= sprite (test_back).y + Height (test_back)) then
                            drawBack (test_back)
                            new redraw, upper (redraw) + 1
                            redraw (upper (redraw)) := test_back
                        end if
                    end if
                    if (sprite (test_back).x >= x & sprite (test_back).x <= x1)|
                            (sprite (test_back).x + Width (test_back) >= x &
                            sprite (test_back).x + Width (test_back) <= x1) then
                        if (sprite (test_back).y >= y & sprite (test_back).y <= y1)|
                                (sprite (test_back).y + Height (test_back) >= y &
                                sprite (test_back).y + Height (test_back) <= y1) then
                            drawBack (test_back)
                            new redraw, upper (redraw) + 1
                            redraw (upper (redraw)) := test_back
                        end if
                    end if
                end if
            end if
        end for

I don't use BSprites myself, but my friend does and he had some layering problems, a part of his picture merged into the background and this change solved all of his problems. Also if you are using 2d mapping, wouldn't it be more efficient to just update the tiles you are about to walk into/ are in?

Author:  Saveron [ Sun Feb 18, 2007 5:43 pm ]
Post subject:  Re: Sprites - Is There Another Way?

I used photoshop to save the pictures and I did a bit of testing. I managed to make more of the pixels transparent but some are still not pure white, but they are off by just 1 or two on the RGB scale, one could be 254,255,254. I tink a way you can fix this is instead of making only one RGB colour transparent, make several of them transparent.

For example make everything from 250,250,250 to 255,255,255 transparent. This should fix the transparancy problem, but it would require the creator to have photoshop or similar to save the jpg at the maximum quality, paint will not work.


: