对mouse_even模拟鼠标操作函数的一点认识

作者学习了mouse_event函数用于模拟鼠标选择文本,介绍了该函数各参数含义,如dwFlags可指定鼠标动作及位置参数类型,还说明了不同设置下dx、dy取值及坐标换算。同时提出两个问题,一是MOUSEEVENT_MOVE置位时dx和dy才有意义是否正确,二是坐标值计算方式存疑。

今天看了一篇mouse_event函数用于模拟鼠标选择文本的文章,学习了一下这个函数。有一点认识记录如下:

VOID mouse_event(
  DWORD
dwFlags, // 用来指示模拟怎么养的鼠标动作,并且可以指定鼠标动作的位置参数是绝对量还是相对量
  DWORD dx,      // 水平方向的鼠标位置移动量
  DWORD dy,      // 垂直方向的鼠标位置移动量
  DWORD dwData// 鼠标滚轮的移动量
  DWORD dwExtraInfo
                 // 32位的附加信息
);

1.   dwFlags这个量可以设置MOUSEEVENTF_ABSOLUTE来指定dx,dy表示的是绝对的位置改变量
2.   当dwFlags这个量设置了MOUSEEVENT_MOVE时,dx,dy的值取值在0~65,535之间,此时的坐标为整个屏幕的坐标,也就是说(0,0)对应的是屏幕左上角,(65,535,65,535)对应的是屏幕右下角。所以,对于不同分辨率的屏幕应该采取换算。例如1024×768的分辨率下,(x,y)就应该换算成((65535/1024)*x, (65535/768)*y)

问题:
1.  似乎当MOUSEEVENT_MOVE被置位1时,dx和dy才有实际意义,否则,他们的值都不会对鼠标位置有影响。不知这点是否正确~~!
2.  当MOUSEEVENT_MOVE置位1时,可以配合其他的flag、如MOUSEEVENTF_LEFTDOWN一起使用,可以达到移动鼠标的效果,但是不知道这个坐标值是怎么算的,好像不是按照一个象素一个象素算的。难道是坐标映射模式的问题?我再看看吧

