设为首页收藏本站

Crossin的编程教室

 找回密码
 立即加入
查看: 38444|回复: 37
打印 上一主题 下一主题

【Pygame 第6课】 面向对象的游戏设计

[复制链接]

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

跳转到指定楼层
楼主
发表于 2013-8-28 20:28:13 |只看该作者 |正序浏览
上节课中,我们的飞机已经可以发射子弹了,尽管只有一颗。为什么我只加了一颗?试着多加几颗你就会发现,你得用好几个变量去分别记录它们的xy坐标,在主循环中判断每一颗子弹的状态。你可以用list把程序写得稍稍不那么复杂,但这还没完。别忘了你打飞机的对手--敌机还没有加入到游戏。到时候你又需要更多的变量去记录它们的坐标,去判断它们的状态,去处理敌机、子弹、玩家飞机之间的关系。想想都觉得头大。

于是乎,我之前煞费苦心讲解的面向对象就该派上用场了。我要把子弹相关的东西都封装在一起。

先看看目前子弹相关的有哪些东西:x、y坐标,一张图片,好像就这么多。然后,还有一段处理子弹运动状态的代码。来建一个Bullet类,把x、y、image作为成员变量,再提供一个叫做move的成员函数,处理子弹的运动。

#定义一个Bullet类,封装子弹相关的数据和方法
  1. class Bullet:
  2.     def __init__(self):
  3.         #初始化成员变量,x,y,image
  4.         self.x = 0
  5.         self.y = -1
  6.         self.image = pygame.image.load('bullet.png').convert_alpha()

  7.     def move(self):
  8.         #处理子弹的运动
  9.         if self.y < 0:
  10.             mouseX, mouseY = pygame.mouse.get_pos()
  11.             self.x = mouseX - self.image.get_width() / 2
  12.             self.y = mouseY - self.image.get_height() / 2
  13.         else:
  14.             self.y -= 5
复制代码
代码的内容基本和之前一样,只是改为了面向对象的写法。如果你对__init__,self这些字眼感到陌生的话,请发送数字47到50,回顾一下关于python面向对象的课程。

接下来,程序主体就可以瘦身了。在原本加载子弹图片、初始化位置的地方,直接创建一个Bullet的实例。
  1. bullet = Bullet()
复制代码
在主循环中处理子弹运动的地方,调用Bullet的move方法。
  1. bullet.move()
复制代码
绘制子弹的时候,从bullet实例中取数据。
  1. screen.blit(bullet.image, (bullet.x, bullet.y))
复制代码
就这么简单。

运行程序看看效果是否正常。相比昨天,游戏的功能没有任何进展,但在结构上清晰了许多。之后,可以放心地添加更多子弹和敌机,而不会导致代码变成一坨。


6.png

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

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

#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

14

积分

新手上路

Rank: 1

38#
发表于 2018-8-19 19:55:08 |只看该作者
crossin先生 发表于 2018-8-19 14:34
执行先后顺序不一样
不放在 __init__ 里,你这句话执行的时候,pygame还没初始化 ...

原來如此
谢谢老师
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

37#
发表于 2018-8-19 14:34:40 |只看该作者
ericlinmk2 发表于 2018-8-18 17:34
我嘗試了在Class裡不要使用__init__,
但都會出錯顯示
    image = pygame.image.load('bullet.png').conve ...

执行先后顺序不一样
不放在 __init__ 里,你这句话执行的时候,pygame还没初始化
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

14

积分

新手上路

Rank: 1

36#
发表于 2018-8-18 17:34:53 |只看该作者

  1. class Bullet:
  2.     x = 0
  3.     y = -1
  4.     image = pygame.image.load('bullet.png').convert_alpha()

  5.     def move(self):
  6.         if self.y < 0:
  7.             bulletX, bulletY = pygame.mouse.get_pos()
  8.             self.x = bulletX - self.image.get_width() / 2
  9.             self.y = bulletY - self.image.get_height() / 2
  10.         else:
  11.             self.y -= 1
