Computer Science Canada

Animating Background picture, while having a picture in front (and staying there)

Author:  TigerFallOut [ Tue Nov 01, 2011 9:51 pm ]
Post subject:  Animating Background picture, while having a picture in front (and staying there)

What is it you are trying to achieve?
I have a picture with a background, and I want the background to change colours, while the picture on front stays there. (The background a bunch of triangles that meet in the (near)middle of the screen, the first on is green, the next blue, then green, etc.) I want the 2 colours to alternate (the green become blue for a sec, then back to green) so it looks like its flashing. There are also circles randomly between the 2 layers (the blue triangles, then circles, then green triangles)

I can't really describe it, you should just look at my 2 attachments.


What is the problem you are having?
Trying to keep the background in the background (while alternating colours), while there are other pictures on top. The background just goes right on top.


Describe what you have tried to solve this problem
- using a loop to alternate colours (that ends up filling the screen)
- using a process and fork. the process has the colours looping. (im pretty sure im doing something wrong), this succeeds in alternating colours, but the background is the whole picture. (and when it starts out, one of the triangles is supposed to be green, but starts out blue (but in the next loop its green)
- tried putting it in different spots.
- teacher did some complicated loop thing that made one colour alternate, but not the other set of triangles. (i coulnt get it to do the other set to change colours)


Post any relevant code (You may choose to attach the file instead of posting the code if it is too long)
*I dont want people in my class copying, i am not going to post the whole picture*


Please specify what version of Turing you are using
4.11

One other question
If you see my picture, i have a few stars. can you make them move off the screen? I know to animate it normally, you 'erase' it by redrawing it in the background colour, but my background is not a solid colour, how would you make it move?

Author:  Tony [ Tue Nov 01, 2011 10:33 pm ]
Post subject:  RE:Animating Background picture, while having a picture in front (and staying there)

The analogy you should be thinking of for animations are movie frames, from a cinema tape. That is, an animation is a sequence of frames, one after another.

code:

loop
   draw background
   draw foreground
   clear*
end loop


* Because you'll be drawing parts slower than the screen updates, you'll start getting incomplete frames. This will be especially apparent when clear's blank screen has a high contrast to the rest of the frame (will appear as flashing). This is fixable with offscreenonly and View.Update -- you can read about those after you get the frames to work.

Author:  Beastinonyou [ Tue Nov 01, 2011 10:34 pm ]
Post subject:  Re: Animating Background picture, while having a picture in front (and staying there)

Instead of using all those lines in the program, run the program once, with the one background image, and take an image of the entire thing, and save it as a .jpg or .bmp.

Then do that for the second background image.

Or you could just make a picture in turing after drawing the image once. No need for processes when you can do this:

Turing:

% Background 1 Lines of code
var backGround1 : int := Pic.New (0, 0, maxx, maxy)
cls

% Background 2 Lines of Code
var backGround2 : int := Pic.New (0, 0, maxx, maxy)
cls

% Domo Image lines of code
var domoPic : int := Pic.New (280, 140, 475, 380)
cls

var counter : int
process bgDelay
     counter := 1
     delay (500)
     counter := 2
     delay (500)
end bgDelay

View.Set ("offscreenonly")
loop
     if counter = 1 then
          Pic.Draw (backGround1, 0, 0, picUnderMerge)
     else
          Pic.Draw (backGround2, 0, 0, picUnderMerge)
     end if
     fork bgDelay
     Pic.Draw (domoPic, 280, 140, picMerge)
     View.Update
     % Possible Delay
end loop


I haven't tried this with your entire code , but in theory, it should work. You could either create these pictures using Pic.New (), or load them externally using Pic.FileNew ().

Basically, You just create a picture for background 1 and 2, and a picture for domo. Then you stick it in a loop, and draw them. bgDelay is used for a 500ms delay between displaying the images. So it will draw backGround1, then delay without halting the program for 500ms, then counter becomes 2, which makes it draw the second background.

Notice the way I'm drawing the backGround pictures? using: picUnderMerge, which acts as it sounds,

Meanwhile, you're drawing Domo on top of the program. Lastly, you're eliminating flickering using View.Update (in conjunction with View.Set ("offscreenonly")). I suppose you could also add a small delay to that.

Author:  TigerFallOut [ Tue Nov 01, 2011 10:58 pm ]
Post subject:  Re: Animating Background picture, while having a picture in front (and staying there)

I forgot to mention that the the assignment needs me to actually draw my stuff (not just putting images in, trust me, i wanted to do that). But i figured out how to animate the background without it starting weirdly. I havent tried to put the bg into the bigger picture yet.

Do i need a process to get the background to stay at the back, instead of it coming to the front all the time?

EDIT: One question: Can someone explain to me what exactly is a process and a fork? And how do you use one? The teacher mentioned it, and told me to use one, but didnt really explain it.

Author:  Dreadnought [ Tue Nov 01, 2011 11:24 pm ]
Post subject:  Re: Animating Background picture, while having a picture in front (and staying there)

I really don't think that running concurrent processes is what you're looking for, especially if you're trying to keep the background in the back, since you have no way of telling the computer in what order, or with what priority to run the separate processes.

Tony's post pretty much says it all really. Make a loop that create frames. Draw the background first, then the foreground over top for each. Then call View.Update to update the entire run window at once. The idea is to not show the frame where the background covers the foreground. Here's some links that might be helpful.

Why avoid processes: http://compsci.ca/v3/viewtopic.php?t=7842
View.Update tutorial: http://compsci.ca/v3/viewtopic.php?t=12533
Turing Walkthrough: http://compsci.ca/v3/viewtopic.php?t=8808

Good luck.

Author:  Zren [ Tue Nov 01, 2011 11:30 pm ]
Post subject:  Re: Animating Background picture, while having a picture in front (and staying there)

If you ever go about doing this effect again, consider the following diagram:

Posted Image, might have been reduced in size. Click Image to view fullscreen.

While more complex, it's much more dynamic.

Basically you iterate (loop) over each section of the pie, while iterating over a list of colours. Drawing a section of a circle can be done with Draw.FillArc in Turing.

Things we need to know first however, is the radius of the circle. That can be found by finding the maximum distance to the edges of the screen. The maximum will be one of the 4 corners. In the diagram, the focal point (center of the circle) is slightly above and to the right the middle of the screen, so the bottom left is the furthest distance.

Author:  Beastinonyou [ Wed Nov 02, 2011 6:15 am ]
Post subject:  Re: Animating Background picture, while having a picture in front (and staying there)

TigerFallOut @ Tue Nov 01, 2011 10:58 pm wrote:
I forgot to mention that the the assignment needs me to actually draw my stuff (not just putting images in, trust me, i wanted to do that).


So, The assignment needs you to manually draw all those. You've already done that. So Create a Picture In-Turing sort of speak, that way, say you needed to draw it again, you just use Pic.Draw ().

I don't see the point in messing around trying to get it to work without pictures. You just make it harder on your part.

I did suggest Pic.FileNew(), but since that is loaded externally, then just use:

Turing:

var picture : int := Pic.New (x1, y1, x2, y2)


Which creates a picture between those co-ordinates in Turing, and stores it in a variable.

If you really don't wish for convenience using pictures, then I would suggest procedures.

Author:  TigerFallOut [ Wed Nov 02, 2011 3:56 pm ]
Post subject:  Re: Animating Background picture, while having a picture in front (and staying there)

Thanks for your help and links. I've tried putting the whole thing in a loop, and adding if statements, but i think somethings missing.

In the loop before the picture

Turing:

var count:int:=0

loop
count:=count+1

if (count=1) then

draw Background1

elsif (count=2) then

draw Background2

end if

draw RestOfPicture




At the end i put

Turing:

if (count=1) then
    count:=2
else
    count:=1
end if

end loop



The screen ends up flashing between different parts of the picture.

Author:  Tony [ Wed Nov 02, 2011 4:14 pm ]
Post subject:  Re: Animating Background picture, while having a picture in front (and staying there)

TigerFallOut @ Wed Nov 02, 2011 3:56 pm wrote:
The screen ends up flashing between different parts of the picture.


Tony @ Tue Nov 01, 2011 10:33 pm wrote:

* Because you'll be drawing parts slower than the screen updates, you'll start getting incomplete frames. This will be especially apparent when clear's blank screen has a high contrast to the rest of the frame (will appear as flashing). This is fixable with offscreenonly and View.Update -- you can read about those after you get the frames to work.

Author:  TigerFallOut [ Wed Nov 02, 2011 5:27 pm ]
Post subject:  RE:Animating Background picture, while having a picture in front (and staying there)

I think i got Very Happy.

I tried earlier offscreenonly and one view.update, but turns out it works with 2 Very Happy.

EDIT: er, now i have another problem. I'm trying to animate domo's eyes to blink at the same time, so i used a process earlier and forked them. but now it doesnt work. What should i use to correct this?

Author:  Tony [ Wed Nov 02, 2011 5:46 pm ]
Post subject:  RE:Animating Background picture, while having a picture in front (and staying there)

Not use process. It's fundamentally incompatible with with the idea of View.Update (unless you use synchronization; but using a procedure instead of a process is much easier to understand).

Author:  TigerFallOut [ Wed Nov 02, 2011 5:51 pm ]
Post subject:  Re: Animating Background picture, while having a picture in front (and staying there)

I tried using 2 procedures (1 for each eye), and putting them into a loop with a view.update. but only 1 eye blinks, the other eye doesnt ever show up

Turing:

View.Set ("graphics:640;480,offscreenonly")

%domos body
drawfillbox (280,140, 475, 380, 114)


%domos left eye
procedure lefteye
loop
    drawfilloval (320, 320, 15, 15, 16)
    delay (1000)
    drawfilloval (320, 320, 15, 15, 114)
    Draw.ThickLine (305,320,335,320,3,16)
    delay (220)
    Draw.ThickLine (305,320,335,320,3,114)
end loop
end lefteye


%domos right eye
procedure righteye
loop
    drawfilloval (435, 320, 15, 15, 16)
    delay (1000)
    drawfilloval (435, 320, 15, 15, 114)
    Draw.ThickLine (420,320,450,320,3,16)
    delay (220)
    Draw.ThickLine (420,320,450,320,3,114)
end loop
end righteye

loop
lefteye
righteye

View.Update
end loop


What is synchronization in turing? and how do you use it?

Author:  Tony [ Wed Nov 02, 2011 6:05 pm ]
Post subject:  RE:Animating Background picture, while having a picture in front (and staying there)

when does the lefteye's loop exit, to give righteye a chance to draw anything?

Author:  Beastinonyou [ Wed Nov 02, 2011 6:59 pm ]
Post subject:  Re: RE:Animating Background picture, while having a picture in front (and staying there)

Tony @ Wed Nov 02, 2011 6:05 pm wrote:
when does the lefteye's loop exit, to give righteye a chance to draw anything?


Exactly.

Why are the eye's even in their own loop, when they're also within the loop of the main program.

You enter a loop, then enter another loop to draw the left eye blinking. No exit condition...... How is it supposed to even reach the right eye?

Author:  TigerFallOut [ Wed Nov 02, 2011 8:41 pm ]
Post subject:  Re: Animating Background picture, while having a picture in front (and staying there)

Yeah, i realized i could put them both in one loop....

I got them to blink:

Turing:

%domo
drawfillbox (280,140, 475, 380, 114)

%blinking eyes
loop
    drawfilloval (320, 320, 15, 15, 16)
    drawfilloval (435, 320, 15, 15, 16)
    delay (1500)
   
    drawfilloval (320, 320, 15, 15, 114)
    Draw.ThickLine (305,320,335,320,3,16)
   
    drawfilloval (435, 320, 15, 15, 114)
    Draw.ThickLine (420,320,450,320,3,16)
    delay (220)
    Draw.ThickLine (305,320,335,320,3,114)
    Draw.ThickLine (420,320,450,320,3,114)
end loop


But how do i insert it into the main loop? do i just put it in without the loop, and let the main loop loop it? If i do that, how do i control the blinking speed?

Author:  Beastinonyou [ Wed Nov 02, 2011 9:26 pm ]
Post subject:  Re: Animating Background picture, while having a picture in front (and staying there)

/facepalm

You could have kept your code in the procedures. Just remove the loops from the procedures. That would ensure that it runs the first and second procedure without getting caught in another loop.

You could control it with a delay, if you wanted.

Turing:

procedure leftEye
     % Code
end leftEye

procedure rightEye
     % Code
end rightEye

% Main Program
loop
     leftEye
     delay (1000)
     rightEye
     delay (1000)
end loop


Those delay's might not exactly be what you want. But those procedures should make it easier ....

Author:  TigerFallOut [ Wed Nov 02, 2011 10:18 pm ]
Post subject:  RE:Animating Background picture, while having a picture in front (and staying there)

err, now one left eye appears, it disappears, then right eye appears, and it disappears....

And i think i have too much code in the program... it runs quite slowly....

Author:  Dreadnought [ Thu Nov 03, 2011 12:38 pm ]
Post subject:  Re: Animating Background picture, while having a picture in front (and staying there)

So you want to have two eyes blinking at the same time on this domo thing. So I suggest have one procedure to draw both eyes when they are closed, another to draw them when they are opened, and one to draw the body.

Sorta like this

Turing:

proc drawBody
%code to draw the body of the domo thing
end drawBody

proc drawEyesOpen
% code to draw the eyes when they are open
end drawEyesOpen

proc drawEyesClosed
% code to draw the eyes when they are closed
end drawEyexClosed


loop

% Eyes are open
drawBody
drawEyesOpen
Time.Delay(1000)

% Eyes are closed
drawBody
drawEyesClosed
Time.Delay(300)

end loop


You can add in View.Update to make it prettier.

Hope this helps.

Author:  Zren [ Thu Nov 03, 2011 2:27 pm ]
Post subject:  RE:Animating Background picture, while having a picture in front (and staying there)

Again, I'll touch on the more advanced thinking than the 'just making it work' method.


As your eventual goal is to have some blinking eyes on top a background that's being animated every frame, you'll want to stop bottlenecking your program by throwing tons of delays in there. This doesn't mean take your current code and delete all your delays, but to rethink your program's flow.

When drawing, you should be thinking along the lines of "What is the state of the left eye?" and "What is the state of the background?"

There are two states for your background. backgroundState = start with green or start with purple. As well as two states for your eyes eyeState = open or closed. An example of the program flow would be (render = draw):

code:

proc update
    updateEyes
    updateBackground
end

loop
    update
    renderFrame
end loop


But now we're updating every frame! Say we have a program that only has objects that change state periodically, like if we were just controlling the eyes (and not the background), how would we use the same program flow, but reduce redundant rendering? We'll we'd check if we've changed states during the update, which would then trigger a redraw.

A good way to do this might be to use a flag variable in the scope that all the update functions can access.

code:

var changed :boolean := false

proc updateEyes()
    ...
   
    changed := true
end updateEyes

loop
    update
    if changed then
        renderFrame
        changed:= false
    end if
end loop


In both cases, we'll still want to limit the framerate with a delay so our simple program doesn't max out our CPU. Eg: fpsDelay = 1000 / desiredFPS

code:

loop
    if update then
        renderFrame
    end if
    delay(fpsDelay)
end loop


A simple way to update your eyes would be to store the last time your eye changed states, then check if it's been 3 seconds since they've opened or half a second since they've closed. The updateBackground would be easier since it's cycling every frame and you don't need to keep track of anything extra.

Author:  TigerFallOut [ Thu Nov 03, 2011 6:44 pm ]
Post subject:  RE:Animating Background picture, while having a picture in front (and staying there)

I didnt really get that......

but right now, my picture is working.... so, I'll try to figure that out later, cuz this thing is due tomorrow.

Thanks for everybody's help, i learned quite a lot Very Happy (although a lot of it was kinda advanced for me since i just started using turing in september with barely any previous programming knowledge)


: