Pygame collision interaction

牧云@^-^@ 提交于 2019-12-13 05:11:27

问题


Here is my code:

import pygame, sys
from pygame.locals import * 

try:
    import Android
except ImportError:
    Android = None

try:
   import pygame.mixer as mixer
except ImportError:
    import android.mixer as mixer    

pygame.init()

#Android to cross platform

if Android:
    android.init()
    android.map_key(android.KEYCODE_BACK, pygame.K_ESCAPE)

#Variables

score = 0
health = 100


#Colours

RED = (255 ,0 ,0)
BLACK = (0, 0, 0)

# Left Edge of rectangle, top, width, height
player_rect = pygame.Rect(540, 0, 32, 32)
enemy = pygame.image.load("monster.png")

size = width, height = 1276,650
screen = pygame.display.set_mode(size)

direction ="down"  

# This is the score text
gamefont = pygame.font.Font(None, 30)
scoretext = gamefont.render('Player Score: '+ str(score), 2, [255,0,0])
boxsize=scoretext.get_rect()
scoreXpos=(width-boxsize[2])/2  
scoreYpos=(height-boxsize[2])/2  
screen.blit(scoretext, [scoreXpos,20])

# This is the health 
gamefonts = pygame.font.Font(None, 30) 
scoretexts = gamefonts.render('Player Health: '+ str(health), 2, [255,0,0])
boxsizes=scoretexts.get_rect()
scoreXposs=(width-boxsizes[2])/2 
scoreYposs=(height-boxsizes[2])/2  
screen.blit(scoretexts, [scoreXposs,20])

PAUSED = False
font = pygame.font.SysFont("serif", 72)
text_paused = font.render("PAUSED", True, (255, 0, 0))


sound = mixer.Sound('maintheme.ogg')
sound.play()


r = 0
bif = pygame.image.load("map5.png") 
pygame.display.set_caption("Pygame 2D RPG !")
x,y=0,0
movex, movey=0,0
character="boy.png"
player=pygame.image.load(character).convert_alpha()

while True:

# --- events ---

for event in pygame.event.get():

    if event.type == pygame.QUIT:
        pygame.quit()
        sys.exit()

    if event.type==KEYDOWN:
        if event.key == K_ESCAPE:
            pygame.quit()
            sys.exit()
        elif event.key==K_q:
            PAUSED = not PAUSED

    if not PAUSED:
        if event.type==KEYDOWN:
            if event.key==K_a:
                movex=-10
            elif event.key==K_d:
                movex=+10
            elif event.key==K_w:
                movey=-10
            elif event.key==K_s:
                movey=+10
        if event.type==KEYUP:
            if event.key==K_a:
                movex=0
            elif event.key==K_d:
                movex=0
            elif event.key==K_w:
                movey=0
            elif event.key==K_s:
                movey=0
# Enemy 
if direction == "down":
        player_rect.centery += 1
elif direction == "up":
        player_rect.centery -= 1  

if player_rect.bottom > size[1]:
    direction = "up"
if player_rect.top < 0:
    direction = "down"                   

if not PAUSED:
    x+=movex
    y+=movey   
    print x,y
if x in range(680,702) and y in range(377,403):  # This is the location of the tile.
    bif = pygame.image.load("map6.png")
screen.fill((r,0,0))
screen.blit(bif,(0,0))
screen.blit(player,(x,y))
screen.blit(enemy, player_rect)
#pygame.draw.rect(screen, RED, player_rect) 

screen.blit(scoretexts, [scoreYposs, 45])
scoretexts = gamefonts.render('Player Health: '+ str(health), 2, [25,25,112])
#health +=10


screen.blit(scoretext, [scoreYpos,70])
scoretext = gamefont.render('Player Score: '+ str(score), 2, [25,25,112])
#score +=10   

if PAUSED:
    screen.blit(text_paused, (100, 100))    

pygame.display.update() 

Now I was wondering if anybody knows how to do collision, for example is the player boy is touching the enemy monster then the health which is draw to the screen goes down. Thaks for your help!


回答1:


It is code from my answer to another question on stackoverflow with some modification made later.

I have collision detection here but it is not ideal.

Look for pygame.sprite.collide_rect(self.ball, self.player1)

It use rectangle area to detect collision

More collision detect functions on PyGame Sprite (rectangle, circle, with mask)

(move player1 (keys: W/S) or player2 (keys: ARROWS UP/DOWN) to make collision with ball)


ps.: player and ball required self.rect (pygame.Rect()) with position (self.rect.x, self.rect.y) and size (self.rect.width, self.rect.height) to can be used with pygame.sprite.collide_rect(). If you use PyGame Sprite to create player class (class Player(pygame.sprite.Sprite):) you don't have to create self.rect because Sprite already has self.rect - but you still have to change self.rect.x and self.rect.y as you move player.


