日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

vpython 贞测碰撞_7、Pygame碰撞检测

發(fā)布時(shí)間:2024/10/8 python 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vpython 贞测碰撞_7、Pygame碰撞检测 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文目標(biāo)

1,本章我們繼續(xù)學(xué)習(xí)使用sprite木塊,來實(shí)現(xiàn)我們游戲當(dāng)中的碰撞檢測

2,完成游戲?qū)嵗?#xff1a;吃蘋果小游戲

Pygame模塊的Sprite碰撞檢測

下面是幾種常見的碰撞檢測以及實(shí)現(xiàn)代碼。

1.兩個(gè)精靈之間的矩形檢測

在只有兩個(gè)精靈的時(shí)候我們可以使用pygame.sprite.collide_rect()函數(shù)來進(jìn)行一對(duì)一的沖突檢測。這個(gè)函數(shù)需要傳遞2個(gè)參數(shù),并且每個(gè)參數(shù)都是需要繼承自pygame.sprite.Sprite。

舉個(gè)例子:

Python

spirte_1 = MySprite("sprite_1.png",200,200,1)

sprite_2 = MySprite("sprite_2.png",50,50,1)

result = pygame.sprite.collide_rect(sprite_1,sprite_2)

if result:

print("Collision occurred")

1

2

3

4

5

spirte_1=MySprite("sprite_1.png",200,200,1)

sprite_2=MySprite("sprite_2.png",50,50,1)

result=pygame.sprite.collide_rect(sprite_1,sprite_2)

ifresult:

print("Collision occurred")

MySprite使我們上個(gè)博客中創(chuàng)建的類,他繼承自sprite。

Hint:這個(gè)函數(shù)還有一個(gè)非常有用的變體:pygame.sprite.collide_rect_ratio()。這個(gè)函數(shù)需要一個(gè)額外的浮點(diǎn)類型的參數(shù)。這個(gè)參數(shù)用來指定檢測矩形的百分比。

有的時(shí)候我們希望沖突檢測更精準(zhǔn)一些的話,就可以收縮檢測的區(qū)域,讓矩形更小一些,就是通過這個(gè)參數(shù)控制的。使用方法如下:

Python

result = pygame.sprite.collide_rect_ratio( 0.5 )(sprite_1,sprite_2)

1

result=pygame.sprite.collide_rect_ratio(0.5)(sprite_1,sprite_2)

2.兩個(gè)精靈之間的圓檢測

矩形沖突檢測并不適用于所有形狀的精靈,因此pygame中還有個(gè)圓形沖突檢測。pygame.sprite.collide_circle(),這個(gè)函數(shù)是基于每個(gè)精靈的半徑值來進(jìn)行檢測的。

你可以自己指定半徑,或者讓函數(shù)自己計(jì)算半徑。

Python

result = pygame.sprite.collide_circle(sprite_1,sprite_2)

if result:

print "Collision occurred"

1

2

3

result=pygame.sprite.collide_circle(sprite_1,sprite_2)

ifresult:

print"Collision occurred"

這個(gè)函數(shù)也有一個(gè)變體:pygame.sprite.collide_circle_ratio()。函數(shù)的功能和用法和上面的pygame.sprite.collide_rect_ratio()是類似的。

3.兩個(gè)精靈之間的像素遮罩檢測

如果矩形檢測和圓形檢測都不能滿足我們的需求怎么辦?別擔(dān)心,pygame還為我們提供了一個(gè)更加精確的檢測:pygame.sprite.collide_mask()。

這個(gè)函數(shù)接收兩個(gè)精靈作為參數(shù),返回值是一個(gè)bool變量。

Python

if pygame.sprite.collide_mask(sprite_1,sprite_2):

print ("Collision occurred")

1

2

ifpygame.sprite.collide_mask(sprite_1,sprite_2):

print("Collision occurred")

4.精靈和組之間的矩形沖突檢測

Python

pygame.sprite.spritecollide(sprite,sprite_group,bool)。

1

pygame.sprite.spritecollide(sprite,sprite_group,bool)。

調(diào)用這個(gè)函數(shù)的時(shí)候,一個(gè)組中的所有精靈都會(huì)逐個(gè)地對(duì)另外一個(gè)單個(gè)精靈進(jìn)行沖突檢測,發(fā)生沖突的精靈會(huì)作為一個(gè)列表返回。

這個(gè)函數(shù)的第一個(gè)參數(shù)就是單個(gè)精靈,第二個(gè)參數(shù)是精靈組,第三個(gè)參數(shù)是一個(gè)bool值,最后這個(gè)參數(shù)起了很大的作用。當(dāng)為True的時(shí)候,會(huì)刪除組中所有沖突的精靈,False的時(shí)候不會(huì)刪除沖突的精靈

