关于python pygame convert()以及convert_alpha()函数怎么理解.. 怎样查看pygame中提供的函数

作者&投稿:望厘 (若有异议请与网页底部的电邮联系)
convert函数作用是将图片转化为Surface对象,pygame现在会自动这么做,不用你去写;convert_alpha相对于convert,保留了图像的Alpha 通道信息,这个你可以去百度一下,可以认为是保留了透明的部分,这样图片才可以是不规则的。

一样的,没什么区别,有些东西不用去纠结,浪费时间

convert_alpha可支持透明
convert不支持

透明转换

帮忙看下这段pygame的碰撞检测有什么问题?~

你这排版看的我脑阔疼……
百度有现成的代码框不用= =
关键问题是这里
class Ball(pygame.sprite.Sprite): def __init__(self,image,position,speed,bg_size): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load(image).convert_alpha() self.rect = self.image.get_rect() self.speedx,self.speedy = speed self.rect.x,self.rect.y= position self.rect.width,self.rect.height=bg_size[0],bg_size[1] #<-don't change the object 'rect'!首先你需要明确bg_size是干什么的
通过观察代码 很容易理解bg_size是窗体的大小(也就是背景的大小)
再根据Ball对象的move方法中有关出界反弹的代码可以得知:bg_size是用来判定球是否有击打到边界的。
但是在代码中,你却对self.rect对象进行了操作,这就不对了
首先,rect是什么?他是储存位置、大小等信息的对象,在Ball中,self.rect.width指的就是球的宽度。
再看到碰撞判定函数:
def collide_check(item,target): col_balls=[] for each in target: distance = math.sqrt(math.pow((item.rect.center[0]-each.rect.center[0]),2)+math.pow((item.rect.center[1]-each.rect.center[1]),2)) if distance <=(item.rect.width+each.rect.width)/2: col_balls.append(each)很明显,是否碰撞是根据object.rect.width来判定的
你把object.rect.width设置为了bg_size(也就是1600),他当然认为时刻都在碰撞
所以对Ball类修改如下:
class Ball(pygame.sprite.Sprite): def __init__(self,image,position,speed,bg_size): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load(image).convert_alpha() self.rect = self.image.get_rect() self.speedx,self.speedy = speed self.rect.x,self.rect.y= position self.width,self.height=bg_size[0],bg_size[1] def move(self): self.rect = self.rect.move(self.speedx,self.speedy) if self.rect.xself.width-250: self.speedx = -self.speedx elif self.rect.y self.height-250: self.speedy = -self.speedy这里我们直接给Ball的对象新建两个属性,一个是width,一个是height,让他们来实现move方法中的“打到墙壁就反弹”功能,同时不改变Rect对象的width值,让碰撞检测函数能够正常运行。
(完整代码在最后)
另外你的代码中还有一些小错误或者不到位的地方
比如这里:
ball_num = 5 for i in range(ball_num): position=randint(0,width-250),randint(0,height-250) speed = randint(-10,10),randint(-10,10) ball = Ball(ball_image,position,speed,bg_size) balls.append(ball)这里生成的求都是完全随机位置的,如果两个球生成的时候恰好重叠(虽然概率只有千分之width,但是也是有可能的),那么他们就会一直在原地鬼畜。
(两个卡在一起的小球,这里因为没有小球的资源,我自己做了一张正方形的方块来代替小球)
解决方案就是每次生成新球的时候判断一下这个位置是否已经有球了,判定方法很简单,用现成的碰撞检测函数collide_check就行了
第二个就是碰撞函数
碰撞函数的功能就是告知是否有球和他碰撞,至少在目前的功能中,我们不需要知道有哪些球和他碰撞,那么我们可以直接在检测到碰撞以后返回True或者False就行了,每次全部遍历完,又要返回一个列表,相比之下效率很低。
改成这样即可:
def collide_check(item,target): for each in target: distance = math.sqrt(math.pow((item.rect.center[0]-each.rect.center[0]),2)+math.pow((item.rect.center[1]-each.rect.center[1]),2)) if distance <=(item.rect.width+each.rect.width)/2: return True第三个就是某些网络教程的遗传病,不知道从哪里传出来的教程,现在很多人学pygame的时候退出就简单的写一个sys.exit(),然而发现游戏是停下来了,窗口还在那里,怎么关也关不掉。
那是当然,你pygame都没退出,窗口怎么能被关。
在sys.exit()上一行加一句
pygame.quit()
完整代码:
import pygameimport sysfrom pygame.locals import *from random import *import mathclass Ball(pygame.sprite.Sprite): def __init__(self,image,position,speed,bg_size): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load(image).convert_alpha() self.rect = self.image.get_rect() self.speedx,self.speedy = speed self.rect.x,self.rect.y= position self.width,self.height=bg_size[0],bg_size[1] def move(self): self.rect = self.rect.move(self.speedx,self.speedy) if self.rect.xself.width-250: self.speedx = -self.speedx elif self.rect.y self.height-250: self.speedy = -self.speedydef collide_check(item,target): for each in target: distance = math.sqrt(math.pow((item.rect.center[0]-each.rect.center[0]),2)+math.pow((item.rect.center[1]-each.rect.center[1]),2)) if distance <=(item.rect.width+each.rect.width)/2: #print(distance,(item.rect.width+each.rect.width)/2) return Truedef main(): pygame.init() ball_image = "qipao.png" bg_image = "bg.jpg" running = True bg_size = width,height = 1600,900 screen = pygame.display.set_mode(bg_size) pygame.display.set_caption('hello') background = pygame.image.load(bg_image).convert_alpha() balls = [] ball_num = 5 i = 0 while i < ball_num: i += 1 position=randint(0,width-250),randint(0,height-250) speed = randint(-10,10),randint(-10,10) ball = Ball(ball_image,position,speed,bg_size) if collide_check(ball, balls): #already a ball i -= 1 continue balls.append(ball) clock = pygame.time.Clock() while running: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() screen.fill((0,0,0)) screen.blit(background,(0,0)) for each in balls: each.move() screen.blit(each.image,each.rect) for i in range(ball_num): item = balls.pop(i) if collide_check(item,balls): item.speedx=-item.speedx item.speedy=-item.speedy balls.insert(i,item) pygame.display.flip() clock.tick(60)if __name__ == "__main__": main()另外我把你的clock.tick(144)改成了60,我觉得144fps太高了,因为这种模型中,逻辑帧=显示帧,过高的fps会导致小球移动速度过快(而且因为pygame的tick本质上还是简单延时,过高的fps会导致帧率不稳定,进而带来游戏忽快忽慢的问题)

你想要运行教程中的示例,你至少需要在你的电脑上安装了以下一些:
Python
NumPy
这些是可能对你有帮助的:
ipython是一个净强化的交互Python Shell,对探索NumPy的特性非常方便。
matplotlib将允许你绘图
Scipy在NumPy的基础上提供了很多科学模块
基础篇
NumPy的主要对象是同种元素的多维数组。这是一个所有的元素都是一种类型、通过一个正整数元组索引的元素表格(通常是元素是数字)。在NumPy中维度(dimensions)叫做轴(axes),轴的个数叫做秩(rank)。
例如,在3D空间一个点的坐标[1, 2, 3]是一个秩为1的数组