Crossin的编程教室

标题: 【Pygame 第5课】 游戏中的运动 [打印本页]

作者: crossin先生    时间: 2013-8-27 21:36
标题: 【Pygame 第5课】 游戏中的运动
本来,在上一次pygame的教程中,我只是顺手拿了微信“打飞机”里的图来演示用鼠标控制图片位置的操作。后来觉得,这个游戏还算比较适合用来做例子,也有朋友反馈说想做这个游戏,那不如就以“打飞机”为例来说python游戏开发好了。

今天,就再进一步:既然要打飞机,那得能发射子弹才行。所以从最简单的做起,来给游戏加上“一颗”子弹。

上次的背景图和飞机图,我自己稍微处理了下,包括这一课要用到的子弹图片,都放在论坛上,需要的自行下载。

大体的思路是这样的:


理清了如上的思路之后,能不能搞定代码了?如果能的话,就先别往下看,试着在程序里写写看。

以下是我的实现代码:
  1. # -*- coding: utf-8 -*-
  2. import pygame
  3. from sys import exit
  4. pygame.init()
  5. screen = pygame.display.set_mode((450, 800), 0, 32)
  6. pygame.display.set_caption("Hello, World!")
  7. background = pygame.image.load('back.jpg').convert()
  8. plane = pygame.image.load('plane.png').convert_alpha()
  9. bullet = pygame.image.load('bullet.png').convert_alpha()
  10. #加载子弹图像
  11. bullet_x = 0
  12. bullet_y = -1
  13. #初始化子弹位置
  14. while True:
  15.     for event in pygame.event.get():
  16.         if event.type == pygame.QUIT:
  17.             pygame.quit()
  18.             exit()
  19.     screen.blit(background, (0,0))
  20.     x, y = pygame.mouse.get_pos()
  21.     if bullet_y < 0:
  22.         #如果子弹位置超出了屏幕上端
  23.         bullet_x = x - bullet.get_width() / 2
  24.         bullet_y = y - bullet.get_height() / 2
  25.         #把子弹的中心位置设为鼠标坐标
  26.     else:
  27.         bullet_y -= 5
  28.         #子弹的位置往上移
  29.     screen.blit(bullet, (bullet_x, bullet_y))
  30.     #把子弹画到屏幕上
  31.     x-= plane.get_width() / 2
  32.     y-= plane.get_height() / 2
  33.     screen.blit(plane, (x, y))
  34.     pygame.display.update()
复制代码
5-2.png

5-1.png

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

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




back.jpg (17.86 KB, 下载次数: 2127)

back.jpg

bullet.png (308 Bytes, 下载次数: 2325)

bullet.png

plane.png (9.18 KB, 下载次数: 2277)

plane.png


作者: crossin先生    时间: 2013-8-27 21:42
补充一下:当你需要绘制一张带透明部分的图片时,要用convert_alpha()替代之前的convert(),具体用法参见代码中。


今天微信上推送的里面忘说了。
作者: xiaotong125    时间: 2013-8-27 21:50
支持,一直期待中
作者: Myk_cc    时间: 2013-8-27 22:34
在今天内容的基础上增加一行子弹。ps:两行子弹真霸气
  1. # !/usr/bin/python

  2. import pygame
  3. from sys import exit

  4. pygame.init()
  5. screen = pygame.display.set_mode((450, 800), 0, 32)
  6. pygame.display.set_caption("Hello, World!")

  7. bullet = pygame.image.load('bullet.png').convert_alpha() #load bullet image
  8. bullet1 = bullet
  9. backgroud = pygame.image.load('back.jpg').convert()
  10. plane = pygame.image.load('plane.png') #load plane image

  11. bullet_x = 0
  12. bullet_y = -1
  13. bullet1_x = 0
  14. bullet1_y = -1
  15. running = True

  16. while running:
  17.    for event in pygame.event.get():
  18.         if event.type == pygame.QUIT:
  19.            pygame.quit()
  20.            exit()
  21.   screen.blit(backgroud, (0, 0))
  22.   x, y = pygame.mouse.get_pos() # get the position of mouse
  23.    if bullet_y < 0:
  24.         bullet_x = x - bullet.get_width() / 2 - 23
  25.       bullet_y = y - bullet.get_height() / 2
  26.       bullet1_x = x - bullet.get_width() / 2 + 25
  27.      bullet1_y = y - bullet.get_height() / 2
  28. else:
  29.        bullet_y -= 3
  30.        bullet1_y -= 3
  31.   plane_x = x - plane.get_width() / 2
  32. plane_y = y - plane.get_height() / 2
  33.     screen.blit(bullet, (bullet_x, bullet_y))
  34.    screen.blit(bullet1, (bullet1_x, bullet1_y))
  35.     screen.blit(plane, (plane_x, plane_y))
  36.   pygame.display.update()
