我如何在pygame中鼠标滚动二维贴图



我正在尝试玩pygame,我已经使用了一些例子,我发现学习和创建一个简单的。我的下一个目标是创建一个比屏幕大的2D贴图,然后可以用鼠标滚动。我想做一些类似于战略游戏的东西,如果你将鼠标移动到屏幕边缘,"摄像机"将朝着那个方向移动,显示地图的那一部分(如果摄像机到达地图的尽头,我也想让它停止)。此时,如果我将鼠标悬停在边缘上,它只会移动一次。

import pygame, os
from pygame.locals import *
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
SCREEN_WIDTH = 5*40
SCREEN_HEIGHT = 7*40
#functions to create our resources
def load_image(name, colorkey=None):
    try:
        image = pygame.image.load(name) 
    except pygame.error, message:
        print 'Cannot load image:', name
        raise SystemExit, message
    image = image.convert_alpha()
    if colorkey is not None:
        if colorkey is -1:
            colorkey = image.get_at((0,0))
        image.set_colorkey(colorkey, RLEACCEL)
    return image, image.get_rect()
#classes for our game objects
class Camera(object):
    def __init__(self, camera_func, width, height):
        self.camera_func = camera_func
        self.state = pygame.Rect(100,100, width, height)
    def apply(self, rect):
        l, t, w, h = rect
        if 0 <= self.state[0] <= (SCREEN_WIDTH/5):
            l += 10
        elif (SCREEN_WIDTH - (SCREEN_WIDTH/5)) < self.state[0] <= SCREEN_WIDTH:
            l -=10
        if 0 <= self.state[1] <= (SCREEN_HEIGHT/5):
            t += 10
        elif (SCREEN_HEIGHT - (SCREEN_HEIGHT/5)) < self.state[1] <= SCREEN_HEIGHT:
            t -=10
        return rect.move(l,t)
    def update(self):
        pos = pygame.mouse.get_pos()
        self.state.topleft = pos
        #self.state = self.camera_func(self.state)
def complex_camera(camera):
    l, t, w, h = camera
    l, t, _, _ = -l, -t, w, h
    l = min(0, l)                           # stop scrolling at the left edge
    l = max(-(camera.width-SCREEN_WIDTH), l)   # stop scrolling at the right edge
    t = max(-(camera.height-SCREEN_HEIGHT), t) # stop scrolling at the bottom
    t = min(0, t)                           # stop scrolling at the top
    return pygame.Rect(l, t, w, h)