# Memory Puzzle, by Al Sweigart al@inventwithpython.com # (Requires Pygame) A simple memory matching game. __version__ = 1 import random, pygame, sys from pygame.locals import * FPS = 20 # frames per second, the general speed of the program 每秒帧数,程序的一般速度 WINDOWWIDTH = 640 # size of window's width in pixels 窗口宽度的大小(像素) WINDOWHEIGHT = 480 # size of windows' height in pixels REVEALSPEED = 8 # speed boxes' sliding reveals and covers BOXSIZE = 50 # size of box height & width in pixels 框的高度和宽度大小(像素) GAPSIZE = 10 # size of gap between boxes in pixels BOARDWIDTH = 10 # number of columns of icons 图标列数 BOARDHEIGHT = 7 # number of rows of icons assert (BOARDWIDTH * BOARDHEIGHT) % 2 == 0, 'Board needs to have an even number of boxes for pairs of matches.' XMARGIN = int((WINDOWWIDTH - (BOARDWIDTH * (BOXSIZE + GAPSIZE))) / 2) YMARGIN = int((WINDOWHEIGHT - (BOARDHEIGHT * (BOXSIZE + GAPSIZE))) / 2) #RGB GRAY = (100, 100, 100) NAVYBLUE = (60, 60, 100) WHITE = (255, 255, 255) RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) YELLOW = (255, 255, 0) ORANGE = (255, 128, 0) PURPLE = (255, 0, 255) CYAN = (0, 255, 255) BGCOLOR = NAVYBLUE LIGHTBGCOLOR = GRAY BOXCOLOR = WHITE HIGHLIGHTCOLOR = BLUE # === 新增:水果图标定义 === APPLE = 'apple' BANANA = 'banana' #ORANGE = 'orange' STRAWBERRY = 'strawberry' GRAPE = 'grape' WATERMELON = 'watermelon' PEAR = 'pear' PINEAPPLE = 'pineapple' CHERRY = 'cherry' LEMON = 'lemon' ALLCOLORS = (RED, GREEN, BLUE, YELLOW, ORANGE, PURPLE, CYAN) #ALLSHAPES = (APPLE,BANANA,ORANGE,STRAWBERRY,GRAPE,WATERMELON,PEAR,PINEAPPLE,CHERRY,LEMON) ALLSHAPES = (APPLE,BANANA,PINEAPPLE,STRAWBERRY,GRAPE) assert len(ALLCOLORS) * len( ALLSHAPES) * 2 >= BOARDWIDTH * BOARDHEIGHT, "Board is too big for the number of shapes/colors defined." def main(): global FPSCLOCK, DISPLAYSURF, BASICFONT pygame.init() FPSCLOCK = pygame.time.Clock() DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT)) BASICFONT = pygame.font.Font('freesansbold.ttf', 24) # 新增字体用于界面文字 pygame.display.set_caption('Memory Game') # 显示初始界面 showStartScreen() while True: # 主游戏循环 # 游戏逻辑保持不变... mousex = 0 # used to store x coordinate of mouse event 用于存储鼠标事件的x坐标 mousey = 0 # used to store y coordinate of mouse event mainBoard = getRandomizedBoard() revealedBoxes = generateRevealedBoxesData(False) firstSelection = None # stores the (x, y) of the first box clicked. 存储单击的第一个框的(x,y) DISPLAYSURF.fill(BGCOLOR) startGameAnimation(mainBoard) game_running = True while game_running: # 游戏运行循环 mouseClicked = False DISPLAYSURF.fill(BGCOLOR) # drawing the window 绘制窗口 drawBoard(mainBoard, revealedBoxes) for event in pygame.event.get(): # event handling loop 事件处理循环 if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE): game_running = False showExitScreen() # 显示退出界面 elif event.type == MOUSEMOTION: mousex, mousey = event.pos elif event.type == MOUSEBUTTONUP: mousex, mousey = event.pos mouseClicked = True boxx, boxy = getBoxAtPixel(mousex, mousey) if boxx != None and boxy != None: # The mouse is currently over a box. 鼠标当前位于一个框上 if not revealedBoxes[boxx][boxy]: drawHighlightBox(boxx, boxy) if not revealedBoxes[boxx][boxy] and mouseClicked: revealBoxesAnimation(mainBoard, [(boxx, boxy)]) revealedBoxes[boxx][boxy] = True # set the box as "revealed" 将盒子设置为“显示” if firstSelection == None: # the current box was the first box clicked firstSelection = (boxx, boxy) else: # the current box was the second box clicked 当前框是单击的第二个框 # Check if there is a match between the two icons. 检查两个图标之间是否匹配 icon1shape, icon1color = getShapeAndColor(mainBoard, firstSelection[0], firstSelection[1]) icon2shape, icon2color = getShapeAndColor(mainBoard, boxx, boxy) if icon1shape != icon2shape or icon1color != icon2color: # Icons don't match. Re-cover up both selections. 图标不匹配。重新覆盖这两个选项。 pygame.time.wait(1000) # 1000 milliseconds = 1 sec coverBoxesAnimation(mainBoard, [(firstSelection[0], firstSelection[1]), (boxx, boxy)]) revealedBoxes[firstSelection[0]][firstSelection[1]] = False revealedBoxes[boxx][boxy] = False elif hasWon(revealedBoxes): # check if all pairs found gameWonAnimation(mainBoard) pygame.time.wait(2000) # Reset the board mainBoard = getRandomizedBoard() revealedBoxes = generateRevealedBoxesData(False) # Show the fully unrevealed board for a second. drawBoard(mainBoard, revealedBoxes) pygame.display.update() pygame.time.wait(1000) # 回到初始界面 game_running = False showStartScreen() firstSelection = None # reset firstSelection variable # Redraw the screen and wait a clock tick. pygame.display.update() FPSCLOCK.tick(FPS) def showStartScreen(): """显示游戏初始界面""" while True: DISPLAYSURF.fill(BGCOLOR) # 绘制标题 title_font = pygame.font.Font('freesansbold.ttf', 48) title_surf = title_font.render('Memory Puzzle', True, WHITE) title_rect = title_surf.get_rect() title_rect.center = (WINDOWWIDTH // 2, WINDOWHEIGHT // 3) DISPLAYSURF.blit(title_surf, title_rect) # 绘制作者信息 author_font = pygame.font.Font('freesansbold.ttf', 16) author_surf = author_font.render('By Al Sweigart', True, WHITE) author_rect = author_surf.get_rect() author_rect.center = (WINDOWWIDTH // 2, WINDOWHEIGHT // 3 + 50) DISPLAYSURF.blit(author_surf, author_rect) # 绘制开始游戏按钮 button_color = BLUE button_rect = pygame.Rect(WINDOWWIDTH // 2 - 100, WINDOWHEIGHT // 2, 200, 50) pygame.draw.rect(DISPLAYSURF, button_color, button_rect) pygame.draw.rect(DISPLAYSURF, WHITE, button_rect, 2) # 边框 button_font = pygame.font.Font('freesansbold.ttf', 24) button_surf = button_font.render('Start Game', True, WHITE) button_rect_text = button_surf.get_rect(center=button_rect.center) DISPLAYSURF.blit(button_surf, button_rect_text) # 绘制退出游戏按钮 exit_button_rect = pygame.Rect(WINDOWWIDTH // 2 - 100, WINDOWHEIGHT // 2 + 70, 200, 50) pygame.draw.rect(DISPLAYSURF, button_color, exit_button_rect) pygame.draw.rect(DISPLAYSURF, WHITE, exit_button_rect, 2) # 边框 exit_button_surf = button_font.render('Exit Game', True, WHITE) exit_button_rect_text = exit_button_surf.get_rect(center=exit_button_rect.center) DISPLAYSURF.blit(exit_button_surf, exit_button_rect_text) # 事件处理 for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == MOUSEBUTTONUP: mouse_x, mouse_y = event.pos if button_rect.collidepoint(mouse_x, mouse_y): return # 退出此函数,开始游戏 elif exit_button_rect.collidepoint(mouse_x, mouse_y): pygame.quit() sys.exit() pygame.display.update() FPSCLOCK.tick(FPS) def showExitScreen(): """显示游戏退出界面""" while True: DISPLAYSURF.fill(BGCOLOR) # 绘制退出信息 title_font = pygame.font.Font('freesansbold.ttf', 48) title_surf = title_font.render('Thanks for Playing!', True, WHITE) title_rect = title_surf.get_rect() title_rect.center = (WINDOWWIDTH // 2, WINDOWHEIGHT // 3) DISPLAYSURF.blit(title_surf, title_rect) # 绘制再次游戏按钮 button_color = GREEN button_rect = pygame.Rect(WINDOWWIDTH // 2 - 100, WINDOWHEIGHT // 2, 200, 50) pygame.draw.rect(DISPLAYSURF, button_color, button_rect) pygame.draw.rect(DISPLAYSURF, WHITE, button_rect, 2) # 边框 button_font = pygame.font.Font('freesansbold.ttf', 24) button_surf = button_font.render('Play Again', True, WHITE) button_rect_text = button_surf.get_rect(center=button_rect.center) DISPLAYSURF.blit(button_surf, button_rect_text) # 绘制退出游戏按钮 exit_button_rect = pygame.Rect(WINDOWWIDTH // 2 - 100, WINDOWHEIGHT // 2 + 70, 200, 50) pygame.draw.rect(DISPLAYSURF, RED, exit_button_rect) pygame.draw.rect(DISPLAYSURF, WHITE, exit_button_rect, 2) # 边框 exit_button_surf = button_font.render('Exit Game', True, WHITE) exit_button_rect_text = exit_button_surf.get_rect(center=exit_button_rect.center) DISPLAYSURF.blit(exit_button_surf, exit_button_rect_text) # 事件处理 for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == MOUSEBUTTONUP: mouse_x, mouse_y = event.pos if button_rect.collidepoint(mouse_x, mouse_y): return # 退出此函数,重新开始游戏 elif exit_button_rect.collidepoint(mouse_x, mouse_y): pygame.quit() sys.exit() pygame.display.update() FPSCLOCK.tick(FPS) def generateRevealedBoxesData(val): revealedBoxes = [] for i in range(BOARDWIDTH): revealedBoxes.append([val] * BOARDHEIGHT) return revealedBoxes def getRandomizedBoard(): # Get a list of every possible shape in every possible color. 获取每种可能颜色的每种可能形状的列表。 icons = [] for color in ALLCOLORS: for shape in ALLSHAPES: icons.append((shape, color)) random.shuffle(icons) # randomize the order of the icons list numIconsUsed = int(BOARDWIDTH * BOARDHEIGHT / 2) # calculate how many icons are needed icons = icons[:numIconsUsed] * 2 # make two of each random.shuffle(icons) # Create the board data structure, with randomly placed icons. board = [] for x in range(BOARDWIDTH): column = [] for y in range(BOARDHEIGHT): column.append(icons[0]) del icons[0] # remove the icons as we assign them board.append(column) return board def splitIntoGroupsOf(groupSize, theList): # splits a list into a list of lists, where the inner lists have at # most groupSize number of items. result = [] for i in range(0, len(theList), groupSize): result.append(theList[i:i + groupSize]) return result def leftTopCoordsOfBox(boxx, boxy): # Convert board coordinates to pixel coordinates left = boxx * (BOXSIZE + GAPSIZE) + XMARGIN top = boxy * (BOXSIZE + GAPSIZE) + YMARGIN return (left, top) def getBoxAtPixel(x, y): for boxx in range(BOARDWIDTH): for boxy in range(BOARDHEIGHT): left, top = leftTopCoordsOfBox(boxx, boxy) boxRect = pygame.Rect(left, top, BOXSIZE, BOXSIZE) if boxRect.collidepoint(x, y): return (boxx, boxy) return (None, None) def drawIcon(shape, color, boxx, boxy): quarter = int(BOXSIZE * 0.25) # syntactic sugar half = int(BOXSIZE * 0.5) # syntactic sugar left, top = leftTopCoordsOfBox(boxx, boxy) # get pixel coords from board coords 从板坐标中获取像素坐标 # Draw the shapes 绘制形状 #, , , , , WATERMELON, PEAR, PINEAPPLE, CHERRY, LEMON if shape == APPLE: pygame.draw.circle(DISPLAYSURF, color, (left + BOXSIZE // 2, top + BOXSIZE // 2), BOXSIZE // 2 - 2) pygame.draw.line(DISPLAYSURF, GREEN, (left + BOXSIZE // 2, top + BOXSIZE // 4), (left + BOXSIZE // 2 + BOXSIZE // 8, top + BOXSIZE // 6), 2) elif shape == BANANA: points = [ (left + BOXSIZE // 4, top + BOXSIZE // 4), (left + BOXSIZE * 3 // 4, top + BOXSIZE // 3), (left + BOXSIZE * 2 // 3, top + BOXSIZE * 3 // 4), (left + BOXSIZE // 5, top + BOXSIZE * 2 // 3)] pygame.draw.polygon(DISPLAYSURF, color, points) elif shape == PINEAPPLE: points = [ (left + BOXSIZE // 4, top + BOXSIZE // 4), (left + BOXSIZE * 3 // 4, top + BOXSIZE // 4), (left + BOXSIZE * 3 // 4, top + BOXSIZE * 3 // 4), (left + BOXSIZE // 4, top + BOXSIZE * 3 // 4) ] pygame.draw.polygon(DISPLAYSURF, color, points) # 叶子 pygame.draw.polygon(DISPLAYSURF, GREEN, [ (left + BOXSIZE // 4, top + BOXSIZE // 4), (left + BOXSIZE // 2, top + BOXSIZE // 8), (left + BOXSIZE * 3 // 4, top + BOXSIZE // 4) ]) elif shape == STRAWBERRY: pygame.draw.polygon(DISPLAYSURF, color, [ (left + BOXSIZE // 2, top + BOXSIZE // 6), (left + BOXSIZE * 5 // 6, top + BOXSIZE * 5 // 6), (left + BOXSIZE // 6, top + BOXSIZE * 5 // 6) ]) # 叶子 pygame.draw.polygon(DISPLAYSURF, GREEN, [ (left + BOXSIZE // 3, top + BOXSIZE // 6), (left + BOXSIZE * 2 // 3, top + BOXSIZE // 6), (left + BOXSIZE * 5 // 6, top + BOXSIZE // 3), (left + BOXSIZE // 6, top + BOXSIZE // 3) ]) # 白色斑点 pygame.draw.circle(DISPLAYSURF, WHITE, (left + BOXSIZE // 3, top + BOXSIZE // 3), 2) pygame.draw.circle(DISPLAYSURF, WHITE, (left + BOXSIZE * 2 // 3, top + BOXSIZE // 3), 2) pygame.draw.circle(DISPLAYSURF, WHITE, (left + BOXSIZE // 2, top + BOXSIZE // 2), 2) elif shape == GRAPE: pygame.draw.ellipse(DISPLAYSURF, color, (left + BOXSIZE // 4, top + BOXSIZE // 6, BOXSIZE // 3, BOXSIZE // 3)) pygame.draw.ellipse(DISPLAYSURF, color, (left + BOXSIZE // 2, top + BOXSIZE // 6, BOXSIZE // 3, BOXSIZE // 3)) pygame.draw.ellipse(DISPLAYSURF, color, (left + BOXSIZE // 4, top + BOXSIZE // 3, BOXSIZE // 3, BOXSIZE // 3)) pygame.draw.ellipse(DISPLAYSURF, color, (left + BOXSIZE // 2, top + BOXSIZE // 3, BOXSIZE // 3, BOXSIZE // 3)) def getShapeAndColor(board, boxx, boxy): # shape value for x, y spot is stored in board[x][y][0] # color value for x, y spot is stored in board[x][y][1] return board[boxx][boxy][0], board[boxx][boxy][1] def drawBoxCovers(board, boxes, coverage): # Draws boxes being covered/revealed. "boxes" is a list # of two-item lists, which have the x & y spot of the box. for box in boxes: left, top = leftTopCoordsOfBox(box[0], box[1]) pygame.draw.rect(DISPLAYSURF, BGCOLOR, (left, top, BOXSIZE, BOXSIZE)) shape, color = getShapeAndColor(board, box[0], box[1]) drawIcon(shape, color, box[0], box[1]) if coverage > 0: # only draw the cover if there is an coverage pygame.draw.rect(DISPLAYSURF, BOXCOLOR, (left, top, coverage, BOXSIZE)) pygame.display.update() FPSCLOCK.tick(FPS) def revealBoxesAnimation(board, boxesToReveal): # Do the "box reveal" animation. 执行“盒子露出”动画。 for coverage in range(BOXSIZE, (-REVEALSPEED) - 1, -REVEALSPEED): drawBoxCovers(board, boxesToReveal, coverage) def coverBoxesAnimation(board, boxesToCover): # Do the "box cover" animation. 制作“盒子封面”动画。 for coverage in range(0, BOXSIZE + REVEALSPEED, REVEALSPEED): drawBoxCovers(board, boxesToCover, coverage) def drawBoard(board, revealed): # Draws all of the boxes in their covered or revealed state. 绘制所有处于覆盖或暴露状态的框。 for boxx in range(BOARDWIDTH): for boxy in range(BOARDHEIGHT): left, top = leftTopCoordsOfBox(boxx, boxy) if not revealed[boxx][boxy]: # Draw a covered box. pygame.draw.rect(DISPLAYSURF, BOXCOLOR, (left, top, BOXSIZE, BOXSIZE)) else: # Draw the (revealed) icon. shape, color = getShapeAndColor(board, boxx, boxy) drawIcon(shape, color, boxx, boxy) def drawHighlightBox(boxx, boxy): left, top = leftTopCoordsOfBox(boxx, boxy) pygame.draw.rect(DISPLAYSURF, HIGHLIGHTCOLOR, (left - 5, top - 5, BOXSIZE + 10, BOXSIZE + 10), 4) def startGameAnimation(board): # Randomly reveal the boxes 8 at a time. 一次随机显示8个框。 coveredBoxes = generateRevealedBoxesData(False) boxes = [] for x in range(BOARDWIDTH): for y in range(BOARDHEIGHT): boxes.append((x, y)) random.shuffle(boxes) boxGroups = splitIntoGroupsOf(4, boxes) drawBoard(board, coveredBoxes) for boxGroup in boxGroups: revealBoxesAnimation(board, boxGroup) coverBoxesAnimation(board, boxGroup) def gameWonAnimation(board): # flash the background color when the player has won 当玩家获胜时,闪烁背景颜色 coveredBoxes = generateRevealedBoxesData(True) color1 = LIGHTBGCOLOR color2 = BGCOLOR for i in range(30): color1, color2 = color2, color1 # swap colors 交换颜色 DISPLAYSURF.fill(color1) drawBoard(board, coveredBoxes) pygame.display.update() pygame.time.wait(100) def hasWon(revealedBoxes): # Returns True if all the boxes have been revealed, otherwise False 如果所有框都已显示,则返回True,否则返回False for i in revealedBoxes: if False in i: return False # return False if any boxes are covered. 如果有任何箱子被覆盖,则返回False。 return True if __name__ == '__main__': main() 依据这个代码生成python记忆游戏的实现与分析的论文框架
最新发布
06-25
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值