复制代码

2013-08-27 22:30:56的屏幕截图.png (90.64 KB, 下载次数: 855)

2013-08-27 22:30:56的屏幕截图.png


作者: crossin先生    时间: 2013-8-27 23:47
Myk_cc 发表于 2013-8-27 22:34
在今天内容的基础上增加一行子弹。ps:两行子弹真霸气


作者: 香蕉哥哥    时间: 2013-8-28 09:43
赞一个
作者: lufo    时间: 2013-8-28 10:05
不错,希望尽快把打飞机教程写完!
作者: xiaotong125    时间: 2013-8-28 14:30
支持
作者: OrangeScript    时间: 2013-8-28 14:53
本帖最后由 OrangeScript 于 2013-8-28 14:57 编辑
  1. # -*- coding: utf-8 -*-
  2. import pygame
  3. from sys import exit
  4. pygame.init()
  5. SCREEN_SIZE=(450,800)
  6. screen = pygame.display.set_mode(SCREEN_SIZE,0,32)
  7. pygame.display.set_caption("plane")
  8. background=pygame.image.load('back.jpg').convert()
  9. plane=pygame.image.load('plane.png').convert_alpha()
  10. bullet=pygame.image.load('bullet.png').convert_alpha()
  11. x=0
  12. y=0
  13. while True:
  14.     for event in pygame.event.get():
  15.         if event.type == pygame.QUIT:
  16.             pygame.quit()
  17.             exit()
  18.     x,y=pygame.mouse.get_pos()
  19.     bullet_x,bullet_y=pygame.mouse.get_pos()
  20.     x-=plane.get_width()/2
  21.     y-=plane.get_height()/2
  22.     screen.blit(background,(0,0))
  23.     screen.blit(plane,(x,y))
  24.     bullet_x-=bullet.get_width()/2;
  25.     bullet_y-=bullet.get_height()/2;
  26.     while bullet_y>=0:
  27.         screen.blit(bullet,(bullet_x,bullet_y))
  28.         bullet_y=bullet_y-100;
  29.         pygame.display.update()
复制代码
这样写可以吗?
作者: crossin先生    时间: 2013-8-28 20:24
OrangeScript 发表于 2013-8-28 14:53
这样写可以吗?

不太对哦
你运行试试

这样每次都会把子弹坐标设在鼠标位置上,然后。。。后面逻辑有点乱

作者: 浮生湮灭了美好    时间: 2013-10-19 19:01
先生我想问下 那个坐标为什么是
  1. bullet_x = x - bullet.get_width() / 2
  2.         bullet_y = y - bullet.get_height() / 2
复制代码
还有子弹上移是
  1. bullet_y -= 5
复制代码
我觉得本来应该是+的在第四象限。
作者: shallecker    时间: 2013-10-19 23:57
虚心求教
作者: nemo    时间: 2014-1-7 18:26
浮生湮灭了美好 发表于 2013-10-19 19:01
先生我想问下 那个坐标为什么是还有子弹上移是我觉得本来应该是+的在第四象限。 ...

我感觉pygame里的坐标是反着的。-是朝上和朝右,+是朝下和朝左。
作者: crossin先生    时间: 2014-1-9 11:20
浮生湮灭了美好 发表于 2013-10-19 19:01
先生我想问下 那个坐标为什么是还有子弹上移是我觉得本来应该是+的在第四象限。 ...

因为是要往左上移动,所以是-
作者: 牵着蚂蚁遛达    时间: 2014-8-13 13:59
Myk_cc 发表于 2013-8-27 22:34
在今天内容的基础上增加一行子弹。ps:两行子弹真霸气

请问第36,37,40行代码是什么作用啊?去掉以后同样能运行。
作者: Jerome    时间: 2015-4-14 22:35
pygame.display.set_mode()
第二个参数是是否全屏,那请问第三个参数代表什么?
作者: crossin先生    时间: 2015-4-15 13:53
Jerome 发表于 2015-4-14 22:35
pygame.display.set_mode()
第二个参数是是否全屏,那请问第三个参数代表什么?

图片位深度
文档里似乎说这个值最好不要给,它会用系统默认的
作者: Jerome    时间: 2015-4-15 19:35
crossin先生 发表于 2015-4-15 13:53
图片位深度
文档里似乎说这个值最好不要给,它会用系统默认的