Python

list_collide = pygame.sprite.spritecollide(sprite,sprite_group,False);

1

list_collide=pygame.sprite.spritecollide(sprite,sprite_group,False);

另外這個(gè)函數(shù)也有一個(gè)變體:pygame.sprite.spritecollideany()。這個(gè)函數(shù)在判斷精靈組和單個(gè)精靈沖突的時(shí)候,會(huì)返回一個(gè)bool值。

5.精靈組之間的矩形沖突檢測

Python

pygame.sprite.groupcollide()。

1

pygame.sprite.groupcollide()。

利用這個(gè)函數(shù)可以檢測兩個(gè)組之間的沖突,他返回一個(gè)字典。(鍵-值對(duì))

游戲?qū)嵗蕴O果小游戲

先看一下效果圖:

游戲開始會(huì)在屏幕上隨機(jī)生成一些蘋果,玩家通過上下左右方向鍵來控制人物去吃蘋果。

吃到一個(gè)蘋果,能量條就會(huì)增長一些,直到吃完所有的蘋果,游戲結(jié)束。

【源代碼+素材下載地址】

1.模塊化編程

這個(gè)游戲會(huì)使用到我們上個(gè)博客創(chuàng)建的MySprite類,為了讓這個(gè)類變的更具有可重用性,我們將它做成一個(gè)模塊。

只要將類的實(shí)現(xiàn)代碼放進(jìn)一個(gè)單獨(dú)的py,然后在使用的時(shí)候引入他就可以了。比如我們將這個(gè)單獨(dú)的py取名為:MyLibrary.py

Python

import MyLibrary

1

importMyLibrary

這樣在使用這個(gè)模塊里面的函數(shù)和類的時(shí)候我們只需要這樣做:MyLibrary.fun()。但是這樣看起來也不是很方便的說,因此我們使用import的變體:

Python

from MyLibrary import *

#將文件中的所有內(nèi)容引入

1

2

fromMyLibraryimport*

#將文件中的所有內(nèi)容引入

2.高級(jí)行走動(dòng)畫

通過效果圖,我們可以看到程序里面用到了高級(jí)的行走動(dòng)畫,人物一共有上下左右四個(gè)方向的行走動(dòng)畫。

實(shí)際上這個(gè)精靈序列圖里面一共有8個(gè)方向的行走動(dòng)畫,為了簡便,我們只是使用了其中的四方向,如圖:

通過行的數(shù)目就可以來方便的區(qū)分,動(dòng)畫是向左走還是向右走的。現(xiàn)在說起來可能有點(diǎn)比較難以理解,看完下面的代碼就比較好理解了。我們還為Mysprite這個(gè)類增加了一個(gè)velocity屬性,以便精靈可以根據(jù)其方向來移動(dòng)。

Python

class MySprite(pygame.sprite.Sprite):

def __init__(self):

pygame.sprite.Sprite.__init__(self)

self.master_image = None

self.frame = 0

self.old_frame = -1

self.frame_width = 1

self.frame_height = 1

self.first_frame = 0

self.last_frame = 0

self.columns = 1

self.last_time = 0

self.direction = 0

#新增了velocity屬性,他是一個(gè)point

self.velocity = Point(0.0,0.0)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

classMySprite(pygame.sprite.Sprite):

def__init__(self):

pygame.sprite.Sprite.__init__(self)

self.master_image=None

self.frame=0

self.old_frame=-1

self.frame_width=1

self.frame_height=1

self.first_frame=0

self.last_frame=0

self.columns=1

self.last_time=0

self.direction=0

#新增了velocity屬性,他是一個(gè)point

self.velocity=Point(0.0,0.0)

當(dāng)按UP鍵的時(shí)候,將方向設(shè)置為0(向上),按DOWN鍵的時(shí)候,將方向設(shè)置為4(向下),按LEFT鍵,將方向設(shè)置為6(向左),按RIGHT鍵,將方向設(shè)置為2(向右)

Python

if keys[K_ESCAPE]: sys.exit()

elif keys[K_UP] or keys[K_w]:

player.direction = 0

player_moving = True

elif keys[K_RIGHT] or keys[K_d]:

player.direction = 2

player_moving = True

elif keys[K_DOWN] or keys[K_s]:

player.direction = 4

player_moving = True

elif keys[K_LEFT] or keys[K_a]:

player.direction = 6

player_moving = True

1

2

3

4

5

6

7

8

9

10

11

12

13

ifkeys[K_ESCAPE]:sys.exit()

elifkeys[K_UP]orkeys[K_w]:

player.direction=0

player_moving=True

elifkeys[K_RIGHT]orkeys[K_d]:

player.direction=2

player_moving=True

elifkeys[K_DOWN]orkeys[K_s]:

player.direction=4

player_moving=True

elifkeys[K_LEFT]orkeys[K_a]:

player.direction=6

player_moving=True

這個(gè)方向就是我們之前說的用來決定使用動(dòng)畫幀的范圍方法。并且還有一個(gè)player_moving變量,在按鍵按下的時(shí)候?qū)⑺脼門rue,也就是按鍵按下的時(shí)候才會(huì)有行走動(dòng)畫,否則人物將會(huì)是靜止的。

3.判斷人物與蘋果的沖突

為了獲得更精準(zhǔn)的沖突,我們組合使用了不同的沖突函數(shù)。

首先用pygame.sprite.spritecollideany來判斷玩家是否與任意的蘋果產(chǎn)生了碰撞,如果產(chǎn)生碰撞,則再使用pygame.sprite.collide_circle_ratio縮小檢測范圍做一次檢測,

看看到底是哪個(gè)蘋果和人物產(chǎn)生了沖突,然后將產(chǎn)生碰撞的果實(shí)從精靈組中移除(remove)。

Python

#檢測玩家是否與食物沖突,是否吃到果實(shí)

attacker = None

attacker = pygame.sprite.spritecollideany(player, food_group)

if attacker != None:

if pygame.sprite.collide_circle_ratio(0.65)(player,attacker):

player_health +=2;

food_group.remove(attacker);

1

2

3

4

5

6

7

#檢測玩家是否與食物沖突,是否吃到果實(shí)

attacker=None

attacker=pygame.sprite.spritecollideany(player,food_group)

ifattacker!=None:

ifpygame.sprite.collide_circle_ratio(0.65)(player,attacker):

player_health+=2;

food_group.remove(attacker);

吃了果實(shí)以后,能量值會(huì)增加,然后我們通過繪制一個(gè)矩形的能量條來反映給用戶。

好了最后上一下全部的源代碼(不包含MyLibrary模塊):

Python

import itertools, sys, time, random, math, pygame

from pygame.locals import *

from MyLibrary import *

def calc_velocity(direction, vel=1.0):

velocity = Point(0,0)

if direction == 0: #上

velocity.y = -vel

elif direction == 2: #右

velocity.x = vel

elif direction == 4: #下

velocity.y = vel

elif direction == 6: #左

velocity.x = -vel

return velocity

pygame.init()

screen = pygame.display.set_mode((800,600))

pygame.display.set_caption("吃蘋果")

font = pygame.font.Font(None, 36)

timer = pygame.time.Clock()

#創(chuàng)建精靈組

player_group = pygame.sprite.Group()

food_group = pygame.sprite.Group()

#初始化玩家精靈組

player = MySprite()

player.load("farmer walk.png", 96, 96, 8)

player.position = 80, 80

player.direction = 4

player_group.add(player)

#初始化food精靈組

for n in range(1,50):

food = MySprite();

food.load("food_low.png", 35, 35, 1)

food.position = random.randint(0,780),random.randint(0,580)

food_group.add(food)

game_over = False

player_moving = False

player_health = 0

while True:

timer.tick(30)

ticks = pygame.time.get_ticks()

for event in pygame.event.get():

if event.type == QUIT:

pygame.quit()

sys.exit()

keys = pygame.key.get_pressed()

if keys[K_ESCAPE]: sys.exit()

elif keys[K_UP] or keys[K_w]:

player.direction = 0

player_moving = True

elif keys[K_RIGHT] or keys[K_d]:

player.direction = 2

player_moving = True

elif keys[K_DOWN] or keys[K_s]:

player.direction = 4

player_moving = True

elif keys[K_LEFT] or keys[K_a]:

player.direction = 6

player_moving = True

else:

player_moving = False

if not game_over:

#根據(jù)角色的不同方向,使用不同的動(dòng)畫幀

player.first_frame = player.direction * player.columns

player.last_frame = player.first_frame + player.columns-1

if player.frame < player.first_frame:

player.frame = player.first_frame

if not player_moving:

#當(dāng)停止按鍵(即人物停止移動(dòng)的時(shí)候),停止更新動(dòng)畫幀

player.frame = player.first_frame = player.last_frame

else:

player.velocity = calc_velocity(player.direction, 1.5)

player.velocity.x *= 1.5

player.velocity.y *= 1.5

#更新玩家精靈組

player_group.update(ticks, 50)

#移動(dòng)玩家

if player_moving:

player.X += player.velocity.x

player.Y += player.velocity.y

if player.X < 0: player.X = 0

elif player.X > 700: player.X = 700

if player.Y < 0: player.Y = 0

elif player.Y > 500: player.Y = 500

#檢測玩家是否與食物沖突,是否吃到果實(shí)

attacker = None

