2013-03-27 5 views
2

내가 파일을 실행할 때
왼쪽 화살표의 화살표 컨트롤과 움직임이 화살표 키를 계속 누르고 있어도 왼쪽 사각형의 움직임이 계속 위아래로 움직이지 않는다는 것이 궁금합니다. 장기.파이 게임 화살표 컨트롤

import pygame 

black = ( 0, 0, 0) 
white = (255, 255, 255) 
green = ( 0, 255, 0) 
red  = (255, 0, 0) 

pygame.init() 

size = [700,500] 
screen = pygame.display.set_mode(size) 

fonto = pygame.font.SysFont("algerian", 100) 
font = pygame.font.SysFont("algerian", 12) 
text = fonto.render("Game Over", True, (0, 128, 10)) 

pygame.display.set_caption("Vasanths First Legit Game") 

done = False 
pygame.mouse.set_visible(0) 

clock = pygame.time.Clock() 
score = 1 

rect_x = 50 
rect_y = 50 
rect_xp = 10 
rect_yp = 10 

rect_change_x = 10 
rect_change_y = 10 
rect_change_xp = 10 
rect_change_yp = 3 

while done == False: 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      done=True 

     if event.type == pygame.KEYDOWN: 
      if event.key == pygame.K_DOWN: 
       rect_yp = rect_change_yp+rect_yp 
     if event.type == pygame.KEYUP: 
      if event.key == pygame.K_DOWN: 
       rect_yp = 0+rect_yp 

     if event.type == pygame.KEYDOWN: 
      if event.key == pygame.K_LEFT: 
       rect_yp=-3+rect_yp 
      if event.key == pygame.K_RIGHT: 
       rect_yp=3+rect_yp 
      if event.key == pygame.K_UP: 
       rect_yp=-3+rect_yp 
      if event.key == pygame.K_DOWN: 
       rect_yp=3+rect_yp 

     if event.type == pygame.KEYUP: 
      if event.key == pygame.K_LEFT: 
       rect_yp=0+rect_yp 
      if event.key == pygame.K_RIGHT: 
       rect_yp=0+rect_yp 
      if event.key == pygame.K_UP: 
       rect_yp=0+rect_yp 
      if event.key == pygame.K_DOWN: 
       rect_yp=0+rect_yp 

    pos = pygame.mouse.get_pos() 

    x = pos[0] 
    y = pos[1] 

    screen.fill(black) 

    pygame.draw.rect(screen,white,[rect_x,rect_y,10,10]) 
    pygame.draw.rect(screen,green,[x,490,50,10]) 
    pygame.draw.rect(screen,green,[10,rect_yp,10,50]) 
    # Move the rectangle starting point 
    rect_x += rect_change_x 
    rect_y += rect_change_y 

    if rect_y == 0: 
     rect_change_x=rect_change_x*1 
     rect_change_y=rect_change_y*-1 
    if rect_y == 490: 
     if rect_x < x + 50 : 
      scoref = font.render(score, True, (0, 128, 0)) 
      screen.blit(scoref, 
       (20 - scoref.get_width() // 10, 20 - scoref.get_height() // 10)) 
      rect_change_x=rect_change_x*1 
      rect_change_y=rect_change_y*-1 

     if rect_x < x: 
      rect_change_y = 0 
      rect_change_x = 0 

      #dont do this , it will go bizzonkes 
      score = str(score) 
      score = int(score) 

    if rect_y == 490: 
     if rect_x < x + 50 : 
      if rect_change_x !=0: 
       if rect_change_y !=0: 
        score=int(score) 
        score = score + 1 
        score=str(score) 
    if rect_change_x == 0: 
     if rect_change_y == 0: 
        screen.blit(text, 
         (320 - text.get_width() // 2, 240 - text.get_height() // 2)) 

    if rect_x == 700: 
     rect_change_x = rect_change_x*-1 
     rect_change_y = rect_change_y*1 

    if rect_x == 0: 
     rect_change_x = rect_change_x*0 
     rect_change_y = rect_change_y*0 

    if rect_y == 500: 
     rect_change_y = 0 
     rect_change_x = 0 
     screen.blit(text, 
      (320 - text.get_width() // 2, 240 - text.get_height() // 2)) 
     score=str(score) 


    print(score) 
    score = str(score) 

    scoref = font.render(score, True, (0, 128, 0)) 
    screen.blit(scoref, 
       (20 - scoref.get_width() // 10, 20 - scoref.get_height() // 10)) 

    clock.tick(30) 

    pygame.display.flip() 

pygame.quit() 

답변

4

입력 이벤트는 이벤트 루프에서 처리됩니다. 이벤트 대기열이 있고 시스템이 키보드에서 입력을 전송하며 pygame.event.get()을 호출하면 대기열의 첫 번째 이벤트가 표시됩니다. 다양한 유형의 이벤트가 있으며 가장 인기있는 것은 KEYUPKEYDOWN입니다. 대부분의 초급 사람들이하는 실수는 버튼을 누르면 KEYDOWN 이벤트가 전체적으로 전송된다고 생각하는 것입니다. 버튼을 누르면 해제 할 때까지 눌려지기 때문에 필요하지 않습니다. 따라서 버튼을 눌렀는지 확인하려면 특정 플래그가 필요합니다.

이렇게하는 가장 일반적인 방법은 d = v*t 수식을 사용하는 것입니다. 속도가 일정하기 때문에 방향을 도입해야합니다. 그래서 우리의 방정식은 다음과 같을 것이다 :

distance_changed = 방향 * 속도 * 이벤트 루프에서 time_change

, 당신은 그 방향을 변경 :

한 경우를 keyDown-RIGHT

-1 KEYDOWN-LEFT 인 경우

0 KEYUP-LEFToright.

이제 time_change를 사용하는 이유는 무엇입니까? 프로그램이 작동하는 기계를 예측할 수 없으므로 루프가 반복되는 시간은 알려지지 않습니다. 오래된 컴퓨터를 사용하면 게임이 훨씬 느리게 작동합니다. 그래서 우리는 마지막 움직임으로부터 걸린 시간을 측정합니다. 그래서 그것은 다른 기계에서 바뀌지 않을 것입니다.

저는 pygame.tick (30)을 사용하는 것을 보았습니다. pygame.tick (30)은 루프가 완료되는 데 걸리는 시간이 일정하기를 기다립니다. 이 문제는 오래된 시스템에서 실행할 때 발생합니다. 루프가 속도를 낼 수 없습니다.

제안 사항에 따라 게임을 기능으로 나누어야합니다. 훨씬 더 읽기 쉽고 다른 장소에서 코드를 사용할 수 있습니다. 또한 이벤트 루프는 많은 ifs가 있습니다. 왼쪽 버튼을 이미 눌렀다면 RIGTH 키를 눌렀는지 확인할 필요가 없으므로 elif를 사용하십시오. 다음 다른, 파이 게임 키에,

class Inputs: 

def __init__(self): 
    self.bindings = {"up": pygame.K_UP, 
        "down": pygame.K_DOWN, 
        "left": pygame.K_LEFT, 
        "right": pygame.K_RIGHT, 
        "lp": pygame.K_a, 
        "mp": pygame.K_s, 
        "hp": pygame.K_d, 
        "lk": pygame.K_z, 
        "mk": pygame.K_x, 
        "hk": pygame.K_c, 
        "pause": pygame.K_RETURN} 

    self.inputState = {"up": False, 
        "down": False, 
        "right": False, 
        "left": False, 
        "lp": False, 
        "mp": False, 
        "hp": False, 
        "lk": False, 
        "mk": False, 
        "hk": False, 
        "pause": False} 

    self.buffer = InputBuffer() 

def lookupBinding(self, keyEntered): 
    for binding, keyBound in self.bindings.items(): 
     if keyEntered == keyBound: 
      return binding 

    return "not found" 

def getInputState(self, events): 
    for event in events: 

     if event.type == pygame.KEYDOWN: 
      binding = self.lookupBinding(event.key) 
      if binding != "not found": 
       newInput = Input() 
       newInput.inputName = binding 
       newInput.timeSinceInput = 0 
       self.buffer.push(newInput) 
       self.inputState[binding] = True 

     if event.type == pygame.KEYUP: 
      binding = self.lookupBinding(event.key) 
      if binding != "not found": 
       self.inputState[binding] = False 

    return self.inputState 

내가 두 개의 사전, 같은 방향 같은 게임 "명령"중 하나를 계속 :

+1

어떻게 단순히'pygame.key.get_pressed() '사용에 대한? – sloth

+0

도 작동하지만 성능은 어떻습니까? –

+0

'KEY_UP' /'KEY_DOWN' 이벤트를 검사하고 깃발을 관리하는 대신에 (intelressted 키에 하나씩)'pygame.key.get_pressed()'를 사용하여 성능 저하를 보지 못합니다. – sloth

1

이것은 내가 내 자신의 파이 게임 프로젝트 중 하나를 처리하는 방법입니다 명령의 on/off 상태를 나타내는 부울 값을 반환합니다. KEYDOWN 및 KEYUP 이벤트를 관찰하여 매핑 된 입력이 켜져 있고 어느 입력이 꺼져 있는지 확인할 수 있습니다.

편집 : 내가 언급해야하는이 방법의 이점은 나중에 키 매핑을 변경하거나 사용자 지정 키 매핑을 허용하는 것이 매우 쉽다는 것입니다. 게임 논리는 점프 또는 이동 입력과 같은 기본 입력에만 의존해야하며 키 매핑이 변경되면 변경하지 않아도됩니다.

1

나는 pygame.key.get_pressed()을 사용할 것이지만, 또한 pygame.key.set_repeat()을 잊어 버리고 있습니다. 첫 번째 인수는 반복 시작에 걸리는 시간 (밀리 초)이고 두 번째 인수는 키가 반복되는 간격입니다.

이 모두 사용하는 예는 다음과 같습니다

x = 400 
y = 300 

import pygame, sys 

bkg = (255, 211, 0) 
clr = (0, 0, 0) 
squ = (8, 11, 134) 

pygame.init() 
size = (800, 600) 
screen = pygame.display.set_mode(size) 
pygame.display.set_caption("Bloxy") 
pygame.key.set_repeat(1, 1) 
font = pygame.font.SysFont("Stencil", 20) 
clock = pygame.time.Clock() 

while True: 
    for event in pygame.event.get(): 
     if event.type == pygame.QUIT: 
      pygame.quit() 
      sys.exit() 

    keys_pressed = pygame.key.get_pressed() 

    if keys_pressed[pygame.K_LEFT]: 
     x -= 5 
    if keys_pressed[pygame.K_RIGHT]: 
     x += 5 
    if keys_pressed[pygame.K_UP]: 
     y -= 5 
    if keys_pressed[pygame.K_DOWN]: 
     y += 5 

    if x > 800: 
     x = 0 
    if x < 0: 
     x = 800 
    if y > 600: 
     y = 0 
    if y < 0: 
     y = 600 

    screen.fill(bkg) 
    text = font.render('(' + str(x) + ',' + str(y) + ')', True, clr) 
    screen.blit(text, [10, 10]) 
    pygame.draw.rect(screen, squ, [x - 10, y - 10, 20, 20]) 

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