我查过资料,这个可能玩photoshop的高手更懂些,是图像方面的知识。
作者: 冷月无声    时间: 2015-11-30 21:37
子弹的那张图片一直用不了啊。。。。。

捕获11.JPG (20.53 KB, 下载次数: 610)

捕获11.JPG


作者: 冷月无声    时间: 2015-11-30 21:51
解决了,之前没有转义

捕获5555.JPG (12.09 KB, 下载次数: 592)

捕获5555.JPG


作者: 周末晒被子    时间: 2015-12-26 13:41
  1. # -*- coding: utf-8 -*-
  2. import pygame
  3. from sys import exit
  4. pygame.init()
  5. screen = pygame.display.set_mode((450,800),0,32)
  6. pygame.display.set_caption('Hello World')

  7. #加载需要的图片
  8. background = pygame.image.load('f:\plane\some.jpg')
  9. plane = pygame.image.load('f:\plane\plane.png').convert_alpha()
  10. bullet = pygame.image.load('f:\plane\sullet.png')

  11. #初始化子弹位置
  12. bullet_x = 0
  13. bullet_y = -1
  14. bullet_left_x = 0
  15. bullet_left_y = -1
  16. bullet_right_x = 0
  17. bullet_right_y = -1

  18. #开始游戏循环
  19. while True:
  20.     for event in pygame.event.get():
  21.         if event.type == pygame.QUIT:
  22.             pygame.quit()
  23.             exit()
  24.     #创建背景窗口
  25.     screen.blit(background,(0,0))
  26.     x,y = pygame.mouse.get_pos()
  27.    
  28.     #获取左、右两个子弹起始点位置
  29.     left_x = x - plane.get_width() / 3
  30.     left_y = y
  31.     right_x = x + plane.get_width() / 3
  32.     right_y = y
  33.    
  34.     if bullet_y < 0:
  35.         bullet_x = x - bullet.get_width() / 2
  36.         bullet_y = y - bullet.get_height() / 2
  37.         #把子弹图片的中心设置为鼠标坐标
  38.     else:
  39.         bullet_y -= 5

  40.     if bullet_left_y < 0:
  41.         bullet_left_x = left_x - bullet.get_width() / 2
  42.         bullet_left_y = left_y - bullet.get_height() / 2
  43.     else:
  44.         bullet_left_y -= 5

  45.     if bullet_right_y < 0:
  46.         bullet_right_x = right_x - bullet.get_width() / 2
  47.         bullet_right_y = right_y - bullet.get_height() / 2
  48.     else:
  49.         bullet_right_y -= 5

  50.    
  51.     #加载3个子弹图片
  52.     screen.blit(bullet,(bullet_x,bullet_y))
  53.     screen.blit(bullet,(bullet_left_x,bullet_left_y))
  54.     screen.blit(bullet,(bullet_right_x,bullet_right_y))
  55.    
  56.     #把飞机图片的中心设置为鼠标坐标
  57.     x-= plane.get_width() / 2
  58.     y-= plane.get_height() / 2
  59.     screen.blit(plane,(x,y))
  60.     pygame.display.update()
复制代码

作者: 周末晒被子    时间: 2015-12-26 13:47
先生先生看我的\(^o^)/~三行子弹最霸气

77D8.tmp.jpg (85.99 KB, 下载次数: 593)

77D8.tmp.jpg


作者: crossin先生    时间: 2015-12-26 18:24
周末晒被子 发表于 2015-12-26 13:47
先生先生看我的\(^o^)/~三行子弹最霸气

举一反三
作者: 周末晒被子    时间: 2015-12-27 15:32

先生,我发现我的代码子弹的往上移动的幅度,和先生的一样,同样是 y -= 5 ,但是运行后发现,先生的代码(就是本节课的代码)的子弹很快——仅仅能看见影子,而我的子弹就是一只略快的蚂蚁,窗口一样是(450,800)。

我修改一下自己的子弹上移幅度,发现我的代码 y -= 50 左右才相当于先生的子弹速度。
不应该啊。
作者: crossin先生    时间: 2015-12-27 20:46
周末晒被子 发表于 2015-12-27 15:32
先生,我发现我的代码子弹的往上移动的幅度,和先生的一样,同样是 y -= 5 ,但是运行后发现,先生的代 ...

不可能所有代码都一样,执行出来不一样吧。肯定有哪里不同,你分析下不一样的代码。
我猜测,大概是因为帧率不一样,我的代码帧率快,所以每帧5像素就很快了。你的代码里,可能因为某些原因导致帧率较低
作者: 周末晒被子    时间: 2015-12-28 09:38
找到原因了,奇怪。