attacker = pygame.sprite.spritecollideany(player, food_group)

if attacker != None:

if pygame.sprite.collide_circle_ratio(0.65)(player,attacker):

player_health +=2;

food_group.remove(attacker);

if player_health > 100: player_health = 100

#更新食物精靈組

food_group.update(ticks, 50)

if len(food_group) == 0:

game_over = True

#清屏

screen.fill((50,50,100))

#繪制精靈

food_group.draw(screen)

player_group.draw(screen)

#繪制玩家血量條

pygame.draw.rect(screen, (50,150,50,180), Rect(300,570,player_health*2,25))

pygame.draw.rect(screen, (100,200,100,180), Rect(300,570,200,25), 2)

if game_over:

print_text(font, 300, 100, "G A M E O V E R")

pygame.display.update()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

importitertools,sys,time,random,math,pygame

frompygame.localsimport*

fromMyLibraryimport*

defcalc_velocity(direction,vel=1.0):

velocity=Point(0,0)

ifdirection==0:#上

velocity.y=-vel

elifdirection==2:#右

velocity.x=vel

elifdirection==4:#下

velocity.y=vel

elifdirection==6:#左

velocity.x=-vel

returnvelocity

pygame.init()

screen=pygame.display.set_mode((800,600))

pygame.display.set_caption("吃蘋果")

font=pygame.font.Font(None,36)

timer=pygame.time.Clock()

#創(chuàng)建精靈組

player_group=pygame.sprite.Group()

food_group=pygame.sprite.Group()

#初始化玩家精靈組

player=MySprite()

player.load("farmer walk.png",96,96,8)

player.position=80,80

player.direction=4

player_group.add(player)

#初始化food精靈組

forninrange(1,50):

food=MySprite();

food.load("food_low.png",35,35,1)

food.position=random.randint(0,780),random.randint(0,580)

food_group.add(food)

game_over=False

player_moving=False

player_health=0

whileTrue:

timer.tick(30)

ticks=pygame.time.get_ticks()

foreventinpygame.event.get():

ifevent.type==QUIT:

pygame.quit()

sys.exit()

keys=pygame.key.get_pressed()

ifkeys[K_ESCAPE]:sys.exit()

elifkeys[K_UP]orkeys[K_w]:

player.direction=0

player_moving=True

elifkeys[K_RIGHT]orkeys[K_d]:

player.direction=2

player_moving=True

elifkeys[K_DOWN]orkeys[K_s]:

player.direction=4

player_moving=True

elifkeys[K_LEFT]orkeys[K_a]:

player.direction=6

player_moving=True

else:

player_moving=False

ifnotgame_over:

#根據(jù)角色的不同方向,使用不同的動(dòng)畫幀

player.first_frame=player.direction*player.columns

player.last_frame=player.first_frame+player.columns-1

ifplayer.frame

player.frame=player.first_frame

ifnotplayer_moving:

#當(dāng)停止按鍵(即人物停止移動(dòng)的時(shí)候),停止更新動(dòng)畫幀

player.frame=player.first_frame=player.last_frame

else:

player.velocity=calc_velocity(player.direction,1.5)

player.velocity.x*=1.5

player.velocity.y*=1.5

#更新玩家精靈組

player_group.update(ticks,50)

#移動(dòng)玩家

ifplayer_moving:

player.X+=player.velocity.x

player.Y+=player.velocity.y

ifplayer.X<0:player.X=0

elifplayer.X>700:player.X=700

ifplayer.Y<0:player.Y=0

elifplayer.Y>500:player.Y=500

#檢測玩家是否與食物沖突,是否吃到果實(shí)

attacker=None

attacker=pygame.sprite.spritecollideany(player,food_group)

ifattacker!=None:

ifpygame.sprite.collide_circle_ratio(0.65)(player,attacker):

player_health+=2;

food_group.remove(attacker);

ifplayer_health>100:player_health=100

#更新食物精靈組

food_group.update(ticks,50)

iflen(food_group)==0:

game_over=True

#清屏

screen.fill((50,50,100))

#繪制精靈

food_group.draw(screen)

player_group.draw(screen)

#繪制玩家血量條

pygame.draw.rect(screen,(50,150,50,180),Rect(300,570,player_health*2,25))

pygame.draw.rect(screen,(100,200,100,180),Rect(300,570,200,25),2)

ifgame_over:

print_text(font,300,100,"G A M E?? O V E R")

pygame.display.update()

在下個(gè)博客里面我們將一起學(xué)習(xí)在游戲里面常用的一些數(shù)據(jù)結(jié)構(gòu): 數(shù)據(jù),列表,元組,隊(duì)列,棧。

總結(jié)

以上是生活随笔為你收集整理的vpython 贞测碰撞_7、Pygame碰撞检测的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。