2013-10-24 3 views
0

У меня есть задание, которое просит меня сделать следующее: расширенный поиск изображенияPygame: переместить спиннинг изображение вокруг края окна

Используйте Google, чтобы найти достаточно размер изображения шара, который свободно повторное использование и включает прозрачность. Измените образец кода так, чтобы ваш шар скользил взад-вперед в нижней части экрана. Для прохождения мяча с левой стороны вправо должно пройти 2 секунды. Улучшите анимацию для вопроса 5, чтобы мяч вращался, точно, как будто он катился назад и вперед. Измените свою анимацию для вопроса 6, чтобы шар перемещался против часовой стрелки вокруг края экрана.

Я нахожусь на последней части. Пытаясь модифицировать анимацию для вопроса 6, выполните следующие действия: (1:24) http://www.youtube.com/watch?v=CEiLc_UFNLI&feature=c4-overview&list=UUpbgjjXBL3hdTKDZ0gZvdWg

Я в ужасе плохо. Я просто не могу понять, как я получу мяч, чтобы он медленно переходил из одной точки в другую. Мяч - это изображение. Это то, что у меня есть до сих пор, но это не сработает.

"""Some simple skeleton code for a pygame game/animation 

This skeleton sets up a basic 800x600 window, an event loop, and a 
redraw timer to redraw at 30 frames per second. 
""" 
from __future__ import division 
import math 
import sys 
import pygame 