加载这两张图片的时候,我的是这样:
background = pygame.image.load('f:\plane\some.jpg')
bullet = pygame.image.load('f:\plane\sullet.png')
而先生的是这样:
background = pygame.image.load('f:\plane\some.jpg').convert()
bullet = pygame.image.load('f:\plane\sullet.png').convert_alpha()

应该是背景图片 background = pygame.image.load('f:\plane\some.jpg').convert() 的问题。这个会影响帧率吗?
作者: crossin先生    时间: 2015-12-28 16:22
周末晒被子 发表于 2015-12-28 09:38
找到原因了,奇怪。

加载这两张图片的时候,我的是这样:

会的。你去搜索一下 pygame convert ,了解它的作用
作者: 周末晒被子    时间: 2016-1-8 01:55
crossin先生 发表于 2015-12-28 16:22
会的。你去搜索一下 pygame convert ,了解它的作用

mark,查了就回来写心得。
作者: 百分之三十    时间: 2016-1-13 13:30
刚开始学编程,来这里学习学习
作者: catherinemic    时间: 2016-2-1 14:28
加了一些限制让飞机不飞出窗外,外加从飞机中心飞出的三行子弹,做出来好有成就感呀~~

Python28.png (106.2 KB, 下载次数: 624)

Python28.png


作者: crossin先生    时间: 2016-2-2 11:51
catherinemic 发表于 2016-2-1 14:28
加了一些限制让飞机不飞出窗外,外加从飞机中心飞出的三行子弹,做出来好有成就感呀~~ ...


作者: shangyaoshi    时间: 2016-4-1 16:29
C老师,我拷贝您的代码,怎么感觉子弹好快啊,没有一颗子弹消失另一颗才出现的感觉,只有把速度降到‘1’的时候,才好一些,您的电脑速度是‘5’的时候效果啥样啊,是不是感觉到一串子弹的样子。
作者: crossin先生    时间: 2016-4-1 17:34
shangyaoshi 发表于 2016-4-1 16:29
C老师,我拷贝您的代码,怎么感觉子弹好快啊,没有一颗子弹消失另一颗才出现的感觉,只有把速度降到‘1’的 ...

这个代码里没有考虑程序的运行速度对帧数的影响。所以应该是你电脑上帧数高,子弹就快。
通常游戏里会把每一帧的时间考虑进去,保证速度一致
作者: shangyaoshi    时间: 2016-4-4 16:33
crossin先生 发表于 2016-4-1 17:34
这个代码里没有考虑程序的运行速度对帧数的影响。所以应该是你电脑上帧数高,子弹就快。
通常游戏里会把 ...

晓得啦,谢谢c老师指点。
作者: Yumiao_HyunMin    时间: 2016-7-1 16:34
太好玩了哈哈哈~继续学习下去!
作者: xiao1272209235    时间: 2016-8-23 16:09
import pygame
#导入pygame库
from sys import exit
#向sys模块接一个exit函数用来退出程序

pygame.init()
#初始化pygame,为使用硬件做准备

screen = pygame.display.set_mode( (450, 800), 0, 32)
#创建一个窗口,窗口大小和背景图片一样大小

pygame.display.set_caption('Hello, World')
#设置窗口标题

background = pygame.image.load('background.jpg').convert()
#加载病转换图片

plane = pygame.image.load('plane.png').convert()
#加载飞机图片

bullet = pygame.image.load('bullet.png').convert_alpha()
#加载子弹图片
bullet_x = 0
bullet_y = 0
#初始化子弹的位置

while True:
#游戏主循环
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
        #接受到退出事件就退出程序
            pygame.quit()
            exit()
    screen.blit(background, (0, 0))
    #将背景图画上去

    x,y = pygame.mouse.get_pos()
    #获取鼠标位置
    if bullet_y < 0:
    #如果子弹超出屏幕范围
        bullet_x = x   #- bullet.get_width()   这里这样改也可以?!!
        bullet_y = y   #- bullet.get_height()  
        #把子弹的中心位置设为鼠标坐标
    else:
        bullet_y -= 5
        #子弹位置往上移
    screen.blit(bullet, (bullet_x, bullet_y) )
    x -= plane.get_width() / 2
    y -= plane.get_height() / 2
    #计算飞机左上角位置
    screen.blit(plane, (x, y))
    #把飞机画到屏幕上
    pygame.display.update()
    #刷新一下图片