复制代码
我嘗試了在Class裡不要使用__init__,
但都會出錯顯示
    image = pygame.image.load('bullet.png').convert_alpha()
pygame.error: cannot convert without pygame.display initialized

感覺只有 image = pygame.image.load('bullet.png').convert_alpha()才有問題
所以寫成下面這樣子就沒錯了
  1. class Bullet:
  2.     x = 0
  3.     y = -1
  4.     def __init__(self):
  5.         self.image = pygame.image.load('bullet.png').convert_alpha()
复制代码
但是我不懂為什麼子彈圖片一定要初始化?
不是給了圖片就好了嗎?
想了很久  没有搞明白
谢谢老师
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

35#
发表于 2018-6-5 23:36:39 |只看该作者
koalaoycx 发表于 2018-6-5 16:56
import pygame
from sys import exit

不错
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

1

主题

0

好友

35

积分

新手上路

Rank: 1

34#
发表于 2018-6-5 16:56:24 |只看该作者
import pygame
from sys import exit

pygame.init()
screen=pygame.display.set_mode((600,170),0,32)
pygame.display.set_caption('Game in object!')
bg=pygame.image.load('./Figure/back.jpg').convert()

#定义子弹的类
class Bullet:
    def __init__(self):
        self.x=0
        self.y=-1
        self.image=pygame.image.load('./Figure/bullet.png').convert_alpha()

    def move(self):
        if self.y < 0:
            mouseX,mouseY=pygame.mouse.get_pos()
            self.x=mouseX-self.image.get_width()/2
            self.y=mouseY-self.image.get_height()/2
        else:
            self.y -= 5

class Plane:
    def __init__(self):
        self.image=pygame.image.load('./Figure/plane.png').convert_alpha()

    def move(self):
        mouseX, mouseY = pygame.mouse.get_pos()
        self.x = mouseX-self.image.get_width()/2
        self.y = mouseY-self.image.get_height()/2

#调用飞机的函数
plane=Plane()
#调用子弹的函数
bullet=Bullet()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

    #根据图片调整窗口位置并显示背景图片
    width=bg.get_width()
    height=bg.get_height()
    screen_size=(width,height)
    screen=pygame.display.set_mode(screen_size, 0, 32)
    screen.blit(bg, (0,0))

    #调用子弹的Move方法
    bullet.move()
    #绘制子弹
    screen.blit(bullet.image,(bullet.x-22,bullet.y))
    screen.blit(bullet.image, (bullet.x+24, bullet.y))

    #调用飞机的Move方式
    plane.move()
    #绘制飞机
    screen.blit(plane.image,(plane.x,plane.y))

    #更新
    pygame.display.update()
修改了一下,封装了子弹跟飞机,双弹齐发,同时跟前面已经发过的朋友又有点小小的区别。



回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

33#
发表于 2018-4-22 18:11:04 |只看该作者
Joseph丶Joe 发表于 2018-4-22 09:26
我想问一下子弹的向上运动为什么是bullet_y -= 5呢?而不是 bullet_y += 5呢,我试了一下 这种情况没有子弹 ...

坐标原点在左上角

一连串是你没控制好间隔的数值
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

16

积分

新手上路

Rank: 1

32#
发表于 2018-4-22 09:26:47 |只看该作者
我想问一下子弹的向上运动为什么是bullet_y -= 5呢?而不是 bullet_y += 5呢,我试了一下 这种情况没有子弹出现。而且我这样发出子弹不是一颗,而是一连串的
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

31#
发表于 2018-4-11 11:54:30 |只看该作者
花花啊 发表于 2018-4-11 10:28
self.y -= 5,这个5是什么单位,是像素点吗?

#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

2

主题

0

好友

66

积分

注册会员

Rank: 2

30#
发表于 2018-4-11 10:28:56 |只看该作者
     self.y -= 5,这个5是什么单位,是像素点吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即加入

QQ|手机版|Archiver|Crossin的编程教室 ( 苏ICP备15063769号  

GMT+8, 2024-5-3 14:23 , Processed in 0.032119 second(s), 26 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部