class MyGame(object): 
    def __init__(self): 
     """Initialize a new game""" 
     pygame.mixer.init() 
     pygame.mixer.pre_init(44100, -16, 2, 2048) 
     pygame.init() 

     # set up a 640 x 480 window 
     self.width = 800 
    self.height = 600 
    self.img = pygame.image.load('ball.png') 
    self.screen = pygame.display.set_mode((self.width, self.height)) 
    self.x = 0 
    self.y = 0 
    self.angle = 0 
    self.rotate_right=True 
    self.first = True 
    #0: Move bottomleft to bottomright 1: Move from bottomright to topright 2:Move from topright to topleft 3:Move from topleft to bottomleft 
    self.mode = 0 
    # use a black background 
    self.bg_color = 0, 0, 0 

    # Setup a timer to refresh the display FPS times per second 
    self.FPS = 30 
    self.REFRESH = pygame.USEREVENT+1 
    pygame.time.set_timer(self.REFRESH, 1000//self.FPS) 


def get_mode(self): 
    rect = self.img.get_rect() 

    if self.first == True: 
     self.first = False 
     return 

    if (self.x, self.y) == (0, self.height - rect.height): 
     #Our starting point, bottom left 
     self.mode = 0 
    elif (self.x, self.y) == (self.width-rect.width, self.height-rect.height): 
     #Bottom right 
     self.mode = 1 
    elif (self.x, self.y) == (self.width-rect.width, 0): 
     #Top Right 
     self.mode = 2 
    elif (self.x, self.y) == (0,0): 
     #Top Left 
     self.mode = 3 

def get_target(self): 
    rect = self.img.get_rect() 

    if self.mode == 0: 
     targetPosition = (0, self.height - rect.height) 

    elif self.mode == 1: 
     targetPosition = (self.width-rect.width, self.height-rect.height) 

    elif self.mode == 2: 
     targetPosition = (self.width-rect.width, 0) 

    elif self.mode == 3: 
     targetPosition = (0,0) 

    return targetPosition 

def get_angle(self): 
    if self.angle == 360: 
     self.rotate_right = False 
    elif self.angle == 0: 
     self.rotate_right = True 

    if self.rotate_right == True: 
     self.angle+=12 
    else: 
     self.angle-=12 

def run(self): 
    """Loop forever processing events""" 
    running = True 
    while running: 
     event = pygame.event.wait() 

     # player is asking to quit 
     if event.type == pygame.QUIT: 
      running = False 

     # time to draw a new frame 
     elif event.type == self.REFRESH: 
      self.draw() 

     else: 
      pass # an event type we don't handle    

def draw(self): 
    """Update the display""" 
    # everything we draw now is to a buffer that is not displayed 
    self.screen.fill(self.bg_color) 

    #Draw img 
    rect = self.img.get_rect() 

    #Note: this can be made dynamic, but right now since this is typically a poor structure, we will use static values. 
    #80 is the padding, so it hits right before. 

    #0,0 : top left 
    #self.width-rect.width, 0 : top right 
    #0, self.height-rect.height : bottom left 
    #self.width-rect.width, self.height-rect.height : bottom right 

    targetPosition =() 

    #img = pygame.transform.rotate(self.img, self.angle) 
    img = self.img 

    self.get_angle() 
    self.get_mode() 

    targetPosition = self.get_target() 

    print targetPosition 
    print self.x, self.y 
    if self.x < targetPosition[0]: 
     self.x+= targetPosition[0]-self.x//self.FPS 

    elif self.x > targetPosition[0]: 
     self.x-= targetPosition[0]+self.x//self.FPS 

    if self.y < targetPosition[1]: 
     print "s" 
     self.y+= targetPosition[1]-self.y//self.FPS 

    elif self.y > targetPosition[1]: 
     self.y-= targetPosition[1]+self.y//self.FPS 


    rect = rect.move(self.x, self.y) 

    self.screen.blit(img, rect) 

    # flip buffers so that everything we have drawn gets displayed 
    pygame.display.flip() 


MyGame().run() 
pygame.quit() 
sys.exit() 
+0

Здравствуйте! Что вы подразумеваете под словом «это не работает?» Похоже, у вас есть код для перемещения мяча - что должен делать код и что он делает в настоящее время? –

+0

Ну, это должно начаться в левом нижнем углу, медленно переместиться в нижнее правое, затем в верхнее правое, затем вверху слева и повторить. В настоящее время он даже не двигается. Я также разместил ссылку на YouTube, в которой объясняется, что она должна делать. – user2417731

ответ

0

Что происходит, что ваш шар начиная с (0,0) (вверху слева) с мишенью (0,550) (внизу слева), обнаруживает, что это на более низком y, чем его цель, и быстро переходит к увеличиваем свою позицию

targetPosition[1] - (self.y // self.FPS)

, который, конечно, равный 550, поэтому он сразу же привязывается к нижней части экрана.

Затем во время следующего цикла ничьей get_mode() приходит и говорит: «Хорошо, я нахожусь в (0, 550), поэтому я перейду и установил режим 0». Затем приходит get_target() и говорит: «Ладно, я в режиме 0, перейдем к (0, 550).

А потом это повторится во время следующего цикла ничьи, а затем следующего и следующего ... Так что, конечно, ваш шар никуда не денется.

Вам нужно сделать несколько вещей, чтобы исправить ваш пример:

  • Исправьте целевые позиции в get_target(). Прямо сейчас они нацелены на те же точки, где происходят переходы, которые запускают эти режимы, поэтому ваш мяч никуда не денется.
  • Рассмотрите свои инструкции скорости более внимательно: прямо сейчас они будут вести себя несколько странно. Один из способов сделать это правильно - определить (dx, dy), то есть абсолютный вектор от вас до пункта назначения, а затем нормализовать этот вектор так, чтобы он указывал в одном направлении, но имел величину, равную желаемой скорости. Этот подход будет работать для любой желаемой позиции.

Чтобы остановиться на втором пункте:

Предположим, что мы находимся в (x, y), и мы пытаемся добраться до (target_x, target_y).

Let dx = target_x - x, dy = target_y - y. Это должно быть бесспорным: мы просто понимаем разницу.

Затем мы помним теорему Пифагора: с учетом правильного треугольника со сторонами a, b, c и гипотенузы c, напомним, что len(c)**2 == len(a)**2 + len(b)**2. То же самое происходит с векторами: длина вектора (x, y) является гипотенузой правого треугольника с боковыми длинами x и y. Вы можете нарисовать это на листе бумаги, если хотите доказать это самому себе.

Учитывая, что мы можем найти длину (dx, dy): это всего лишь L(dx, dy) = sqrt(dx*dx + dy*dy). Это поддается любопытным наблюдениям: если умножить как dx, так и dy на скаляр k, мы также умножаем длину на k, начиная с sqrt(dx*k*dx*k + dy*k*dy*k) == sqrt(k*k*(dx*dx + dy*dy)) == k*sqrt(dx*dx + dy*dy).

Отсюда следует, что мы можем найти вектор параллельно (dx, dy), но длины 1, путем деления как dx и dy по L(dx, dy). Precompute L, чтобы избежать некоторых потенциальных проблем. Умножьте этот новый вектор на любую вашу скорость: это ваша желаемая скорость.

+0

Это та часть, где я застреваю - математическую часть. Я не уверен, как сделать векторный материал. Можете ли вы уточнить? – user2417731

+0

@ user2417731 обновленный ответ – atomicinf

+0

Ну, потому что мне все еще трудно понять это, я как бы справился с этим. Только проблема, с которой я сталкиваюсь сейчас, заключается в том, что когда я пытаюсь ее повернуть, она начинает дрожать. – user2417731

Смежные вопросы