作者: Phoestia    时间: 2016-9-10 00:59
改了下子弹的X坐标,变成散弹了
  1. # -*- coding: utf-8 -*-
  2. import pygame
  3. from sys import exit
  4. pygame.init()
  5. screen = pygame.display.set_mode((450, 800), 0, 32)
  6. pygame.display.set_caption("Hello, World!")
  7. background = pygame.image.load('back.jpg').convert()
  8. plane = pygame.image.load('plane.png').convert_alpha()
  9. bullet=pygame.image.load('bullet.png').convert_alpha()
  10. bullet1=bullet
  11. bullet2=bullet
  12. bullet_x=0
  13. bullet_y=-1
  14. bullet1_x=0
  15. bullet1_y=0
  16. bullet2_x=0
  17. bullet2_y=0
  18. while True:
  19.     for event in pygame.event.get():
  20.         if event.type == pygame.QUIT:
  21.             pygame.quit()
  22.             exit()
  23.     screen.blit(background, (0,0))
  24.     x, y = pygame.mouse.get_pos()
  25.     if bullet_y<0:
  26.         bullet_x=x-bullet.get_width()/2
  27.         bullet_y=y-bullet.get_height()/2
  28.         bullet1_x=x-bullet.get_width()/2-23
  29.         bullet1_y=y-bullet.get_height()/2
  30.         bullet2_x=x-bullet.get_width()/2+23
  31.         bullet2_y=y-bullet.get_height()/2
  32.     else:
  33.         bullet_y-=2
  34.         bullet1_y-=2
  35.         bullet1_x-=0.5
  36.         bullet2_y-=2
  37.         bullet2_x+=0.5
  38.     screen.blit(bullet,(bullet_x,bullet_y))
  39.     screen.blit(bullet1,(bullet1_x,bullet1_y))
  40.     screen.blit(bullet2,(bullet2_x,bullet2_y))
  41.     x-= plane.get_width() / 2
  42.     y-= plane.get_height() / 2
  43.     #print (x,y,bullet_x,bullet_y)
  44.     screen.blit(plane, (x,y))
  45.     pygame.display.update()
复制代码

作者: crossin先生    时间: 2016-9-11 00:23
Phoestia 发表于 2016-9-10 00:59
改了下子弹的X坐标,变成散弹了

有点意思
作者: cxh19920318    时间: 2016-12-7 21:38
鼠标操控模式,但是这跟线太难看了……不知道有没方法弄得好看点

#-*-coding:utf-8-*-
import pygame
from sys import exit

pygame.init()
screen=pygame.display.set_mode((450,800),0,32)
pygame.display.set_caption("Plane")
background=pygame.image.load(r"C:\pythonexam\game\image\background.jpg").convert()
plane=pygame.image.load(r"C:\pythonexam\game\image\plane.png").convert_alpha()
bullet=pygame.image.load(r"C:\pythonexam\game\image\bullet.png").convert_alpha()

while True:
    for event in pygame.event.get():
        if event.type==pygame.QUIT:
            pygame.quit()
            exit()
    screen.blit(background,(0,0))

    x,y=pygame.mouse.get_pos()
    x_plane=x-plane.get_width()/2
    y_plane=y-plane.get_height()/2
    y_value=y
    x_bullet=x-bullet.get_width()/2
    y_bullet=y-plane.get_height()/2
    screen.blit(plane,(x_plane,y_plane))
    if event.type==pygame.MOUSEBUTTONDOWN:
        for i in range(y_value):
            if y_bullet<0:
                y_bullet=y-bullet.get_width()/2
            if y_bullet>0:
                y_bullet-=1
            screen.blit(bullet,(x_bullet,y_bullet))
            pygame.display.update()
    pygame.display.update()






作者: brahmagupta    时间: 2017-3-5 17:13
关于文件路径可以直接用 斜杠/ 啊,斜杠/不需要转义,而反斜杠\是需要转义的
作者: brahmagupta    时间: 2017-3-5 18:06
本帖最后由 brahmagupta 于 2017-3-5 18:19 编辑

crossin老师:
我想问几个问题

