Crossin的编程教室

标题: 【Pygame 第4课】 获取鼠标位置 [打印本页]

作者: crossin先生    时间: 2013-8-23 20:55
标题: 【Pygame 第4课】 获取鼠标位置
最近微信上很火的“打飞机”游戏,通过手指在屏幕上触摸的位置来移动你的飞机。在电脑上,我们没法直接用手操作,但可以用鼠标替代手指。

在电脑游戏里,鼠标是个很好用的输入设备。因此在很多游戏中,都需要得到鼠标的位置,以响应用户的操作。

现在,我们要在之前hello world的程序上增加一架飞机,并且用鼠标来控制飞机的位置。

得到鼠标位置坐标的方法是:
  1. pygame.mouse.get_pos()
复制代码
与以往用的函数有些不同,这个函数会返回两个值:鼠标的x坐标和y坐标。所以你需要两个变量来记录返回值:
  1. x, y = pygame.mouse.get_pos()
复制代码
然后,在游戏主循环中,把实现准备好的飞机图片画到屏幕上,位置就是(x,y):
  1. screen.blit(plane, (x,y))
复制代码
运行程序,你会发现,鼠标移动到哪,飞机就会“飞”到哪。但是,飞机图片始终在鼠标的右下方。这是因为图片的坐标原点是在左上角,原点与鼠标的位置对齐。

如果你想让图片的中心和鼠标位置对齐,则需要再调整一下x,y的位置:
  1. x-= plane.get_width() / 2
  2. y-= plane.get_height() / 2
复制代码
get_width和get_height分别是获取图片的宽和高。

你可以挑张合适的背景图和一张边缘透明的飞机图,再把窗口的长宽调整一下,让它看上去更舒服一些。

完整代码:
  1. # -*- coding: utf-8 -*-
  2. import pygame
  3. from sys import exit
  4. pygame.init()
  5. screen = pygame.display.set_mode((600, 170), 0, 32)
  6. pygame.display.set_caption("Hello, World!")
  7. background = pygame.image.load('bg.jpg').convert()
  8. plane = pygame.image.load('plane.jpg').convert()
  9. #加载飞机图像
  10. while True:
  11.     for event in pygame.event.get():
  12.         if event.type == pygame.QUIT:
  13.             pygame.quit()
  14.             exit()
  15.     screen.blit(background, (0,0))

  16.     x, y = pygame.mouse.get_pos()
  17.     #获取鼠标位置
  18.     x-= plane.get_width() / 2
  19.     y-= plane.get_height() / 2
  20.     #计算飞机的左上角位置
  21.     screen.blit(plane, (x,y))
  22.     #把飞机画到屏幕上
  23.     pygame.display.update()
复制代码
0.png

#==== Crossin的编程教室 ====#
微信ID:crossincode
论坛:http://crossin.me
QQ群:312723402

面向零基础初学者的编程课
每天5分钟,轻松学编程


作者: xiaotong125    时间: 2013-8-25 11:47
要做打飞机游戏吗?支持啊
作者: Victor    时间: 2013-8-29 08:13
我得抓紧时间跟上crossin先生~
作者: dark    时间: 2013-9-8 16:20
得抓鸡啊。。。。。
作者: simple    时间: 2013-9-24 13:40
有点卡,这个可能和什么有关啊。发一颗子弹后,移动到其他地方就停顿一下了。是图片的刷新的频率太慢了吗。
作者: crossin先生    时间: 2013-9-24 18:02
simple 发表于 2013-9-24 13:40
有点卡,这个可能和什么有关啊。发一颗子弹后,移动到其他地方就停顿一下了。是图片的刷新的频率太慢了吗。 ...

有可能。也可能你的显卡对pygame支持的不太好。
所以pygame写写小游戏玩玩还行,开发商业游戏就差太多了
作者: shallecker    时间: 2013-10-18 18:52
灰机灰机。。。
作者: jane    时间: 2013-11-22 19:57
怎么样可以让飞机不被遮住呢?   像这样的话 窗口是固定的  但是飞机还是可以移过去

