[英]Pygame: stopping character movement when a key is pressed in the opposite direction
基本上,我的游戲涉及在屏幕上移動角色,並帶有可收集的矩形和障礙物。 那不是我遇到的問題。 我的問題出現在“簡單”模式下,我希望角色在按下與他們移動方向相反的鍵時停止移動。 例如,如果角色向左移動並且按下了向右箭頭,我希望他們停止移動。 我認為問題在於程序認為當它阻止角色移動時正確的壓力會繼續過去,因此檢測到它只是試圖向右移動。 如果您足夠快地敲擊該鍵,則不會發生。 這只是我為自己做的一個項目,所以真的很煩人。 另外請原諒代碼有多么混亂,我嘗試了許多不同的方法,所以如果任何東西看起來沒有任何進展,那是因為它沒有。
import os, random, pygame, time
difficulty = input("Enter difficulty level. \nEASY\nNORMAL\n>>> ")
while difficulty.lower() not in ("easy", "normal"):
difficulty = input("Enter difficulty level. \nEASY\nNORMAL\n>>> ")
if "easy" in difficulty:
easy = True
else:
easy = False
pygame.init()
# Defining variables
SCREEN_W, SCREEN_H = 600, 600
MAP_W, MAP_H = 2000, 2000
BACKGROUND = pygame.transform.scale(pygame.image.load(
os.path.join("Assets", "image.png")), (MAP_W, MAP_H)) # Change this to work with whatever images you have
cameraOffset = [MAP_W//2-SCREEN_W//2, MAP_H//2-SCREEN_H//2]
move_dir = ""
objects = []
apples = []
deadly_objects = []
wallobjects = []
start_of_game = True
wall_text, wall_pop_text = None, None
SPEED = 10
WIN = pygame.display.set_mode((SCREEN_W, SCREEN_H))
FPS = 60
clock = pygame.time.Clock()
delay = 8
PLAYER_W, PLAYER_H = 40, 40
player = pygame.Rect(MAP_W//2-PLAYER_W, MAP_H//2-PLAYER_H, PLAYER_W, PLAYER_H)
for i in range(5):
apple = pygame.Rect(i*200, i*200, 30, 30)
apples.append(apple)
right_wall, left_wall = pygame.Rect(MAP_W, 0, 200, MAP_H+30), pygame.Rect(20, 0, 20, MAP_H+30)
up_wall = pygame.Rect(0,20,MAP_W,20)
down_wall = pygame.Rect(0, MAP_H, MAP_W, 20)
for i in range(10):
if random.randint(0,1) == 1:
mid_wall = pygame.Rect(random.randint(100, MAP_W-100), random.randint(100, MAP_H-100), 20, 80)
else:
mid_wall = pygame.Rect(random.randint(100, MAP_W-100), random.randint(100, MAP_H-100), 80, 20)
for i in apples:
while pygame.Rect.colliderect(mid_wall, i):
if random.randint(0,1) == 1:
mid_wall = pygame.Rect(random.randint(100, MAP_W-100), random.randint(100, MAP_H-100), 20, 80)
else:
mid_wall = pygame.Rect(random.randint(100, MAP_W-100), random.randint(100, MAP_H-100), 80, 20)
objects.append(mid_wall)
wallobjects.append(right_wall)
wallobjects.append(left_wall)
wallobjects.append(up_wall)
wallobjects.append(down_wall)
text_font = pygame.font.SysFont("times new roman", 40)
death_font = pygame.font.SysFont("times new roman",60)
press_font = pygame.font.SysFont("times new roman",30, False, True)
notification = pygame.font.SysFont("times new roman", 15, True, True)
notification_big = pygame.font.SysFont("times new roman", 20, True, True)
score = 0
def collision(x, y): # Looking for a collision with an object
global player, objects, wallobjects
new_player = pygame.Rect(x,y, PLAYER_W, PLAYER_H)
for i in objects:
if pygame.Rect.colliderect(i, new_player):
return True
for i in wallobjects:
if pygame.Rect.colliderect(i, new_player):
return True
return False
def display_death_screen():
global move_dir, score
score = 0
move_dir = ""
player.x, player.y = MAP_W//2, MAP_H//2
text = death_font.render("YOU DIED", 1, (0,0,255))
WIN.blit(text, (SCREEN_W//2-SCREEN_W//3, SCREEN_H//2-50))
press_enter = press_font.render("Press enter to respawn...", 0, (255,0,50))
WIN.blit(press_enter, (SCREEN_W//2-140, SCREEN_H//2+10))
if wall_pop_text != None and pygame.time.get_ticks() < wall_end_pop:
WIN.blit(wall_pop_text, (SCREEN_W-140, 15))
pygame.display.update()
def handle_movement(pressed, player): # Problem is in this function I think
global cameraOffset, playerScreenPos, move_dir, start_of_game
# The collision checking could probably be done better but it works like this (actually probably the case with most of this code lol)
movement_window = pygame.time.get_ticks() + # Even if you put a ridiculous number here it makes no difference
if easy == False:
if (pressed[pygame.K_a] or pressed[pygame.K_LEFT] or move_dir == "left") and player.x - (SPEED + player.width//2) > 0 and move_dir != "right": # left
move_dir = "left"
player.x -= SPEED
if (pressed[pygame.K_d] or pressed[pygame.K_RIGHT] or move_dir == "right") and player.x + (SPEED + player.width//2) < MAP_W and move_dir != "left": # right
move_dir = "right"
player.x += SPEED
if (pressed[pygame.K_w]or pressed[pygame.K_UP] or move_dir == "up") and player.y - (SPEED + player.width//2) > 0 and move_dir != "down": # up
move_dir = "up"
player.y -= SPEED
if (pressed[pygame.K_s] or pressed[pygame.K_DOWN] or move_dir == "down") and player.y + (SPEED + player.height//2) < MAP_H and move_dir != "up": # down
move_dir = "down"
player.y += SPEED
else:
if move_dir == "":
if pygame.time.get_ticks() < movement_window:
start_of_game = False
move_dir = "."
if (pressed[pygame.K_a] or pressed[pygame.K_LEFT] or move_dir == "left") and player.x - (SPEED + player.width//2) > 0 and move_dir != "": # left
if move_dir == "right":
move_dir = ""
if move_dir != "" and not start_of_game:
move_dir = "left"
player.x -= SPEED
if (pressed[pygame.K_d] or pressed[pygame.K_RIGHT] or move_dir == "right") and player.x + (SPEED + player.width//2) < MAP_W and move_dir != "": # right
if move_dir == "left":
move_dir = ""
if move_dir != "" and not start_of_game:
move_dir = "right"
player.x += SPEED
if (pressed[pygame.K_w]or pressed[pygame.K_UP] or move_dir == "up") and player.y - (SPEED + player.width//2) > 0 and move_dir != "": # up
if move_dir == "down":
move_dir = ""
if move_dir != ""and not start_of_game:
move_dir = "up"
player.y -= SPEED
if (pressed[pygame.K_s] or pressed[pygame.K_DOWN] or move_dir == "down") and player.y + (SPEED + player.height//2) < MAP_H and move_dir != "": # down
if move_dir == "up":
move_dir = ""
if move_dir != "" and not start_of_game:
move_dir = "down"
player.y += SPEED
cameraOffset[0] += (player.x - cameraOffset[0] - (SCREEN_W * 0.5)) / delay
cameraOffset[1] += (player.y - cameraOffset[1] - (SCREEN_H * 0.5)) / delay
cameraOffset[0] = max(0, min(cameraOffset[0], MAP_W - SCREEN_W))
cameraOffset[1] = max(0, min(cameraOffset[1], MAP_H - SCREEN_H))
def add_wall():
global mid_wall, objects, wall_text, wall_end
wall_text = notification.render("Wall added", 1, (255,0,0))
wall_end = pygame.time.get_ticks() + 3000
if random.randint(0,1) == 1:
mid_wall = pygame.Rect(random.randint(100, MAP_W-100), random.randint(100, MAP_H-100), 20, 80)
else:
mid_wall = pygame.Rect(random.randint(100, MAP_W-100), random.randint(100, MAP_H-100), 80, 20)
for i in apples:
while pygame.Rect.colliderect(mid_wall, i) or pygame.Rect.colliderect(mid_wall, pygame.Rect(player.x-100, player.y-100, player.width+100, player.height+100)):
if random.randint(0,1) == 1:
mid_wall = pygame.Rect(random.randint(100, MAP_W-100), random.randint(100, MAP_H-100), 20, 80)
else:
mid_wall = pygame.Rect(random.randint(100, MAP_W-100), random.randint(100, MAP_H-100), 80, 20)
objects.append(mid_wall)
def remove_wall():
global wall_pop_text, wall_end_pop
if len(objects) > 0:
wall_remove = random.choice(objects)
wall_pop_text = notification.render("Wall removed", 1, (255,0,0))
wall_end_pop = pygame.time.get_ticks() + 3000
objects.remove(wall_remove)
def handle_apple():
global score
for i in apples:
x, y = i.x-cameraOffset[0], i.y-cameraOffset[1]
pygame.draw.circle(WIN, (255,0,0), (x, y), i.width//2)
if pygame.Rect.colliderect(player, i):
apples.remove(i)
score += 1
if score % 5 == 0 and score != 0:
add_wall()
xx, yy = random.randint(40,MAP_H-40), random.randint(40,MAP_H-40)
for i in objects:
while pygame.Rect.colliderect(pygame.Rect(xx, yy, 30, 30), i):
xx, yy = random.randint(40,MAP_H-40), random.randint(40,MAP_H-40)
apple = pygame.Rect(xx, yy, 30, 30)
apples.append(apple)
def draw_screen(player): # Drawing to the screen
global wall_text, wall_end
WIN.blit(BACKGROUND, (0 - cameraOffset[0], 0 - cameraOffset[1]))
score_disp = text_font.render("Score: "+str(score), 0, (255,255,255))
wall_amount = notification_big.render("Walls: "+str(len(objects)), 0, (255,255,255))
press_space_text = notification_big.render("Movement Paused", 0, (255,255,255))
handle_apple()
playerPos = ((player.x - PLAYER_W//2) - cameraOffset[0], (player.y-PLAYER_H//2) - cameraOffset[1])
pygame.draw.rect(WIN, (100, 10, 255), (*playerPos, player.width, player.height))
for i in objects:
numberx = i.width // 20
numbery = i.height // 20
try:
pygame.draw.rect(WIN, (0,0,0), (i.x - cameraOffset[0] - i.width// numberx, i.y - cameraOffset[1] - i.height//numbery, i.width, i.height))
except:
numberx = i.width
numbery = i.height
for i in wallobjects:
numberx = i.width // 20
numbery = i.height // 20
try:
pygame.draw.rect(WIN, (0,0,0), (i.x - cameraOffset[0] - i.width// numberx, i.y - cameraOffset[1] - i.height//numbery, i.width, i.height))
except:
numberx = i.width
numbery = i.height
if wall_text != None and pygame.time.get_ticks() < wall_end:
WIN.blit(wall_text, (SCREEN_W-120, 15))
if wall_pop_text != None and pygame.time.get_ticks() < wall_end_pop:
WIN.blit(wall_pop_text, (SCREEN_W-140, 15))
if easy and move_dir == "":
WIN.blit(press_space_text, (SCREEN_W//2-200, SCREEN_H//2+player.height+5))
WIN.blit(score_disp, (10, 10))
WIN.blit(wall_amount, (10, SCREEN_H-30))
pygame.display.update()
def main():
global cameraOffset, move_dir
running, dead = True, False
while running:
clock.tick(FPS)
if collision(player.x, player.y):
remove_wall()
dead = True
if dead:
display_death_screen()
if not dead:
draw_screen(player)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
if event.key == pygame.K_RETURN and dead:
dead = False
keys_pressed = pygame.key.get_pressed()
handle_movement(keys_pressed, player)
pygame.quit()
if __name__ == "__main__":
main()
簡化邏輯:
left = pressed[pygame.K_a] or pressed[pygame.K_LEFT]
right = pressed[pygame.K_d] or pressed[pygame.K_RIGHT]
up = pressed[pygame.K_w] or pressed[pygame.K_UP]
down = pressed[pygame.K_s] or pressed[pygame.K_DOWN]
player.x += (right - left) * SPEED
player.y += (down - up) * SPEED
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.