Python游戏系列之四_发射子弹
2017-03-24 16:04
232 查看
Python游戏系列之四_发射子弹
在上一讲中,我们已经做到了飞机的自由移动,但还有一点小问题,就是飞机可能会移到屏幕外。
我们来加上边界检测的代码,使程序更严谨:
在本节中,我们将让飞机发射子弹。
主要规则如下:
1. 我方飞机会自动发射子弹,发射频率是固定的。
2. 子弹方向自下向上,移动速度固定。
3. 子弹超出屏幕显示范围,则消失。
4. 本节暂不考虑子弹击中敌机的问题。
一、技术铺垫
本节中会用到Python面向对象编程的知识,所以先介绍一下Python中的“类”。
学过Java的同学,应该会比较容易接受Python中“类”的概念。
先来看一段代码:
与Java语言差别较大的,就是在定义每个方法时,都有一个名为“self”的参数。
实际上,在调用方法时,会把当前对象传递给形参”self“。
例如:s1.detail(),这时会把s1对象传递给”self“形参。
“self”的用法,相当于Java语言中的”this“。
__init__()方法是构造方法,可以重载。
二、精灵类
”精灵(Sprite)“,是游戏编程的术语,用于表示在背景上可以自由移动的一个图形块。
在我们的游戏中,有我方飞机,有敌方飞机,有无数子弹,如果什么都要我们处理,那就太麻烦了。
在pygame.sprite模块中,精灵类(Sprite)提供了很多常用功能,可以让我们自己的类(如飞机、子弹)继承它。
精灵组类(Group)可以将多个精灵构成一组,适用于子弹的管理。
精灵组的使用示例:
三、源代码
下面是重构后的代码,由于引入了类,所以代码有较大的变动:
在程序的开始部分,定义了一个“我方飞机”类和“子弹”类,其中“我方飞机”类中定义了一个名为bullets的属性,它是一个精灵组,存储了所有子弹。
在游戏循环中主要做了这三件事情:
1. 更新游戏数据(例如定时产生子弹、子弹定时移动、我方飞机的图片切换以产生动画效果等)
2. 绘制游戏界面(第1步的更新游戏数据只是修改变量的值,这一步是根据变量的值绘制界面)
3. 用户事件处理
具体代码请根据注释自行研读。
在上一讲中,我们已经做到了飞机的自由移动,但还有一点小问题,就是飞机可能会移到屏幕外。
我们来加上边界检测的代码,使程序更严谨:
x = hero_pos[0] + offset[pygame.K_RIGHT] - offset[pygame.K_LEFT] y = hero_pos[1] + offset[pygame.K_DOWN] - offset[pygame.K_UP] # 判断x坐标是否左边或右边越界 if x < 0: x = 0 elif x > SCREEN_WIDTH - hero_rect1.width: x = SCREEN_WIDTH - hero_rect1.width else: x = x # 判断y坐标是否上边或下边越界 if y < 0: y = 0 elif y > SCREEN_HEIGHT - hero_rect1.height: y = SCREEN_HEIGHT - hero_rect1.height else: y = y hero_pos[0] = x hero_pos[1] = y
在本节中,我们将让飞机发射子弹。
主要规则如下:
1. 我方飞机会自动发射子弹,发射频率是固定的。
2. 子弹方向自下向上,移动速度固定。
3. 子弹超出屏幕显示范围,则消失。
4. 本节暂不考虑子弹击中敌机的问题。
一、技术铺垫
本节中会用到Python面向对象编程的知识,所以先介绍一下Python中的“类”。
学过Java的同学,应该会比较容易接受Python中“类”的概念。
先来看一段代码:
#!/usr/bin/python # -*- coding: UTF-8 -*- # 定义一个学生类 class Student: # 构造方法1 def __init__(self): self.name = 'Unknown' self.age = 0 # 构造方法2 def __init__(self, name, age): self.name = name self.age = age # 普通方法 def detail(self): print 'Name: ', self.name print 'Age: ', self.age # 创建Student类的对象,并调用构造方法2 s1 = Student('Lily', 16) # 调用普通方法 s1.detail()
与Java语言差别较大的,就是在定义每个方法时,都有一个名为“self”的参数。
实际上,在调用方法时,会把当前对象传递给形参”self“。
例如:s1.detail(),这时会把s1对象传递给”self“形参。
“self”的用法,相当于Java语言中的”this“。
__init__()方法是构造方法,可以重载。
二、精灵类
”精灵(Sprite)“,是游戏编程的术语,用于表示在背景上可以自由移动的一个图形块。
在我们的游戏中,有我方飞机,有敌方飞机,有无数子弹,如果什么都要我们处理,那就太麻烦了。
在pygame.sprite模块中,精灵类(Sprite)提供了很多常用功能,可以让我们自己的类(如飞机、子弹)继承它。
精灵组类(Group)可以将多个精灵构成一组,适用于子弹的管理。
精灵组的使用示例:
# 创建精灵组 group = pygame.sprite.Group() # 向精灵组中添加精灵 group.add(精灵) # 更新精灵组,此时会调用每个精灵的update()方法 group.update() # 将精灵组绘制在surface上 group.draw(screen)
三、源代码
下面是重构后的代码,由于引入了类,所以代码有较大的变动:
#!/usr/bin/python # -*- coding: UTF-8 -*- import pygame from sys import exit # 我方飞机类,继承自Sprite类 class Hero(pygame.sprite.Sprite): # 构造方法,参数分别是我方飞机图片和起始坐标 def __init__(self, hero_surface, hero_init_pos): # 调用父类的构造方法 pygame.sprite.Sprite.__init__(self) # 设置属性 self.image = hero_surface # image属性:我方飞机图片 self.rect = self.image.get_rect() # rect属性:矩形 self.rect.topleft = hero_init_pos # 矩形左上角坐标 self.speed = 6 # speed属性:我方飞机移动速度,比上例调快了一倍 self.bullets = pygame.sprite.Group() # bullets属性:子弹组,使用精灵组 # 移动方法,参数是offset列表 def move(self, offset): # 计算新的x、y坐标 x = self.rect.left + offset[pygame.K_RIGHT] - offset[pygame.K_LEFT] y = self.rect.top + offset[pygame.K_DOWN] - offset[pygame.K_UP] # 对rect属性赋值,调整我方飞机位置 # 同时防止我方飞机越出边界 if x < 0: self.rect.left = 0 elif x > SCREEN_WIDTH - self.rect.width: self.rect.left = SCREEN_WIDTH - self.rect.width else: self.rect.left = x if y < 0: self.rect.top = 0 elif y > SCREEN_HEIGHT - self.rect.height: self.rect.top = SCREEN_HEIGHT - self.rect.height else: self.rect.top = y # 发射子弹方法,参数为子弹图片 def shoot(self, bullet_surface): # 子弹初始位置在我方飞机的上方居中位置 bullet = Bullet(bullet_surface, self.rect.midtop) # 将子弹添加到子弹组中 self.bullets.add(bullet) # 子弹类,继承自Sprite类 class Bullet(pygame.sprite.Sprite): # 构造方法,参数分别是子弹图片和起始位置 def __init__(self, bullet_surface, bullet_init_pos): # 调用父类的构造方法 pygame.sprite.Sprite.__init__(self) # 设置属性 self.image = bullet_surface # image属性:子弹图片 self.rect = self.image.get_rect() # rect属性:矩形 self.rect.topleft = bullet_init_pos # 矩形左上角坐标 self.speed = 8 # speed属性:子弹移动速度 # 移动方法 def update(self): # 修改子弹坐标 self.rect.top -= self.speed # 如果子弹移出屏幕上方,则销毁子弹对象 if self.rect.top < -self.rect.height: self.kill() # 屏幕宽、高 SCREEN_WIDTH = 480 SCREEN_HEIGHT = 640 # 游戏帧率 FRAME_RATE = 60 # 动画周期 ANIMATE_CYCLE = 30 # 创建游戏窗口 pygame.init() screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT]) pygame.display.set_caption('飞机游戏') # 加载图片资源 bg = pygame.image.load('bg1.jpg') # 背景图片 shoot_img = pygame.image.load('shoot.png') # 游戏资源图片 hero_surface = list() hero_surface.append(shoot_img.subsurface(pygame.Rect(0, 99, 102, 126))) # 我方飞机图片1 hero_surface.append(shoot_img.subsurface(pygame.Rect(165, 360, 102, 126))) # 我方飞机图片2 bullet_surface = shoot_img.subsurface(pygame.Rect(1004, 987, 9, 21)) # 子弹图片 # 创建我方飞机对象 hero_pos = [200, 500] hero = Hero(hero_surface[0], hero_pos) # 其它变量 ticks = 0 # 计数器 offset = {pygame.K_LEFT: 0, pygame.K_RIGHT: 0, pygame.K_UP: 0, pygame.K_DOWN: 0} # 我方飞机移动值 clock = pygame.time.Clock() # 时钟 while True: # 控制游戏帧率 clock.tick(FRAME_RATE) # 改变我方飞机图片,以产生动画效果 ticks += 1 if ticks >= ANIMATE_CYCLE: ticks = 0 hero.image = hero_surface[ticks // (ANIMATE_CYCLE // 2)] # 我方飞机发射子弹 # 每10帧发射1次子弹 if ticks % 10 == 0: hero.shoot(bullet_surface) # 子弹移动 hero.bullets.update() # 精灵组update时,会调用所有精灵的update方法 # 绘制背景 screen.blit(bg, [0, 0]) # 绘制我方飞机 screen.blit(hero.image, hero.rect) # 绘制子弹 hero.bullets.draw(screen) # 精灵组draw时,会将所有精灵绘制在surface上 # 更新屏幕 pygame.display.update() # pygame.event.get()方法可以从“事件队列”中,得到所有的事件 for event in pygame.event.get(): # 退出事件 if event.type == pygame.QUIT: pygame.quit() exit() # 键盘按下事件 if event.type == pygame.KEYDOWN: if event.key in offset: offset[event.key] = hero.speed # 我方飞机的移动值为speed属性值 # 键盘松开事件 if event.type == pygame.KEYUP: if event.key in offset: offset[event.key] = 0 # 根据我方飞机的移动值,移动飞机 hero.move(offset)
在程序的开始部分,定义了一个“我方飞机”类和“子弹”类,其中“我方飞机”类中定义了一个名为bullets的属性,它是一个精灵组,存储了所有子弹。
在游戏循环中主要做了这三件事情:
1. 更新游戏数据(例如定时产生子弹、子弹定时移动、我方飞机的图片切换以产生动画效果等)
2. 绘制游戏界面(第1步的更新游戏数据只是修改变量的值,这一步是根据变量的值绘制界面)
3. 用户事件处理
具体代码请根据注释自行研读。
相关文章推荐
- 09-html5游戏坦克大战第五战(自己的坦克可以发射单颗子弹)
- Android基于box2d开发弹弓类游戏[五]-------------发射子弹
- Python游戏系列之五_创建敌机
- Python案例:飞船向右发射子弹
- python 发射子弹
- 游戏开发之,发射子弹,中弹后退
- Python游戏系列之二_显示飞机
- Python游戏系列之一_pygame
- cocos2d-x游戏开发系列教程-坦克大战游戏之子弹和地图碰撞
- cocos2d-x 3.0游戏实例学习笔记《卡牌塔防》第十步---发射子弹&怪物受伤---所有源码和资源完结下载
- 带有武器发射子弹的游戏主界面
- Python游戏系列之三_控制飞机移动
- 树莓派学习系列5——使用python编写简单的游戏程序
- 10-html5游戏坦克大战第六战(自己的坦克可以连续发射子弹)
- cocos2d-x游戏开发系列教程-坦克大战游戏之子弹的碰撞检测处理
- 边做游戏边学android—5(飞机大战④子弹发射和碰撞检测)
- Python游戏系列之七_显示得分
- 飞机游戏移动和发射子弹的小模型
- Python游戏系列之六_击落敌机
- cocos2d-x游戏开发系列教程-坦克大战游戏之子弹的碰撞检测处理