请选择 进入手机版 | 继续访问电脑版
设为首页收藏本站

Crossin的编程教室

 找回密码
 立即加入
楼主: crossin先生

【Pygame 第12课】 屡败屡战

[复制链接]

0

主题

0

好友

558

积分

高级会员

Rank: 4

发表于 2014-9-21 19:08:41 |显示全部楼层
crossin先生 发表于 2014-9-21 15:24
为你点赞!

先生,不知道”打飞机“里面可不可以加点声音文件呢?我想应该可以吧。这几天我再扩展一下代码。
学习,纯粹。
回复

使用道具 举报

174

主题

45

好友

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

发表于 2014-9-22 10:27:29 |显示全部楼层
liu-pengfei 发表于 2014-9-21 19:08
先生,不知道”打飞机“里面可不可以加点声音文件呢?我想应该可以吧。这几天我再扩展一下代码。 ...

可以的,但是我没有用过。你可以自行在网上搜索,然后尝试下
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

53

积分

注册会员

Rank: 2

发表于 2014-10-26 20:39:12 |显示全部楼层
我将碰撞后的重置写在了一起
def restart(plane,e,enemies,b,bullets,score,gameover)
    plane.restart()
    for e in enemies:
        e.restart()
    for b in bullets:
        b.active = False
    score = 0
    gameover = False
但是在后面调用并不能正常运行了,我想是不是作用域的问题,另外我实验了一下,如果
def r(a,b):
    if a>0:
        b=True
    else:
        b=False
b=False
r(3,b)
print b
这样输出b也是false,请问这个和游戏中的差别在什么地方呢,为什么呢。有点混淆了,谢谢
回复

使用道具 举报

174

主题

45

好友

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

发表于 2014-10-27 16:35:53 |显示全部楼层
lovingyun 发表于 2014-10-26 20:39
我将碰撞后的重置写在了一起
def restart(plane,e,enemies,b,bullets,score,gameover)
    plane.restart() ...

的确是作用域。如果你想在函数中改变一个变量的值,要么你把它定义为global全局变量,要么作为返回值return
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

53

积分

注册会员

Rank: 2

发表于 2014-11-6 21:07:46 |显示全部楼层
crossin先生 发表于 2014-10-27 16:35
的确是作用域。如果你想在函数中改变一个变量的值,要么你把它定义为global全局变量,要么作为返回值retu ...

感觉得到这个地方还有一个迷惑的地方在于,检测碰撞的函数中,都可以把状态在函数中改掉,那么对象中的变量的作用域又是什么样的呢?对象中变量的值可以被函数修改吗?
回复

使用道具 举报

174

主题

45

好友

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

发表于 2014-11-7 20:56:05 |显示全部楼层
lovingyun 发表于 2014-11-6 21:07
感觉得到这个地方还有一个迷惑的地方在于,检测碰撞的函数中,都可以把状态在函数中改掉,那么对象中的变 ...

对象中变量的作用域是看对象的。只要这个对象存在,就可以对它的成员变量进行操作。
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

0

好友

18

积分

新手上路

Rank: 1

发表于 2015-10-3 22:17:04 |显示全部楼层
下面是我改编了一点点的打飞机游戏,本意是:每次游戏只有5次机会(n<5),分数是累加的,最后一条命用完就输出 GAME OVER。可是写完之后发现,只玩5次可以实现,但是不能输出GEME OVER,请师父指点下我呗?多谢啦。


# -*- coding: cp936 -*-
import pygame
import random
from sys import exit

class Bullet():   #建一个子弹类
    def __init__(self):  #初始化位置
        self.x = 0
        self.y = -1
        self.image = pygame.image.load('bullet.png').convert_alpha() #载入子弹图片
        self.active = False  #默认不激活
        
    def move(self):
        if self.active:  #激活状态下向上移动
            self.y -= 1
        if self.y < 0:   #当飞出屏幕就设为不激活
            self.active = False
            
    def reset(self): #重置子弹位置
            mousex, mousey = pygame.mouse .get_pos()   #获取鼠标位置,也就是飞机的位置
            self.x = mousex - self.image.get_width()/2
            self.y = mousey - self.image.get_height()/2
            self.active = True  #重新激活      

class Enemy():   #创建敌机类
    def reset(self):  #初始化敌机位置
        self.x = random.randint(50,400)
        self.y = random.randint(-200,-50)
        self.speed = random.random()/5 + 0.1
        #print self.speed
        
    def __init__(self):  #初始化的时候调用reset()
        self.reset()
        self.image = pygame.image.load('enemy.png').convert_alpha()
        
    def move(self):
        if self.y < 800:
            self.y += self.speed
        else:   #若飞机掉出屏幕则重置
            self.reset()