import sys

import pygame
from pygame.locals import *

#----------------------------------------------------------------------

UP   = 1
DOWN = 2 

#----------------------------------------------------------------------

class Player():

    def __init__(self, screen, x, y):

        self.screen = screen

        self.rect = pygame.Rect(0,0,0,0)

        self.image = pygame.image.load('player.png')

        self.rect.size = self.image.get_size()

        self.rect.center = (x, y)

        self.speed_x = 0
        self.speed_y = 15

        self.direction = None

    def draw(self):
        self.screen.blit(self.image,(self.rect.x,self.rect.y))

    def move(self):
        if self.direction:
            if self.direction == UP :
                self.rect.y -= self.speed_y
                if self.rect.y < 0 :
                    self.rect.y = 0
            elif self.direction == DOWN :
                self.rect.y += self.speed_y
                if self.rect.y > self.screen.get_size()[1] - self.rect.height :
                    self.rect.y = self.screen.get_size()[1] - self.rect.height

#----------------------------------------------------------------------

class Ball():

    def __init__(self, screen, x, y):

        self.screen = screen

        self.rect = pygame.Rect(0,0,0,0)

        self.image = pygame.image.load('ball.png')

        self.rect.size = self.image.get_size()

        self.rect.center = (x, y)

        self.speed_x = 15
        self.speed_y = 15

    def draw(self):
        self.screen.blit(self.image,(self.rect.x,self.rect.y))

    def move(self):
        self.rect.x += self.speed_x
        self.rect.y += self.speed_y

        if self.rect.left < 0 or self.rect.right > self.screen.get_size()[0]:
            self.speed_x = -self.speed_x
        if self.rect.top < 0 or self.rect.bottom > self.screen.get_size()[1]:
            self.speed_y = -self.speed_y

#----------------------------------------------------------------------

class Game():

    def __init__(self):

        self.FPS = 25

        pygame.init()


        self.fpsClock = pygame.time.Clock()

        self.background = pygame.image.load('background.jpg')
        self.size = self.width, self.height = self.background.get_size()

        self.screen = pygame.display.set_mode(self.size,0,32)

        self.ball = Ball(self.screen, 100, 100)

        self.player1 = Player(self.screen, 35, self.height/2)
        self.player2 = Player(self.screen, self.width-35, self.height/2)

        print self.screen.get_rect().center


        font = pygame.font.SysFont("", 72)

        self.text_paused = font.render("PAUSE", True, (255, 0, 0))

        print self.text_paused.get_rect()

        screen_rect = self.screen.get_rect()
        self.text_rect = self.text_paused.get_rect()
        self.text_rect.center = screen_rect.center

        print self.text_rect

    def run(self):

        RUNNING = True

        PAUSED = False
        while RUNNING:

            # --- events ---

            for event in pygame.event.get():
                if event.type==QUIT:
                    RUNNING = False

                if event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        RUNNING = False
                    elif event.key == K_SPACE:
                        PAUSED = not PAUSED
                    elif not PAUSED:
                        if event.key == K_w:
                            self.player1.direction = UP
                        elif event.key == K_s:
                            self.player1.direction = DOWN
                        elif event.key == K_UP:
                            self.player2.direction = UP
                        elif event.key == K_DOWN:
                            self.player2.direction = DOWN

                if event.type == KEYUP:
                    if not PAUSED:
                        if event.key in (K_w, K_s):
                            self.player1.direction = None
                        elif event.key in (K_UP, K_DOWN):
                            self.player2.direction = None

            # --- recalculations ---

            if not PAUSED:      
                self.player1.move()
                self.player2.move()
                self.ball.move()

            #~ print self.ball.get_rect()

            if pygame.sprite.collide_rect(self.ball, self.player1):
                self.ball.speed_x = -self.ball.speed_x

            if pygame.sprite.collide_rect(self.ball, self.player2):
                self.ball.speed_x = -self.ball.speed_x

            # --- drawing ---

            self.screen.blit(self.background,(0,0))
            self.player1.draw()
            self.player2.draw()
            self.ball.draw()

            if PAUSED:

                self.screen.blit(self.text_paused, self.text_rect.topleft)

            pygame.display.update()

            # --- FPS ---

            self.fpsClock.tick(self.FPS)

        # --- finish ---

        pygame.quit()
        sys.exit()

#----------------------------------------------------------------------

Game().run()

Screenshot


Images used in game:

ball.png

player.png

background.jpg



来源:https://stackoverflow.com/questions/19823805/pygame-collision-interaction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!