所以我为烟雾制作了一个粒子引擎,我对此非常满意,我认为它非常适合我的游戏。
我现在需要将它实现到我的游戏中,但我遇到了一些麻烦。我想知道是否有人可以解释我将如何在我的游戏中使用我的粒子引擎。
我在下面添加了我的代码(用于烟雾和我的游戏文件)。
我想将粒子与游戏文件分开,但在我的游戏中调用它。
最终,我想在引擎中制作更多我也可以调用的粒子效果。
有人可以帮忙吗?它可能需要一些调整才能工作。
颗粒代码:
import pygame,random
from pygame.locals import *
xmax = 1000 #width of window
ymax = 600 #height of window
class Smoke():
def __init__(self, startx, starty, col):
self.x = startx
self.y = random.randint(0, starty)
self.col = col
self.sx = startx
self.sy = starty
def move(self):
if self.y < 0:
self.x = self.sx
self.y = self.sy
else:
self.y -= 1
self.x += random.randint(-1, 2)
def main():
pygame.init()
screen = pygame.display.set_mode((xmax,ymax))
black = (0,0,0)
grey = (145,145,145)
light_grey = (192,192,192)
dark_grey = (183, 183, 183)
clock = pygame.time.Clock()
particles = []
for part in range(600):
if part % 2 > 0: col = grey
#elif part % 5 > 0: col = dark_grey
elif part % 3 > 0: col = dark_grey
else: col = light_grey
particles.append( Smoke(0, 500, col) )
exitflag = False
while not exitflag:
for event in pygame.event.get():
if event.type == QUIT:
exitflag = True
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
exitflag = True
screen.fill(black)
for p in particles:
p.move()
pygame.draw.circle(screen, p.col, (p.x, p.y), 15)
pygame.display.flip()
clock.tick(80)
pygame.quit()
if __name__ == "__main__":
main()
游戏代码
import pygame
from pygame import *
WIN_WIDTH = 1120 - 320
WIN_HEIGHT = 960 - 320
HALF_WIDTH = int(WIN_WIDTH / 2)
HALF_HEIGHT = int(WIN_HEIGHT / 2)
DISPLAY = (WIN_WIDTH, WIN_HEIGHT)
DEPTH = 0
FLAGS = 0
CAMERA_SLACK = 30
levels = {0: {'level': [
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" E ",
" PPPPPPPPPPPPPPPP",
" PPPPPPPPPPPPPPPP",
" PPPPPPPPPPPPPPPP",
" PPPPP PPPPPPPPPPPPPPPP",
" PPPPPPPPPPPPPPPP",
" PPPP P",
" PPPP P",
" PPPP PPPPPPP",
" PPPPPPPPPP PPPPPPP",
" PPPP PPPPPPP",
" PPPP PPPP PPPPPPP",
" PPPP PPPPPPP",
" PPPP PPPPPPP",
" PPPP PPPPPPP",
"PPPPP PPPP PPPPPPP",
"PPP PPPP PPPPPPP",
"PPP PPPP PPPPPPP",
"PPP PPPP PPPPPPP",
"PPP PPPPP PPPP PPPPPPP",
"PPP PPPP",
"PPP PPPP",
"PPP PPPP",
"PPP PPPPPPPPPPPPPPPPPP",
"PPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",],
'enemies': [(9, 38)]},
1: {'level': [
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" E ",
" PPPPPPPPPPPPPPPP",
" PPPPPPPPPPPPPPPP",
" PPPPPPPPPPPPPPPP",
" PPPPP PPPPPPPPPPPPPPPP",
" PPPPPPPPPPPPPPPP",
" PPPP P",
" PPPP P",
" PPPP PPPPPPP",
" PPPPPPPPPP PPPPPPP",
" PPPP PPPPPPP",
" PPPP PPPP PPPPPPP",
" PPPP PPPPPPP",
" PPPP PPPPPPP",
" PPPP PPPPPPP",
"PPPPP PPPP PPPPPPP",
"PPP PPPPPPPPPPP PPPPPPP",
"PPP PPPP PPPPPPP",
"PPP PPPP PPPPPPP",
"PPP PPPPPPPP PPPP PPPPPPP",
"PPP PPPP",
"PPP PPPP",
"PPP PPPPP PPPP",
"PPP P PPPPPPPPPPPPPPPPPP",
"PPP P PPPPPPPPPPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",
"PPPPPPPPPPPPPPP PPPPPPPPPPPPPPPPPP",],
'enemies': [(9, 38), (18, 38), (15, 15)]}}
class Scene(object):
def __init__(self):
pass
def render(self, screen):
raise NotImplementedError
def update(self):
raise NotImplementedError
def handle_events(self, events):
raise NotImplementedError
class GameScene(Scene):
def __init__(self, levelno):
super(GameScene, self).__init__()
self.bg = Surface((32,32))
self.bg.convert()
self.bg.fill(Color("#0094FF"))
up = left = right = False
self.entities = pygame.sprite.Group()
self.player = Player(5, 40)
self.player.scene = self
self.platforms = []
self.levelno = levelno
levelinfo = levels[levelno]
self.enemies = [Enemy(*pos) for pos in levelinfo['enemies']]
level = levelinfo['level']
total_level_width = len(level[0]) * 32
total_level_height = len(level) * 32
# build the level
x = 0
y = 0
for row in level:
for col in row:
if col == "P":
p = Platform(x, y)
self.platforms.append(p)
self.entities.add(p)
if col == "E":
e = ExitBlock(x, y)
self.platforms.append(e)
self.entities.add(e)
x += 32
y += 32
x = 0
self.camera = Camera(complex_camera, total_level_width, total_level_height)
self.entities.add(self.player)
for e in self.enemies:
self.entities.add(e)
def render(self, screen):
for y in range(20):
for x in range(25):
screen.blit(self.bg, (x * 32, y * 32))
for e in self.entities:
screen.blit(e.image, self.camera.apply(e))
def update(self):
pressed = pygame.key.get_pressed()
up, left, right = [pressed[key] for key in (K_UP, K_LEFT, K_RIGHT)]
self.player.update(up, left, right, self.platforms)
for e in self.enemies:
e.update(self.platforms)
self.camera.update(self.player)
def exit(self):
if self.levelno+1 in levels:
self.manager.go_to(GameScene(self.levelno+1))
else:
self.manager.go_to(CustomScene("You win!"))
def die(self):
self.manager.go_to(CustomScene("You lose!"))
def handle_events(self, events):
for e in events:
if e.type == KEYDOWN and e.key == K_ESCAPE:
self.manager.go_to(TitleScene())
class CustomScene(object):
def __init__(self, text):
self.text = text
super(CustomScene, self).__init__()
self.font = pygame.font.SysFont('Arial', 56)
def render(self, screen):
# ugly!
screen.fill((0, 200, 0))
text1 = self.font.render(self.text, True, (255, 255, 255))
screen.blit(text1, (200, 50))
def update(self):
pass
def handle_events(self, events):
for e in events:
if e.type == KEYDOWN:
self.manager.go_to(TitleScene())
class TitleScene(object):
def __init__(self):
super(TitleScene, self).__init__()
self.font = pygame.font.SysFont('Arial', 56)
self.sfont = pygame.font.SysFont('Arial', 32)
def render(self, screen):
# ugly!
screen.fill((0, 200, 0))
text1 = self.font.render('Crazy Game', True, (255, 255, 255))
text2 = self.sfont.render('> press space to start <', True, (255, 255, 255))
screen.blit(text1, (200, 50))
screen.blit(text2, (200, 350))
def update(self):
pass
def handle_events(self, events):
for e in events:
if e.type == KEYDOWN and e.key == K_SPACE:
self.manager.go_to(GameScene(0))
class SceneMananger(object):
def __init__(self):
self.go_to(TitleScene())
def go_to(self, scene):
self.scene = scene
self.scene.manager = self
def main():
pygame.init()
screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
pygame.display.set_caption("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
timer = pygame.time.Clock()
running = True
manager = SceneMananger()
while running:
timer.tick(60)
if pygame.event.get(QUIT):
running = False
return
manager.scene.handle_events(pygame.event.get())
manager.scene.update()
manager.scene.render(screen)
pygame.display.flip()
class Camera(object):
def __init__(self, camera_func, width, height):
self.camera_func = camera_func
self.state = Rect(0, 0, width, height)
def apply(self, target):
try:
return target.rect.move(self.state.topleft)
except AttributeError:
return map(sum, zip(target, self.state.topleft))
def update(self, target):
self.state = self.camera_func(self.state, target.rect)
def complex_camera(camera, target_rect):
l, t, _, _ = target_rect
_, _, w, h = camera
l, t, _, _ = -l + HALF_WIDTH, -t +HALF_HEIGHT, w, h
l = min(0, l) # stop scrolling left
l = max(-(camera.width - WIN_WIDTH), l) # stop scrolling right
t = max(-(camera.height-WIN_HEIGHT), t) # stop scrolling bottom
return Rect(l, t, w, h)
class Entity(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
class Player(Entity):
def __init__(self, x, y):
Entity.__init__(self)
self.xvel = 0
self.yvel = 0
self.onGround = False
self.image = Surface((32,32))
self.image.fill(Color("#0000FF"))
self.image.convert()
self.rect = Rect(x*32, y*32, 32, 32)
def update(self, up, left, right, platforms):
if self.rect.top > 1440 or self.rect.top < 0:
self.scene.die()
if self.rect.left > 1408 or self.rect.right < 0:
self.scene.die()
if up:
if self.onGround:
self.yvel = 0
self.yvel -= 10 # only jump if on the ground
if left:
self.xvel = -10
if right:
self.xvel = 10
if not self.onGround:
self.yvel += 0.3 # only accelerate with gravity if in the air
if self.yvel > 80: self.yvel = 80 # max falling speed
if not(left or right):
self.xvel = 0
self.rect.left += self.xvel # increment in x direction
if self.collide(self.xvel, 0, platforms): # do x-axis collisions
self.rect.top += self.yvel # increment in y direction
self.onGround = False; # assuming we're in the air
self.collide(0, self.yvel, platforms) # do y-axis collisions
def collide(self, xvel, yvel, platforms):
for p in platforms:
if pygame.sprite.collide_rect(self, p):
if isinstance(p, ExitBlock):
self.scene.exit()
return False
if xvel > 0: self.rect.right = p.rect.left
if xvel < 0: self.rect.left = p.rect.right
if yvel > 0:
self.rect.bottom = p.rect.top
self.onGround = True
if yvel < 0:
self.rect.top = p.rect.bottom
return True
class Enemy(Entity):
def __init__(self, x, y):
Entity.__init__(self)
self.yVel = 0
self.xVel = 2 # start moving immediately
self.image = Surface((32,32))
self.image.fill(Color("#00FF00"))
self.image.convert()
self.rect = Rect(x*32, y*32, 32, 32)
self.onGround = False
def update(self, platforms):
if not self.onGround:
self.yVel += 0.3
# no need for right_dis to be a member of the class,
# since we know we are moving right if self.xVel > 0
right_dis = self.xVel > 0
# create a point at our left (or right) feet
# to check if we reached the end of the platform
m = (1, 1) if right_dis else (-1, 1)
p = self.rect.bottomright if right_dis else self.rect.bottomleft
fp = map(sum, zip(m, p))
# if there's no platform in front of us, change the direction
collide = any(p for p in platforms if p.rect.collidepoint(fp))
if not collide:
self.xVel *= -1
self.rect.left += self.xVel # increment in x direction
self.collide(self.xVel, 0, platforms) # do x-axis collisions
self.rect.top += self.yVel # increment in y direction
self.onGround = False; # assuming we're in the air
self.collide(0, self.yVel, platforms) # do y-axis collisions
def collide(self, xVel, yVel, platforms):
for p in platforms:
if pygame.sprite.collide_rect(self, p):
if xVel > 0:
self.rect.right = p.rect.left
self.xVel *= -1 # hit wall, so change direction
if xVel < 0:
self.rect.left = p.rect.right
self.xVel *= -1 # hit wall, so change direction
if yVel > 0:
self.rect.bottom = p.rect.top
self.onGround = True
if yVel < 0:
self.rect.top = p.rect.bottom
class Platform(Entity):
def __init__(self, x, y):
Entity.__init__(self)
#self.image = Surface([32, 32], pygame.SRCALPHA, 32) #makes blocks invisible for much better artwork
self.image = Surface((32,32)) #makes blocks visible for building levels
self.image.convert()
self.rect = Rect(x, y, 32, 32)
def update(self):
pass
class ExitBlock(Platform):
def __init__(self, x, y):
Platform.__init__(self, x, y)
self.image = Surface((32,32)) #makes blocks visible for building levels
self.image.convert()
self.rect = Rect(x, y, 32, 32)
if __name__ == "__main__":
main()