1.如何实现“异步”多子弹?
我的想法是在循环中添加一个MouseButtonDown的Event的判断,来让玩家在每次按下鼠标左键的时候都发射一枚子弹。我想到的可以实现的方法只有 提高“载弹量” 。 就是在代码中记录N颗子弹的位置(比如说N=10,就是十颗子弹)然后在检测到“鼠标按下”操作的时候依次绘制这N颗子弹。(我觉得这里子弹可以用之前python基础课中讲的 class 来构造)
但是我觉得这个方法代码上有些臃肿,而且 载弹量必须要事先确定好。 我希望:能实现,每次按下鼠标左键的时候都发射一枚子弹,而且总“载弹量”不确定(示例代码中的载弹量为1,只有在这颗子弹飞出边界的时候才会再次发射。。所以鼠标越靠近上边界射速越快。。。)。就是说我点几次鼠标就发射几颗(可以很多很多,而不是一个确定的数值N),而且这些子弹可以说 可以互不干扰地 “并行” 飞行。(不知道我说清楚没。。)
(就好像C语言中,如果我想要接收一段文字,但不确定他的长度,有没有一种类型的 变量 x或者方法,我可以不用指定这个变量 x的空间大小---例如x[100]这样,给个100单位长度的空间。而是 它接受了多少字符就可以开多少空间。   这种好像在C里没有)

优化问题:
2.如何任意 控制帧率/提高 帧率|画面刷新频率
我好像在之前的教程贴里看到过有人也提出过这个问题。。当时没太在意,现在又找不到了。。。

3.如何解决飞机卡顿问题
我发现,在我仅在您的代码基础上添加了 MouseButtonDown事件来发射子弹 的功能时,在玩的时候有个不好的体验:
在按下鼠标之后的一小段时间(从代码上看应该是 子弹从发射到飞出边界的这段时间),飞机仍然停在按下鼠标的那个位置。。也就是说这段时间
(if event.type==pygame.MOUSEBUTTONDOWN:    绘制飞行的子弹-直到飞出边界为止)飞机是卡住了一样。 我不知道这个怎么解决。
(第三个问题好像和前两个问题有些重复的地方: 不知道怎么样 在代码已经执行到一个if代码块中 的时候,还可以进行这同一个if判断?就好像 我已经 在一个叫做if的坑里了,但是我怎么样在  我还在坑里的时候再跳进来。。。也许这是一个 伪需求。。。)
作者: brahmagupta    时间: 2017-3-5 18:15
因为我是学硬件的,学过verilog这种硬件语言。这种硬件语言可以实现 “时序逻辑”,就是以硬件上的一个元件(比如石英、振荡器啥的)提供的 ”频率“---即”时间“,作为执行代码的依据---有些代码块可以在同一个时间点下一起同时执行。而不是像解释器一样一行一行执行。
不知道有没有高级编程语言有类似的功能啊
作者: brahmagupta    时间: 2017-3-5 18:17
本帖最后由 brahmagupta 于 2017-3-5 18:27 编辑

貌似可以将 ”MouseButtonDown的判断“ 和  ”绘制子弹“ 分开来进行?
并且我又有一个想法是引入 数字逻辑 里面的 ”有限状态机“0.0 来用 状态转移的 思路来解决 "判断和 绘制子弹"的问题。。(然而还没有想清楚。)


作者: brahmagupta    时间: 2017-3-5 18:29
我直接去 编程擂台 开一个帖子跟大家慢慢讨论好了
作者: crossin先生    时间: 2017-3-6 14:42
brahmagupta 发表于 2017-3-5 18:06
crossin老师:
我想问几个问题

1子弹的问题,你只要做成按照你点击发射,而不是自动发射,这个问题就很好解决了。把子弹的销毁和发射分成两件事来做。然后你也可以不回收子弹,每次打出去的,最后从游戏里移除就可以

2 帧率有办法设置降低,但你没办法无限提高帧率,就像老电脑玩游戏帧率就是会很低一样,这是由性能所限。

3 卡顿的问题有可能是代码上实现的不好。另外你说的事件响应和渲染分离,这个很多游戏引擎都是这么做的,只是pygame现在这样写是比较原始的做法
作者: saberetoile    时间: 2017-3-13 18:50
怎么感觉子弹越射越慢了
作者: crossin先生    时间: 2017-3-13 20:59
saberetoile 发表于 2017-3-13 18:50
怎么感觉子弹越射越慢了

可能帧率下降了
作者: python2730    时间: 2017-3-27 11:37
赞,刚开始学习!
作者: python2730    时间: 2017-3-27 11:38
学习啦
作者: zuojintao    时间: 2017-11-14 23:16
本帖最后由 zuojintao 于 2017-11-14 23:18 编辑

谢谢老师
作者: siyuagata    时间: 2018-1-8 16:10
求助!

