鱼C论坛

 找回密码
 立即注册
查看: 1493|回复: 2

[已解决]零基础入门学习Python - 81讲 的问题

[复制链接]
发表于 2018-5-14 17:01:56 | 显示全部楼层 |阅读模式
20鱼币
这是我根据小甲鱼的需求和代码,在自己理解的基础上写的。这里面有一截没看懂。
  1. '''
  2. 综合练习
  3. 改变小乌龟的速度,大小,透明度
  4. 改变窗口的大小
  5. '''
  6. import pygame
  7. from pygame.locals import *
  8. import sys

  9. '''
  10. 目标元素
  11. 在pygame中显示的元素, 定义其各种参数和动作
  12. '''
  13. class Target:
  14.     def __init__(self, image_path, direction=1,speed=[1,1], transparent=255, ratio=1.0):
  15.         # 加载后的图片
  16.         image = pygame.image.load( image_path )
  17.         self.image = image
  18.         self.oimage = image
  19.         # 方向, 1右0左
  20.         self.direction = direction
  21.         # 位置
  22.         self.oposition = image.get_rect()
  23.         self.position = image.get_rect()
  24.         # 速度, [x,y]
  25.         self.speed = list(speed)
  26.         # 透明度, 0-255, 越来越不透明
  27.         self.transparent = transparent
  28.         # 放大缩小比例
  29.         self.ratio = ratio

  30.     '''
  31.     移动位置, 可以外部给定速度
  32.     speed: [speed_x, speed_y]
  33.     '''
  34.     def move(self, speed=None):
  35.         if speed==None:
  36.             speed = self.speed
  37.         self.position = self.position.move( speed )
  38.         self.correct()

  39.     '''
  40.     纠正位置
  41.     可能在各种变化后, 元素的位置不在限定范围了
  42.     limit: [limit_x, limit_y]
  43.     '''
  44.     def correct(self, limit=None):
  45.         if limit == None:
  46.             t = pygame.display.get_surface().get_rect()
  47.             limit = t.width, t.height
  48.         p = self.position
  49.         if p.left < 0:
  50.             p.left = 0
  51.             self.speed[0] *= -1
  52.             self.image = pygame.transform.flip(self.image,True, False)
  53.             self.direction = 1
  54.         elif p.right > limit[0]:
  55.             p.right = limit[0]
  56.             self.speed[0] *= -1
  57.             self.image = pygame.transform.flip(self.image,True, False)
  58.             self.direction = 0
  59.         elif p.top < 0:
  60.             p.top = 0
  61.             self.speed[1] *= -1
  62.         elif p.bottom > limit[1]:
  63.             p.bottom = limit[1]
  64.             self.speed[1] *= -1

  65.     '''
  66.     变化大小
  67.     '''
  68.     def change_ratio(self, d_ratio):
  69.         if d_ratio == 0:
  70.             return
  71.         ratio = self.ratio + d_ratio
  72.         if ratio < 0.5 or ratio > 2:
  73.             return
  74.         self.ratio = ratio
  75.         op = self.oposition
  76.         image = pygame.transform.smoothscale(self.oimage,(int(op.width*ratio),int(op.height*ratio)) )
  77.         if self.direction == 0:
  78.             image = pygame.transform.flip(image,True, False)
  79.         self.image = image
  80.         p = image.get_rect()
  81.         self.position.width, self.position.height = p.width, p.height
  82.         
  83.     '''
  84.     改变速度
  85.     d_speed: [d_speed_x, d_speed_y]
  86.     '''
  87.     def change_speed(self, d_speed):
  88.         if isinstance(d_speed, int):
  89.             d_speed = (d_speed, d_speed)
  90.         t = self.speed[0]
  91.         self.speed[0] += d_speed[0]
  92.         self.speed[1] += d_speed[1]
  93.         if t * self.speed[0] < 0 \
  94.            or (t==0 and self.speed[0]<0 and self.direction==1) \
  95.            or (t==0 and self.speed[0]>0 and self.direction==0):
  96.             self.image = pygame.transform.flip(self.image,True, False)
  97.             self.direction = 1 - self.direction
  98.             
  99.     '''
  100.     改变透明度
  101.     '''
  102.     def change_transparent(self, d_transparent):
  103.         t = self.transparent + d_transparent
  104.         if t < 0:
  105.             t = 0
  106.         elif t > 255:
  107.             t = 255
  108.         self.transparent = t
  109.    

  110. # 初始化 Pygame
  111. pygame.init()

  112. pygame.mixer.init()
  113. pygame.mixer.music.load('刘珂矣 - 半壶纱.mp3')
  114. pygame.mixer.music.set_volume(0.2)
  115. pygame.mixer.music.play(-1)

  116. # 窗口大小
  117. sizes = pygame.display.list_modes()
  118. size_i = len(sizes) - 1

  119. # 全屏标志
  120. fullscreen = False


  121. # 加载元素
  122. turtle = Target('turtle.png')

  123. # 加载背景图片
  124. obg = pygame.image.load( 'background.jpg' )
  125. bg = obg

  126. # 时钟
  127. clock = pygame.time.Clock()

  128. # 创建指定大小的窗口
  129. screen = pygame.display.set_mode(sizes[size_i])

  130. # 设置窗口标题
  131. pygame.display.set_caption("综合练习")

  132. # 通过按键键值获取按键代码
  133. def fun(key, info):
  134.     try:
  135.         d = fun.love
  136.         # print('已有 love')
  137.         return d[key]
  138.     except AttributeError:
  139.         print('没有 love, 创建')
  140.         fun.love = dict()
  141.     except KeyError:
  142.         print('键 %d 不存在' % key)
  143.     for x in info:
  144.         if eval(x) == key:
  145.             fun.love[key] = x
  146.             return x
  147.     print('没有这样的 key ?:',key)
  148.    
  149. info = dir()

  150. def blit_alpha(target, source, location, opacity):
  151.     x = location[0]
  152.     y = location[1]
  153.     temp = pygame.Surface((source.get_width(), source.get_height())).convert()
  154.     temp.blit(target, (-x, -y ))
  155.     temp.blit(source, (0, 0))
  156.     temp.set_alpha(opacity)        
  157.     target.blit(temp, location)

  158. while True:
  159.     for event in pygame.event.get():
  160.         if event.type == pygame.QUIT:
  161.             pygame.mixer.music.stop()
  162.             pygame.display.quit()
  163.             sys.exit()
  164.         
  165.         if event.type == KEYDOWN:
  166.             print('key :', event.key, fun(event.key,info))
  167.             # F11 全屏, ESC退出全屏
  168.             if event.key == K_F11 or ( event.key == K_ESCAPE and fullscreen ):
  169.                 fullscreen = not fullscreen
  170.                 if fullscreen:
  171.                     screen = pygame.display.set_mode(sizes[0], FULLSCREEN | HWSURFACE)
  172.                 else:
  173.                     screen = pygame.display.set_mode(sizes[size_i])
  174.                
  175.             # (CTRL + X,S)放大缩小屏幕
  176.             elif event.key in (K_x,K_s) and event.mod & KMOD_CTRL:
  177.                 d = 1 if event.key==K_s else -1
  178.                 size_i = ( size_i + d ) % len(sizes)
  179.                 if size_i == 0:
  180.                     fullscreen = True
  181.                     screen = pygame.display.set_mode(sizes[0], FULLSCREEN | HWSURFACE)
  182.                 else:
  183.                     fullscreen = False
  184.                     screen = pygame.display.set_mode(sizes[size_i])
  185.                 bg = pygame.transform.scale(obg, sizes[size_i])
  186.                
  187.             # (+,-,空格)放大缩小乌龟
  188.             elif event.key in (K_KP_PLUS,K_EQUALS,K_KP_MINUS,K_MINUS,K_SPACE):
  189.                 if event.key in (K_KP_PLUS,K_EQUALS):
  190.                     turtle.change_ratio( 0.1 )
  191.                 elif event.key in (K_KP_MINUS,K_MINUS):
  192.                     turtle.change_ratio( -0.1 )
  193.                 else:
  194.                     turtle.change_ratio( 1.0 - turtle.ratio )
  195.                     
  196.             # (方向键)乌龟速度控制
  197.             elif event.key in (K_UP,K_DOWN,K_LEFT,K_RIGHT):
  198.                 dx = 1 if event.key == K_RIGHT else ( -1 if event.key == K_LEFT else 0)
  199.                 dy = 1 if event.key == K_DOWN else ( -1 if event.key == K_UP else 0)
  200.                 turtle.change_speed( (dx, dy) )

  201.         elif event.type == MOUSEBUTTONDOWN:
  202.             print('button :', event.button)
  203.             # (鼠标滑轮)乌龟透明度控制
  204.             if event.button in (4,5):
  205.                 turtle.change_transparent( 5 if event.button == 4 else -5)
  206.             
  207.    
  208.     turtle.move()
  209.    
  210.     # 填充背景
  211.     screen.blit(bg, (0,0) )

  212.     # 更新图像
  213.     blit_alpha(screen, turtle.image, turtle.position, turtle.transparent)

  214.     # 更新界面
  215.     pygame.display.flip()

  216.     # 延迟 10 毫秒
  217.     # pygame.time.delay(10)
  218.    
  219.     # 帧
  220.     clock.tick(30)
