Grid PyGame:视口单击&;拖曳
我正在尝试复制某些栅格视口的行为(如3ds Max的正交视图)Grid PyGame:视口单击&;拖曳,grid,pygame,drag,viewport,Grid,Pygame,Drag,Viewport,我正在尝试复制某些栅格视口的行为(如3ds Max的正交视图) 或者像(谷歌地图)这样的地图浏览者,我们有地图或网格,它要大得多 然后,我们通过单击视口中的某个位置并拖动来导航 到目前为止,我已经成功地创建了一个相当大的网格,绘制它,并使视口仅显示它应该显示的瓷砖 以下是我目前的代码: import pygame, sys, math from pygame.locals import * FPS = 30 WINDOWWIDTH = 640 WINDOWHEIGHT = 480 GRIDWI
或者像(谷歌地图)这样的地图浏览者,我们有地图或网格,它要大得多
然后,我们通过单击视口中的某个位置并拖动来导航 到目前为止,我已经成功地创建了一个相当大的网格,绘制它,并使视口仅显示它应该显示的瓷砖 以下是我目前的代码:
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、sys、math
从pygame.locals导入*
FPS=30
窗宽=640
窗高=480
网格宽度=256
网格高度=256
网格大小=256
TILESIZE=40
BGCOLOR=(128128128)
FGCOLOR=(64,64,64)
网格=[]
fpscall=pygame.time.Clock()
indexX=无
indexY=无
minVPcoordX=0
minVPcoordY=0
maxVPcoordX=(TILESIZE*GRIDSIZE)-窗口宽度
maxVPcoordY=(波浪大小*网格大小)-窗口高度
视口偏移=(0,0)
vpStartXTile=0
vpStartYTile=0
viewportCoord=(0,0)
coordX=0
coordY=0
movedDistanceX=0
MovedInstancey=0
速度=4
def main():
全球时钟,DISPLAYSURF
全球合作
全局偏移量,偏移量,负偏移量,负偏移量
全局movedInstancex,movedInstancey
DISPLAYSURF=pygame.display.set_模式((窗口宽度、窗口高度))
mouseX=0
mouseY=0
generateGrid(GRIDSIZE,GRIDSIZE)
LeftButton=False
鼠标点=(0,0)
dragStart=(0,0)
dragEnd=(0,0)
pygame.font.init()
arialFnt=pygame.font.SysFont('Arial',16)
尽管如此:
显示冲浪填充(BGCOLOR)
对于pygame.event.get()中的事件:
如果event.type==退出:
pygame.quit()
sys.exit()
#X
如果coordX
如您所见,它按预期工作(我没有实现任何形式的单击和拖动在本示例中) pygame似乎没有这方面的活动,因此它必须是
鼠标按钮按下和鼠标情感 我尝试用get_pos()存储前一帧的位置,并减去当前帧的位置,但我无法计算出下一帧的位置。 它加速太快了。
我也用鼠标的get_rel()方法尝试过,但没有成功。
(尽管我很确定我不应该将鼠标位置转换为屏幕位置) 我四处研究,看看是否有其他人这样做,但我只找到了如何拖拉某物
在固定屏幕上。我需要相反的方法-在固定的网格上拖动屏幕 所以,如果有人对如何制作这个机械师有任何想法或建议,或者我可以研究的任何链接,我将不胜感激 ps:我发现了一些类似的东西,但它是用JS编写的,翻译起来很痛苦)我让它工作起来了 在zoomIn/zoomOut添加方面仍然存在一些问题,但主要问题是拖动
周围的网格是固定的
import pygame, sys, math
from pygame.locals import *
FPS = 30
WINDOWWIDTH = 640
WINDOWHEIGHT = 480
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
def main():
global FPSCLOCK, DISPLAYSURF
global coordX, coordY
global offsetX, offsetY, negativeOffsetX, negativeOffsetY
global movedDistanceX, movedDistanceY
global isDragging
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
mouseX = 0
mouseY = 0
generateGrid(GRIDSIZE, GRIDSIZE)
isDragging = 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()
if event.type == MOUSEBUTTONDOWN:
if event.button == 2:
isDragging = True
elif event.button == 4:
zoomIn()
elif event.button == 5:
zoomOut()
elif event.type == MOUSEMOTION:
mouseRel = pygame.mouse.get_rel()
moveGrid(mouseRel)
elif event.type == MOUSEBUTTONUP:
isDragging = False
viewportCoord = (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(rel):
global coordX, coordY, isDragging
if isDragging == True:
#X
if coordX <= maxVPcoordX and coordX >= minVPcoordX:
coordX = coordX - rel[0]
if coordX > maxVPcoordX:
coordX = maxVPcoordX
if coordX < minVPcoordX:
coordX = 0
#Y
if coordY <= maxVPcoordY and coordY >= minVPcoordY:
coordY = coordY - rel[1]
if coordY > maxVPcoordY:
coordY = maxVPcoordY
elif coordY < minVPcoordY:
coordY = 0
#-------------
def zoomIn():
global TILESIZE, maxVPcoordX, maxVPcoordY
TILESIZE += 4
print("Tile size: ", TILESIZE)
generateGrid(GRIDSIZE, GRIDSIZE)
maxVPcoordX = (TILESIZE*GRIDSIZE)-WINDOWWIDTH
maxVPcoordY = (TILESIZE*GRIDSIZE)-WINDOWHEIGHT
def zoomOut():
global TILESIZE, maxVPcoordX, maxVPcoordY
TILESIZE -= 4
if TILESIZE <= 0:
TILESIZE = 4
print("Tile size: ", TILESIZE)
generateGrid(GRIDSIZE, GRIDSIZE)
maxVPcoordX = (TILESIZE*GRIDSIZE)-WINDOWWIDTH
maxVPcoordY = (TILESIZE*GRIDSIZE)-WINDOWHEIGHT
main()
导入pygame、sys、math
从pygame.locals导入*
FPS=30
窗宽=640
窗高=480
网格大小=256
TILESIZE=40
BGCOLOR=(128128128)
FGCOLOR=(64,64,64)
网格=[]
fpscall=pygame.time.Clock()
indexX=无
indexY=无
minVPcoordX=0
minVPcoordY=0
maxVPcoordX=(TILESIZE*GRIDSIZE)-窗口宽度
maxVPcoordY=(波浪大小*网格大小)-窗口高度
视口偏移=(0,0)
vpStartXTile=0
vpStartYTile=0
viewportCoord=(0,0)
coordX=0
coordY=0
def main():
全球时钟,DISPLAYSURF
全球合作
格洛