在pygame中绘制方波

时间:2014-07-22 20:06:27

标签: python pygame draw sine

这个python代码说明了pygame窗口中的sin wave。

我想以同样的方式绘制方波,但我不知道这个代码可能是什么,或者如何绘制方波/如何在python中构造方波。

有人知道我怎么做吗?是否可以使用相同的进口产品,还是需要新产品呢?

代码:

    import sys, pygame, math
    from pygame.locals import *

    # set up a bunch of constants
    WHITE      = (255, 255, 255)
    DARKRED    = (128,   0,   0)
    RED        = (255,   0,   0)
    BLACK      = (  0,   0,   0)

    BGCOLOR = WHITE

    WINDOWWIDTH = 640 # width of the program's window, in pixels
    WINDOWHEIGHT = 480 # height in pixels
    WIN_CENTERX = int(WINDOWWIDTH / 2) # the midpoint for the width of the window
    WIN_CENTERY = int(WINDOWHEIGHT / 2) # the midpoint for the height of the window

    FPS = 160 # frames per second to run at

    AMPLITUDE = 80 # how many pixels tall the waves with rise/fall.

    # standard pygame setup code
    pygame.init()
    FPSCLOCK = pygame.time.Clock()
    DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
    pygame.display.set_caption('Trig Waves')
    fontObj = pygame.font.Font('freesansbold.ttf', 16)

    # variables that track visibility modes
    showSine = True

    pause = False

    xPos = 0
    step = 0 # the current input f
    posRecord = {'sin': []} # keeps track of the ball positions for drawing the waves

    # making text Surface and Rect objects for various labels
    sinLabelSurf         = fontObj.render('sine', True, RED, BGCOLOR)

    sinLabelRect         = sinLabelSurf.get_rect()


    instructionsSurf = fontObj.render('Press Q to toggle wave. P to pause.', True, BLACK, BGCOLOR)
    instructionsRect = instructionsSurf.get_rect()
    instructionsRect.left = 10
    instructionsRect.bottom = WINDOWHEIGHT - 10

    # main application loop
    while True:
        # event handling loop for quit events
        for event in pygame.event.get():
            if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
                pygame.quit()
                sys.exit()

            # check for key presses that toggle pausing and wave visibility
            if event.type == KEYUP:
                if event.key == K_q:
                    showSine = not showSine
                elif event.key == K_p:
                    pause = not pause

        # fill the screen to draw from a blank state
        DISPLAYSURF.fill(BGCOLOR)

        # draw instructions
        DISPLAYSURF.blit(instructionsSurf, instructionsRect)



        # sine wave
        yPos = -1 * math.sin(step) * AMPLITUDE
        posRecord['sin'].append((int(xPos), int(yPos) + WIN_CENTERY))
        if showSine:
            # draw the sine ball and label
            pygame.draw.circle(DISPLAYSURF, RED, (int(xPos), int(yPos) + WIN_CENTERY), 10)
            sinLabelRect.center = (int(xPos), int(yPos) + WIN_CENTERY + 20)
            DISPLAYSURF.blit(sinLabelSurf, sinLabelRect)

        # draw the waves from the previously recorded ball positions
        if showSine:
            for x, y in posRecord['sin']:
                pygame.draw.circle(DISPLAYSURF, DARKRED, (x, y), 4)


        # draw the border
        pygame.draw.rect(DISPLAYSURF, BLACK, (0, 0, WINDOWWIDTH, WINDOWHEIGHT), 1)

        pygame.display.update()
        FPSCLOCK.tick(FPS)

        if not pause:
            xPos += 0.5
            if xPos > WINDOWWIDTH:
                xPos = 0
                posRecord = {'sin': []}
                step = 0
            else:
                step += 0.008
                step %= 2 * math.pi

Python ver.2.6,Pygame ver.1.9.2

1 个答案:

答案 0 :(得分:2)

我做了一些修改以添加平方波。

查看### HERE的地方。

import sys, pygame, math
from pygame.locals import *

# set up a bunch of constants
WHITE      = (255, 255, 255)
DARKRED    = (128,   0,   0)
RED        = (255,   0,   0)
BLACK      = (  0,   0,   0)
GREEN      = (  0, 255,   0) ### HERE
BLUE       = (  0,   0, 255) ### HERE

BGCOLOR = WHITE