1.jpg
作者: crossin先生    时间: 2013-11-25 16:07
jane 发表于 2013-11-22 19:57
怎么样可以让飞机不被遮住呢?   像这样的话 窗口是固定的  但是飞机还是可以移过去

...

那你需要在计算飞机位置时候加上点限制,比如鼠标位置小于飞机的width/2时,飞机的x就不再减小了
作者: ajh99990    时间: 2015-5-16 15:53
老师,对于下面这几行代码,我有一个问题。
    x, y = pygame.mouse.get_pos()
    #获取鼠标位置
    x-= plane.get_width() / 2
    y-= plane.get_height() / 2
我想问,首先我们把x,y的位置定位到了飞机图片的左上角。然后,我们又计算出了图片的长和宽。比如图片左上角坐标为,(100,100) 计算得出的图片长和宽的一半为50,50. 我们知道,游戏窗口的最左上角坐标应该是(0,0),也就是说,坐标值越小越接近左上角,那么 您用 100-50作为新的x 100-50 作为新的y 这个新的坐标(50,50)应该是比一开始的图片左上角坐标(100,100)还要小的。那这个坐标应该更接近窗口左上角,也就是更加偏离了飞机图片的中心位置啊! 可为什么实际运行出来的结果反而是新坐标跑到飞机图片的中心了呢? 麻烦讲一下好吗?困扰了很久,谢谢老师了!
作者: ajh99990    时间: 2015-5-16 16:09
ajh99990 发表于 2015-5-16 15:53
老师,对于下面这几行代码,我有一个问题。
    x, y = pygame.mouse.get_pos()
    #获取鼠标位置

我又想了想。。。竟然自己想明白了。 因为打印图片永远都是图片左上角对着鼠标坐标点的。所以只要把鼠标的坐标值往左上角位移半个图片的长和宽之后再去打印,那就能让打印出来的图片的中心正好对应着鼠标坐标点了。 原来如此。。。
作者: ajh99990    时间: 2015-5-16 16:09
ajh99990 发表于 2015-5-16 15:53
老师,对于下面这几行代码,我有一个问题。
    x, y = pygame.mouse.get_pos()
    #获取鼠标位置

我又想了想。。。竟然自己想明白了。 因为打印图片永远都是图片左上角对着鼠标坐标点的。所以只要把鼠标的坐标值往左上角位移半个图片的长和宽之后再去打印,那就能让打印出来的图片的中心正好对应着鼠标坐标点了。 原来如此。。。
作者: crossin先生    时间: 2015-5-17 00:47
ajh99990 发表于 2015-5-16 16:09
我又想了想。。。竟然自己想明白了。 因为打印图片永远都是图片左上角对着鼠标坐标点的。所以只要把鼠标 ...

是的,坐标点对于图片来说并没有变,只是看上去位置对了
作者: daiqifan012    时间: 2015-10-10 17:12
ajh99990 发表于 2015-5-16 15:53
老师,对于下面这几行代码,我有一个问题。
    x, y = pygame.mouse.get_pos()
    #获取鼠标位置

  x-= plane.get_width() / 2
  y-= plane.get_height() / 2

这两行是为了让飞机图片移动而不是让鼠标位置移动。 你可以把(x,y)值打印出来看就理解了。
作者: cossin咸鱼    时间: 2015-12-19 19:07
  1.     plane=pygame.image.load(plane.jpg).convert_alpha()
  2. NameError: name 'plane' is not defined
复制代码
老师为啥我的有错误呢,如果def 一个plane的话就闪退
作者: cossin咸鱼    时间: 2015-12-19 19:10
cossin咸鱼 发表于 2015-12-19 19:07
老师为啥我的有错误呢,如果def 一个plane的话就闪退

