Python Pygame-预览图片的blitting
首先,这是一项学校作业,所以我想提前说明。第二,我只是在征求关于方法的建议,可能的代码帮助。我正在使用我们书中的一些预先存在的代码进行MSPAINT风格的克隆。当按下鼠标按钮1时,该代码已使用draw.line。老师想让我们增加画圆或矩形的能力。我正在研究circle部分,我已经想出了(感谢这里的论坛)如何实现我想对MOUSEBUTTONDOWN和MOUSEBUTTONUP事件执行的操作。。这给我带来了一个新问题。。我该如何删除然后删除,然后预览一个圆圈,直到它的大小是用户想要的,他们释放鼠标按钮,并查看最终的blitPython Pygame-预览图片的blitting,python,python-2.7,pygame,Python,Python 2.7,Pygame,首先,这是一项学校作业,所以我想提前说明。第二,我只是在征求关于方法的建议,可能的代码帮助。我正在使用我们书中的一些预先存在的代码进行MSPAINT风格的克隆。当按下鼠标按钮1时,该代码已使用draw.line。老师想让我们增加画圆或矩形的能力。我正在研究circle部分,我已经想出了(感谢这里的论坛)如何实现我想对MOUSEBUTTONDOWN和MOUSEBUTTONUP事件执行的操作。。这给我带来了一个新问题。。我该如何删除然后删除,然后预览一个圆圈,直到它的大小是用户想要的,他们释放鼠标按
while keepGoing:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
elif event.type == pygame.MOUSEMOTION:
lineEnd = pygame.mouse.get_pos()
if pygame.mouse.get_pressed() == (1,0,0):
pygame.draw.line(background, drawColor, lineStart, lineEnd, lineWidth)
lineStart = lineEnd
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 3:
circleStart = pygame.mouse.get_pos()
elif event.type == pygame.MOUSEBUTTONUP and event.button == 3:
circleEnd = pygame.mouse.get_pos()
size = (circleEnd[0] - circleStart[0])
pygame.draw.circle(background, drawColor, circleStart, size, lineWidth)
elif event.type == pygame.KEYDOWN:
myData = (event, background, drawColor, lineWidth, keepGoing)
myData = checkKeys(myData)
event, background, drawColor, lineWidth, keepGoing) = myData
非常感谢
-Ben经过思考,这是我用pygame想出的最好的解决方案。告诉我你的想法,以及它是否对你有帮助
import pygame,sys,math #---- Import modules we will need
pygame.init() #---- Initialize the module
def get_rad(origin_x,origin_y,x,y): #----- Returns the appropriate radius
return math.sqrt((origin_x - x)**2 + (origin_y - y)**2) #----- Distance between 2
#----- points
screen = pygame.display.set_mode((400,400)) #----- Sets up the screen
clock = pygame.time.Clock() #------- Sets up the clock
mouse_button = 0 #--------- This variable is used to determine whether a mouse button
#--------- has been pressed
draw_final_circle = False #---------- This variable lets us know that we should draw the
#---------- final circle
while True: #------ main loop
clock.tick(60) #------ Limit the Fps
mouse_button0 = mouse_button #-------- This variable holds the previous value of
#-------- mouse_button(it will be useful later)
mouse_x,mouse_y = pygame.mouse.get_pos() #----- Get the mosue coordinates
for e in pygame.event.get(): #---- Cycle through events
if e.type == pygame.QUIT: pygame.quit();sys.exit() #--Quit when window is closed
if e.type == pygame.MOUSEBUTTONDOWN: #---- If the mouse button is pressed
if mouse_button == 0: #---- if the mouse button is released
mouse_button = 1 #----- set it to pressed basically
originx,originy = mouse_x,mouse_y #---- keep the mouse_x,mouse_y pos
if e.type == pygame.MOUSEBUTTONUP: #---- if the mouse button is released
if mouse_button == 1: #-------- if it is pressed
mouse_button = 0 #--------- set it to released
screen.fill((255,255,255)) #---- clear the screen
#-------- If a mouse button is pressed and a circle can be drawn (rad>width) ------#
if mouse_button == 1 and get_rad(originx,originy,mouse_x,mouse_y) > 1:
rad = int(get_rad(originx,originy,mouse_x,mouse_y)) #---- get the radius(as int)
pos = mouse_x,mouse_y
pygame.draw.circle(screen,(0,0,0),pos,rad,1) #--- draw the circle
#----------------------------------------------------------------------------------#
#---------- if the button is released but in the previous loop it was pressed -----#
if mouse_button == 0 and mouse_button0 == 1:
draw_final_circle = True #----- set the final circle boolean to True
if draw_final_circle: #----- if the final circle is decided
pygame.draw.circle(screen,(0,0,0),pos,rad,1) #---- keep drawing it
pygame.display.flip() #----- flip the buffer
我建议您将绘图程序的不同模式实现到表示当前模式及其状态的不同类中。这样,实现不同的模式变得非常容易
对于圆形绘图模式,您希望在用户按下鼠标按钮时复制屏幕表面,并在每一帧将该复制复制复制到屏幕上 然后在副本上画圆圈。这样,基本上可以“擦除”临时圆圈
这里有一个简单的例子。按空格键可在不同模式(绘制、圆形、矩形)和制表符之间循环使用不同的颜色:
import pygame
from math import hypot
from itertools import cycle
from operator import itemgetter
pygame.init()
screen = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
colors = cycle(sorted(pygame.color.THECOLORS.iteritems(), key=itemgetter(0)))
color = next(colors)[1]
class DrawMode(object):
def __init__(self):
self.last = None
def handle(self, e):
if e.type == pygame.MOUSEBUTTONDOWN and e.button == 1:
self.last = pygame.mouse.get_pos()
if e.type == pygame.MOUSEBUTTONUP and e.button == 1:
self.last = None
def draw(self, screen):
pos = pygame.mouse.get_pos()
if self.last:
pygame.draw.line(screen, color, self.last, pos)
self.last = pos
class ClickReleaseMode(object):
def __init__(self):
self.tmp = None
self.start = None
def handle(self, e):
if e.type == pygame.MOUSEBUTTONDOWN and e.button == 1:
self.start = pygame.mouse.get_pos()
if e.type == pygame.MOUSEBUTTONUP and e.button == 1:
self.start = self.tmp = None
def draw(self, screen):
if not self.tmp:
self.tmp = screen.copy()
pos = pygame.mouse.get_pos()
screen.blit(self.tmp, (0,0))
if self.start:
self.do_draw(screen, pos)
class CircleMode(ClickReleaseMode):
def __init__(self):
super(CircleMode, self).__init__()
def do_draw(self, screen, pos):
r = hypot(pos[0] - self.start[0], pos[1] - self.start[1])
if r >= 2:
pygame.draw.circle(screen, color, self.start, int(r), 2)
class RectMode(ClickReleaseMode):#
def __init__(self):
super(RectMode, self).__init__()
def do_draw(self, screen, pos):
p = pos[0] - self.start[0], pos[1] - self.start[1]
pygame.draw.rect(screen, color, pygame.Rect(self.start, p), 2)
quit = False
modes = cycle((DrawMode, CircleMode, RectMode))
mode = next(modes)()
while not quit:
quit = pygame.event.get(pygame.QUIT)
for e in pygame.event.get():
if e.type == pygame.KEYDOWN:
if e.key == pygame.K_SPACE:
mode = next(modes)()
print 'enter', mode.__class__.__name__
if e.key == pygame.K_TAB:
name, color = next(colors)
print 'changing color to', name, color
mode.handle(e)
mode.draw(screen)
pygame.display.flip()
clock.tick(60)
好的,我在这里做了更多的调查,找到了我关于鼠标按钮事件的答案,但现在我要问另一个问题。我如何在鼠标按钮事件之前预览圆圈?如果您的问题发生了变化,你应该使用它来表示你现在的实际问题是什么,根据需要添加/删除信息。我现在就做!你的例子真的帮助了我。。。我喜欢圆位置的x、y坐标与鼠标坐标相等。。这使得使用元组更容易。。并在鼠标存储位置的元组处绘制圆圈,以及释放按钮时鼠标移动的距离。。。这就是为什么我喜欢这个网站!!!非常感谢!!!没问题,伙计:)如果你认为某个答案对你有帮助,你可以总是用勾号来标记它,这样其他用户就可以知道你的问题已经解决了!多米尼克,谢谢你的例子!我从您的示例中了解到,我可以使用函数创建类,该函数允许我调用鼠标位置和/或鼠标输入,以便在绘图函数中使用。。我可以假设这将有助于提高系统速度,因为您没有将其包含在主循环中!