WINDOWWIDTH = 640 # width of the program's window, in pixels
WINDOWHEIGHT = 480 # height in pixels
WIN_CENTERX = int(WINDOWWIDTH / 2) # the midpoint for the width of the window
WIN_CENTERY = int(WINDOWHEIGHT / 2) # the midpoint for the height of the window

FPS = 160 # frames per second to run at

AMPLITUDE = 80 # how many pixels tall the waves with rise/fall.

# standard pygame setup code
pygame.init()
FPSCLOCK = pygame.time.Clock()
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
pygame.display.set_caption('Trig Waves')
fontObj = pygame.font.Font('freesansbold.ttf', 16)

# variables that track visibility modes
showSine = True
showSquare = True ### HERE

pause = False

xPos = 0
step = 0 # the current input f

### HERE 
posRecord = {'sin': [], 'square': []} # keeps track of the ball positions for drawing the waves

# making text Surface and Rect objects for various labels

### HERE 
squareLabelSurf = fontObj.render('square', True, BLUE, BGCOLOR)
squareLabelRect = squareLabelSurf.get_rect()

sinLabelSurf = fontObj.render('sine', True, RED, BGCOLOR)
sinLabelRect = sinLabelSurf.get_rect()


instructionsSurf = fontObj.render('Press Q to toggle wave. P to pause.', True, BLACK, BGCOLOR)
instructionsRect = instructionsSurf.get_rect()
instructionsRect.left = 10
instructionsRect.bottom = WINDOWHEIGHT - 10

### HERE
yPosSquare = AMPLITUDE # starting position

# main application loop
while True:
    # event handling loop for quit events
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
            pygame.quit()
            sys.exit()

        # check for key presses that toggle pausing and wave visibility
        if event.type == KEYUP:
            if event.key == K_q:
                showSine = not showSine
            elif event.key == K_p:
                pause = not pause

    # fill the screen to draw from a blank state
    DISPLAYSURF.fill(BGCOLOR)

    # draw instructions
    DISPLAYSURF.blit(instructionsSurf, instructionsRect)

    # sine wave
    yPos = -1 * math.sin(step) * AMPLITUDE
    posRecord['sin'].append((int(xPos), int(yPos) + WIN_CENTERY))
    if showSine:
        # draw the sine ball and label
        pygame.draw.circle(DISPLAYSURF, RED, (int(xPos), int(yPos) + WIN_CENTERY), 10)
        sinLabelRect.center = (int(xPos), int(yPos) + WIN_CENTERY + 20)
        DISPLAYSURF.blit(sinLabelSurf, sinLabelRect)

    # draw the waves from the previously recorded ball positions
    if showSine:
        for x, y in posRecord['sin']:
            pygame.draw.circle(DISPLAYSURF, DARKRED, (x, y), 4)

    ### HERE - drawing horizontal lines
    # square 
    posRecord['square'].append((int(xPos), int(yPosSquare) + WIN_CENTERY))
    if showSquare:
        # draw the sine ball and label
        pygame.draw.circle(DISPLAYSURF, GREEN, (int(xPos), int(yPosSquare) + WIN_CENTERY), 10)
        squareLabelRect.center = (int(xPos), int(yPosSquare) + WIN_CENTERY + 20)
        DISPLAYSURF.blit(squareLabelSurf, squareLabelRect)

    # draw the waves from the previously recorded ball positions
    if showSquare:
        for x, y in posRecord['square']:
            pygame.draw.circle(DISPLAYSURF, BLUE, (x, y), 4)

    # draw the border
    pygame.draw.rect(DISPLAYSURF, BLACK, (0, 0, WINDOWWIDTH, WINDOWHEIGHT), 1)

    pygame.display.update()
    FPSCLOCK.tick(FPS)

    if not pause:
        xPos += 0.5

        if xPos > WINDOWWIDTH:
            #sine ### HERE
            xPos = 0
            posRecord['sin'] = []
            step = 0

            # square ### HERE
            yPosSquare = AMPLITUDE
            posRecord['square'] = []
        else:
            #sine ### HERE
            step += 0.008
            #step %= 2 * math.pi

            # square ### HERE
            # jump top and bottom every 100 pixels
            if xPos % 100 == 0:
                yPosSquare *= -1
                # add vertical line
                for x in range(-AMPLITUDE, AMPLITUDE):
                    posRecord['square'].append((int(xPos), int(x) + WIN_CENTERY))

enter image description here