|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
Bartl
Joined: 16 Oct 2009 Posts: 58 Location: München
|
Posted: Wed Nov 14, 2012 3:28 pm Post subject: moving rectangle |
|
|
Hi,
according to the experience of my last forum subject I tried to write a example for a moving rectangle which works fine.
But I am not sure if the code is very good.
Following questions:
- exist a better solution to erase the whole screen instead of delete the old rectangle
- how to make the code faster?
- the lines marked with "! I don't understand why" I do not understand, the code is from a earlier forum example, but without these lines it does not work
- exist a complete better solution for this example?
Johann
Code: |
winapp
module common_variables
real*8 seconds
real*4 rad,deg
integer*4 k,i,ix1,iy1,r,iHandle,ans,xcenter,ycenter
end module common_variables
program test
use common_variables
implicit none
INCLUDE <windows.ins>
external startit, stopit, exitit
r= 50
xcenter=130; ycenter=100 ! values as example
deg=0.0
seconds=0.001
ans=winio@('%ca[test: drawing of moving rectangle]&')
ans=winio@('%bg[grey]&')
ans=winio@('%`gr[white,rgb_colours]&',300L,300L, iHandle)
ans=winio@('%ff%2nl%^bt[start] &',startit)
ans=winio@('%^bt[stop] &' ,stopit)
ans=winio@('%^bt[exit] ' ,exitit)
end program
!-------------------------------------------------
integer function startit ()
use common_variables
implicit none
INCLUDE <windows.ins>
real*4 sec
k=1 ! I don't understand why
sec = seconds
call PERMIT_ANOTHER_CALLBACK@
do ! I don't understand why
!call temporary_yield@
!CALL window_update@(k)
if (k==0) exit ! I don't understand why
call circle
! draw a new rectangle
CALL DRAW_RECTANGLE@ (ix1,iy1,ix1+50,iy1+50, '[black]' )
call sleep@ (sec)
! erase the old rectangle
CALL DRAW_RECTANGLE@ (ix1,iy1,ix1+50,iy1+50,rgb@(255,255,255) )
deg = deg + 2.0
end do
startit = 1
end function startit
!-----------------------------------------------------
integer function stopit ()
use common_variables
implicit none
k=0
stopit = 1
end function stopit
!------------------------------------------------------
integer function exitit ()
use common_variables
implicit none
k=0
exitit = 0 ! return zero to stop
end function exitit
!--------------------------------------------------------
subroutine circle
use common_variables
rad = deg*3.14159 / 180
ix1 = xcenter + cos(rad)*r
iy1 = ycenter - sin(rad)*r ! circle movement
!iy1 = ycenter ! left/right movement
return
end
|
|
|
Back to top |
|
|
jalih
Joined: 30 Jul 2012 Posts: 196
|
Posted: Wed Nov 14, 2012 6:30 pm Post subject: Re: moving rectangle |
|
|
Bartl wrote: |
Following questions:
- exist a better solution to erase the whole screen instead of delete the old rectangle
|
If there is only a small amount of moving objects, then erasing only the "dirty" rectangle is probably the best approach.
With a lot of moving objects, I think the double buffered approach works the best.
A little double buffered example for you to play with available here |
|
Back to top |
|
|
LitusSaxonicum
Joined: 23 Aug 2005 Posts: 2388 Location: Yateley, Hants, UK
|
Posted: Wed Nov 14, 2012 9:37 pm Post subject: |
|
|
Regarding the two lines you don't understand, you need to find out if the user has pressed either 'stop' or 'exit' buttons. So you set k=1, and each time you are about to draw the new rectangle, you see if k is still 1. But startit is the callback to a button press. The only way that k can be anything else but 1 is for it to be changed by one of the other button presses. But those buttons' callbacks will only happen when the callback for 'startit' has completed. That is why a few lines before, the routine PERMIT_ANOTHER_CALLBACK@ has been called. Now, the callbacks for 'stopit' and 'exitit' are enabled. If one of those buttons is pressed, k is set to 0, and the next time round the indefinite loop (I never used such a thing, and except that it works, I would not have believed it even existed!) the program exits the 'startit' button's callback.
You ought to be able to speed up the movement by changing the value of sec in call sleep@ (sec), but this is accurate only to a 'tick' of which there are 18.2 ticks per second, so as sec is set to 0.001, you can only sleep@ for one tick! (But you can definitely slow it down by making sec bigger!). If you comment out the sleep@ call, the program becomes unresponsive, which is what the temporary_yield@ and window_update@ lines are there to fix.
In your case, you always know the value of the coordinates of the last rectangle to be drawn, so you can clear that. The speed at which your rectangle is moving depends on sec. It is not a slowness created by blanking the last rectangle and drawing a new one. If you don't know what area to blank, you can blank the whole of the %gr area, and on a modern pc of just about any type, the speed at which this occurs will amaze you (unless each step requires drawing possibly hundreds or thousands of graphic elements, not just one empty rectangle).
Jalih prefers the double-buffered approach, and this is what you would do for a fast-moving game. For relatively static graphics, you can just redraw the screen. As long as it is fast enough to trick the eye of the user, then it is fast enough to give the impression of movement, or immediate change
Eddie |
|
Back to top |
|
|
Bartl
Joined: 16 Oct 2009 Posts: 58 Location: München
|
Posted: Mon Nov 19, 2012 10:19 am Post subject: |
|
|
Eddi,
thank you very much for your helpful explanation.
I think that that I can live first of all with erasing only the "dirty" rectangle.
The double buffered example seems difficulty for me on the first view,
but I hope that understand it when I have more time to study it.
Thank you very much for your help.
Johann |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|