# How to implement rectangle selection?

I don't know if there is another term for it, but I mean this: You hold down a mouse button. A rectangle forms when you move the mouse around. The units inside the box get selected when you let go of the mouse button. I need this for a RTS style game I'm working on, but I don't know how to approach it.

I currently have functionality for selecting a unit, basically if you click within a certain area the unit is added to the list of selected units,

def mouseUp(self, button, pos):
if button==1:
for a in self.agent_list:
self.selected.append(a)
elif a in self.selected and a.pos.get_distance(self.coord_convert_adjusted(pos)) > 16:
self.selected.remove(a)


The next step would be to allow for selecting multiple units at once by checking if they are inside a box, can you provide some guidance on how I should proceed?

Edit: To clarify, I'm asking how to create a box which starts at the position of MOUSEDOWN, and changes in size relative to mouse movement while holding the pressed button down, until let go.

• possible duplicate of How do I create a selection rectangle? – MichaelHouse Jan 28 '13 at 4:12
• Finding the units inside is a simple collision test or contains test. If the unit position is greater than the box minimum position and less than the box maximum position it's inside the box. – MichaelHouse Jan 28 '13 at 4:15
• Yes pygame has a collidepoint function built in, which I'm already using elsewhere in the program. My question is about how to make the box itself. – Anonymous Entity Jan 28 '13 at 6:25
• In that case, see the duplicate. – MichaelHouse Jan 28 '13 at 6:48
• Your link is about how to make a rect not fill up (the accepted answer is to use width=1) and that thread says nothing about the question I'm asking. I'm sorry if my question is unclear, I'll try to fix it, but you have not understood what I'm asking for. – Anonymous Entity Jan 28 '13 at 7:19

For a rectangular selection, it would be a lot like your existing code.

def mouseDown(self, button, pos):
self.selection_rectangle_start = self.coord_convert(pos)

def mouseMotion(self, pos):
self.selection_rectangle_end = self.coord_convert(pos)
self.selection_rectangle = calc_rect(self.selection_rectangle_start, self.selection_rectangle_end)
for a in self.agent_list:
if a not in self.selected and a.intersects(selection_rectangle):
self.selected.append(a)
if a in self.selected and not a.intersects(selection_rectangle):
self.selected.remove(a)


intersects is just a simple overlapping rectangle check. Pygame provides Rect.colliderect for such purposes (http://www.pygame.org/docs/ref/rect.html#Rect.colliderect). calc_rect would check both the points to find the top/left/width/height and construct a valid rectangle from them.

I have to admit i am unfamiliar with python, but i think following steps seem appropriate:

1. Once the mouse is pressed down store the position it is currently at.
2. Start checking for a change in the mouse's position whenever the mouse is moved, or every X milliseconds.
3. If the mouse position has changed before the mouse is released then store the new mouse position in another variable.
4. Draw a rectangle from one position to the other.
5. When the mouse is released check each of your units x and y values to see if they are between the 2 positions.
6. Select each unit.

Hope this helps.

• This is assuming you're viewing them in 2D, if not then disregard. – Kris Welsh Jan 28 '13 at 16:09