簡體   English   中英

將幾個立方體放入 pygame

[英]drop several cubes in pygame

我上周開始了 Python 並且我正在嘗試創建一個游戲來學習。 屏幕中有 4 個移動圓圈,從屏幕中間移動到 4 個邊緣。 我想得到這部分。

現在我正在嘗試將立方體從 4 個邊緣放到中間。 目標是通過按鍵盤箭頭阻止這些立方體到達屏幕中間。 如果一個立方體到達中心,則游戲結束。

我設法同時將 4 個立方體丟到中間,但我的想法是隨機丟幾個立方體。

知道我應該如何繼續創建這個嗎? 或者我應該學什么才能做到這一點?

到目前為止,這是我的工作:

# ---------- Packages ----------

import pygame, random
pygame.init()

# ---------- Constants ----------

SCREEN_WIDTH  = 600
SCREEN_HEIGHT = 600
FPS = 60 
SPEED = 1
SPEED_ENEMIES = 1
CIRCLE_RADIUS = 50
ENNEMY_SIZE = 40

red    = (255,000,000)
blue   = (000,000,255)
yellow = (255,255,000)
green  = (000,128,000)
pink   = (255,192,203)
black  = (000,000,000)
transparent = (0, 0, 0, 0)

# ---------- Classes ----------

class Ennemies:

    def __init__(self, x, y, size=ENNEMY_SIZE, thick=5, color=blue, speed=SPEED_ENEMIES):

        self.rect = pygame.Rect(0, 0, 2*size, 2*size)

        self.rect.centerx = x
        self.rect.centery = y
        self.size = size
        self.thick = thick
        self.color = color
        self.speed = speed

        if speed >= 0:
            self.directionX = 'right'
            self.direction = 'up'
        else:
            self.directionX = 'left'
            self.direction = 'down'

    def draw(self, screen):
        pygame.draw.rect(screen, self.color,(self.rect.centerx,self.rect.centery,self.size,self.size))

    def move_up(self):
        self.rect.y -= self.speed

        if self.rect.centery < int(SCREEN_HEIGHT/2) - self.size/2:
            self.color = transparent

    def move_down(self):
        self.rect.y += self.speed

        if self.rect.centery > int(SCREEN_HEIGHT/2) - self.size/2:
            self.color = transparent

    def move_left(self):
        self.rect.x -= self.speed

        if self.rect.centerx < int(SCREEN_WIDTH/2) - self.size/2:
            self.color = transparent

    def move_right(self):
        self.rect.x += self.speed

        if self.rect.centerx > int(SCREEN_WIDTH/2) - self.size/2:
            self.color = transparent

class Circle:

    def __init__(self, x, y, radius=CIRCLE_RADIUS, thick=5, color=blue, speed=SPEED):

        self.rect = pygame.Rect(0, 0, 2*radius, 2*radius)

        self.rect.centerx = x
        self.rect.centery = y
        self.radius = radius
        self.thick = thick
        self.color = color
        self.speed = speed

        if speed >= 0:
            self.directionX = 'right'
            self.direction = 'up'
        else:
            self.directionX = 'left'
            self.direction = 'down'

    def draw(self, screen):
        pygame.draw.circle(screen, self.color, self.rect.center, self.radius, self.thick)

    def swing_top(self):
        self.rect.y -= self.speed

        if self.rect.top <= 0  and self.direction == 'up':
            self.direction = 'down'
            self.speed = -self.speed

        if self.rect.bottom > int(SCREEN_HEIGHT/2) - self.radius  and self.direction == 'down':
            self.direction = 'up'
            self.speed = -self.speed

    def swing_bot(self):
        self.rect.y -= self.speed

        if self.rect.top < int(SCREEN_HEIGHT/2) + self.radius  and self.direction == 'up':
            self.direction = 'down'
            self.speed = -self.speed

        if self.rect.bottom >= SCREEN_HEIGHT and self.direction == 'down':
            self.direction = 'up'
            self.speed = -self.speed

    def swing_left(self):
        self.rect.x -= self.speed

        if self.rect.right > int(SCREEN_WIDTH/2) - self.radius and self.directionX == 'left':
            self.directionX = 'right'
            self.speed = -self.speed

        if self.rect.left <= 0 and self.directionX == 'right':
            self.directionX = 'left'
            self.speed = -self.speed

    def swing_right(self):
        self.rect.x -= self.speed

        if self.rect.left < int(SCREEN_WIDTH/2) + self.radius  and self.directionX == 'right':
            self.directionX = 'left'
            self.speed = -self.speed

        if self.rect.right >= SCREEN_WIDTH and self.directionX == 'left':
            self.directionX = 'right'
            self.speed = -self.speed

# ---------- Main ----------

