how to do event checks for loops?
- by yao jiang
I am having some trouble getting the logic down for this.
Currently, I have an app that animates the astar pathfinding algorithm. On start of the app, the ui will show the following:
User can press "space" to randomly choose start/end coords, then the app will animate it.
Or, user can choose the start/end by left-click/right-click.
During the animation, the user can also left-click to generate blocks, or right-click to choose a new destiantion.
Where I am stuck at is how to handle the events while the app is animating. Right now, I am checking events in the main loop, then when the app is animating, I do event checks again. While it works fine, I feel that I am probably doing it wrong.
What is the proper way of setting up the main loop that will handle the events while the app is animating?
In main loop, the app start animating once user choose start/end. In my draw function, I am putting another event checker in there.
def clear(rows):
for r in range(rows):
for c in range(rows):
if r%3 == 1 and c%3 == 1:
color = brown;
grid[r][c] = 1;
buildCoor.append(r);
buildCoor.append(c);
else:
color = white;
grid[r][c] = 0;
pick_image(screen, color, width*c, height*r);
pygame.display.flip();
os.system('cls');
# draw out the grid
def draw(start, end, grid, route_coord):
# draw the end coords
color = red;
pick_image(screen, color, width*end[1],height*end[0]);
pygame.display.flip();
# then draw the rest of the route
for i in range(len(route_coord)):
# pausing because we want animation
time.sleep(speed);
# get the x/y coords
x,y = route_coord[i];
event_on = False;
if grid[x][y] == 2:
color = green;
elif grid[x][y] == 3:
color = blue;
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 3:
print "destination change detected, rerouting";
# get mouse position, px coords
pos = pygame.mouse.get_pos();
# get grid coord
c = pos[0] // width;
r = pos[1] // height;
grid[r][c] = 4;
end = [r, c];
elif event.button == 1:
print "user generated event";
pos = pygame.mouse.get_pos();
# get grid coord
c = pos[0] // width;
r = pos[1] // height;
# mark it as a block for now
grid[r][c] = 1;
event_on = True;
if check_events([x,y]) or event_on: # there is an event
# mark it as a block for now
grid[y][x] = 1;
pick_image(screen, event_x, width*y, height*x);
pygame.display.flip();
# then find a new route
new_start = route_coord[i-1];
marked_grid, route_coord = find_route(new_start, end, grid);
draw(new_start, end, grid, route_coord);
return; # just end draw here so it wont throw the "index out of range" error
elif grid[x][y] == 4:
color = red;
pick_image(screen, color, width*y, height*x);
pygame.display.flip();
# clear route coord list, otherwise itll just add more unwanted coords
route_coord_list[:] = [];
clear(rows);
# main loop
while not done:
# check the events
for event in pygame.event.get():
# mouse events
if event.type == pygame.MOUSEBUTTONDOWN:
# get mouse position, px coords
pos = pygame.mouse.get_pos();
# get grid coord
c = pos[0] // width;
r = pos[1] // height;
# find which button pressed, highlight grid accordingly
if event.button == 1:
# left click, start coords
if grid[r][c] == 2:
grid[r][c] = 0;
color = white;
elif grid[r][c] == 0 or grid[r][c] == 4:
grid[r][c] = 2;
start = [r,c];
color = green;
else:
grid[r][c] = 1;
color = brown;
elif event.button == 3:
# right click, end coords
if grid[r][c] == 4:
grid[r][c] = 0;
color = white;
elif grid[r][c] == 0 or grid[r][c] == 2:
grid[r][c] = 4;
end = [r,c];
color = red;
else:
grid[r][c] = 1;
color = brown;
pick_image(screen, color, width*c, height*r);
# keyboard events
elif event.type == pygame.KEYDOWN:
clear(rows);
# one way to quit program
if event.key == pygame.K_ESCAPE:
print "program will now exit.";
done = True;
# space key for random start/end
elif event.key == pygame.K_SPACE:
# first clear the ui
clear(rows);
# now choose random start/end coords
buildLoc = zip(buildCoor,buildCoor[1:])[::2];
#print buildLoc;
(start_x, start_y, end_x, end_y) = pick_point();
while (start_x, start_y) in buildLoc or (end_x, end_y) in buildLoc:
(start_x, start_y, end_x, end_y) = pick_point();
clear(rows);
print "chosen random start/end coords: ", (start_x, start_y, end_x, end_y);
if (start_x, start_y) in buildLoc or (end_x, end_y) in buildLoc:
print "error";
# draw the route
marked_grid, route_coord = find_route([start_x,start_y],[end_x,end_y], grid);
draw([start_x, start_y], [end_x, end_y], marked_grid, route_coord);
# return key for user defined start/end
elif event.key == pygame.K_RETURN:
# first clear the ui
clear(rows);
# get the user defined start/end
print "user defined start/end are: ", (start[0], start[1], end[0], end[1]);
grid[start[0]][start[1]] = 1;
grid[end[0]][end[1]] = 2;
# draw the route
marked_grid, route_coord = find_route(start, end, grid);
draw(start, end, marked_grid, route_coord);
# c to clear the screen
elif event.key == pygame.K_c:
print "clearing screen.";
clear(rows);
# go fullscreen
elif event.key == pygame.K_f:
if not full_sc:
pygame.display.set_mode([1366, 768], pygame.FULLSCREEN);
full_sc = True;
rows = 15;
clear(rows);
else:
pygame.display.set_mode(size);
full_sc = False;
# +/- key to change speed of animation
elif event.key == pygame.K_LEFTBRACKET:
if speed >= 0.1:
print SPEED_UP;
speed = speed_up(speed);
print speed;
else:
print FASTEST;
print speed;
elif event.key == pygame.K_RIGHTBRACKET:
if speed < 1.0:
print SPEED_DOWN;
speed = slow_down(speed);
print speed;
else:
print SLOWEST
print speed;
# second method to quit program
elif event.type == pygame.QUIT:
print "program will now exit.";
done = True;
# limit to 20 fps
clock.tick(20);
# update the screen
pygame.display.flip();