python - 在pygame中设置 Sprite 行程限制

标签 python pygame

在我的代码中,我的 Sprite 可以在 x 轴上左右移动。但是,它可能会离开屏幕。我想阻止它走出屏幕。我不知道该怎么做,我尝试过写:

if event.key == pygame.K_LEFT and player.rect.x > 0:
    #player moves left

但是没有成功。玩家 Sprite 刚刚跑出了屏幕,我无法让它回来。我愿意接受所有建议。提前致谢!我将代码分成三个不同的文件 --> ma​​in.py:

import pygame
import os
import sys
import time
from pygame import mixer
from Sprite1 import *
from settings import *

'''
Setup
'''
pygame.init()

clock = pygame.time.Clock()

all_sprites = pygame.sprite.Group()
player = Player(all_sprites)
player.rect.x = 100
player.rect.y = 500

enemy_list = pygame.sprite.Group()   # create enemy group
enemy = Enemy(enemy_list)# spawn enemy
enemy.rect.x = 400
enemy.rect.y = 470


showStartScreen(surface)
x = 0
'''
Main loop
'''

main = True

while main == True:
    background = pygame.image.load(os.path.join('images', 'Bg.png')).convert()

    font = pygame.font.Font('freesansbold.ttf', 32)
    text = font.render('Health:', True, BLACK, surface)
    textRect = text.get_rect()
    textRect.center = (60, 30)

    rel_x = x % background.get_rect().width
    surface.blit(background, (rel_x - background.get_rect().width, 0))
    if rel_x < width:
        surface.blit(background, (rel_x, 0))

    if player.rect.x >= 560:
        x -= 10
    elif player.rect.x <= 400:
        x += 10

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

        if event.type == pygame.KEYDOWN:

            if event.key == pygame.K_LEFT:
                player.control(-steps,0)

            if event.key == pygame.K_RIGHT:
                player.control(steps,0)

        if event.type == pygame.KEYUP:

            if event.key == pygame.K_LEFT:
                player.control(steps,0)

            if event.key == pygame.K_RIGHT:
                player.control(-steps,0)

    keys = pygame.key.get_pressed()
    if not(isJump):
        if keys[pygame.K_UP]:
            isJump = True
    else:
        if jumpCount >= -10:
            player.rect.y -= (jumpCount * abs(jumpCount)) * 1
            jumpCount -= 2
        else:
            jumpCount = 10
            isJump = False

    if player.rect.y > width:
        go_screen(surface)

    surface.blit(text, textRect)
    # dt = time since last tick in milliseconds.
    dt = clock.tick(60) / 1000
    all_sprites.update(dt, enemy_list)
    player.update(dt, enemy_list)
    enemy_list.update(dt, all_sprites)
    all_sprites.draw(surface) #refresh player position
    enemy_list.draw(surface)
    for e in enemy_list:
        e.move()
    pygame.display.flip()

settings.py:

import pygame
isJump = False
jumpCount = 10
width = 960
height = 720
FONT_NAME = 'arial'
fps = 40        # frame rate
pygame.display.set_caption('B.S.G.')
surface = pygame.display.set_mode((width, height))
PLAYER_ACC = 0.5
PLAYER_FRICTION = -0.12
PLAYER_GRAV = 0.8
PLAYER_JUMP = 20
PLAYER_LAYER = 2
PLATFORM_LAYER = 1
BLACK = (0, 0, 0)
steps = 10      # how fast to move

Sprite1:

import pygame
import sys
import os
import time
from pygame import mixer
from pygame.locals import *
from settings import *
vec = pygame.math.Vector2
clock = pygame.time.Clock()

def showStartScreen(surface):
    show = True
    while (show == True):
        background = pygame.image.load(os.path.join('images', 'Starting_scr.png'))
        surface.blit(background, (0,0))
        pygame.display.flip()
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONDOWN:
                show = False

def go_screen(surface):
    show = True
    while (show == True):
        background = pygame.image.load(os.path.join('images', 'GO_screen.png'))
        surface.blit(background, (0,0))
        pygame.display.flip()
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONDOWN:
                pygame.quit()
                sys.exit()


