我试图在我用pygame制作的2d游戏中实现相机功能,但我唯一获得的是我在窗口中间设置的玩家。我看到它的x和y如何变化,但玩家不会移动。我知道我必须使用相机的apply方法到地图但我不知道该怎么做,因为这是我第一次接触pygame。这是我的代码:
import pygame, sys
from pygame.locals import *
import random
"""
dirt 0
grass 1
water 2
coal 3
"""
DIRT = 0
GRASS = 1
WATER = 2
COAL = 3
DIAMOND = 4
CLOUD = 5
cloudx = -200
cloudy = 0
WHITE = (255, 255, 255)
BLACK = (0, 0, 0 )
BROWN = (153, 76, 0 )
GREEN = (0, 255, 0 )
BLUE = (0, 0, 255)
TILESIZE = 40
MAPWIDTH = 140
MAPHEIGHT = 120
WIN_WIDTH = 800
WIN_HEIGHT = 600
HALF_WIDTH = int(WIN_WIDTH / 2)
HALF_HEIGHT = int(WIN_HEIGHT / 2)
fpsClock = pygame.time.Clock()
colours = {
DIRT: BROWN,
GRASS: GREEN,
WATER: BLUE,
COAL: BLACK
}
"""tilemap = [
[GRASS, COAL, DIRT ],
[WATER, WATER, GRASS],
[COAL, WATER, GRASS],
[DIRT, WATER, COAL ],
[GRASS, WATER, DIRT]
]"""
resources = [WATER, GRASS, COAL, DIRT, DIAMOND]
tilemap = [[random.choice(resources) for w in range(MAPWIDTH)] for h in range(MAPHEIGHT)]
textures = {
DIRT: pygame.image.load("dirt.gif"),
GRASS: pygame.image.load("grass.gif"),
COAL: pygame.image.load("coal.gif"),
WATER: pygame.image.load("water.gif"),
DIAMOND: pygame.image.load("diamond.gif"),
CLOUD: pygame.image.load("nube.gif")
}
inventory = {
DIRT :0,
WATER :0,
GRASS :0,
COAL :0,
DIAMOND :0
}
playerPos = [50,50]
move = 0
vel_x = 0
vel_y = 0
speed = 1
class Camera(object):
def __init__(self, camera_func, width, height):
self.camera_func = camera_func
self.state = pygame.Rect(0, 0, width, height)
def apply(self, rect):
return rect.move(self.state.topleft)
def update(self, target_rect):
self.state = self.camera_func(self.state, target_rect)
def simple_camera(camera, target_rect):
l, t, _, _ = target_rect
_, _, w, h = camera
return pygame.Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h)
def complex_camera(camera, target_rect):
l, t, _, _ = target_rect
_, _, w, h = camera
l, t, _, _ = -l+HALF_WIDTH, -t+HALF_HEIGHT, 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)
global cameraX, cameraY
total_level_width = len(tilemap[0]) * TILESIZE
total_level_height = len(tilemap)*TILESIZE
camera = Camera(simple_camera ,total_level_width, total_level_height)
pygame.init()
DISPLAYSURF = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))
pygame.display.set_caption("My first game :)")
pygame.display.set_icon(pygame.image.load("player.gif"))
PLAYER = pygame.image.load("player.gif")
playerrect = PLAYER.get_rect()
for rw in range(MAPHEIGHT):
for cl in range(MAPWIDTH):
randomNumber = random.randint(0,50)
if randomNumber <= 10:
tile = COAL
elif randomNumber > 11 and randomNumber <= 20:
tile = WATER
elif randomNumber > 21 and randomNumber <= 45:
tile = GRASS
elif randomNumber > 46 and randomNumber <= 49:
tile = DIRT
else:
tile = DIAMOND
tilemap[rw][cl] = tile
INVFONT = pygame.font.Font("freeSansBold.ttf", 18)
while True:
for event in pygame.event.get():
if event.type == QUIT or event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
#movement
if event.key == K_RIGHT and playerPos[0] < MAPWIDTH - 1:
playerPos[0] += move
elif event.key == K_LEFT and playerPos[0] > 1/TILESIZE:
playerPos[0] -= move
elif event.key == K_DOWN and playerPos[1] < MAPHEIGHT - 1:
playerPos[1] += move
elif event.key == K_UP and playerPos[1] > 1/TILESIZE:
playerPos[1] -= move
#pick up resource
elif event.key == K_SPACE:
currentTile = tilemap[playerPos[1]][playerPos[0]]
inventory[currentTile] += 1
tilemap[playerPos[1]][playerPos[0]] = DIRT
#place resources
elif event.key == K_1:
currentTile = tilemap[playerPos[1]][playerPos[0]]
if inventory[WATER] > 0:
inventory[WATER] -= 1
tilemap[playerPos[1]][playerPos[0]] = WATER
inventory[currentTile] += 1
elif event.key == K_2:
currentTile = tilemap[playerPos[1]][playerPos[0]]
if inventory[GRASS] > 0:
inventory[GRASS] -= 1
tilemap[playerPos[1]][playerPos[0]] = GRASS
inventory[currentTile] += 1
elif event.key == K_3:
currentTile = tilemap[playerPos[1]][playerPos[0]]
if inventory[COAL] > 0:
inventory[COAL] -= 1
tilemap[playerPos[1]][playerPos[0]] = COAL
inventory[currentTile] += 1
elif event.key == K_4:
currentTile = tilemap[playerPos[1]][playerPos[0]]
if inventory[DIRT] > 0:
inventory[DIRT] -= 1
tilemap[playerPos[1]][playerPos[0]] = DIRT
inventory[currentTile] += 1
elif event.key == K_5:
currentTile = tilemap[playerPos[1]][playerPos[0]]
if inventory[DIAMOND] > 0:
inventory[DIAMOND] -= 1
tilemap[playerPos[1]][playerPos[0]] = DIAMOND
inventory[currentTile] += 1
keys = pygame.key.get_pressed()
if keys[K_LEFT] and playerPos[0] > 1/TILESIZE:
playerPos[0] -= speed
if keys[K_RIGHT] and playerPos[0] < MAPWIDTH - 1:
playerPos[0] += speed
if keys[K_UP] and playerPos[1] > 1/TILESIZE:
playerPos[1] -= speed
if keys[K_DOWN] and playerPos[1] < MAPHEIGHT - 1:
playerPos[1] += speed
for row in range(MAPHEIGHT):
for column in range(MAPWIDTH):
DISPLAYSURF.blit(textures[tilemap[row][column]], (column*TILESIZE, row*TILESIZE))
#DISPLAYSURF.blit(PLAYER, (playerPos[0]*TILESIZE, playerPos[1]*TILESIZE))
DISPLAYSURF.blit(PLAYER, camera.apply(pygame.Rect(playerPos[0],playerPos[1],42,42)))
camera.update(PLAYER.get_rect().move((playerPos[0],playerPos[1])))
pygame.display.update()
fpsClock.tick(10)
print playerPos
答案 0 :(得分:1)
首先,删除这段代码:
if event.key == K_RIGHT and playerPos[0] < MAPWIDTH - 1:
playerPos[0] += move
elif event.key == K_LEFT and playerPos[0] > 1/TILESIZE:
playerPos[0] -= move
elif event.key == K_DOWN and playerPos[1] < MAPHEIGHT - 1:
playerPos[1] += move
elif event.key == K_UP and playerPos[1] > 1/TILESIZE:
playerPos[1] -= move
您已使用pygame.key.get_pressed()
进行移动,因此无需检查按键操作(不要忘记将以下elif
更改为if
)。
我知道我必须将相机的应用方法用于地图
是的,你正走在正确的轨道上。
您已经创建了一个变量playerrect
,因此我们可以使用它来存储播放器的位置。另外,让我们创建一个Rect
来存储地图的大小。这很快就会派上用场:
playerrect = PLAYER.get_rect(top=50, left=50)
mapsize = pygame.rect.Rect(0, 0, MAPWIDTH*TILESIZE, MAPHEIGHT*TILESIZE)
现在,当按住键移动播放器时,我们可以简单地使用
keys = pygame.key.get_pressed()
if keys[K_LEFT]: playerrect.move_ip(-speed, 0)
if keys[K_RIGHT]: playerrect.move_ip(speed, 0)
if keys[K_UP]: playerrect.move_ip(0, -speed)
if keys[K_DOWN]: playerrect.move_ip(0, speed)
playerrect.clamp_ip(mapsize)
更改播放器的位置,playerrect.clamp_ip(mapsize)
确保玩家永远不会离开地图。
对于绘图,您应该首先清除屏幕。要绘制切片,您必须为每个切片创建一个Rect
(稍后您可以创建一次并存储/重复使用它们)。
DISPLAYSURF.fill(pygame.color.Color('Black'))
for row in range(MAPHEIGHT):
for column in range(MAPWIDTH):
DISPLAYSURF.blit(textures[tilemap[row][column]], camera.apply(pygame.rect.Rect((column*TILESIZE, row*TILESIZE), (TILESIZE, TILESIZE))))
DISPLAYSURF.blit(PLAYER, camera.apply(playerrect))
camera.update(playerrect)