如何扩展我的 RTS 游戏中的单位选择逻辑以应用于多个单位?
How can I extend the unit selection logic in my RTS game to apply to multiple units?
目前如果你左键点击单位,它会变成'selected'(或'de-selected'),并在它周围画一个绿色方块。然后,当您右键单击屏幕上的某处时,该单位会整齐地移动到您单击位置的正方形中。
此外,如果您使用向上、向下、向左或向右键,它会滚动屏幕。
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] >= character_location_x and mouse_position[0] <= character_location_x + character_width and mouse_position[1] >= character_location_y and mouse_position[1] <= 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] > 175:
mouse_position_x *= 0
mouse_position_y *= 0
if mouse_position[0] >= assign_square(mouse_position[0]):
mouse_position_x += assign_square(mouse_position[0])
elif mouse_position[0] <= assign_square(mouse_position[0]):
mouse_position_x -= 35
mouse_position_x += assign_square(mouse_position[0])
if mouse_position[1] >= assign_square(mouse_position[1]):
mouse_position_y += assign_square(mouse_position[1])
elif mouse_position[1] <= 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] < character_location_x or mouse_position[0] > character_location_x + character_width or mouse_position[1] < character_location_y or mouse_position[1] > 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 > -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 < 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 < 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 > -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 < mouse_position_x:
character_location_x += movement
if character_location_x > mouse_position_x:
character_location_x -= movement
if character_location_y < mouse_position_y:
character_location_y += movement
if character_location_y > 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()
问题是我不知道如何将其扩展到多个单元 - 目前如果我想添加更多单元我只能设法:
a) 一次移动它们
或
b) 多次粘贴相同的代码调整字符变量(不是稳健/可扩展的解决方案)
如何调整我的代码,以便我有一个可扩展的解决方案,其中:
1) 我可以 select 移动一个单元,而不是一次移动每个单元
2) 我可以 select 多个单位通过单独点击每个单位,然后一次移动它们(现在不用担心寻路)
我也尝试过使用 类 来实现这一点,但我仍然觉得我在复制/粘贴多个函数,而不是拥有一个可靠的解决方案。
我删除了与该问题无关的所有代码,同时保持程序正常运行。
谢谢
有几件事要做:
- 将变量
character_*
更改为包含有关该单元的所有数据的对象。
- 创建单位/字符数组。这样阵列中的每个单元都可以具有唯一的位置、速度等。
- 在您检查
character_*
的代码中的任何地方,更改为迭代字符数组以检查每个单元的 for 循环。
- 下一步应该是为角色添加移动/射击等功能class,让按键事件适用于多个单位。
那应该给你代码,你可以 select 多个单位(如果它们占据相同的位置)并独立于 deselected 单位移动它们。
目前如果你左键点击单位,它会变成'selected'(或'de-selected'),并在它周围画一个绿色方块。然后,当您右键单击屏幕上的某处时,该单位会整齐地移动到您单击位置的正方形中。
此外,如果您使用向上、向下、向左或向右键,它会滚动屏幕。
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] >= character_location_x and mouse_position[0] <= character_location_x + character_width and mouse_position[1] >= character_location_y and mouse_position[1] <= 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] > 175:
mouse_position_x *= 0
mouse_position_y *= 0
if mouse_position[0] >= assign_square(mouse_position[0]):
mouse_position_x += assign_square(mouse_position[0])
elif mouse_position[0] <= assign_square(mouse_position[0]):
mouse_position_x -= 35
mouse_position_x += assign_square(mouse_position[0])
if mouse_position[1] >= assign_square(mouse_position[1]):
mouse_position_y += assign_square(mouse_position[1])
elif mouse_position[1] <= 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] < character_location_x or mouse_position[0] > character_location_x + character_width or mouse_position[1] < character_location_y or mouse_position[1] > 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 > -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 < 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 < 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 > -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 < mouse_position_x:
character_location_x += movement
if character_location_x > mouse_position_x:
character_location_x -= movement
if character_location_y < mouse_position_y:
character_location_y += movement
if character_location_y > 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()
问题是我不知道如何将其扩展到多个单元 - 目前如果我想添加更多单元我只能设法:
a) 一次移动它们
或
b) 多次粘贴相同的代码调整字符变量(不是稳健/可扩展的解决方案)
如何调整我的代码,以便我有一个可扩展的解决方案,其中:
1) 我可以 select 移动一个单元,而不是一次移动每个单元
2) 我可以 select 多个单位通过单独点击每个单位,然后一次移动它们(现在不用担心寻路)
我也尝试过使用 类 来实现这一点,但我仍然觉得我在复制/粘贴多个函数,而不是拥有一个可靠的解决方案。
我删除了与该问题无关的所有代码,同时保持程序正常运行。
谢谢
有几件事要做:
- 将变量
character_*
更改为包含有关该单元的所有数据的对象。 - 创建单位/字符数组。这样阵列中的每个单元都可以具有唯一的位置、速度等。
- 在您检查
character_*
的代码中的任何地方,更改为迭代字符数组以检查每个单元的 for 循环。 - 下一步应该是为角色添加移动/射击等功能class,让按键事件适用于多个单位。
那应该给你代码,你可以 select 多个单位(如果它们占据相同的位置)并独立于 deselected 单位移动它们。