def main ():
    pygame.init()
    screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT])
    pygame.display.set_caption("W40K")
    grasstile = pygame.image.load('./textures/grass.png')
    watertile = pygame.image.load('./textures/water.png')
    waterbeach = pygame.image.load('./textures/dirt.png')
    grassrect = grasstile.get_rect()
    waterrect = watertile.get_rect()
    waterb = waterbeach.get_rect()
    TILESIZE = 40
    tilemap = [
        [grasstile,grasstile,waterbeach,waterbeach,watertile,watertile,waterbeach,waterbeach,grasstile,grasstile,waterbeach,watertile,watertile,watertile,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],   
        [grasstile,waterbeach,waterbeach,waterbeach,watertile,watertile,watertile,waterbeach,grasstile,grasstile,waterbeach,watertile,watertile,watertile,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],
        [waterbeach,waterbeach,waterbeach,waterbeach,watertile,watertile,watertile,waterbeach,grasstile,grasstile,waterbeach,watertile,watertile,watertile,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],
        [grasstile,waterbeach,waterbeach,waterbeach,waterbeach,waterbeach,grasstile,waterbeach,grasstile,grasstile,waterbeach,watertile,watertile,watertile,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],
        [grasstile,grasstile,waterbeach,waterbeach,watertile,watertile,waterbeach,waterbeach,grasstile,grasstile,waterbeach,waterbeach,watertile,watertile,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],
        [watertile,grasstile,waterbeach,watertile,watertile,watertile,waterbeach,waterbeach,grasstile,grasstile,waterbeach,watertile,watertile,watertile,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],
        [watertile,watertile,waterbeach,waterbeach,waterbeach,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach,waterbeach,watertile,watertile,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],
        [grasstile,watertile,waterbeach,waterbeach,grasstile,grasstile,waterbeach,waterbeach,grasstile,grasstile,waterbeach,waterbeach,waterbeach,waterbeach,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],
        [grasstile,grasstile,waterbeach,waterbeach,watertile,watertile,waterbeach,waterbeach,grasstile,grasstile,waterbeach,watertile,watertile,watertile,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],
        [grasstile,grasstile,waterbeach,waterbeach,watertile,watertile,waterbeach,waterbeach,grasstile,grasstile,waterbeach,grasstile,watertile,watertile,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],
        [grasstile,grasstile,waterbeach,waterbeach,watertile,watertile,waterbeach,waterbeach,grasstile,grasstile,waterbeach,watertile,grasstile,watertile,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],
        [grasstile,grasstile,waterbeach,waterbeach,watertile,watertile,waterbeach,waterbeach,grasstile,grasstile,waterbeach,watertile,watertile,watertile,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],
        [grasstile,grasstile,waterbeach,waterbeach,watertile,watertile,waterbeach,waterbeach,grasstile,grasstile,waterbeach,watertile,watertile,watertile,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],
        [grasstile,grasstile,waterbeach,waterbeach,watertile,watertile,waterbeach,waterbeach,grasstile,grasstile,waterbeach,watertile,watertile,watertile,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],
        [grasstile,grasstile,waterbeach,waterbeach,watertile,watertile,waterbeach,waterbeach,grasstile,grasstile,waterbeach,watertile,watertile,watertile,waterbeach,waterbeach,waterbeach,grasstile,grasstile,waterbeach],
    ]
    #Creates surface of the background
    map_surface = pygame.Surface((len(tilemap[0])*TILESIZE, len(tilemap)*TILESIZE))
    #Display the surface
    for y,row in enumerate(tilemap):
        for x,tile_surface in enumerate(row):
            map_surface.blit(tile_surface,(x*TILESIZE,y*TILESIZE))
    total_level_width = len(tilemap[0]) * 40
    total_level_height = len(tilemap) * 40
    camera = Camera(complex_camera,total_level_width, total_level_height)
    #mouse = Mouse()
    #allsprites = pygame.sprite.RenderPlain((mouse))
    clock = pygame.time.Clock()
    while 1:
        clock.tick(60)
    #Handle Input Events
        for event in pygame.event.get():
            if event.type == QUIT:
                return
            elif event.type == KEYDOWN and event.key == K_ESCAPE:
                return
        screen.fill(BLACK)
        #Camera moves.
        camera.update()
        #Display background.
        screen.blit(map_surface, camera.apply(waterrect))
        pygame.display.flip()
if __name__ == "__main__":
    main()
pygame.quit()

我认为问题是在camara功能和应用功能,但我没有线索来改进这一点,使camara正常工作。

谢谢!

我很难确切地说你的代码出了什么问题(我在编码方面的经验太少),但我刚刚意识到在我的脚本中通过鼠标移动屏幕,我这样做了:

screen=pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT),32)
Map=pygame.image.load(os.path.join('Image','MAP.png')).convert_alpha()
startX,startY=0,0                   # starting coordinates for Map
while 1:
    screen.fill(white)
    screen.blit(Map,(startX,startY))
    for event in pygame.event.get():
        if event.type == MOUSEMOTION :
            mousepos=pygame.mouse.get_pos()
    if WINDOWHEIGHT-mousepos[1]<50:     # if  y-position of mouse is 50 pixel far from lower edge ..
        startY -= 5                     # ..move Map by 5 px
    if mousepos [1]<50:
        startY += 5
    if mousepos [0]<50 :
        startX += 5
    if WINDOWWIDTH - mousepos[0]<50:
        startX -= 5
    pygame.display.flip()

最新更新