How can I extend the unit selection logic in my RTS game to apply to multiple units?
<p>Currently if you left-click on the unit, it becomes 'selected' (or 'de-selected'), and a green square is drawn around it. Then when you right-click somewhere on the screen, the unit moves neatly into the square in the location that you clicked.</p>

<p>Also if you use the up, down, left or right keys it will scroll the screen.</p>

<pre><code>import pygame
import random
pygame.init()

#Define mouse position
mouse_position_x = 525
mouse_position_y = 315

# Define colors
green = (0,255,0)
brown = (150,75,0)

#Define border position
border_x = 0
border_y = 0

#Define character selection box
def character_selection_box():
    pygame.draw.line(screen,green,(character_location_x,character_location_y),(character_location_x+character_width,character_location_y),2) # Top bar
    pygame.draw.line(screen,green,(character_location_x,character_location_y+character_height),(character_location_x+character_width,character_location_y+character_height),2) # Bottom bar
    pygame.draw.line(screen,green,(character_location_x,character_location_y),(character_location_x,character_location_y+character_height),2) # Left bar
    pygame.draw.line(screen,green,(character_location_x+character_width,character_location_y),(character_location_x+character_width,character_location_y+character_height+1),2) # Right bar

#Define round
def assign_square(n):
    div = (n/35)
    rou = round(div)
    mul = (35*rou)
    return int(mul)

#Set window
screen_width = 981
screen_height = 700
game_screen_width = 800
game_screen_height = 700
screen_size = (screen_width,screen_height)
screen = pygame.display.set_mode(screen_size)
pygame.display.set_caption("Warpath")

#Set block character
character_width = 35
character_height = 35
character_location_x = 525
character_location_y = 315
movement = 1
unit_selected = 0

#Load images
orc_grunt_forward = pygame.image.load('orc_forward3.png') #(35 by 35 pixel image)
character_image = orc_grunt_forward

#Loop until the user clicks the close button
shutdown = False

#Set clock
clock = pygame.time.Clock()

#Set scroll limit
scroll_x = 0
scroll_y = 0

 # ---------- Main program loop -----------
while not shutdown:

    # --- Main event loop ---
    for event in pygame.event.get():

        # --- If quit button pressed, shutdown
        if event.type == pygame.QUIT: 
            shutdown = True

        # --- If mouse button pressed
        elif event.type == pygame.MOUSEBUTTONDOWN: # If a mouse button is pressed
            mouse_position = pygame.mouse.get_pos() # Get mouse position
            button_type = pygame.mouse.get_pressed() # Check which button was pressed

            # --- If left click pressed and the curser was on a character, select that character 
            if button_type[0] == 1 and mouse_position[0] &gt;= character_location_x and mouse_position[0] &lt;= character_location_x + character_width and mouse_position[1] &gt;= character_location_y and mouse_position[1] &lt;= character_location_y + character_height:
                print("Unit selected",unit_selected)
                print(button_type)
                unit_selected += 1
                unit_selected /= unit_selected #(Otherwise it will add up unit selected if you click more than once)
                int(unit_selected)

            # --- If right click pressed and a character was selected (and it's within the game screen), move the character to the location     
            elif button_type[2] == 1 and unit_selected == 1 and mouse_position[0] &gt; 175: 
                mouse_position_x *= 0
                mouse_position_y *= 0

                if mouse_position[0] &gt;= assign_square(mouse_position[0]):
                    mouse_position_x += assign_square(mouse_position[0])

                elif mouse_position[0] &lt;= assign_square(mouse_position[0]):
                    mouse_position_x -= 35
                    mouse_position_x += assign_square(mouse_position[0])

                if mouse_position[1] &gt;= assign_square(mouse_position[1]):
                    mouse_position_y += assign_square(mouse_position[1])

                elif mouse_position[1] &lt;= assign_square(mouse_position[1]):
                    mouse_position_y -= 35
                    mouse_position_y += assign_square(mouse_position[1])

            # --- If left click pressed and the curser was not on a character, deselect the character        
            elif button_type[0] == 1 and mouse_position[0] &lt; character_location_x or mouse_position[0] &gt; character_location_x + character_width or mouse_position[1] &lt; character_location_y or mouse_position[1] &gt; character_location_y + character_height:
                print("Unit not selected")
                print(button_type)
                unit_selected *= 0
                int(unit_selected)

        # --- If key pressed, scroll the screen
        elif event.type == pygame.KEYDOWN:

            if event.key == pygame.K_RIGHT and scroll_x &gt; -10:
                direction = "right"
                character_location_x -= 35
                mouse_position_x -= 35
                border_x -= 35
                scroll_x -= 1

            if event.key == pygame.K_LEFT and scroll_x &lt; 10:
                direction = "left"
                character_location_x += 35
                mouse_position_x += 35
                border_x += 35
                scroll_x += 1

            if event.key == pygame.K_UP and scroll_y &lt; 10:
                direction = "up"
                character_location_y += 35
                mouse_position_y += 35
                border_y += 35
                scroll_y += 1

            if event.key == pygame.K_DOWN and scroll_y &gt; -10:
                direction = "down"
                character_location_y -= 35
                mouse_position_y -= 35
                border_y -= 35
                scroll_y -= 1

    # --- Game logic ---

    # --- Set character movement      
    if character_location_x &lt; mouse_position_x:
        character_location_x += movement
    if character_location_x &gt; mouse_position_x:
        character_location_x -= movement
    if character_location_y &lt; mouse_position_y:
        character_location_y += movement
    if character_location_y &gt; mouse_position_y:
        character_location_y -= movement

    # --- Drawing ---
    screen.fill(brown) # Draw background
    screen.blit(character_image,(character_location_x,character_location_y)) # Draw character

    if unit_selected == 1: 
        character_selection_box() # Draw character selection box if unit is selected

    clock.tick(30)
    pygame.display.flip()

#Shutdown
if shutdown == True:
    pygame.quit()
</code></pre>

<p>The problem is that I can't figure out how to extend this to multiple units - currently if I want to add more units I can only either manage to:</p>

<p>a) Move them all at once</p>

<p>or </p>

<p>b) Paste the same code multiple times adjusting the character variable (not a robust / scalable solution)</p>

<p>How can I adjust my code so that I have a scalable solution where:</p>

<p>1) I can select a single unit and move it, without moving every unit at once</p>

<p>2) I can select multiple units by clicking on each one individually, and move them all at once (not worrying about pathfinding right now)</p>

<p>I also tried using classes to achieve this but it still felt like I was copying / pasting multiple functions rather than having a robust solution.</p>

<p>I've removed any code that doesn't concern the issue while keeping a functioning program.</p>

<p>Thanks</p>

<p>There are few things to do:</p>

<ol>
<li>Change variables <code>character_*</code> to object that holds all data about the unit.</li>
<li>Create array of units / characters. That way each unit in array can have unique position, velocity ets. </li>
<li>Everywhere in code where you check <code>character_*</code>, change to for loops where you iterate over characters array to check every unit.</li>
<li>Next step should be adding functions like move / shoot to character class, to make keypress event working for multiple units.</li>
</ol>

<p>That should give you code where you can select multiple units (if they occupy same spot) and move them independently of deselected units.</p>

python python-3.x pygame 2d-games