Crossin的编程教室

标题: 【关于打飞机游戏】按照教程一步步写的个别参数可能不... [打印本页]

作者: leopotter6    时间: 2018-5-2 21:06
标题: 【关于打飞机游戏】按照教程一步步写的个别参数可能不...
本帖最后由 leopotter6 于 2018-5-2 21:07 编辑

按照教程一步步写的,个别参数可能不一样。
运行之后,飞机和敌机并没有碰撞,程序却认为碰撞而终止了。
有没有知道的帮忙看看。谢谢!!

代码在二楼
作者: leopotter6    时间: 2018-5-2 21:07
本帖最后由 leopotter6 于 2018-5-2 21:09 编辑

# -*- coding: utf-8 -*-
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-=0.8
        if self.y<0:            #当飞出屏幕,就设为不激活
            self.active=False
    def restart(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 restart(self):         
        self.x=random.randint(0,391)
        self.y=random.randint(-200,-50)
        self.speed=random.random()+0.1
    def __init__(self):         
        self.restart()
        self.image=pygame.image.load('enemy.png').convert_alpha()  
    def move(self):            
        if self.y<798:
            self.y+=self.speed  
        else:
            self.restart()

class Plane:
    def restart(self):
        self.x=200
        self.y=600
    def __init__(self):
        self.restart()
        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(enemy,bullet):     #子弹碰撞飞机
    if(bullet.x>enemy.x and bullet.x<enemy.x+enemy.image.get_width())and\
    (bullet.y>enemy.y and bullet.y<enemy.y+enemy.image.get_height()):                  #如果子弹在敌机的范围内“碰撞检测”
        enemy.restart()         #重置敌机
        bullet.active=False     #重置子弹
        return True
    return False

def checkCrash(enemy,plane):    #敌机碰飞机
    if((enemy.x<plane.x+0.7*plane.image.get_width())and\
    (enemy.x+enemy.image.get_width()>plane.x+0.3*plane.image.get_width()))and\
    ((enemy.y<plane.y+0.7*plane.image.get_height())and\
    (enemy.y+enemy.image.get_height()>plane.x+0.3*plane.image.get_height())):
        return True
    return False

pygame.init()               
screen=pygame.display.set_mode((452,798),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                    #发射子弹的间隔
enemise=[]                      #创建5个Enemy的对象,把它们添加到一个叫做enemies的list中
for i in range(5):
    enemise.append(Enemy())
gameover=False
score=0                         #分数
font=pygame.font.Font(None,32)  #创建一个font对象,None表示使用默认字体,32是字号
   
while True:                                 
    for event in pygame.event.get():
        if event.type==pygame.QUIT:   
            pygame.quit()
            exit()
        if gameover and event.type==pygame.MOUSEBUTTONUP:#重置游戏
            plane.restart()
            for e in enemise:
                e.restart()
            for b in bullets:
                b.active=False
            score=0
            gameover=False
    screen.blit(background,(0,0))
    if not gameover:                #当gameover为False的时候,游戏逻辑才正常运行
        interval_b-=1               #发射间隔递减
        if interval_b<0:
            bullets[index_b].restart()
            interval_b=200          #重置间隔时间
            index_b=(index_b+1)%count_b#子弹序号周期性递增
        for b in bullets:
            if b.active:
                for e in enemise:
                    if checkHit(e,b):
                        score+=100
                b.move()
                screen.blit(b.image,(b.x,b.y))
        for e in enemise:
            if checkCrash(e,plane):          #如果撞上敌机,设gameover为True
                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))             #(0,0)是屏幕左上角的位置
    else:
        text=font.render("Score: %d" % score,1,(0,0,0))
        screen.blit(text,(180,383))             #屏幕中央显示分数
        pass   
    pygame.display.update()             #刷新一下画面

作者: crossin先生    时间: 2018-5-2 23:30
这种情况一般问题在 checkHit
把相关数值输出来检查,或者如果能画个方块出来就更直观了
作者: leopotter6    时间: 2018-5-4 10:08
crossin先生 发表于 2018-5-2 23:30
这种情况一般问题在 checkHit
把相关数值输出来检查,或者如果能画个方块出来就更直观了 ...

看哪些数值呢?画方块是什么意思?
作者: crossin先生    时间: 2018-5-4 15:01
leopotter6 发表于 2018-5-4 10:08
看哪些数值呢?画方块是什么意思?

checkHit 里涉及的所有数值
画方块就是在图像上可视化地显示这些数值的位置,不然的话你就自己在纸上比较下数值,看看为什么碰撞位置不对
作者: leopotter6    时间: 2018-5-4 20:04
crossin先生 发表于 2018-5-4 15:01
checkHit 里涉及的所有数值
画方块就是在图像上可视化地显示这些数值的位置,不然的话你就自己在纸上比较 ...

具体怎么可视化显示?
作者: leopotter6    时间: 2018-5-4 20:34
本帖最后由 leopotter6 于 2018-5-4 20:35 编辑
crossin先生 发表于 2018-5-4 15:01
checkHit 里涉及的所有数值
画方块就是在图像上可视化地显示这些数值的位置,不然的话你就自己在纸上比较 ...

解决了!
checkCrash里面有个参数写错了,改完之后就正常了。
但是,在对照论坛资源的时候,我发现资源里也有个参数有错误(只是相对于我的那个参数来说,资源里错误的参数对碰撞影响比较小)。

最后,我还是想知道管理员您说的可视化显示是怎么进行的,能给出代码吗?
python小白在此谢过!!!
作者: crossin先生    时间: 2018-5-5 15:30
leopotter6 发表于 2018-5-4 20:34
解决了!
checkCrash里面有个参数写错了,改完之后就正常了。
但是,在对照论坛资源的时候,我发现资源 ...

pygame.draw.rect
作者: wallker    时间: 2018-10-30 11:14
leopotter6 发表于 2018-5-4 20:34
解决了!
checkCrash里面有个参数写错了,改完之后就正常了。
但是,在对照论坛资源的时候,我发现资源 ...

请问改了哪个参数?为什么我运行你的代码,一下子就结束了??

作者: crossin先生    时间: 2018-10-30 13:06
wallker 发表于 2018-10-30 11:14
请问改了哪个参数?为什么我运行你的代码,一下子就结束了??

你可以公众号里回复  pygame
有完整示例代码下载




欢迎光临 Crossin的编程教室 (https://bbs.crossincode.com/) Powered by Discuz! X2.5