【发布时间】:2013-12-08 05:01:50
【问题描述】:
所以我有这些敌人,它们应该像旧街机游戏 RoboTron 中那样吞噬玩家。
问题是,只有几个敌人会追捕玩家,而其他人则只是站在周围,可能或更多的敌人会追捕玩家。这是怎么回事?
这是移动敌人的代码:
class Beetle(pygame.sprite.Sprite):
'''class that builds up the player class'''
x_speed = 0
y_speed = 0
#Beetle construction stuff (images, goes here)
.
.
.
def speedChange(self,x,y):
self.x_speed += x
self.y_speed += y
def move_towards_player(self, player):
#contains the beetle to the screen
self.rect.clamp_ip(screen_rect)
# find normalized direction vector (dx, dy) between enemy and player
dx, dy = self.rect.x - player.rect.x, self.rect.y - player.rect.y
dist = math.hypot(dx, dy)
if dist == 0: #prevents a divide by zero erro
dist = 1
else:
dx, dy = dx / dist, dy / dist
# move along this normalized vector towards the player at current speed
self.rect.x += dx * self.x_speed
self.rect.y += dy * self.y_speed
while done == False:
while beetleCount < 10:
beetle = Beetle() #make a beetle
random1 = randint(0, width -1 ) #make random positions for the beetle
random2 = randint(0, height - 1)
beetle.rect.x = random1 #make new random nums
beetle.rect.y = random2
beetle_list.add(beetle) #add beetle to list
all_sprites_list.add(beetle)
beetleCount += 1 #increment count'''
for bug in beetle_list:
random1 = randint(-1, 1)
if random1 != 0:
random2 = randint(-1, 1)
else:
random2 = 0
bug.speedChange(random1, random2)
bug.move_towards_player(player)
以下是完整代码,供参考:
import pygame
import math
from pygame import K_SPACE
from random import randint
#Define some colors
black = (0,0,0)
white = (255,255,255)
magenta = (255,0,255)
darkOrange = (28, 44, 64)
pygame.init()
#beetleCount
beetleCount = 0
#set the width and height of the screen
width = 800
height = 400
size = [width,height]
mainScreen = pygame.display.set_mode(size)
#make a rectangle of the screen size. This is for keeping
#the moving non-player objects in bounds
screen_rect = pygame.Rect((0,0), (width,height))
#set the window title
pygame.display.set_caption("My Game")
#Loop until the user clicks the close button.
done = False
#clock that is used to manage how fast the screen updates
clock = pygame.time.Clock()
#list of all the sprites in the game
all_sprites_list = pygame.sprite.Group()
#sounds in the game that are played
gunshot = pygame.mixer.Sound("gunshot.ogg")
beetleDie = pygame.mixer.Sound("orc_die.ogg")
pygame.mixer.music.load("DeadCity.ogg")
pygame.mixer.music.play(-1)
#Functions VVV
def sprite_sheet_load(colorKey, spriteLocX, spriteLocY, spriteSizeX, spriteSizeY, fileName):
'''purpose: to extract a sprite from a sprite sheet at the choosen location'''
'''credit to StackOverFlow User hammyThePig for original concept.'''
sheet = pygame.image.load(fileName).convert()#loads up the sprite sheet.
sheet.set_colorkey(colorKey) #set the color key
#grabs the sprite at the given location
sprite = sheet.subsurface(pygame.Rect(spriteLocX, spriteLocY, spriteSizeX, spriteSizeY))
#returns the sprite to where ever it was called
return sprite
##Functions! ^^^
#classes VV
class Player(pygame.sprite.Sprite):
'''class that builds up the player class'''
x_speed = 0
y_speed = 0
imageIndex = 0
playerImagesUp = [] #lists for the player images
playerImagesDown = [] #lists for the player images
playerImagesLeft = [] #lists for the player images
playerImagesRight = [] #lists for the player images
playerDeathImages = [] # ""
#constructor function
def __init__(self):#create a self variable to refer to the object
#call up the pygame sprite constructor
pygame.sprite.Sprite.__init__(self)
#get the first row of the sprite sheet (moving up)
spriteXLoc = 15
spriteYLoc = 15
spriteXSize = 34
spriteYSize = 47
for x in range(0,9):
self.playerImagesUp.append(sprite_sheet_load(white, spriteXLoc, spriteYLoc, spriteXSize, spriteYSize, "mainCharacter.png"))
spriteXLoc += 64
#get the second row (moving left)
spriteXLoc = 15
spriteYLoc = 78
spriteXSize = 34
spriteYSize = 48
for x in range(0,9):
self.playerImagesLeft.append(sprite_sheet_load(white, spriteXLoc, spriteYLoc, spriteXSize, spriteYSize, "mainCharacter.png"))
spriteXLoc += 65
#get the third row (moving down)
spriteXLoc = 15
spriteYLoc = 143
spriteXSize = 33
spriteYSize = 49
for x in range(0,9):
self.playerImagesDown.append(sprite_sheet_load(white, spriteXLoc, spriteYLoc, spriteXSize, spriteYSize, "mainCharacter.png"))
spriteXLoc += 64
#get the fourth row (moving right)
spriteXLoc = 15
spriteYLoc = 207
spriteXSize = 34
spriteYSize = 48
for x in range(0,9):
self.playerImagesRight.append(sprite_sheet_load(white, spriteXLoc, spriteYLoc, spriteXSize, spriteYSize, "mainCharacter.png"))
spriteXLoc += 65
self.image = self.playerImagesDown[0]
self.rect = self.image.get_rect()
def speedChange(self,x,y):
'''adjust the player speed'''
self.x_speed += x
self.y_speed += y
def update(self):
'''animate and move the player'''
#move the character according to the speed it's moving
#self.rect.x += self.x_speed
#self.rect.y += self.y_speed
self.rect.move_ip(self.x_speed,self.y_speed)
if self.y_speed < 0: #if the player is moving up
self.image = self.playerImagesUp[self.imageIndex]
self.imageIndex += 1
if self.imageIndex >= len(self.playerImagesUp):
self.imageIndex = 0
if self.y_speed > 0: #if the player is moving down
self.image = self.playerImagesDown[self.imageIndex]
self.imageIndex += 1
if self.imageIndex >= len(self.playerImagesDown):
self.imageIndex = 0
if self.x_speed > 0: #if the player is moving right
self.image = self.playerImagesRight[self.imageIndex]
self.imageIndex += 1
if self.imageIndex >= len(self.playerImagesRight):
self.imageIndex = 0
if self.x_speed < 0: #if the player is moving left
self.image = self.playerImagesLeft[self.imageIndex]
self.imageIndex += 1
if self.imageIndex >= len(self.playerImagesLeft):
self.imageIndex = 0
class Bullet(pygame.sprite.Sprite):
'''class the builds up the bullets that the player shoots'''
#constructor function
def __init__(self):
#call up the parent's constructor
pygame.sprite.Sprite.__init__(self)
#set the size of the bullet
self.image = img = pygame.image.load("bullet.png").convert()
self.rect = self.image.get_rect()
def move_bullet(self):
'''function tells the bullet what direction to go into'''
bulletSpeed=25
bulletDirection = 'down'
if self.bulletDirection =='left':#if the player is facing left
bullet.rect.x -= bulletSpeed #bullet will go in this direction at that speed
elif self.bulletDirection == 'right': #if the player is facing right
bullet.rect.x += bulletSpeed
elif self.bulletDirection == 'down': #if the player is facing down
bullet.rect.y += bulletSpeed
elif self.bulletDirection == 'up': #if the player if facing up
bullet.rect.y -=bulletSpeed
class Beetle(pygame.sprite.Sprite):
'''class that builds up the player class'''
x_speed = 0
y_speed = 0
imageIndex = 0
BeetleImagesDown = [] #lists for the beetle images
BeetleImagesUp = [] #lists for the beetle images
BeetleImagesLeft = [] #lists for the beetle images
BeetleImagesRight = [] #lists for the beetle images
#constructor function
def __init__(self): #create a self variable to refer to the object
#call up the parent's constructor
pygame.sprite.Sprite.__init__(self)
spriteXLoc=11
spriteYLoc=14
spriteXSize=30
spriteYSize=30
for x in range (0,5):
self.BeetleImagesDown.append(sprite_sheet_load(magenta,spriteXLoc,spriteYLoc,spriteXSize,spriteYSize, "beetle.png"))
spriteXLoc + 49
spriteXLoc=12
spriteYLoc=65
spriteXSize=28
spriteYSize=31
for x in range (0,5):
self.BeetleImagesUp.append(sprite_sheet_load(magenta,spriteXLoc,spriteYLoc,spriteXSize,spriteYSize,"beetle.png"))
spriteXLoc + 49
spriteXLoc=8
spriteYLoc=120
spriteXSize=35
spriteYSize=24
for x in range (0,5):
self.BeetleImagesRight.append(sprite_sheet_load(magenta,spriteXLoc,spriteYLoc,spriteXSize,spriteYSize,"beetle.png"))
spriteXLoc + 49
spriteXLoc=9
spriteYLoc=171
spriteXSize=36
spriteYSize=22
for x in range (0,5):
self.BeetleImagesLeft.append(sprite_sheet_load(magenta,spriteXLoc,spriteYLoc,spriteXSize,spriteYSize,"beetle.png"))
spriteXLoc + 49
self.image = self.BeetleImagesUp[0]
self.rect = self.image.get_rect()
def speedChange(self,x,y):
self.x_speed += x
self.y_speed += y
def update(self):
#moves the beetle
self.rect.move_ip(self.x_speed,self.y_speed)
#contains the beetle to the screen
self.rect.clamp_ip(screen_rect)
if self.y_speed < 0: #if the beetle is moving up
self.image = self.BeetleImagesUp[self.imageIndex]
self.imageIndex += 1
if self.imageIndex >= len(self.BeetleImagesUp):
self.imageIndex = 0
if self.y_speed > 0: #if the beetle is moving down
self.image = self.BeetleImagesDown[self.imageIndex]
self.imageIndex += 1
if self.imageIndex >= len(self.BeetleImagesDown):
self.imageIndex = 0
if self.x_speed > 0: #if the beetle is moving right
self.image = self.BeetleImagesRight[self.imageIndex]
self.imageIndex += 1
if self.imageIndex >= len(self.BeetleImagesRight):
self.imageIndex = 0
if self.x_speed < 0: #if the beetle is moving left
self.image = self.BeetleImagesLeft[self.imageIndex]
self.imageIndex += 1
if self.imageIndex >= len(self.BeetleImagesLeft):
self.imageIndex = 0
def move_towards_player(self, player):
#contains the beetle to the screen
self.rect.clamp_ip(screen_rect)
# find normalized direction vector (dx, dy) between enemy and player
dx, dy = self.rect.x - player.rect.x, self.rect.y - player.rect.y
dist = math.hypot(dx, dy)
if dist == 0: #prevents a divide by zero erro
dist = 1
else:
dx, dy = dx / dist, dy / dist
# move along this normalized vector towards the player at current speed
self.rect.x += dx * self.x_speed
self.rect.y += dy * self.y_speed
##classes ^^
player = Player()
player.rect.x = 350
player.rect.y = 225
#list of all the bullets in the game
bullet_list = []
#default value to what direction the player is facing
faceWhatDirection = 'down'
all_sprites_list.add(player) #add player to list of objects
beetle_list = pygame.sprite.Group() #list of beetles in the game
# add the beetle list to list of objects
all_sprites_list.add(beetle_list)
###Main Program Loop
##NOTE: WATCH WHAT YOU ARE PUTTING IN THE LOOPS! EASY WAY TO GET A BUG!
while done == False:
#Event processing! --------------------------
for event in pygame.event.get(): #User did something
if event.type == pygame.QUIT: #if user clicked close
done = True #flag that we are done so we exit this loop
elif event.type == pygame.KEYDOWN:
if event.key ==pygame.K_LEFT:
player.speedChange(-3,0)
#player.animate()
faceWhatDirection = 'left'
elif event.key == pygame.K_RIGHT:
player.speedChange(3,0)
#player.animate()
faceWhatDirection = 'right'
elif event.key ==pygame.K_UP:
player.speedChange(0,-3)
#player.animate()
faceWhatDirection = 'up'
elif event.key ==pygame.K_DOWN:
player.speedChange(0,3)
#player.animate()
faceWhatDirection = 'down'
elif event.key == pygame.K_SPACE:
gunshot.play()
bullet = Bullet()
bullet_list.append(bullet)#adds the bullet to the bullet list
all_sprites_list.add(bullet)#adds the bullet to the sprite list
#put the bullet in same location as player
bullet.rect.x = player.rect.x
#add in a plus 15 so bullet doesn't spawn in player's face
bullet.rect.y = player.rect.y + 15
bullet.bulletDirection = faceWhatDirection
#user let up on a key
elif event.type ==pygame.KEYUP:
#if it is an arrow key, reset speed back to zero.
if event.key ==pygame.K_LEFT:
player.speedChange(3,0)
elif event.key == pygame.K_RIGHT:
player.speedChange(-3,0)
elif event.key == pygame.K_UP:
player.speedChange(0,3)
elif event.key == pygame.K_DOWN:
player.speedChange(0,-3)
player.update() #moves the player around
#event processing ------------^^
#Game handling! -------------VV
##beetle moving code --------------------------
#make some beetles
while beetleCount < 10:
beetle = Beetle() #make a beetle
random1 = randint(0, width -1 ) #make random positions for the beetle
random2 = randint(0, height - 1)
beetle.rect.x = random1 #make new random nums
beetle.rect.y = random2
beetle_list.add(beetle) #add beetle to list
all_sprites_list.add(beetle)
beetleCount += 1 #increment count'''
for bug in beetle_list:
random1 = randint(-1, 1)
if random1 != 0:
random2 = randint(-1, 1)
else:
random2 = 0
bug.speedChange(random1, random2)
bug.move_towards_player(player)
#moves the bullets
for bullet in bullet_list:
bullet.move_bullet()
#see if the bullet left the screen
if bullet.rect.y > 400 or bullet.rect.y < 0:
all_sprites_list.remove(bullet)
elif bullet.rect.x > 800 or bullet.rect.x < 0:
all_sprites_list.remove(bullet)
#see if bullet hit the beetle
beetle_hit_list = pygame.sprite.spritecollide(bullet,beetle_list,False)
for beetle in beetle_hit_list:
#remove the bullet and beetle if hit
#bullet_list.remove(bullet) #delete the bullet
all_sprites_list.remove(bullet) #remove it from the universal list
all_sprites_list.remove(beetle) #get rid of the bettle from the universal list
beetle_list.remove(beetle) #get rid of it from the beetle list
beetleDie.play() #play the beetle death sound
#Game Handling! -------------^^
#Drawing code! --------------VVV
#clear the screen to a set color
#NOTE, putting any drawing commands above this will erase
#whatever you are trying to put there
mainScreen.fill(white)
#draw the sprites
all_sprites_list.draw(mainScreen)
#update screen on the regular
pygame.display.flip()
#Drawing code! -----------------^^
#limit game frames to 20 frames per second
clock.tick(20)
#quit the program when the loop is ended
pygame.quit()
【问题讨论】:
-
我想你的意思是
spriteXLoc += 49,而不是spriteXLoc + 49 -
感谢您的收获。拥有第二双眼睛总是好的。
-
不!我希望我能提供更多帮助!
标签: python python-2.7 pygame sprite game-physics