2015/11/5用Python写游戏,pygame入门(5):面向对象的游戏设计
昨天的内容里有了运动的子弹,虽然我们只添加了一个子弹,但你可以看到我们需要记录子弹的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
然后用相同的方法给它实例化,显示,就可以得到这样的画面:

敌机和子弹一样,我们就将它显示了出来。
但是,这里有个很明显的问题,那就是敌机每次都从上面的中间飞到下面的中间,和真实游戏相差很多,怎么才能让它多变呢?
这里我们可以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()
#刷新一下画面
今天除了将程序方法改成了面向对象以外,基本上也没有多讲什么。
现在,飞机只有一架,子弹只有一发,敌机也只有一架,感觉不出面向对象的威力,但当它数目多起来时,你会觉得面向对象的抽象的确很省事。
明天我就来给出我的多架飞机的方法。
由于我最近事情比较多,这个更新也写的很拖沓,每天只讲了一点点。对于每天在试着做的人来讲是太慢了。不过我每天都会坚持更新,直到把这个游戏搭建起来。
觉得我讲的慢的朋友,有两个方法,一是自己试着查一些资料,二是先不管我的更新,一周以后再看,到时候就可以看到比较多的变化。
最近比较忙,没办法一气呵成,不好意思了。
2015/11/5用Python写游戏,pygame入门(5):面向对象的游戏设计的更多相关文章
- 2015/11/9用Python写游戏,pygame入门(8):按钮和游戏结束
昨天没有更新内容,今天相对多写一些. 因为我们已经基本完成游戏框架,但是游戏结束后,并不知道怎样比较好开始.我本来本着懒的原则,想结束后显示一个黑屏,然后你重新点一下鼠标就重新开始.但是那样实在太不像 ...
- 2015/11/6用Python写游戏,pygame入门(6):控制大量的对象
昨天我们已经实现了这个游戏的三个基本类. 但是现在它还是没办法做成一个适合玩的游戏,毕竟只有一架敌机的游戏是很乏味的.所以,我们需要好多子弹,也需要好多敌机. 所以,我们要创建list,这个list存 ...
- 2015/11/1用Python写游戏,pygame入门(1):pygame的安装
这两天学习数据结构和算法,有时感觉并不如直接做项目来的有趣.刚刚学完python的基本使用,现在刚好趁热打铁做个小项目. 由于本人一直很想制作一款游戏,就想使用Python制作一个基础的游戏.搜了一下 ...
- 2015/11/4用Python写游戏,pygame入门(4):获取鼠标的位置及运动
按昨天的说法,今天将开始做一个简单的游戏了. 目标是拷贝微信的飞机大战,当然拷贝完以后大家就具备自己添加不同内容的能力了. 首先是要拿到一些图片素材,熟悉使用图像处理软件和绘画的人可以自己制作,并没有 ...
- 2015/11/3用Python写游戏,pygame入门(3):字体模块、事件显示和错误处理
游戏里面一般是肯定会出现文字显示的,即使是俄罗斯方块也应该显示分数.那么我们应该怎样来显示文字呢,今天一起学习一下pygame的font模块. 使用字体模块 pygame可以直接调用系统字体,也可以调 ...
- 2015/11/7用Python写游戏,pygame入门(7):碰撞检测
我们已经完成了飞机大战的大部分东西,但是游戏还是没有办法正式开玩,因为子弹并不能打掉飞机.只有完成了这一个工作,游戏才算基本成型. 今天的内容就非常简单了,就是做到这个碰撞检测,以及控制好子弹和飞机的 ...
- 2015/11/2用Python写游戏,pygame入门(2):游戏中的事件和显示
pygame是一个比较大的库,以我这点弱小的实力是没办法详解的.所以我只讲我懂得那些部分,其他部分由大家慢慢查找了解. ------------------------------- 我用pygame ...
- 用Python写个开心消消乐小游戏
本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 提到开心消消乐这款小游戏,相信大家都不陌生,其曾在 2015 年获得过玩家最喜爱的移动单机游戏奖,受 ...
- python第三十九课——面向对象(二)之设计类
1.设计类class 车: #属性 颜色 = red 品牌 = "BMW" 车牌 = "沪A88888" #函数 行驶(): 停止(): 2.实例化车对象 ca ...
随机推荐
- Week-4-作业1
前言 经过了上周作业的学习拾遗,让我学到了很多东西,也能更好的阅读<构建之法>这本书,下面是我在阅读过第四章和第十七章之后想到的一些问题. 第四章 4.2.1 关于缩进,书中说用四个空格刚 ...
- ACM的fflush(stdin)的问题
在最近的刷题过程中,因为用到了很多字符串的操作,有时需要多次清空缓冲区,所以用了fflush(stdin);的语句,确实很好用,但是发现在OJ上提交后会出现runtime error的问题.当时并没有 ...
- 优先队列的一种实现--堆ADT
二叉堆的两个重要性质: 1.结构性,为完全二叉树,可以用数组方便地表示.2.堆序性:树中每个节点的关键字值大于或等于其父节点的关键字值. 二叉堆的数据结构声明如下: struct HeapStruct ...
- PAT 1069 微博转发抽奖
https://pintia.cn/problem-sets/994805260223102976/problems/994805265159798784 小明 PAT 考了满分,高兴之余决定发起微博 ...
- HDU 2086 A1 = ?
http://acm.hdu.edu.cn/showproblem.php?pid=2086 Problem Description 有如下方程:Ai = (Ai-1 + Ai+1)/2 - Ci ( ...
- 【SQLSERVER】动态游标的实现
方法1: CREATE TABLE #tabTmp(id int) INSERT #tabTmp EXECUTE('SELECT id FROM '+@Table ...
- Linux_Nginx 安装
官网:http://nginx.org/ 1.下载http://nginx.org/download/nginx-1.14.0.tar.gz 2.查看详情 [zwesy@localhost ~]$ l ...
- CSS 绝对定位与弹性布局合作居中
position: absolute; display:flex; justify-content:center;align-items:center;
- spring远程服务知识梳理
序:本文主要是总结和归纳spring的远程服务相关知识,可作为入门学习笔记.写博客目的也是为了进行知识梳理,便于以后查看.本文主要参考资料 spring 实战第三版 本文主要讨论内容如下: 远程调度概 ...
- C# 抽签小程序
设计背景 设置一个Excel名单表,对名单进行随机抽取. 设计思路 使用Timer定时器,运行定时器进行名单随机滚动,停止定时器获得抽签结果 相关技术 随机数 Excel读取/导出 XML文档读写 相 ...