def main():

    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    screen_rect = screen.get_rect()

    enemyTop = [
        Ennemies(int(SCREEN_WIDTH/2)-ENNEMY_SIZE/2, 0, color=yellow)
    ]
    enemyBot = [
        Ennemies(int(SCREEN_WIDTH/2)-ENNEMY_SIZE/2, SCREEN_HEIGHT-ENNEMY_SIZE, color=green)
    ]
    enemyLeft = [
        Ennemies(0, int(SCREEN_HEIGHT/2)-ENNEMY_SIZE/2, color=blue)
    ]
    enemyRight = [
        Ennemies(SCREEN_WIDTH-ENNEMY_SIZE, int(SCREEN_HEIGHT/2)-ENNEMY_SIZE/2, color = red)
    ]

    circleTop = [
        Circle(screen_rect.centerx, screen_rect.centery - 2*CIRCLE_RADIUS)
    ]

    circleBot = [
        Circle(screen_rect.centerx, screen_rect.centery + 2*CIRCLE_RADIUS)
    ]

    circleRight = [
        Circle(screen_rect.centerx + 2*CIRCLE_RADIUS, screen_rect.centery)
    ]

    circleLeft = [
        Circle(screen_rect.centerx - 2*CIRCLE_RADIUS, screen_rect.centery)
    ]

    clock = pygame.time.Clock()

    game_over = False

    while not game_over:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_over = True

        for item in enemyTop:
            item.move_down()
        for item in enemyBot:
            item.move_up()
        for item in enemyLeft:
            item.move_right()
        for item in enemyRight:
            item.move_left()

        for item in circleTop:
            item.swing_top()
        for item in circleBot:
            item.swing_bot()
        for item in circleLeft:
            item.swing_left()
        for item in circleRight:
            item.swing_right()

        screen.fill(black)

        for item in enemyTop:
            item.draw(screen)
        for item in enemyBot:
            item.draw(screen)
        for item in enemyLeft:
            item.draw(screen)
        for item in enemyRight:
            item.draw(screen)

        for item in circleTop:
            item.draw(screen)
        for item in circleBot:
            item.draw(screen)
        for item in circleLeft:
            item.draw(screen)
        for item in circleRight:
            item.draw(screen)

        pygame.display.update()

        clock.tick(FPS)

main()
pygame.quit()

謝謝

我認為這里的答案是修改你的Enemies object 以便它作為更通用的 object 更好地工作。

為此,我修改了 class 以使“立方體”從側面的隨機 position 開始,並且始終進入中間(我不確定這是否正是您的計划,但這是我對您的游戲的解釋描述)。

這是通過計算方向矢量(因為它現在可能是對角線),然后將此量(乘以速度)添加到每個“滴答”的位置來實現的。 這造成的一個問題是,如果方向的分量非常小——比如 0.1 像素/刻度,那么這個量的相加總是四舍五入為零。 因此 class 將該位置保留為浮點數,並且僅在更新 Rect 時轉換回 integer 。

代碼現在保留了Enemies對象的列表。 這使得遍歷這個列表、更新、繪制和檢查位置變得容易。 要添加更多敵人,只需在此列表中添加額外內容 - 也許隨着級別變得越來越難。

如果提供的坐標為 (0,0),則下一個更改是讓敵人從隨機 position 開始。 這允許代碼將舊敵人重新設置為新的隨機起始 position,或添加新敵人。

# ---------- Packages ----------

import pygame, random
pygame.init()

# ---------- Constants ----------

SCREEN_WIDTH  = 600
SCREEN_HEIGHT = 600
FPS = 60 
SPEED = 1
SPEED_ENEMIES = 1
CIRCLE_RADIUS = 50
ENEMY_SIZE = 40

red    = (255,000,000)
blue   = (000,000,255)
yellow = (255,255,000)
green  = (000,128,000)
pink   = (255,192,203)
black  = (000,000,000)
transparent = (0, 0, 0, 0)

# ---------- Classes ----------

class Enemies:

    def __init__(self, x, y, size=ENEMY_SIZE, thick=5, color=blue, speed=SPEED_ENEMIES):

        self.rect = pygame.Rect(0, 0, size, size)
        # if x and y are zero, choose a random starting point
        if ( x == 0 and y == 0 ):
            self.randomise()

        self.rect.centerx = x
        self.rect.centery = y
        self.size = size
        self.thick = thick
        self.color = color
        self.speed = speed
        self.calcDirection()

    def calcDirection( self ):
        """ Work out the direction vector to (0,0) """
        self.x_float = 1.0 * self.rect.centerx  # keep these to stop rounding errors
        self.y_float = 1.0 * self.rect.centery

        # Determine direction vector from (x,y) to the centre of the screen
        self.position_vector = pygame.math.Vector2( self.x_float, self.y_float )
        self.velocity_vector = pygame.math.Vector2( SCREEN_WIDTH/2 - self.x_float, SCREEN_HEIGHT/2 - self.y_float )
        self.velocity_vector = self.velocity_vector.normalize()
        #print("Velocity Vector = "+str(self.velocity_vector) )

    def update( self ):
        x_delta = self.speed * self.velocity_vector[0]
        y_delta = self.speed * self.velocity_vector[1]
        self.x_float += x_delta
        self.y_float += y_delta
        self.rect.centerx = int( self.x_float )
        self.rect.centery = int( self.y_float )

    def draw(self, screen):
        pygame.draw.rect(screen, self.color, self.rect )

    def reachedPoint( self, x, y ):
        return self.rect.collidepoint( x, y )

    def randomise( self ):
        """ Pick a random starting point """
        self.rect.centerx = random.randint( 0, SCREEN_WIDTH )
        self.rect.centery = random.randint( 0, SCREEN_HEIGHT )
        side = random.randint( 0, 4 )
        if ( side == 0 ):   # top
            self.rect.centery = SCREEN_HEIGHT
        elif ( side == 1 ): # bottom
            self.rect.centery = 0
        elif ( side == 2 ): # left
            self.rect.centerx = 0
        else:               # right
            self.rect.centerx = SCREEN_WIDTH
        self.calcDirection()