我自己做错了  ,好难发现啊  应该是‘palne.png’ 两处错误
作者: crossin先生    时间: 2015-12-19 23:46
cossin咸鱼 发表于 2015-12-19 19:10
我自己做错了  ,好难发现啊  应该是‘palne.png’ 两处错误


作者: catherinemic    时间: 2016-1-30 13:03
get it, 原来游戏窗口的最左上角坐标是(0,0),坐标值越小越接近左上角,跟正常的坐标系有点不一样。这样x-= plane.get_width() / 2,y-= plane.get_height() / 2就说得通了。
作者: catherinemic    时间: 2016-1-30 13:45
加了一些限制让飞机保持在窗口内
  1. import pygame
  2. from sys import exit
  3. pygame.init()
  4. screen=pygame.display.set_mode((960,640))
  5. pygame.display.set_caption('Hello, World!')
  6. background=pygame.image.load('.\data file\pypic2.jpg').convert()
  7. plane=pygame.image.load('.\data file\plane.gif').convert()
  8. width=plane.get_width()/2
  9. height=plane.get_height()/2
  10. while True:
  11.     for event in pygame.event.get():
  12.         if event.type==pygame.QUIT:
  13.             pygame.quit()
  14.             exit()
  15.     screen.blit(background,(0,0))
  16.     x,y=pygame.mouse.get_pos()
  17.     if y>=640-height:
  18.         if x<width:
  19.             screen.blit(plane,(0,640-2*height))
  20.         elif x>960-width:
  21.             screen.blit(plane,(960-2*width,640-2*height))
  22.         else:
  23.             screen.blit(plane,(x-width,640-2*height))
  24.     elif y<height:
  25.         if x<width:
  26.             screen.blit(plane,(0,0))
  27.         elif x>960-width:
  28.             screen.blit(plane,(960-2*width,0))
  29.         else:
  30.             screen.blit(plane,(x-width,0))
  31.     else:
  32.         if x<width:
  33.             screen.blit(plane,(0,y-height))
  34.         elif x>960-width:
  35.             screen.blit(plane,(960-2*width,y-height))
  36.         else:
  37.             screen.blit(plane,(x-width,y-height))  
  38.     pygame.display.update()
复制代码

作者: 一路向北    时间: 2016-3-23 15:20
ajh99990 发表于 2015-5-16 15:53
老师,对于下面这几行代码,我有一个问题。
    x, y = pygame.mouse.get_pos()
    #获取鼠标位置

鼠标的坐标为(100,100)
图片的左上顶点为(50,50)长宽为100
所以鼠标在中间
作者: 当当里当当    时间: 2018-1-6 21:01
我想问一下老师与大家,为什么我自己做的小飞机图片,背景已经用PS弄透明了,但是导入到自己的游戏界面,还是有白色的边框?这是什么原因呢?
作者: crossin先生    时间: 2018-1-7 11:21
当当里当当 发表于 2018-1-6 21:01
我想问一下老师与大家,为什么我自己做的小飞机图片,背景已经用PS弄透明了,但是导入到自己的游戏界面,还 ...

格式要是png
你试下我们帖子里提供的图片行不行,如果可以但你的不行,那还是你ps导出的问题
作者: 当当里当当    时间: 2018-1-7 13:34
crossin先生 发表于 2018-1-7 11:21
格式要是png
你试下我们帖子里提供的图片行不行,如果可以但你的不行,那还是你ps导出的问题 ...

好的,谢谢老师,已经解决了,是因为导入图片的时候还没看到老师讲的convert_alpha()这个后缀,用了这个就变透明了打扰了!
作者: koalaoycx    时间: 2018-6-4 20:44
请问先生,为什么使用绝对路径时候始终是无法打开图片呢?本来是想单独建立一个文件夹放图片,现在好像只能跟xxx.py在一个路径下才能打开。
1
作者: crossin先生    时间: 2018-6-5 11:14
字符串被转义了,字符串前面加上r,或者用 /




欢迎光临 Crossin的编程教室 (https://bbs.crossincode.com/) Powered by Discuz! X2.5