为啥代码完全照抄之后
screen.blit(bullet1, (bullet1_x, bullet1_y)) 这一行会报错呢?
系统说是“invalid syntax”
作者: crossin先生    时间: 2018-1-8 16:19
语法错误,肯定是抄错了,少了括号之类,或者用了中文符号
作者: calf_in_cup    时间: 2018-1-17 15:45
飞机对打
  1. # -*- coding:utf-8 -*-
  2. from sys import exit

  3. import pygame

  4. pygame.init()
  5. screen = pygame.display.set_mode((450, 800), 0, 32)
  6. pygame.display.set_caption("Hello, World!")
  7. sky = pygame.image.load('back.jpg').convert()
  8. plane = pygame.image.load('plane.png').convert_alpha()
  9. bullet = pygame.image.load('bullet.png').convert_alpha()
  10. # 加载子弹图像

  11. plane_enemy = pygame.image.load('plane_rev.png').convert_alpha()
  12. # 加载敌军战机图像
  13. bullet_enemy = pygame.image.load('bullet_rev.png').convert_alpha()
  14. # 加载敌军子弹图像


  15. bullet_x = 0
  16. bullet_y = -1
  17. # 设置我方子弹初始位置

  18. bullet_enemy_x = 225-bullet.get_width() / 2
  19. bullet_enemy_y = 801
  20. # 设置敌方子弹初始位置

  21. plane_enemy_x = 225-plane_enemy.get_width() / 2
  22. plane_enemy_y = 0
  23. # 设置敌方战机初始位置

  24. while True:
  25.     for event in pygame.event.get():
  26.         if event.type == pygame.QUIT:
  27.             pygame.quit()
  28.             exit()
  29.     screen.blit(sky, (0, 0))
  30.     screen.blit(plane_enemy, (plane_enemy_x, plane_enemy_y))
  31.     # 把敌方战机画到屏幕上
  32.     x, y = pygame.mouse.get_pos()
  33.     # 我方战机运动情况
  34.     if bullet_y < 0:
  35.         # 如果子弹位置超出了屏幕上端
  36.         bullet_x = x - bullet.get_width() / 2
  37.         bullet_y = y - bullet.get_height() / 2
  38.         # 把子弹位置往上移
  39.     else:
  40.         bullet_y -= 5
  41.     screen.blit(bullet, (bullet_x, bullet_y))
  42.     # 把子弹画到屏幕上
  43.     x -= plane.get_width() / 2
  44.     y -= plane.get_height() / 2
  45.     screen.blit(plane, (x, y))

  46.     # 敌方战机运动情况
  47.     if bullet_enemy_y > 800:
  48.         # 如果敌方子弹超出了屏幕下方
  49.         bullet_enemy_x = 225 - bullet.get_width() / 2
  50.         bullet_enemy_y = 0 - bullet.get_height() / 2
  51.     else:
  52.         bullet_enemy_y += 5
  53.     screen.blit(bullet_enemy,(bullet_enemy_x,bullet_enemy_y))
  54.     #把敌方子弹画到屏幕上


  55.     pygame.display.update()
复制代码

TIM截图20180117154309.jpg (19.66 KB, 下载次数: 671)

TIM截图20180117154309.jpg


作者: crossin先生    时间: 2018-1-18 11:10
calf_in_cup 发表于 2018-1-17 15:45
飞机对打

有意思
作者: 东东哥    时间: 2018-11-13 16:59
  1. # !/usr/bin/python
  2. import pygame
  3. from sys import exit

  4. pygame.init()
  5. screen = pygame.display.set_mode((450,800),0,32)
  6. pygame.display.set_caption('plane')

  7. background = pygame.image.load('back.jpg').convert()
  8. plane = pygame.image.load('plane.png').convert_alpha()
  9. bullet = pygame.image.load('bullet.png').convert_alpha()
  10. bullet1=bullet
  11. #加载子弹图像

  12. width=plane.get_width()/2
  13. height=plane.get_height()/2

  14. bullet_x=0
  15. bullet_y=-1
  16. bullet1_x=0
  17. bullet1_y=-1

  18. #初始化子弹位置
  19. while True:
  20.     for event in pygame.event.get():
  21.         if event.type == pygame.QUIT:
  22.             pygame.quit()
  23.             exit()
  24.     screen.blit(background, (0,0))

  25.     x, y = pygame.mouse.get_pos()
  26.     if bullet_y <0:
  27.         #如果子弹位置超出了屏幕上端
  28.         bullet_x = x - bullet.get_width() / 2 -23
  29.         bullet_y = y - bullet.get_height() / 2
  30.         bullet1_x = x - bullet.get_width() / 2 + 25
  31.         bullet1_y = y - bullet.get_height() / 2
  32.         #把子弹的中心位置设为鼠标坐标
  33.     else:
  34.         bullet_y -= 5
  35.         bullet_y -= 5
  36.         #子弹位置上移
  37.     screen.blit(bullet,(bullet_x,bullet_y))
  38.     screen.blit(bullet1,(bullet1_x,bullet1_y))
  39.     #把子弹画到屏幕上
  40.     if y>=800-height:
  41.         if x<width:
  42.             screen.blit(plane,(0,800-2*height))
  43.         elif x>450-width:
  44.             screen.blit(plane,(450-2*width,800-2*height))
  45.         else:
  46.             screen.blit(plane,(x-width,800-2*height))
  47.     elif y<height:
  48.         if x<width:
  49.             screen.blit(plane,(0,0))
  50.         elif x>450-width:
  51.             screen.blit(plane,(450-2*width,0))
  52.         else:
  53.             screen.blit(plane,(x-width,0))
  54.     else:
  55.         if x<width:
  56.             screen.blit(plane,(0,y-height))
  57.         elif x>450-width:
  58.             screen.blit(plane,(450-2*width,y-height))
  59.         else:
  60.             screen.blit(plane,(x-width,y-height))  
  61.     pygame.display.update()
