1

所以我一直在让精灵保持在屏幕范围内的问题。我让它与一个简单的 rect(0,0,16,16) 一起工作,但我似乎无法让它与一个被 blit 到屏幕上的精灵一起工作。为了使我的精灵保持在屏幕分辨率内,我需要更改什么?我今天才刚刚开始使用类来组织代码,因此任何输入都会受到赞赏和帮助。

import pygame
from pygame.locals import *
from pygame import Color


class Game():
    """ Lets try to get this going by simple steps
    One by one. First step, lets figure how to make a class
    that can do the display stuff. Lord have mercy on my soul"""

    def __init__(self, wi=256, hi=224, multii=3):
        """Initialization"""
        pygame.init()
        self.runGame    = True
        self.width      = wi*multii
        self.height     = hi*multii
        self.spritesize = 16*multii
        self.clock      = pygame.time.Clock()
        self.fps        = self.clock.get_fps()
        self.screen     = pygame.display.set_mode((self.width, self.height))
        self.kl         = []
        self.walk       = [0, 0]
        self.speed      = multii*1.5
        self.x,self.y   = self.width/2, self.height/2
        self.playerSpr  = pygame.image.load('images/'+'link1.png').convert_alpha()
        self.playerRec  = Rect(self.playerSpr.get_rect())


    def mainLoop(self):
        """Loop through the main game routines
        1. Drawing  2. Input handling  3. Updating
        Then loop through it until user quits"""
        while self.runGame:
            self.clock.tick(60)
            self.events()
            self.draw()


    def events(self):
        """Time to handle some events"""
        for e in pygame.event.get():
            if (e.type == pygame.QUIT) or (e.type == KEYDOWN and e.key == K_ESCAPE):
                self.runGame = False
                break                            
            if e.type==KEYDOWN:     
                if e.key==pygame.K_a: self.kl.append(1)
                if e.key==pygame.K_d: self.kl.append(2)
                if e.key==pygame.K_w: self.kl.append(3)
                if e.key==pygame.K_s: self.kl.append(4)             
            if e.type==pygame.KEYUP:
                if e.key==pygame.K_a: self.kl.remove(1)            
                if e.key==pygame.K_d: self.kl.remove(2)
                if e.key==pygame.K_w: self.kl.remove(3)             
                if e.key==pygame.K_s: self.kl.remove(4)

            if   self.kl[-1:]==[1]: self.walk=[-self.speed, 0]
            elif self.kl[-1:]==[2]: self.walk=[ self.speed, 0]
            elif self.kl[-1:]==[3]: self.walk=[0,-self.speed]
            elif self.kl[-1:]==[4]: self.walk=[0, self.speed]
            else:                   self.walk=[0, 0]

        self.x+=self.walk[0]
        self.y+=self.walk[1]


    def draw(self):
        """Draw and update the main screen"""
        self.fps = self.clock.get_fps()
        self.screen.fill(Color('purple'))
        #print self.screen.get_rect()
        #print player_rect
        self.playerSpr.clamp_ip(self.screen.get_rect())
        #pygame.draw.rect(self.screen, (255, 255, 255), self.playerrect)
        self.screen.blit(self.playerSpr, (self.x,self.y), self.playerRec)
        pygame.display.set_caption('Grid2. FPS: '+str(self.fps))
        pygame.display.update()



game = Game()
game.mainLoop()
4

2 回答 2

1

两件事情:

  1. 当精灵离开屏幕时,您并没有停止它的移动。做一个移动函数,它会得到一个方向,并决定它是否可以更多地移动到一边。这样,当精灵的右侧是屏幕时,您将不会向右移动更多。

  2. 由于您将方向键放在一个类似于堆栈的列表中,因此每次按键只能获得 1 个方向。如果您还想沿对角线移动,请为两个方向制作两个列表,或者使用更简单的方法,例如:

    if KEYDOWN == K_LEFT: direction_x = -1
    if KEYUP == K_LEFT AND direction_x == -1: direction_x = 0
    

    对每个键执行此操作。

于 2012-12-18T10:05:56.273 回答
1

为什么不使用附加和属性playerRec来跟踪玩家的位置?xy

我建议也使用move方法(或move_ip):

def events(self):
    for e in pygame.event.get():
       ...

    self.playerRec.move_ip(*self.walk) # instead of self.x+=self.walk[0] / self.y+=self.walk[1]

def draw(self):
    ...

    # probably do this right after 'move_ip'
    self.playerRec.clamp_ip(self.screen.get_rect())

    # note that 'blit' accepts a 'Rect' as second parameter
    self.screen.blit(self.playerSpr, self.playerRec) 

附带说明:您应该考虑使用 a Sprite,因为它基本上结合了 anImage和 a Rect

于 2012-12-18T12:01:23.230 回答