设为首页 收藏本站
查看: 765|回复: 0

[经验分享] 2015/11/5用Python写游戏,pygame入门(5):面向对象的游戏设计

[复制链接]

尚未签到

发表于 2015-11-29 09:54:19 | 显示全部楼层 |阅读模式
  昨天的内容里有了运动的子弹,虽然我们只添加了一个子弹,但你可以看到我们需要记录子弹的x,y坐标,每次要更新它的坐标。如果我们想要有多颗子弹,就需要存储多个坐标。那时候处理起来就不显得那么简单,也许我们可以使用两个list,一个专门存储各个子弹的x坐标,另一个专门存储子弹的y坐标,问题似乎变得没那么复杂,写起来会简单一些。但是我们到现在还没有加入过敌机,如果加入了敌机,加入别的东西的设计,我们将需要很多不同的数据的存储。虽然一个思路清晰的程序员可以记住所有的坐标存储在哪个list里,但是这毕竟比较麻烦。那有什么方法呢?
  这就需要提到程序语言的数据抽象方法了,也就是面向对象的抽象方法,可以让我们更好地处理数据。

  面向对象的关键在于封装,我们来看看应该怎样封装一个子弹。
  描述一个子弹,最主要要用的就是它的图片,坐标的位置。它需要的就这么多,还有是一段处理子弹显示的代码。



#定义一个Bullet类,封装子弹的数据和方法
class Bullet(object):
def __init__(self):
self.x = 0
self.y = -100
self.speed = 600
self.image = pygame.image.load(bullet_image_filename).convert_alpha()
def move(self,passed_time_second):
if self.y < 0:
mouseX, mouseY = pygame.mouse.get_pos()
self.x = mouseX - self.image.get_width()/2
self.y = mouseY - self.image.get_width()/2
else:
self.y -= self.speed*passed_time_seconds
  这段代码的写法和昨天写的完全一样,但是用了面向对象的写法。然后我们将昨天的代码更改一下:



# -*- coding: utf8 -*-

background_image_filename = 'background.png'
mouse_image_filename = 'hero.png'
bullet_image_filename = 'bullet.png'
#指定图像文件名称
import pygame #导入pygame库
from sys import exit #向sys模块借一个exit函数用来退出程序
#定义一个Bullet类,封装子弹的数据和方法
class Bullet(object):
def __init__(self):
self.x = 0
self.y = -100
self.speed = 600
self.image = pygame.image.load(bullet_image_filename).convert_alpha()
def move(self, passed_time_second):
if self.y < 0:
mouseX, mouseY = pygame.mouse.get_pos()
self.x = mouseX - self.image.get_width()/2
self.y = mouseY - self.image.get_width()/2
else:
self.y -= self.speed*passed_time_second
pygame.init() #初始化pygame,为使用硬件做准备
screen = pygame.display.set_mode((480, 650), 0, 32)
#创建了一个窗口
pygame.display.set_caption("PlaneFight!")
#设置窗口标题
pygame.mouse.set_visible(False)
background = pygame.image.load(background_image_filename).convert()
mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha()
#加载并转换图像

bullet = Bullet()
clock = pygame.time.Clock()
while True:
#游戏主循环
for event in pygame.event.get():
if event.type == pygame.QUIT:
#接收到退出事件后退出程序
            pygame.quit()
exit()
time_passed = clock.tick(100)
time_passed_second = time_passed/1000.0
screen.blit(background, (0,0))
#将背景图画上去
x, y = pygame.mouse.get_pos()
#获得鼠标位置
bullet.move(time_passed_second)#移动子弹
        
x-= mouse_cursor.get_width() / 2
y-= mouse_cursor.get_height() / 2
#计算光标的左上角位置
   
screen.blit(bullet.image, (bullet.x, bullet.y))
screen.blit(mouse_cursor, (x, y))
#把元素画上去

pygame.display.update()
#刷新一下画面
  这样,我们就掌握了子弹的创建方法。

  我们用同样的思路去考虑敌机应该怎样创建。
  敌机需要封装的数据,主要也是图片,坐标。以及封装一个处理它坐标变化的方法。
  那么我们就可以定义敌机的类:



class Enemy(object):#定义一个Enemy类,封装敌机的数据和方法
def __init__(self):
self.x = 200
self.y = -50
self.speed = 200
self.image = pygame.image.load(enemy_image_filename).convert_alpha()
def move(self, passed_time_second):
if self.y < 650:
self.y += self.speed*passed_time_second
else:
self.y = -50
  然后用相同的方法给它实例化,显示,就可以得到这样的画面:
