当我施法时,咒语会跟着我移动,而我不希望它跟着我移动。我正在寻找简单的解决方案,我觉得答案就在我的脸上,但我盯着它太久了。咒语会移动,但当我移动角色时,咒语会跟随玩家的方向,即使它离开了玩家的位置。完整的代码在
下面import pygame as py
import sys
from os import path
from settings import *
from sprites import *
from tilemap import *
#HUD
def draw_player_health(surf,x,y,pct):
if pct < 0:
pct = 0
BAR_LENGTH = 100
BAR_HEIGHT = 20
fill = pct * BAR_LENGTH
outline_rect = py.Rect(x,y,BAR_LENGTH,BAR_HEIGHT)
fill_rect = py.Rect(x, y, fill, BAR_HEIGHT)
if pct > 0.6:
color = GREEN
elif pct > 0.3:
color = YELLOW
else:
color = RED
py.draw.rect(surf,color,fill_rect)
py.draw.rect(surf, BLACK, outline_rect, 2)
class Game:
def __init__(self):
py.init()
self.screen = py.display.set_mode((WIDTH, HEIGHT))
py.display.set_caption(TITLE)
self.clock = py.time.Clock()
self.load_data()
def load_data(self):
game_folder = path.dirname(__file__)
self.map = Map(path.join(game_folder, 'imgmap.txt'))
self.player_spritesheet = SpriteSheet('img/player_sheet1.png')
self.wall_spritesheet = SpriteSheet('img/woodwall.png')
self.terrain_spritesheet = SpriteSheet('img/grasstexture.jpg')
self.mob_spritesheet = SpriteSheet('imgmobsheet.png')
self.spell_spritesheet = SpriteSheet('imgspellsheethm.png')
def new(self):
# initialize all variables and do all the setup for a new game
self.all_sprites = py.sprite.LayeredUpdates()
self.walls = py.sprite.LayeredUpdates()
self.mobs = py.sprite.LayeredUpdates()
self.spell = py.sprite.LayeredUpdates()
#self.player = py.sprite.LayeredUpdates()
for row, tiles in enumerate(self.map.data):
for col, tile in enumerate(tiles):
Groundtile(self,col,row)
if tile == '1':
Wall(self, col, row)
if tile == 'P':
self.player = Player(self, col, row)
if tile == 'M':
Mobs(self, col, row)
self.camera = Camera(self.map.width, self.map.height)
def run(self):
# game loop - set self.playing = False to end the game
self.playing = True
while self.playing:
self.dt = self.clock.tick(FPS) / 1000
self.events()
self.update()
self.draw()
def quit(self):
py.quit()
sys.exit()
def update(self):
# update portion of the game loop
self.all_sprites.update()
self.camera.update(self.player)
def draw_grid(self):
for x in range(0, WIDTH, TILESIZE):
py.draw.line(self.screen, LIGHTGREY, (x, 0), (x, HEIGHT))
for y in range(0, HEIGHT, TILESIZE):
py.draw.line(self.screen, LIGHTGREY, (0, y), (WIDTH, y))
def draw(self):
self.screen.fill(BGCOLOR)
# self.draw_grid()
for sprite in self.all_sprites:
if isinstance(sprite, Mobs):
sprite.draw_health()
self.screen.blit(sprite.image, self.camera.apply(sprite))
#HUD
draw_player_health(self.screen,850, 10, self.player.health / PLAYER_HEALTH)
py.display.flip()
def events(self):
# catch all events here
for event in py.event.get():
if event.type == py.QUIT:
self.quit()
if event.type == py.KEYDOWN:
if event.key == py.K_ESCAPE:
self.quit()
if event.key == py.K_SPACE:
if self.player.facing == 'up':
Spells(self, self.player.rect.x, self.player.rect.y)
if self.player.facing == 'down':
Spells(self, self.player.rect.x, self.player.rect.y)
if self.player.facing == 'left':
Spells(self, self.player.rect.x, self.player.rect.y)
if self.player.facing == 'right':
Spells(self, self.player.rect.x, self.player.rect.y)
def show_start_screen(self):
pass
def show_go_screen(self):
pass
# create the game object
g = Game()
g.show_start_screen()
while True:
g.new()
g.run()
g.show_go_screen()
if self.y_change == 0:
self.image = self.game.player_spritesheet.get_sprite(2, 71, self.width,self.height)
else:
self.image = up_animations[math.floor(self.animate_loop)]
self.animate_loop += 0.1
if self.animate_loop >= 4:
self.animate_loop = 1
if self.facing == "right":
if self.x_change == 0:
self.image = self.game.player_spritesheet.get_sprite(6, 37, self.width,self.height)
else:
self.image = right_animations[math.floor(self.animate_loop)]
self.animate_loop += 0.1
if self.animate_loop >= 4:
self.animate_loop = 1
if self.facing == "left":
if self.x_change == 0:
self.image = self.game.player_spritesheet.get_sprite(7, 180, self.width,self.height)
else:
self.image = left_animations[math.floor(self.animate_loop)]
self.animate_loop += 0.1
if self.animate_loop >= 4:
self.animate_loop = 1
def mob_collide(self):
hits = py.sprite.spritecollide(self.game.player,self.game.mobs, False)
for hit in hits:
self.health -= MOB_DMG
def update(self):
self.get_keys()
self.animation()
self.mob_collide()
self.rect.x += self.x_change
self.collide_with_walls('x')
self.rect.y += self.y_change
self.collide_with_walls('y')
self.x_change = 0
self.y_change = 0
if self.health <= 0:
self.kill()
class Mobs(py.sprite.Sprite):
def __init__(self, game, x, y):
self.game = game
self._layer = MOB_LAYER
self.groups = self.game.all_sprites, self.game.mobs
py.sprite.Sprite.__init__(self, self.groups)
self.x = x * TILESIZE
self.y = y * TILESIZE
self.width = TILESIZE
self.height = TILESIZE
self.facing = random.choice(['up','down','left','right'])
self.animate_loop = 1
self.movement_loop = 0
self.max_travel = random.randint(0,200)
self.x_change = 0
self.y_change = 0
self.image = self.game.mob_spritesheet.get_sprite(0,11,self.width,self.height)
self.image.set_colorkey(WHITE)
self.rect = self.image.get_rect()
self.rect.x = self.x
self.rect.y = self.y
self.health = MOB_HEALTH
def update(self):
self.movement()
self.animation()
self.rect.x += self.x_change
self.collide_with_walls('x')
self.rect.y += self.y_change
self.collide_with_walls('y')
self.x_change = 0
self.y_change = 0
if self.health <= 0:
self.kill()
#self.player_collide()
def draw_health(self):
if self.health > 60:
color = GREEN
elif self.health > 30:
color = YELLOW
else:
color = RED
width = int(self.rect.width * self.health / MOB_HEALTH)
self.health_bar = py.Rect(0,0, width, 7)
if self.health < MOB_HEALTH:
py.draw.rect(self.image, color, self.health_bar)
def collide_with_walls(self, dir):
if dir == 'x':
hits = py.sprite.spritecollide(self, self.game.walls, False)
if hits:
if self.x_change > 0:
self.x = hits[0].rect.left - self.rect.width
if self.x_change < 0:
self.x = hits[0].rect.right
self.x_change = 0
self.rect.x = self.x
if dir == 'y':
hits = py.sprite.spritecollide(self, self.game.walls, False)
if hits:
if self.y_change > 0:
self.y = hits[0].rect.top - self.rect.height
if self.y_change < 0:
self.y = hits[0].rect.bottom
self.y_change = 0
self.rect.y = self.y
def movement(self):
if self.facing == 'left':
self.x_change -= MOB_SPEED
self.movement_loop -= 1
if self.movement_loop <= -self.max_travel:
self.facing = 'right'
if self.facing == 'right':
self.x_change += MOB_SPEED
self.movement_loop += 1
if self.movement_loop >= self.max_travel:
self.facing = 'left'
if self.facing == 'up':
self.y_change -= MOB_SPEED
self.movement_loop -= 1
if self.movement_loop <= -self.max_travel:
self.facing = 'down'
if self.facing == 'down':
self.y_change += MOB_SPEED
self.movement_loop += 1
if self.movement_loop >= self.max_travel:
self.facing = 'up'
def animation(self):
down_animations = [self.game.mob_spritesheet.get_sprite(0, 11, self.width, self.height),
self.game.mob_spritesheet.get_sprite(33, 11, self.width, self.height),
self.game.mob_spritesheet.get_sprite(65, 11, self.width, self.height)]
up_animations = [self.game.mob_spritesheet.get_sprite(2, 218, self.width, self.height),
self.game.mob_spritesheet.get_sprite(33, 218, self.width, self.height),
self.game.mob_spritesheet.get_sprite(65, 218, self.width, self.height)]
left_animations = [self.game.mob_spritesheet.get_sprite(3, 70, self.width, self.height),
self.game.mob_spritesheet.get_sprite(35, 70, self.width, self.height),
self.game.mob_spritesheet.get_sprite(67, 70, self.width, self.height)]
right_animations = [self.game.mob_spritesheet.get_sprite(3, 130, self.width, self.height),
self.game.mob_spritesheet.get_sprite(35, 130, self.width, self.height),
self.game.mob_spritesheet.get_sprite(67, 130, self.width, self.height)]
if self.facing == "down":
if self.y_change == 0:
self.image = self.game.mob_spritesheet.get_sprite(2, 1, self.width,self.height)
else:
self.image = down_animations[math.floor(self.animate_loop)]
self.animate_loop += 0.1
if self.animate_loop >= 3:
self.animate_loop = 1
if self.facing == "up":
if self.y_change == 0:
self.image = self.game.mob_spritesheet.get_sprite(2, 71, self.width,self.height)
else:
self.image = up_animations[math.floor(self.animate_loop)]
self.animate_loop += 0.1
if self.animate_loop >= 3:
self.animate_loop = 1
if self.facing == "right":
if self.x_change == 0:
self.image = self.game.mob_spritesheet.get_sprite(6, 37, self.width,self.height)
else:
self.image = right_animations[math.floor(self.animate_loop)]
self.animate_loop += 0.1
if self.animate_loop >= 3:
self.animate_loop = 1
if self.facing == "left":
if self.x_change == 0:
self.image = self.game.mob_spritesheet.get_sprite(7, 180, self.width,self.height)
else:
self.image = left_animations[math.floor(self.animate_loop)]
self.animate_loop += 0.1
if self.animate_loop >= 3:
self.animate_loop = 1
class Spells(py.sprite.Sprite):
def __init__(self, game,x,y):
self.game = game
self._layer = SPELL_LAYER
self.groups = self.game.all_sprites, self.game.spell
py.sprite.Sprite.__init__(self, self.groups)
self.x = x
self.y = y
self.width = TILESIZE
self.height = TILESIZE
self.movement_loop = 0
self.shoodir = 'down'
self.animate_loop = 0
# self.spawn_time = py.time.get_ticks()
self.image = self.game.spell_spritesheet.get_sprite(4,14,self.width,self.height)
self.image.set_colorkey(WHITE)
self.x_change = 0
self.y_change = 0
self.rect = self.image.get_rect()
self.rect.x = self.x
self.rect.y = self.y
def update(self):
self.animate()
self.collide()
self.rect.x += self.x_change
self.collide_with_walls('x')
self.rect.y += self.y_change
self.collide_with_walls('y')
self.x_change = 0
self.y_change = 0
self.movement()
#if py.time.get_ticks() - self.spawn_time > SPELL_LIFETIME:
# self.kill()
def collide(self):
hits = py.sprite.groupcollide(self.game.mobs,self.game.spell, False, True)
for hit in hits:
hit.health -= SPELL_DMG
def collide_with_walls(self, dir):
if dir == 'x':
hits = py.sprite.spritecollide(self, self.game.walls, False)
if hits:
if self.x_change > 0:
self.x = hits[0].rect.left - self.rect.width
self.kill()
if self.x_change < 0:
self.x = hits[0].rect.right
self.kill()
self.x_change = 0
self.rect.x = self.x
if dir == 'y':
hits = py.sprite.spritecollide(self, self.game.walls, False)
if hits:
if self.y_change > 0:
self.y = hits[0].rect.top - self.rect.height
self.kill()
if self.y_change < 0:
self.y = hits[0].rect.bottom
self.kill()
self.y_change = 0
self.rect.y = self.y
def animate(self):
direction = self.game.player.facing
down_animations = [self.game.spell_spritesheet.get_sprite(0, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(35, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(67, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(98, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(128, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(158, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(190, 0, self.width, self.height)]
up_animations = [self.game.spell_spritesheet.get_sprite(0, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(35, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(67, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(98, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(128, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(158, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(190, 0, self.width, self.height)]
left_animations = [self.game.spell_spritesheet.get_sprite(0, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(35, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(67, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(98, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(128, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(158, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(190, 0, self.width, self.height)]
right_animations = [self.game.spell_spritesheet.get_sprite(0, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(35, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(67, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(98, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(128, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(158, 0, self.width, self.height),
self.game.spell_spritesheet.get_sprite(190, 0, self.width, self.height)]
if direction == 'up':
self.image = up_animations[math.floor(self.animate_loop)]
self.animate_loop += 0.5
if self.animate_loop >= 7:
self.animate_loop = 1
if direction == 'down':
self.image = down_animations[math.floor(self.animate_loop)]
self.animate_loop += 0.5
if self.animate_loop >= 7:
#self.kill()
self.animate_loop = 1
if direction == 'left':
self.image = left_animations[math.floor(self.animate_loop)]
self.animate_loop += 0.5
if self.animate_loop >= 7:
#self.kill()
self.animate_loop = 1
if direction == 'right':
self.image = right_animations[math.floor(self.animate_loop)]
self.animate_loop += 0.5
if self.animate_loop >= 7:
#self.kill()
self.animate_loop = 1
def movement(self):
direction = self.game.player.facing
if direction == 'left':
self.shoodir = 'left'
self.x_change -= SPELL_SPEED
self.movement_loop -= 1
if self.movement_loop == -SPELL_LIFETIME:
self.kill()
if direction == 'right':
self.shoodir = 'right'
self.x_change += SPELL_SPEED
self.movement_loop += 1
if self.movement_loop == SPELL_LIFETIME:
self.kill()
if direction == 'up':
self.shoodir = 'up'
self.y_change -= SPELL_SPEED
self.movement_loop -= 1
if self.movement_loop == -SPELL_LIFETIME:
self.kill()
if direction == 'down':
self.shoodir = 'down'
self.y_change += SPELL_SPEED
self.movement_loop += 1
if self.movement_loop == SPELL_LIFETIME:
self.kill()
class Wall(py.sprite.Sprite):
def __init__(self, game, x, y):
self.game = game
self._layer = BLOCK_LAYER
self.groups = self.game.all_sprites, self.game.walls
py.sprite.Sprite.__init__(self, self.groups)
self.x = x * TILESIZE
self.y = y * TILESIZE
self.width = TILESIZE
self.height = TILESIZE
self.image = self.game.wall_spritesheet.get_sprite(0,0,self.width,self.height)
self.rect = self.image.get_rect()
self.rect.x = self.x
self.rect.y = self.y
def update(self):
self.rect.x += self.x_change
self.rect.y += self.y_change
self.x_change = 0
self.y_change = 0
class Groundtile(py.sprite.Sprite):
def __init__(self, game, x , y):
self.game = game
self._layer = GROUND_LAYER
self.groups = self.game.all_sprites
py.sprite.Sprite.__init__(self, self.groups)
self.x = x * TILESIZE
self.y = y * TILESIZE
self.width = TILESIZE
self.height = TILESIZE
self.image = self.game.terrain_spritesheet.get_sprite(0,0,self.width,self.height)
self.rect = self.image.get_rect()
self.rect.x = self.x
self.rect.y = self.y
import pygame as py
from settings import *
def collide_hit_rect(one, two):
return one.hit_rect.colliderect(two.rect)
class Map:
def __init__(self, filename):
self.data = []
with open(filename, 'rt') as f:
for line in f:
self.data.append(line.strip())
self.tilewidth = len(self.data[0])
self.tileheight = len(self.data)
self.width = self.tilewidth * TILESIZE
self.height = self.tileheight * TILESIZE
class Camera:
def __init__(self, width, height):
self.camera = py.Rect(0, 0, width, height)
self.width = width
self.height = height
def apply(self, entity):
return entity.rect.move(self.camera.topleft)
def update(self, target):
x = -target.rect.x + int(WIDTH / 2)
y = -target.rect.y + int(HEIGHT / 2)
# limit scrolling to map size
x = min(0, x) # left
y = min(0, y) # top
x = max(-(self.width - WIDTH), x) # right
y = max(-(self.height - HEIGHT), y) # bottom
self.camera = py.Rect(x, y, self.width, self.height)
///////SETTINGS FILE//////////
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
DARKGREY = (40, 40, 40)
LIGHTGREY = (100, 100, 100)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
# game settings
WIDTH = 1024 # 16 * 64 or 32 * 32 or 64 * 16
HEIGHT = 768 # 16 * 48 or 32 * 24 or 64 * 12
FPS = 60
TITLE = "ZomBlaster"
BGCOLOR = DARKGREY
TILESIZE = 32
GRIDWIDTH = WIDTH / TILESIZE
GRIDHEIGHT = HEIGHT / TILESIZE
# Player settings
PLAYER_SPEED = 3
PLAYER_HEALTH = 10000
#Loading Layers
PLAYER_LAYER = 4
MOB_LAYER = 3
BLOCK_LAYER = 2
GROUND_LAYER = 1
SPELL_LAYER = 4
#Mob settings
MOB_HEALTH = 100
MOB_SPEED = 1
MOB_DMG = 10
MOB_KNOCKBACK = 2
#Spell settings
SPELL_IMG1 = ''
SPELL_SPEED = 5
SPELL_LIFETIME = 2000
SPELL_RATE = 10
SPELL_DMG = 10
def animate(self):
direction = self.game.player.facing
def movement(self):
direction = self.game.player.facing
这几行代码似乎根据每次"动画"时角色的方向来修改咒语的方向。或";movement"方法被调用
我快速浏览了一下代码,寻找"game.player"的定义。但我想我可能错过了它,然而,我做了一个假设,这是你的问题所指的游戏的玩家。
因为玩家的方向会改变你的方向,所以你修改了"shootdir"如果你的法术,以及动画,额外的逻辑等
我可能会建议在你的类构造函数中使用一个额外的变量,其基本方向是不能通过你的方法修改的。如:
class Spells(py.sprite.Sprite):
def __init__(self, game,x,y, direction):
self.game = game
self._layer = SPELL_LAYER
self.groups = self.game.all_sprites, self.game.spell
self.direction = direction
py.sprite.Sprite.__init__(self, self.groups)
并这样命名:
def events(self):
# catch all events here
for event in py.event.get():
if event.type == py.QUIT:
self.quit()
if event.type == py.KEYDOWN:
if event.key == py.K_ESCAPE:
self.quit()
if event.key == py.K_SPACE:
if self.player.facing == 'up':
Spells(self, self.player.rect.x, self.player.rect.y,
self.player.facing)
if self.player.facing == 'down':
Spells(self, self.player.rect.x, self.player.rect.y,
self.player.facing)
if self.player.facing == 'left':
Spells(self, self.player.rect.x, self.player.rect.y,
self.player.facing)
if self.player.facing == 'right':
Spells(self, self.player.rect.x, self.player.rect.y,
self.player.facing)
你应该添加设置文件,精灵,磁贴图,使人们更容易调试,否则你必须缩小当前的代码文件