class Player(pygame.sprite.Sprite):
    def __init__(self, all_sprites):
        pygame.sprite.Sprite.__init__(self)
        self.movex = 0
        self.movey = 0
        self.frame = 0
        self.health = 100
        self.jumping = False
        self.images = []
        self.imagesleft = []
        self.imagesright = []
        self.imagesdownl = []
        self.imagesdownr = []
        self.direction = "right"
        self.alpha = (0,0,0)
        self.ani = 4 # animation cycles
        self.all_sprites = all_sprites
        self.add(self.all_sprites)
        self.fire_timer = .1
        self.bullet_timer = .1
        self.pos = vec(40, height - 100)
        self.vel = vec(0, 0)
        self.counter = 0

        for i in range(1,5):
            img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
            img = pygame.transform.rotate(img, -90)
            img.convert_alpha()
            img.set_colorkey(self.alpha)
            self.imagesdownl.append(img)
            self.image = self.imagesdownl[0]
            self.rect  = self.image.get_rect()

        for i in range(1,5):
            img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
            img = pygame.transform.flip(img, False, True)
            img = pygame.transform.rotate(img, -90)
            img.convert_alpha()
            img.set_colorkey(self.alpha)
            self.imagesdownr.append(img)
            self.image = self.imagesdownr[0]
            self.rect  = self.image.get_rect()

        for i in range(1,5):
            img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
            img = pygame.transform.flip(img, True, False)
            img.convert_alpha()
            img.set_colorkey(self.alpha)
            self.imagesleft.append(img)
            self.image = self.imagesleft[0]
            self.rect  = self.image.get_rect()

        for i in range(1,5):
            img = pygame.image.load(os.path.join('images','hero' + str(i) + '.png')).convert()
            img.convert_alpha()
            img.set_colorkey(self.alpha)
            self.imagesright.append(img)
            self.image = self.imagesright[0]
            self.rect  = self.image.get_rect()


    def control(self,x,y):
        '''
        control player movement
        '''
        self.movex += x
        self.movey -= y

    def update(self, dt, enemy_list):
        '''
        Update sprite position
        '''
        self.rect.x = self.rect.x + self.movex
        self.rect.y = self.rect.y + self.movey

        # moving left
        if self.movex < 0:
            self.frame += 1
            if self.frame > 3*self.ani:
                self.frame = 0
            self.image = self.imagesleft[self.frame//self.ani]
            self.direction = "left"

        # moving right
        if self.movex > 0:
            self.frame += 1
            if self.frame > 3*self.ani:
                self.frame = 0
            self.image = self.imagesright[self.frame//self.ani]
            self.direction = "right"

        enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)
        for enemy in enemy_hit_list:
            self.health -= 10
            if self.direction == "left":
                self.rect.x += 100
            else:
                self.rect.x -= 100
            print(self.health)

        if self.health <= 0:
            distance = 20
            speed = 10

            if self.counter >= distance and self.counter <= distance*2:
                self.rect.y -= speed
            self.counter += 1
            if self.rect.y < 291:
                self.movey = 10
            if self.direction == "left":
                self.frame += 1
                if self.frame > 3*self.ani:
                    self.frame = 0
                self.image = self.imagesdownr[self.frame//self.ani]
            if self.direction == "right":
                self.frame += 1
                if self.frame > 3*self.ani:
                    self.frame = 0
                self.image = self.imagesdownl[self.frame//self.ani]

        if self.rect.y > height:
            self.kill()

        keys = pygame.key.get_pressed()
        if keys[pygame.K_SPACE]:
            self.bullet_timer -= dt  # Subtract the time since the last tick.

        if keys[pygame.K_x]:
            self.fire_timer -= dt

        if self.bullet_timer <= 0:
            self.bullet_timer = 100  # Bullet ready.
            if keys:  # Left mouse button.
                # Create a new bullet instance and add it to the groups.
                if self.direction == "right":
                    Bullet([self.rect.x + self.image.get_width(), self.rect.y + self.image.get_height()/2], self.direction, self.all_sprites)
                else:
                    Bullet([self.rect.x, self.rect.y + self.image.get_height()/2], self.direction, self.all_sprites)
                self.bullet_timer = .5  # Reset the timer.

        if self.fire_timer <= 0:
            self.fire_timer = 100
            if keys:
                if self.direction == "right":
                    Fire([self.rect.x + 170, self.rect.y + self.image.get_height()/2], self.direction, self.all_sprites)
                else:
                    Fire([self.rect.x - 90, self.rect.y + self.image.get_height()/2], self.direction, self.all_sprites)
                self.fire_timer = .1


class Enemy(pygame.sprite.Sprite):
    '''
    Spawn an enemy
    '''
    def __init__(self, enemy_list):
        pygame.sprite.Sprite.__init__(self)
        self.movex = 0
        self.movey = 0
        self.health = 50
        self.frame = 0
        self.alpha = (0,0,0)
        self.ani = 2 # animation cycles
        self.enemy_list = enemy_list
        self.add(self.enemy_list)
        self.counter = 0 # counter variable
        self.imagesleft = []
        self.imagesright = []
        for i in range(1,17):
            img = pygame.image.load(os.path.join('images','Bot' + str(i) + '.png')).convert()
            img.convert_alpha()
            img.set_colorkey(self.alpha)
            self.imagesleft.append(img)
            self.image = self.imagesleft[0]
            self.rect  = self.image.get_rect()
        for i in range(1,17):
            img = pygame.image.load(os.path.join('images','Bot' + str(i) + '.png')).convert()
            img = pygame.transform.flip(img, True, False)
            img.convert_alpha()
            img.set_colorkey(self.alpha)
            self.imagesright.append(img)
            self.image = self.imagesright[0]
            self.rect  = self.image.get_rect()

    def move(self):
        '''
        enemy movement
        '''
        distance = 30
        speed = 10

        if self.counter >= 0 and self.counter <= distance:
            self.rect.x += speed
            self.frame += 1
            if self.frame > 15*self.ani:
                self.frame = 0
            self.image = self.imagesright[self.frame//self.ani]

        elif self.counter >= distance and self.counter <= distance*2:
            self.rect.x -= speed
            self.frame += 1
            if self.frame > 15*self.ani:
                self.frame = 0
            self.image = self.imagesleft[self.frame//self.ani]
        else:
            self.counter = 0

        self.counter += 1

    def update(self, dt, all_sprites):
        self.rect.x = self.rect.x + self.movex
        self.rect.y = self.rect.y + self.movey
        bullet_list = pygame.sprite.spritecollide(self, all_sprites, True)
        for bullets in bullet_list:
            self.health -= 10
            print(self.health)
        if self.health <= 0:
            img = pygame.image.load(os.path.join('images','E_dead.png')).convert()
            img.convert_alpha()
            img.set_colorkey(self.alpha)
            self.image = img
            distance = 5
            speed = 10

            if self.counter >= 0 and self.counter <= distance:
                self.rect.x += speed

            elif self.counter >= distance and self.counter <= distance*2:
                self.rect.x -= speed
            else:
                self.counter = 0

            self.counter += 1
            self.movey = -20
        if self.rect.y < -50:
            self.kill()

class Bullet(pygame.sprite.Sprite):

    IMAGE = None
    FLIPPED_IMAGE = None

    def __init__(self, pos, direction, *sprite_groups):
        super().__init__(*sprite_groups)

        # cache images
        if not Bullet.IMAGE:
            Bullet.IMAGE = pygame.image.load(os.path.join('images','fireball.png'))
            Bullet.FLIPPED_IMAGE = pygame.transform.flip(Bullet.IMAGE, True, False)

        if direction == "right":
            self.vel = pygame.math.Vector2(750, 0)
            self.image = Bullet.IMAGE
        else:
            self.vel = pygame.math.Vector2(-750, 0)
            self.image = Bullet.FLIPPED_IMAGE

        self.pos = pygame.math.Vector2(pos)
        self.rect  = self.image.get_rect(center=pos)

    def update(self, dt, enemy_list):
        # Add the velocity to the position vector to move the sprite
        self.pos += self.vel * dt
        self.rect.center = self.pos  # Update the rect pos.
        if not pygame.display.get_surface().get_rect().colliderect(self.rect):
            self.kill()

class Fire(pygame.sprite.Sprite):

    IMAGE = None
    FLIPPED_IMAGE = None

    def __init__(self, pos, direction, *sprite_groups):
        super().__init__(*sprite_groups)

        # cache images
        if not Fire.IMAGE:
            Fire.IMAGE = pygame.image.load(os.path.join('images','fire_drag.png'))
            Fire.FLIPPED_IMAGE = pygame.transform.flip(Fire.IMAGE, True, False)

        if direction == "right":
            self.image = Fire.IMAGE
            self.vel = pygame.math.Vector2(0, 0)
        else:
            self.image = Fire.FLIPPED_IMAGE
            self.vel = pygame.math.Vector2(0, 0)
        self.pos = pygame.math.Vector2(pos)
        self.rect  = self.image.get_rect(center=pos)

    def update(self, dt, enemy_list):
        self.too = True
        self.pos += self.vel * dt

        self.rect.center = self.pos  # Update the rect pos.
        if self.too == True:
            self.kill()

再次感谢!

最佳答案

Player.control只是设置了玩家的移动方向,但并没有移动玩家,因此省略plyer.control()<的调用是完全没用的。您必须在方法update中阻止和限制玩家的移动:

class Player(pygame.sprite.Sprite):
    # [...]

    def update(self, dt, enemy_list):
        
        self.rect.x += self.movex
        self.rect.y += self.movey

        if self.rect.left < 0:
            self.rect.left = 0
        elif self.rect.right > width:
            self.rect.right = width

        if self.rect.top < 0:
            self.rect.top = 0
        elif self.rect.bottom > height:
            self.rect.bottom = height
 
        # [...]

关于python - 在pygame中设置 Sprite 行程限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63090830/

相关文章:

python - 具有重力的 Sprite 不随重力移动

python - aws-lambda 函数中的异常处理

python - Django admin datetime `now` 按钮选择正确的本地时间,但服务器时间错误

python - 为什么我的代码无法检测到操纵杆上的按钮按下

python - 我的 pygame 俄罗斯方 block 游戏总是卡住

python - Pygame 复制图形

python - 如何询问玩家是否愿意在死亡时重试,如果他们说愿意,则重新启动游戏

python - 仅使用一列对嵌套列表进行排序

python - 如何匹配格式 “Sep-14” 将其转换为 DATETIME

python - 检测机器人在裁剪行之间可以走的路径