Hello guys,
it's a newbie question, sorry,
I've been reading the forum on animating things (bullets, missiles etc...).
I know how to use bullet as a character/object.
I've read that the best method to use is DrawingSurface commands.
I've been playing with it, dynamic sprites too, but cannot understand how to make a bullet fly across the screen.
I can draw it on the screen, but how to make it move? How to erase it, and put it on next location??
I can make a backup of the background, redraw it, move the bullet, and then do that again and again, but that way seems a bit stupid.
I mean, how to make characters move at the same time? And what if there's multiple bullets at the same time?
One more thing bugs me -
If I draw a bullet, then Wait for a while (for it to be visible) and then redraw the backup of the background, wait function blocks the script, so nothing can move at that moment. Should I use Timers here? How do I go about this if there's many bullets on the screen???
Thanks for the help :)
Quote from: Mihailo on Sun 01/04/2012 21:10:12I can make a backup of the background, redraw it, move the bullet, and then do that again and again, but that way seems a bit stupid.
You might be surprised, but that's precisely a) how you're supposed to do it b) how every singly game in existence does it.
Even though it isn't apparent, moving a character across the screen using the .Walk command also means that each frame, the background is restored, then the character's current frame is drawn at its current position.
In other words, keep a database of bullets, and in repeatedly_execute, restore the background, then draw them on top.
Don't use Wait commands, what you do instead is figure out how far the bullet moves in 1/40 seconds.
Since that might end up below 1 for some objects, use floats. Calculate the x and y movement of the bullet each frame, add it to its position, then use FloatToInt(..., eRoundNearest) to get the integer supposed to go into the DrawImage function.
Quote from: Khris on Sun 01/04/2012 21:54:23
In other words, keep a database of bullets, and in repeatedly_execute, restore the background, then draw them on top.
Thanks for the reply Khris, but look at this:
If I grab the background in rep_exec function, it will have previous bullets position and the trajectory will look like a line.
If I grab it outside the function - put
DrawingSurface *surface = Room.GetDrawingSurfaceForBackground();
DrawingSurface *backup = surface.CreateCopy();
outside the rep_exec function), the script won't let me use variable (in this case 'surface and backup') within the rep_exec function (to redraw the background), cause it's been defined outside, and they cannot be declared as global variables...
Eh?
You could also make the bullet an object or character as you already realized.
Or if ya wanna make it realistic don't draw the bullet at all - because in reality bullets are so fast ya can't see them anyways.
Do it like this:
// top of room script
DynamicSprite*backup;
// inside room_Load (enters room before fadein event)
backup = DynamicSprite.CreateFromBackground();
// inside room_RepExec
DrawingSurface*surface = Room.GetDrawingSurfaceForBackground();
surface.DrawImage(0, 0, backup.Graphic);
// draw bullets here
surface.Release();
Thanks Khris, that makes perfect sense, you're the man! :)
ps. Kyodai, your comment was funny, I always enjoy a good laugh - like this ha ha ha!
A follow up question, while we're on the go :)
How do you check if the bullet has hit the object/character/another sprite if using this approach? (drawingsurface)
Thanks!
// turn bullet's room coordinates into screen coordinates if it's a scrolling room
int x = bullet_x - GetViewpointX();
int y = bullet_y - GetViewpointY();
// find out what's at the bullet's position
int lt = GetLocationType(x, y);
if (lt == eLocationNothing) return;
else {
if (lt == eLocationCharacter) {
Character*c = Character.GetAtScreenXY(x, y);
c.Hit();
}
// check objects the same way here
}
Obviously, this has to go into repeatedly_execute, too.
The .Hit() function I used in my example can be added using an extender function:
function Hit(this Character*) {
// add points
// play a sound
this.ChangeRoom(-1); // remove Character
}
Functions can only be called after they are defined, so paste that above rep_ex, if you want to use it.
Thank you Khris :)
Until I come up with another question!