复制代码

这段代码的功能按键有些和小甲鱼的不一样,这不是重点。重点是:这段代码我没有理解到:
  1. def blit_alpha(target, source, location, opacity):
  2.     x = location[0]
  3.     y = location[1]
  4.     temp = pygame.Surface((source.get_width(), source.get_height())).convert()
  5.     temp.blit(target, (-x, -y ))
  6.     temp.blit(source, (0, 0))
  7.     temp.set_alpha(opacity)        
  8.     target.blit(temp, location)
复制代码

知道他的功能是实现透明度控制,但是为啥是 (-x, -y ),期待大神对这段代码的讲解。。
最佳答案
2018-5-14 17:01:57
-x,-y是以temp为参照的位置,对于screen就是0,0
相当于在temp区域重画了这部分的背景,并在temp的0,0重画了甲鱼
将temp这个surface对象一起设置透明度

最佳答案

查看完整内容

-x,-y是以temp为参照的位置,对于screen就是0,0 相当于在temp区域重画了这部分的背景,并在temp的0,0重画了甲鱼 将temp这个surface对象一起设置透明度
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-5-14 17:01:57 | 显示全部楼层    本楼为最佳答案   
-x,-y是以temp为参照的位置,对于screen就是0,0
相当于在temp区域重画了这部分的背景,并在temp的0,0重画了甲鱼
将temp这个surface对象一起设置透明度
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-5-14 21:29:46 | 显示全部楼层
塔利班 发表于 2018-5-14 18:56
-x,-y是以temp为参照的位置,对于screen就是0,0
相当于在temp区域重画了这部分的背景,并在temp的0,0重画 ...

谢谢,忽然间想明白了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-28 22:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表