class Plane():
    def reset(self):
        self.x = 200
        self.y = 600
        
    def __init__(self):
        self.reset()
        self.image = pygame.image.load('plane.png').convert_alpha()#载入飞机图片

    def move(self):
        x, y = pygame.mouse .get_pos()    #子弹和飞机的位置都是由鼠标决定的
        x -= self.image.get_width()/2   
        y -= self.image.get_height()/2
        self.x = x
        self.y = y
        
def checkhit(bullet, enemy):  #命中目标函数
    if (bullet.x > enemy.x and bullet.x < enemy.image.get_width() + enemy.x) and (
        bullet.y > enemy.y and bullet.y < enemy.image.get_height() + enemy.y
    ):
        enemy.reset()
        bullet.active = False
        return True
    return False

def checkcrash(plane,enemy): #飞机与敌机相撞
    if (plane.x + 0.7*plane.image.get_width() > enemy.x ) and (
        plane.x + 0.3*plane.image.get_width() < enemy.x + enemy.image.get_width()) and (
        plane.y + 0.7*plane.image.get_height() > enemy.y ) and (
        plane.y < 0.3*plane.image.get_height() + enemy.y + enemy.image.get_height()
    ):
        return True
    return False
#以上代码都基本没有变化
pygame.init()
screen = pygame .display.set_mode((450, 800), 0, 32)   #创建了一个窗口,其大小与背景图片相同
pygame.display .set_caption("Hello world")
background = pygame.image.load ('back.png').convert()  #载入背景图片
plane = Plane()
bullets = []        #创建子弹list
for i in range(5):
    bullets.append(Bullet())
count_b = len(bullets)
index_b = 0
interval_b = 0
enemies = []         #创建敌机list
for i in range(4):
    enemies.append(Enemy())
gameover = False
n = 0   #记录游戏次数
flag = True    #判断游戏是否结束的标志
score = 0
font = pygame.font.Font(None, 32)
while True :   
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
        #判断在gameover状态下点击了鼠标
        if n < 5:  #最多只有5次复活机会
            if gameover and event.type == pygame.MOUSEBUTTONUP:
                plane.reset()
                for e in enemies:
                    e.reset()
                for b in bullets:
                    b.active = False
                gameover = False
        else:
            flag = False
            text = font.render('GAME OVER !!!', 1, (0,0,0))
            screen.blit(text,(190,400))
            break
    if not flag:  #判断是否结束游戏,输出GAME OVER
        text = font.render('GAME OVER !!!', 1, (0,0,0))
        screen.blit(text,(190,400))
        continue
                  
    screen.blit(background, (0,0))    #画出背景图
    if not gameover and n < 5:
        interval_b -= 1
        if interval_b < 0:
            bullets[index_b].reset()
            interval_b = 200
            index_b = (index_b + 1) % count_b
        for b in bullets:
            if b.active:
                for e in enemies:
                    if checkhit(b,e):
                        score += 100
                b.move()
                screen.blit(b.image, (b.x, b.y)) #画出子弹        
        for e in enemies:
            if checkcrash(plane,e):
                n += 1
                gameover = True
            e.move()
            screen.blit(e.image, (e.x,e.y))
        plane.move()
        screen.blit(plane.image,(plane.x,plane.y))    #画出飞机 先画子弹再画飞机,使得看起来子弹像是从飞机里出来的
        text = font.render('Score:%d' % score, 1, (0,0,0))
        screen.blit(text,(0,0))
        text1 = font.render('%d chances' % (5-n),1, (0,0,0))
        screen.blit(text1,(300,0))
    else:
        text = font.render('Score:%d' % score, 1, (0,0,0))
        screen.blit(text,(190,400))
    pygame.display.update()
        
  


回复

使用道具 举报

174

主题

45

好友

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

发表于 2015-10-3 22:38:06 |显示全部楼层
dreamlxt17 发表于 2015-10-3 22:17
下面是我改编了一点点的打飞机游戏,本意是:每次游戏只有5次机会(n enemy.x and bullet.x < enemy.image. ...

for event in pygame.event.get()

这里面的代码只有在有事件响应的时候才会执行到,为什么要把判断游戏结束状态的代码放在这里面
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

0

主题

1

好友

22

积分

新手上路

Rank: 1

发表于 2015-10-21 10:58:25 |显示全部楼层
先生能不能再出一节说说怎么将.py打包成windows平台下能用的.exe呢 ?  我按网上百度的方法老是不成功
回复

使用道具 举报

174

主题

45

好友

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

发表于 2015-10-21 20:04:36 |显示全部楼层
daiqifan012 发表于 2015-10-21 10:58
先生能不能再出一节说说怎么将.py打包成windows平台下能用的.exe呢 ?  我按网上百度的方法老是不成功 ...

http://tieba.baidu.com/p/2409491530?pid=35352333161
贴吧上有发过一篇,你试试看可不可以
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

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

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

GMT+8, 2024-3-29 23:49 , Processed in 0.028863 second(s), 23 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部