复制代码
老师,为什么我左右两边的子弹的射速不一样,左边的快
作者: crossin先生    时间: 2018-11-13 20:23
东东哥 发表于 2018-11-13 16:59
老师,为什么我左右两边的子弹的射速不一样,左边的快

    else:
        bullet_y -= 5
        bullet_y -= 5
        #子弹位置上移

写错了吧

既然左右子弹不一样,就找代码里关于左右子弹的代码查
作者: 东东哥    时间: 2018-11-14 15:25
crossin先生 发表于 2018-11-13 20:23
else:
        bullet_y -= 5
        bullet_y -= 5

粗心了
作者: PMCoding    时间: 2019-12-17 14:08
先生教我,
问题:子弹太长了。。。。求教,原因出在哪里
[img][/img] 问题图片.png

代码:
# -*- coding: utf-8 -*-
import pygame
#导入pygame
from sys import exit
import time
#sys模块借一个exit函数用来退出程序
pygame.init()
#初始化pygame,为使用硬件做准备
screen = pygame.display.set_mode((600, 419), 0, 32)
#创建了一个窗口,窗口大小和背景图片大小一样
pygame.display.set_caption("Hello, hahaha!")
#设置窗口标题
pic_a='pygame_pic.png'
pic_b='pygame_pic2.png'
pic_c='pygame_pic3.jpg'
pic_all=[pic_a,pic_b,pic_c]
pic_num=3
background = pygame.image.load(pic_all[pic_num%3]).convert()
plane = pygame.image.load('plane.png').convert_alpha()
bullet=pygame.image.load('bullet.png').convert_alpha()
x_bullet = 0
y_bullet = -1
while True:
#游戏主循环

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            pic_num+=1
            background = pygame.image.load(pic_all[pic_num%3]).convert()
            width=background.get_width()
            height=background.get_height()
            screen = pygame.display.set_mode((width, height), 0, 32)
        screen.blit(background, (0, 0))
    x, y = pygame.mouse.get_pos()
    # 获取鼠标位置
    # 计算飞机的左上角位置
    if y_bullet < 0:
        x_bullet = int(x - bullet.get_width()/2)
        y_bullet = int(y - bullet.get_height()/2)
    else:
        y_bullet -= 0.2
    screen.blit(bullet, (x_bullet, y_bullet))  # 把子弹画到屏幕上
    x -= int(plane.get_width() / 2)
    y -= int(plane.get_height() / 2)
    screen.blit(plane, (x, y))  # 将背景图画上去
    #加载并转换图像
    pygame.display.update()#刷新一下画面
作者: PMCoding    时间: 2019-12-17 14:31
PMCoding 发表于 2019-12-17 14:08
先生教我,
问题:子弹太长了。。。。求教,原因出在哪里
[/img]

看了前面的同学反馈,好像是帧率的问题,运行其他同学的双发子弹的代码,子弹射出来很顺畅,我的代码原地射出来就是一条线,换个地方之前的子弹那条线还在
作者: crossin先生    时间: 2019-12-17 16:06
PMCoding 发表于 2019-12-17 14:31
看了前面的同学反馈,好像是帧率的问题,运行其他同学的双发子弹的代码,子弹射出来很顺畅,我的代码原地 ...

screen.blit(background, (0, 0))

这句话的缩进不对,导致背景没有重绘制
作者: PMCoding    时间: 2019-12-17 16:32
crossin先生 发表于 2019-12-17 16:06
screen.blit(background, (0, 0))

这句话的缩进不对,导致背景没有重绘制

gotta,谢谢~




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