DSC0000.png
  敌机和子弹一样,我们就将它显示了出来。
  但是,这里有个很明显的问题,那就是敌机每次都从上面的中间飞到下面的中间,和真实游戏相差很多,怎么才能让它多变呢?
  这里我们可以import另外一个常用的库了,也就是random



from random import randint
  在开始加上这一句,引入randint(),这个方法用于生成随机整数,可以给它两个参数,分别作为下界和上界,使用时下界不能比上界大。
  然后我们把这个Enemy类改写成这样:



class Enemy(object):#定义一个Enemy类,封装敌机的数据和方法
def restart(self):
self.x = randint(-30,400)
self.y = randint(-100, -50)
self.speed = randint(100,400)
def __init__(self):
self.restart()
self.image = pygame.image.load(enemy_image_filename).convert_alpha()
def move(self, passed_time_second):
if self.y < 650:
self.y += self.speed*passed_time_second
else:
self.restart()
  这样,敌机的出现速度,出现位置都会发生变化,就显得没有那么呆板了。
  整体的代码如下:



# -*- coding: utf8 -*-

background_image_filename = 'background.png'
mouse_image_filename = 'hero.png'
bullet_image_filename = 'bullet.png'
enemy_image_filename = 'enemy.png'
#指定图像文件名称
import pygame #导入pygame库
from sys import exit #向sys模块借一个exit函数用来退出程序
from random import randint #引入随机数
#定义一个Bullet类,封装子弹的数据和方法
class Bullet(object):
def __init__(self):
self.x = 0
self.y = -100
self.speed = 600
self.image = pygame.image.load(bullet_image_filename).convert_alpha()
def move(self, passed_time_second):
if self.y < 0:
mouseX, mouseY = pygame.mouse.get_pos()
self.x = mouseX - self.image.get_width()/2
self.y = mouseY - self.image.get_width()/2
else:
self.y -= self.speed*passed_time_second
class Enemy(object):#定义一个Enemy类,封装敌机的数据和方法
def restart(self):
self.x = randint(-30,400)
self.y = randint(-100, -50)
self.speed = randint(100,400)
def __init__(self):
self.restart()
self.image = pygame.image.load(enemy_image_filename).convert_alpha()
def move(self, passed_time_second):
if self.y < 650:
self.y += self.speed*passed_time_second
else:
self.restart()
pygame.init() #初始化pygame,为使用硬件做准备
screen = pygame.display.set_mode((480, 650), 0, 32)
#创建了一个窗口
pygame.display.set_caption("PlaneFight!")
#设置窗口标题
pygame.mouse.set_visible(False)
background = pygame.image.load(background_image_filename).convert()
mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha()
#加载并转换图像

bullet = Bullet()
enemy = Enemy()
clock = pygame.time.Clock()
while True:
#游戏主循环
for event in pygame.event.get():
if event.type == pygame.QUIT:
#接收到退出事件后退出程序
            pygame.quit()
exit()
time_passed = clock.tick(100)
time_passed_second = time_passed/1000.0
screen.blit(background, (0,0))
#将背景图画上去
x, y = pygame.mouse.get_pos()
#获得鼠标位置
bullet.move(time_passed_second)#移动子弹
    enemy.move(time_passed_second)

x-= mouse_cursor.get_width() / 2
y-= mouse_cursor.get_height() / 2
#计算光标的左上角位置

screen.blit(enemy.image, (enemy.x, enemy.y))
screen.blit(bullet.image, (bullet.x, bullet.y))
screen.blit(mouse_cursor, (x, y))
#把各个元素画上去

pygame.display.update()
#刷新一下画面
  今天除了将程序方法改成了面向对象以外,基本上也没有多讲什么。
  现在,飞机只有一架,子弹只有一发,敌机也只有一架,感觉不出面向对象的威力,但当它数目多起来时,你会觉得面向对象的抽象的确很省事。
  明天我就来给出我的多架飞机的方法。

  由于我最近事情比较多,这个更新也写的很拖沓,每天只讲了一点点。对于每天在试着做的人来讲是太慢了。不过我每天都会坚持更新,直到把这个游戏搭建起来。
  觉得我讲的慢的朋友,有两个方法,一是自己试着查一些资料,二是先不管我的更新,一周以后再看,到时候就可以看到比较多的变化。
  最近比较忙,没办法一气呵成,不好意思了。
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-144812-1-1.html 上篇帖子: Python结合NC.exe 实现模拟登录&批量填表 下篇帖子: Python中的类(上)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

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