我試圖複製一些電網視口(如3ds Max中的正高視圖)
或地圖觀衆喜歡(的GoogleMaps),我們有地圖或網格的行爲,這是比屏幕大很多的
,我們通過點擊視口中的某處並拖動進行導航。pygame的:視口中單擊並拖動
到目前爲止,我設法創建了一個非常大的網格,繪製它並使視口僅顯示它應該顯示的圖塊。
這是到目前爲止我的代碼:
import pygame, sys, math
from pygame.locals import *
FPS = 30
WINDOWWIDTH = 640
WINDOWHEIGHT = 480
GRIDWIDTH = 256
GRIDHEIGHT = 256
GRIDSIZE = 256
TILESIZE = 40
BGCOLOR = (128, 128, 128)
FGCOLOR = (64, 64, 64)
GRID = []
FPSCLOCK = pygame.time.Clock()
indexX = None
indexY = None
minVPcoordX = 0
minVPcoordY = 0
maxVPcoordX = (TILESIZE*GRIDSIZE)-WINDOWWIDTH
maxVPcoordY = (TILESIZE*GRIDSIZE)-WINDOWHEIGHT
viewportOffset = (0, 0)
vpStartXTile = 0
vpStartYTile = 0
viewportCoord = (0, 0)
coordX = 0
coordY = 0
movedDistanceX = 0
movedDistanceY = 0
speed = 4
def main():
global FPSCLOCK, DISPLAYSURF
global coordX, coordY
global offsetX, offsetY, negativeOffsetX, negativeOffsetY
global movedDistanceX, movedDistanceY
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
mouseX = 0
mouseY = 0
generateGrid(GRIDSIZE, GRIDSIZE)
LeftButton = False
mousePos = (0, 0)
dragStart = (0,0)
dragEnd = (0,0)
pygame.font.init()
arialFnt = pygame.font.SysFont('Arial', 16)
while True:
DISPLAYSURF.fill(BGCOLOR)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
#X
if coordX < maxVPcoordX:
coordX += speed
elif coordX < minVPcoordX:
coordX = 0
else:
coordX = maxVPcoordX
#Y
if coordY < maxVPcoordY:
coordY += speed
elif coordY < minVPcoordY:
coordY = 0
else:
coordY = maxVPcoordY
#-------------
viewportCoord = (coordX, coordY)
print(coordX, coordY)
vpStartXTile = math.floor(float(viewportCoord[0]/TILESIZE))
vpStartYTile = math.floor(float(viewportCoord[1]/TILESIZE))
GRIDstartTile = GRID[vpStartXTile][vpStartYTile]
negativeOffsetX = viewportCoord[0] - GRID[vpStartXTile][vpStartYTile][0]
negativeOffsetY = viewportCoord[1] - GRID[vpStartXTile][vpStartYTile][1]
offsetX = TILESIZE - negativeOffsetX
offsetY = TILESIZE - negativeOffsetY
repeatX = math.floor(WINDOWWIDTH/TILESIZE)
repeatY = math.floor(WINDOWHEIGHT/TILESIZE)
drawGrid(repeatX, repeatY)
outputLabel = arialFnt.render('(Top-Left)Coordinates: x%s - y%s' % (coordX, coordY), 1, (255,255,255))
DISPLAYSURF.blit(outputLabel, (10, 10))
# frame draw
pygame.display.set_caption("Memory Game - FPS: %.0f" % FPSCLOCK.get_fps())
pygame.display.flip()
pygame.display.update()
FPSCLOCK.tick(FPS)
def generateGrid(xTiles=None, yTiles=None):
global GRID
GRID = []
for i in range(xTiles):
GRID.append([None] * yTiles)
ix = 0
iy = 0
posX = -40
for x in range(len(GRID[ix])):
posX += TILESIZE
posY = -40
iy = 0
for y in range(xTiles):
posY += TILESIZE
position = (posX, posY)
GRID[ix][iy] = position
iy += 1
if ix < xTiles:
ix += 1
else:
return
def drawGrid(x=None, y=None):
lineWidth = 1
xPos = 0
yPos = 0
for i in range(x):
xStart = (xPos + offsetX, 0)
xEnd = (xPos + offsetX, WINDOWHEIGHT + negativeOffsetY)
pygame.draw.line(DISPLAYSURF, FGCOLOR, xStart, xEnd, lineWidth)
xPos += TILESIZE
for i in range(y):
yStart = (0, yPos + offsetY)
yEnd = (WINDOWWIDTH + negativeOffsetX, yPos + offsetY)
pygame.draw.line(DISPLAYSURF, FGCOLOR, yStart, yEnd, lineWidth)
yPos += TILESIZE
def moveGrid():
pass
def zoomIn():
pass
def zoomOut():
pass
main()
正如你所看到的,它按預期工作(我還沒有實現任何形式的點擊&阻力
這個樣本中 的)。
似乎pygame的沒有這個事件,所以它必須是
MOUSEBUTTONDOWN和MOUSEMOTION的組合。
我試着用get_pos()存儲前一幀的位置,並減去當前幀的位置,但我無法弄清楚下一個。 它加速的方式太快..
我也試過這與get_rel()鼠標的方法,沒有成功。
(雖然我敢肯定,我是不應該++鼠標位置在屏幕上的位置)
我研究了四周,看看是否有人這樣做,但我只發現瞭如何拖動東西
在一個固定的屏幕上。我需要相反的 - 在固定的網格上拖動屏幕。所以,如果任何人有任何想法或建議如何使這個機制,或任何我可以研究它的鏈接,我將不勝感激!
PS:我發現類似的東西,但它寫在JS和它的翻譯)
看看這個演示。您可以使用鼠標滾動網格。 http://code.google.com/p/ninmonkey/source/browse/#hg%2Fexamples%2Fmaptiles_numpy%253Fstate%253Dclosed – ninMonkey
謝謝,這對我幫助很大!我將發佈固定代碼。 –