class Circle:

    def __init__(self, x, y, radius=CIRCLE_RADIUS, thick=5, color=blue, speed=SPEED):

        self.rect = pygame.Rect(0, 0, 2*radius, 2*radius)

        self.rect.centerx = x
        self.rect.centery = y
        self.radius = radius
        self.thick = thick
        self.color = color
        self.speed = speed

        if speed >= 0:
            self.directionX = 'right'
            self.direction = 'up'
        else:
            self.directionX = 'left'
            self.direction = 'down'

    def draw(self, screen):
        pygame.draw.circle(screen, self.color, self.rect.center, self.radius, self.thick)

    def swing_top(self):
        self.rect.y -= self.speed

        if self.rect.top <= 0  and self.direction == 'up':
            self.direction = 'down'
            self.speed = -self.speed

        if self.rect.bottom > int(SCREEN_HEIGHT/2) - self.radius  and self.direction == 'down':
            self.direction = 'up'
            self.speed = -self.speed

    def swing_bot(self):
        self.rect.y -= self.speed

        if self.rect.top < int(SCREEN_HEIGHT/2) + self.radius  and self.direction == 'up':
            self.direction = 'down'
            self.speed = -self.speed

        if self.rect.bottom >= SCREEN_HEIGHT and self.direction == 'down':
            self.direction = 'up'
            self.speed = -self.speed

    def swing_left(self):
        self.rect.x -= self.speed

        if self.rect.right > int(SCREEN_WIDTH/2) - self.radius and self.directionX == 'left':
            self.directionX = 'right'
            self.speed = -self.speed

        if self.rect.left <= 0 and self.directionX == 'right':
            self.directionX = 'left'
            self.speed = -self.speed

    def swing_right(self):
        self.rect.x -= self.speed

        if self.rect.left < int(SCREEN_WIDTH/2) + self.radius  and self.directionX == 'right':
            self.directionX = 'left'
            self.speed = -self.speed

        if self.rect.right >= SCREEN_WIDTH and self.directionX == 'left':
            self.directionX = 'right'
            self.speed = -self.speed

# ---------- Main ----------

def main():

    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    screen_rect = screen.get_rect()

    # Start with 4 enemies
    all_enemies = [
        Enemies(random.randint(1,SCREEN_WIDTH), 1, color=yellow),                           # bottom
        Enemies(random.randint(1,SCREEN_WIDTH), SCREEN_HEIGHT-ENEMY_SIZE, color=green),     # top
        Enemies(1, random.randint(1,SCREEN_HEIGHT), color=blue),                            # left
        Enemies(SCREEN_WIDTH-ENEMY_SIZE, random.randint(1,SCREEN_HEIGHT), color = red)      # right
    ]

    circleTop = [
        Circle(screen_rect.centerx, screen_rect.centery - 2*CIRCLE_RADIUS)
    ]

    circleBot = [
        Circle(screen_rect.centerx, screen_rect.centery + 2*CIRCLE_RADIUS)
    ]

    circleRight = [
        Circle(screen_rect.centerx + 2*CIRCLE_RADIUS, screen_rect.centery)
    ]

    circleLeft = [
        Circle(screen_rect.centerx - 2*CIRCLE_RADIUS, screen_rect.centery)
    ]

    clock = pygame.time.Clock()

    game_over = False

    while not game_over:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                game_over = True

        for item in circleTop:
            item.swing_top()
        for item in circleBot:
            item.swing_bot()
        for item in circleLeft:
            item.swing_left()
        for item in circleRight:
            item.swing_right()

        screen.fill(black)

        for e in all_enemies:
            e.update()
            # Did the enemy make it to the centre?
            if ( e.reachedPoint( SCREEN_WIDTH//2, SCREEN_HEIGHT//2 ) ):
                # Game over?
                print("Game Over?")
                e.randomise()
            e.draw( screen )

        for item in circleTop:
            item.draw(screen)
        for item in circleBot:
            item.draw(screen)
        for item in circleLeft:
            item.draw(screen)
        for item in circleRight:
            item.draw(screen)

        pygame.display.update()

        clock.tick(FPS)

main()
pygame.quit()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM