Running once... In a loop?
Author |
Message |
Grim
|
Posted: Thu Oct 21, 2010 7:22 pm Post subject: Running once... In a loop? |
|
|
What is it you are trying to achieve?
I'm trying to create a game using Pac-Man. I am using whatdotcolour for collision detection, but because that code has to be in the same loop as my draw commands, I am re-drawing my background every time, causing an annoying flicker.
Describe what you have tried to solve this problem
Nested loop, Nested for loop, nested decreasing for loop, placing draw command outside loop
Here's the code...
Turing: |
loop
collision := false
mouth := mouth mod 45 + 1 % change size of the mouth
drawfillarc (x, y, 20, 20, mouth + dir, -mouth + dir, yellow)
delay (5)
drawfillarc (x, y, 20, 20, mouth + dir, -mouth + dir, black)
x := x + xx
y := y + yy
Draw.FillBox (0, 0, 1000, 1000, brightblue)
Draw.FillBox (20, 20, maxx - 20, maxy - 20, black)
Draw.FillBox (300, 0, 340, 150, brightblue)
Draw.FillBox (300, 250, 340, 400, brightblue)
if whatdotcolor (x, y ) not= black then
x - = xx
y - = yy
collision := true
end if
end loop
|
Any possible way of making that draw command run only once? |
|
|
|
|
|
Sponsor Sponsor
|
|
|
DanShadow
|
Posted: Thu Oct 21, 2010 8:09 pm Post subject: RE:Running once... In a loop? |
|
|
If flickering is your issue, using:
View.Set ("graphics,offscreenonly")
should fix your problem.
Alternatively, you can draw your background outside your loop, and every time pacman moves you can redraw a portion of the background where pacman used to be (before he moved). Im guessing the background would be black, so pretty easily done.
View.Set("graphics,offscreenonly") is probably a lot easier though. |
|
|
|
|
|
Grim
|
Posted: Thu Oct 21, 2010 8:48 pm Post subject: Re: Running once... In a loop? |
|
|
I'll post the whole program. The flickering is caused because every time my loop runs, it re-draws the background. Perhaps this will show you what I mean.
Turing: |
var dx, dy : int % direction Pacman moves
var mouth : int := 0 % size of mouth
var dir : int := 0 % mouth direction, 0=right, 90=up, etc.
var xx : int := 0
var yy : int := 0
var collision : boolean := false
var check : int := 1
const mup := chr (200)
const mdown := chr (208)
const mleft := chr (203)
const mright := chr (205)
dx := 1
dy := 0
process movement
loop
var key : array char of boolean
loop
xx := round (dx )
yy := round (dy )
Input.KeyDown (key )
if key (mup ) then
dir := 90
dx := 0
dy := 1
elsif key (mdown ) then
dir := 270
dx := 0
dy := - 1
elsif key (mleft ) then
dir := 180
dx := - 1
dy := 0
elsif key (mright ) then
dir := 0
dx := 1
dy := 0
end if
end loop
end loop
end movement
fork movement
process coll
loop
collision := false
mouth := mouth mod 45 + 1 % change size of the mouth
drawfillarc (x, y, 20, 20, mouth + dir, -mouth + dir, yellow)
delay (5)
drawfillarc (x, y, 20, 20, mouth + dir, -mouth + dir, black)
x := x + xx
y := y + yy
Draw.FillBox (0, 0, 1000, 1000, brightblue)
Draw.FillBox (20, 20, maxx - 20, maxy - 20, black)
Draw.FillBox (300, 0, 340, 150, brightblue)
Draw.FillBox (300, 250, 340, 400, brightblue)
if whatdotcolor (x, y ) not= black then
x - = xx
y - = yy
collision := true
end if
end loop
end coll
|
I know processes are a no-no around here, but this seemed the easiest way to do it at the time. |
|
|
|
|
|
TheGuardian001
|
Posted: Thu Oct 21, 2010 9:12 pm Post subject: Re: Running once... In a loop? |
|
|
Grim @ Thu Oct 21, 2010 8:48 pm wrote:
I know processes are a no-no around here, but this seemed the easiest way to do it at the time.
It's not. Processes will basically guarantee flickering, even if you use View.Set("offscreenonly"), which you should be using.
Your layout should look something like this:
code: |
declare variables
View.Set("offscreenonly") %Don't draw anything to the screen until we say so
procedure movement %procedure, not process
%NO LOOPS ALLOWED IN HERE
movement code
%NO LOOPS ALLOWED IN HERE
end movement
procedure coll %again, not a process
%NO LOOPS ALLOWED IN HERE
drawing code
%NO LOOPS ALLOWED IN HERE
end coll
%Main loop.
%This replaces all the loops in your processes, allowing you to use
%procedures instead.
loop
movement %move ONCE
coll %draw ONCE
View.Update %put all of our drawing on screen (needed with offscreenonly)
end loop
|
|
|
|
|
|
|
Grim
|
Posted: Thu Oct 21, 2010 9:34 pm Post subject: RE:Running once... In a loop? |
|
|
Using View.Update, I can't actually get Pac-Man to move. I get the drawing but nothing else. |
|
|
|
|
|
TheGuardian001
|
Posted: Thu Oct 21, 2010 9:38 pm Post subject: Re: RE:Running once... In a loop? |
|
|
Grim @ Thu Oct 21, 2010 9:34 pm wrote: Using View.Update, I can't actually get Pac-Man to move. I get the drawing but nothing else.
1)Are you still using processes
2)Do you have both View.Set("offscreenonly") and View.Update? You need both. |
|
|
|
|
|
Grim
|
Posted: Thu Oct 21, 2010 9:50 pm Post subject: Re: RE:Running once... In a loop? |
|
|
TheGuardian001 @ 21/10/2010, 21:38 wrote: Grim @ Thu Oct 21, 2010 9:34 pm wrote: Using View.Update, I can't actually get Pac-Man to move. I get the drawing but nothing else.
1)Are you still using processes
2)Do you have both View.Set("offscreenonly") and View.Update? You need both.
Yes, using offscreenonly and View.Update, no processes. Here.
Turing: |
View.Set ("graphics, nocursor, offscreenonly")
var x : int := 100
var y : int := maxy - maxy div 2 % x and y of Pacman's centre
var dx, dy : int % direction Pacman moves
var mouth : int := 0 % size of mouth
var dir : int := 0 % mouth direction, 0=right, 90=up, etc.
var xx : int := 0
var yy : int := 0
var collision : boolean := false
var check : int := 1
const mup := chr (200)
const mdown := chr (208)
const mleft := chr (203)
const mright := chr (205)
dx := 1
dy := 0
procedure movement
var key : array char of boolean
xx := round (dx )
yy := round (dy )
Input.KeyDown (key )
if key (mup ) then
dir := 90
dx := 0
dy := 1
elsif key (mdown ) then
dir := 270
dx := 0
dy := - 1
elsif key (mleft ) then
dir := 180
dx := - 1
dy := 0
elsif key (mright ) then
dir := 0
dx := 1
dy := 0
end if
end movement
procedure coll
collision := false
mouth := mouth mod 45 + 1 % change size of the mouth
drawfillarc (x, y, 20, 20, mouth + dir, -mouth + dir, brightred)
delay (5)
drawfillarc (x, y, 20, 20, mouth + dir, -mouth + dir, white)
x := x + xx
y := y + yy
Draw.FillBox (0, 0, 1000, 1000, black)
Draw.FillBox (20, 20, maxx - 20, maxy - 20, white)
Draw.FillBox (300, 0, 340, 150, black)
Draw.FillBox (300, 250, 340, 400, black)
if whatdotcolor (x, y ) not= white then
x - = xx
y - = yy
collision := true
end if
end coll
loop
movement
coll
View.Update
end loop
|
Presumably, I could put View.Update at the end of each procedure, but even that doesn't work. |
|
|
|
|
|
TheGuardian001
|
Posted: Thu Oct 21, 2010 10:52 pm Post subject: Re: Running once... In a loop? |
|
|
Let's take a look at the order you're drawing in:
code: |
Draw pac man
Erase pac man
Draw Background
Draw walls
Update
|
You need to rearrange it so that Pac-Man is drawn last (since he's on top) and isn't erased before you update.
code: |
Draw Background
Draw Walls
Draw Pac-Man
Update
|
Erasing Pac-man is not actually required, since you draw a while box the size of the screen each loop anyway. |
|
|
|
|
|
Sponsor Sponsor
|
|
|
|
|