pygame实现雷电游戏雏形开发

本文实例为大家分享了pygame实现雷电游戏开发代码,供大家参考,具体内容如下

源代码:

stars.py

#-*- coding=utf-8 -*-

#!/usr/bin/python

import pygame

from pygame.locals import *

from random import randint

import math

class Star(object):

def __init__(self, x, y, speed, color=(255,255,255)):

self.x = x

self.y = y

self.speed = speed

self.color = color

class Stars(object):

'''

用于绘制星星背景

'''

def __init__(self, num = 0, SCREEN_SIZE=(800,600), color=(255,255,255)):

self.stars = []

self.MIN_SPEED = 10

self.MAX_SPEED = 300

self.SCREEN_SIZE = SCREEN_SIZE

if num > 0:

self.create_star(num, color)

def set_min_speed(self,speed):

self.MIN_SPEED = speed

def set_max_speed(self,speed):

self.MAX_SPEED = speed

def create_star(self,num = 1, color = (255,255,255)):

'''创建一个或多个星星,颜色可选'''

for i in xrange(0,num):

x = float(randint(0, self.SCREEN_SIZE[0]))

y = float(randint(0, self.SCREEN_SIZE[1]))

speed = float(randint(self.MIN_SPEED, self.MAX_SPEED))

self.stars.append( Star(x, y, speed, color) )

def move(self,time_passed_seconds):

'''移动星星并过滤'''

for star in self.stars:

star.y = star.y + time_passed_seconds * star.speed

#过滤跑出画面的星星

self.stars = filter(lambda one: one.y<=self.SCREEN_SIZE[1], self.stars)

def draw(self, surface):

'''将星星画到指定图像对象'''

for star in self.stars:

#pygame.draw.aaline(surface, star.color,\

# (star.x, star.y), (star.x+1., star.y))

surface.set_at((int(star.x),int(star.y)),star.color)

def test():

pygame.init()

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

stars = Stars()

#stars.set_max_speed(1000)

#stars.set_min_speed(300)

# 在第一帧,画上一些星星

stars.create_star(200)

clock = pygame.time.Clock()

white = (255, 255, 255)

while True:

for event in pygame.event.get():

if event.type == QUIT:

return

if event.type == KEYDOWN:

return

time_passed = clock.tick(30)

time_passed_seconds = time_passed / 1000.

#update_background(stars, screen, time_passed_seconds)

# 增加一颗新的星星

stars.create_star(1)

stars.move(time_passed_seconds)

screen.fill((0, 0, 0))

# 绘制所有的星

stars.draw(screen)

pygame.display.update()

if __name__ == "__main__":

test()

game.py

#-*- coding=utf-8 -*-

#!/usr/bin/python

import pygame

from pygame.locals import *

from random import randint

#from gameobjects import vector2

import math

import time

SCREEN_RECT = pygame.Rect(0,0,800,600)

class Player(pygame.sprite.Sprite):

'''玩家类'''

speed = 10

images = []

def __init__(self):

pygame.sprite.Sprite.__init__(self, self.containers)

self.image = Player.images[0]

self.rect = self.image.get_rect(midbottom=SCREEN_RECT.midbottom)

self.health= 4

#self.time = 0

#self.reloading = False

#def update(self, time_passed_seconds=0.0): if not self.reloading: super(Player,self).update(time_passed_seconds) else: self.time += time_passed_seconds if self.time > 1.5: print self.time self.time = 0.0 self.reloading = False self.groups()[0].remove(self)

def move(self, directions):

'''移动,direction == 'up' or 'down' or 'left' or 'right' '''

for direction in directions:

if direction == 'up':

self.rect.move_ip(0, -1 * Player.speed)

elif direction == 'down':

self.rect.move_ip(0, 1 * Player.speed)

elif direction == 'left':

self.rect.move_ip(-1 * Player.speed, 0)

elif direction == 'right':

self.rect.move_ip(1 * Player.speed, 0)

else:

print 'argument error'

return None

self.rect.clamp_ip(SCREEN_RECT)

def shoted_and_live(self, harm):

'''被攻击处理,依然存活返回True,否则返回False'''

self.health -= harm

if self.health <= 0:

return False

else:

return True

def attack_pos(self):

return self.rect.x + self.rect.width / 2, self.rect.y

class Shot(pygame.sprite.Sprite):

'''通用子弹类'''

speed_tab = [ 13, 13, 26, 30 ]

#子弹攻击力表

harm_tab = [ 1, 2 , 3, 12]

images = []

#子弹大小表

shot_size = []

def __init__(self, pos, angle, id=1 ):

'''pos为射出位置

angle参数为子弹射出的方向角度,以12点钟方向为0度,逆时针增大'''

pygame.sprite.Sprite.__init__(self, self.containers)

self.id = id

self.angle = angle

self.speed = Shot.speed_tab[id-1]

self.harm = Shot.harm_tab[id-1]

self.image = pygame.transform.scale(Shot.images[id-1], Shot.shot_size[id-1])

self.image = pygame.transform.rotate(self.image, angle)

self.rect = self.image.get_rect(midbottom=pos)

def update(self,time_passed_seconds=0.0):

radian = self.angle / 180.0 * math.pi

self.rect.move_ip(math.sin(radian) * -self.speed,\

-self.speed * math.cos(radian) )

if self.rect.x+self.rect.width < 0 or\

self.rect.x > SCREEN_RECT.width or\

self.rect.y+self.rect.height < 0 or\

self.rect.y > SCREEN_RECT.height:

self.kill()

class AlienShot(Shot):

'''

敌方子弹类

为了对象分组专为敌人的子弹使用一个新类,并定制子弹射速

'''

def __init__(self, pos, angle, id=1, speed=20 ):

Shot.__init__(self, pos, angle, id)

self.speed = speed

def SectorShot(pos, shot_id):

'''扇形子弹的封装'''

Shot(pos, 0, shot_id)

Shot(pos, 15, shot_id)

Shot(pos, 30, shot_id)

Shot(pos, 45, shot_id)

Shot(pos, 315,shot_id)

Shot(pos, 330,shot_id)

Shot(pos, 345,shot_id)

def CommonShot(pos, shot_id):

'''常规子弹'''

Shot(pos, 0, shot_id)

class Alien(pygame.sprite.Sprite):

'''通用敌人类'''

#默认速度表,速度为像素/秒

speed_tab = [ 400, 200, 200 ]

images= []

#用于射击间隔

times = [0.15, 0.3, 0.4]

def __init__(self, id=1, health=5):

pygame.sprite.Sprite.__init__(self, self.containers)

self.id = id

self.speed = Alien.speed_tab[id-1]

self.health = health

self.image = Alien.images[id-1]

self.rect = self.image.get_rect()

self.rect.topleft = (randint(0, SCREEN_RECT.width-self.rect.width),0)

self.move_tab = [ self.move_line, self.move_circle, self.move_curve ]

#用于射击的时间计算

self.time = 0.0

def update(self, time_passed_seconds=0.0):

self.move_tab[self.id-1](time_passed_seconds)

if self.rect.x < 0 or self.rect.x > SCREEN_RECT.width or self.rect.y < 0 or self.rect.y > SCREEN_RECT.height:

self.kill()

self.time += time_passed_seconds

if self.time > Alien.times[self.id-1]:

self.time = 0.0

if self.id == 1:

AlienShot(self.attack_pos(), 180, 1, 30)

elif self.id == 2:

AlienShot(self.attack_pos(), 120, 1, 10)

AlienShot(self.attack_pos(), 150, 1, 10)

AlienShot(self.attack_pos(), 180, 1, 10)

AlienShot(self.attack_pos(), 210, 1, 10)

AlienShot(self.attack_pos(), 240, 1, 10)

elif self.id == 3:

AlienShot(self.attack_pos(), 180, 2, 10)

def shoted_and_live(self, harm):

'''被攻击处理,依然存活返回True,否则返回False'''

self.health -= harm

if self.health <= 0:

return False

else:

return True

def move_line(self, time_passed_seconds):

self.rect.move_ip(0, self.speed * time_passed_seconds)

def move_circle(self, time_passed_seconds):

if not hasattr(self, 'angle'):

self.angle = 180

else:

self.angle = self.angle+time_passed_seconds*360

if not hasattr(self, 'radius'):

self.radius = 60

if not hasattr(self, 'center'):

x = self.rect.x+self.radius if self.rect.x < self.radius else self.rect.x-self.radius

self.center = [ x, 0+self.radius]

self.center[1] += 2

new_pos = self.__circle_next( self.center, self.radius, self.angle)

#self.rect.move_ip(new_pos[0], new_pos[1])

self.rect.x, self.rect.y = new_pos[0], new_pos[1]

def __circle_next(self, center, radius, angle):

x = math.sin(angle/180.0*math.pi) * radius + center[0]

y = math.cos(angle/180.0*math.pi) * radius + center[1]

return x, y

def move_curve(self, time_passed_seconds):

if not hasattr(self, 'ray'):

self.ray = self.rect.x

if not hasattr(self, 'angle'):

self.angle = 0

else:

self.angle = self.angle + time_passed_seconds * 360

if not hasattr(self, 'curve_width'):

self.curve_width = 50

x = math.sin(self.angle/180*math.pi) * self.curve_width + self.ray

y = self.rect.y + self.speed * time_passed_seconds

self.rect.x, self.rect.y = x, y

def attack_pos(self):

return self.rect.x + self.rect.width / 2, self.rect.y + self.rect.height

class Explosion(pygame.sprite.Sprite):

'''爆炸类'''

#用于存储爆炸图像每帧的坐标

areas = [\

(0,0,104,135), (104,0,104,135), (208,0,104,135),(312,0,104,135),(416,0,94,135),\

(0,135,102,112),(102,135,102,112),(204,135,102,112),(306,135,102,112),(408,135,102,112),\

(0,247,108,144),(108,247,100,144),(208,247,102,144),(310,247,100,144),(412,247,98,144),\

(0,400,95,100) ]

images = []

def __init__(self, pos, id=1, areas=None):

pygame.sprite.Sprite.__init__(self, self.containers)

self.pos = pos

self.fps = 0

self.image_data = Explosion.images[id-1]

if areas is not None:

self.areas = areas

self.update()

def update(self, time_passed_seconds=0.0):

self.rect = pygame.Rect(self.areas[self.fps])

self.image = self.image_data.subsurface(Rect(self.areas[self.fps]))

self.rect.topleft = self.pos

self.fps += 1

if self.fps >= len(self.areas):

self.kill()

class Score(pygame.sprite.Sprite):

score = 0

health= 0

life = 0

def __init__(self, font_type = "文泉驿点阵正黑"):

pygame.sprite.Sprite.__init__(self)

self.font = pygame.font.SysFont(font_type, 20)

self.color= (255,255,255)

self.msg = u"得分:%d\n生命:%d"

self.update()

self.rect = self.image.get_rect()

self.rect.topleft = (10,10)

def update(self, time_passed_seconds=0.0):

self.msg = u"生命:%d 得分:%d"% (Score.life, Score.score)

self.image = self.font.render(self.msg, True, self.color)

main.py

#-*- coding=utf-8 -*-

#!/usr/bin/python

import os

import time

import pygame

from pygame.locals import *

from random import randint

import stars

from game import *

#默认星空的速度

default_stars_speed = (50, 300)

#子弹种数和当前子弹ID,以及对应的子弹大小、发射频率(个/秒)

SHOT_NUM = 4

shot_id = 1

shot_size= [(2,9), (16, 16), (19,14), (99,120)]

shot_rate= [ 0.15, 0.3, 0.10, 0.7 ]

dest_area = [\

(0,0,104,135), (104,0,104,135), (208,0,104,135),(312,0,104,135),(416,0,104,135),\

(0,135,102,112),(102,135,102,112),(204,135,102,112),(306,135,102,112),(408,135,102,112),\

(0,247,108,144),(108,247,100,144),(208,247,102,144),(310,247,100,144),(412,247,98,144),\

(0,400,95,100) ]

star_bmg = []

def update_background(stars, screen, time_passed_seconds):

'''在指定图像上生成一些星星并移动,绘制'''

stars.create_star(2,(randint(0,255),randint(0,255),randint(0,255)))

#stars.create_star(1,(255,255,255))

stars.move(time_passed_seconds)

screen.fill((0, 0, 0))

stars.draw(screen)

#screen.blit(star_bmg[0],(100,100))

#screen.blit(star_bmg[1],(100,100))

def load_image(file, alpha=False):

'''加载一张图片,可指定是否为alpha转换'''

file = 'data/image/' + file

try:

surface = pygame.image.load(file)

except pygame.error:

raise SystemExit('加载图像 "%s" 失败 %s' % (file, pygame.get_error()) )

if alpha:

return surface.convert_alpha()

return surface.convert()

def load_sound(file):

file = 'data/music/' + file

try:

sound = pygame.mixer.Sound(file)

return sound

except pygame.error:

print ('加载音乐 "%s" 失败' % file)

return None

def main():

global shot_id

global star_bmg

pygame.mixer.pre_init(44100, -16, 2, 4096)

pygame.init()

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

#加载各种资源数据

image_list = os.listdir('data/image')

image_list.sort()

Player.images = [ load_image(file,True) for file in image_list if 'player' in file ]

Alien.images = [ pygame.transform.rotate(load_image(file,True),180)\

for file in image_list if 'alien' in file ]

Shot.images = [ load_image(file,True) for file in image_list if 'shot' in file ]

star_bmg = [ load_image(file,True) for file in image_list if 'star' in file ]

Shot.shot_size = shot_size

shot_sound = load_sound('shot2.wav')

Explosion.images = [ load_image(file,True) for file in image_list if 'explosion' in file ]

explosion_sound1 = load_sound('explosion1.wav')

explosion_sound2 = load_sound('explosion2.wav')

change_shot_sound = load_sound('change_shot.wav')

alarm_sound = load_sound('alarm.wav')

#加载并播放BGM

pygame.mixer.music.load('data/music/bgm01.ogg')

pygame.mixer.music.play(-1)

# 初始化并生成一些星星

world = stars.Stars(200)

world.set_min_speed(default_stars_speed[0])

world.set_max_speed(default_stars_speed[1])

#为各种游戏对象分组,all组存储了所有游戏对象

shots = pygame.sprite.Group() #玩家的子弹和敌人的子弹分成2组

alien_shots = pygame.sprite.Group()

aliens= pygame.sprite.Group()

explosions = pygame.sprite.Group()

all = pygame.sprite.Group()

Player.containers = all

Alien.containers = aliens, all

Shot.containers = shots, all

AlienShot.containers = alien_shots, all

Explosion.containers = explosions, all

player = Player()

#玩家生命数,重载标志和重载时间

life = 3

reloading = False

reloading_time = 1.5

Score.score = 0

Score.life = life

score = Score()

all.add(score)

#无敌标志,重生后需要进入一段无敌时间

iamyourdaddy = False

clock = pygame.time.Clock()

prev_time = 0.0

while life or len(explosions.sprites())>0:

allkill=None

for event in pygame.event.get():

if event.type == QUIT:

return

if event.type == KEYDOWN and event.key == K_ESCAPE:

return

if event.type == KEYDOWN:

#处理子弹切换

if event.key == K_TAB:

shot_id = shot_id % SHOT_NUM + 1

change_shot_sound.play()

elif event.key == K_x:

for alien in aliens:

alien.kill()

explosion_sound2.play()

Explosion(alien.rect.topleft)

for shot in alien_shots:

shot.kill()

explosion_sound2.play()

Explosion(shot.rect.topleft)

keystate = pygame.key.get_pressed()

time_passed = clock.tick(30)

time_passed_seconds = time_passed / 1000.

update_background(world, screen, time_passed_seconds)

#all.clear(screen, screen)

all.update(time_passed_seconds)

#处理方向控制

direct = []

if keystate[K_UP]:

direct.append('up')

#模拟加速星空

world.set_min_speed(default_stars_speed[0] * 10)

world.set_max_speed(default_stars_speed[1] * 2)

if keystate[K_DOWN]:

direct.append('down')

#模拟减速星空

world.set_min_speed(10)

world.set_max_speed(default_stars_speed[1] / 2)

if keystate[K_LEFT]:

direct.append('left')

if keystate[K_RIGHT]:

direct.append('right')

player.move(direct)

#若不是上下则恢复默认速度

if not (keystate[K_UP] or keystate[K_DOWN]):

world.set_min_speed(default_stars_speed[0])

world.set_max_speed(default_stars_speed[1])

#处理攻击行为,用攻击间隔控制频率

if not reloading and keystate[K_SPACE]:

if time.time()-prev_time > shot_rate[shot_id-1]:

#第二个参数为射出角度,以12点钟方向为0度逆时针变大

#Shot(player.attack_pos(), 45, shot_id)

if shot_id==1:

SectorShot(player.attack_pos(), shot_id)

else:

CommonShot(player.attack_pos(), shot_id)

shot_sound.play()

#Explosion(player.attack_pos())

prev_time = time.time()

#随机生成敌人,不同敌人血量不同

n = randint(0,100)

if n==1:

Alien(1,3)

elif n==2:

Alien(2,5)

elif n==3:

Alien(3,5)

#处理玩家子弹与敌方的碰撞,碰撞字典键为第一个组的对象,值为第二个组的对象列表

collide_dict = pygame.sprite.groupcollide(aliens,shots,False,False)

for alien in collide_dict:

for shot in collide_dict[alien]:

if shot_id!=4:

shot.kill()

explosion_sound1.play()

harm = shot.harm

if not alien.shoted_and_live(harm):

Score.score += 1

alien.kill()

explosion_sound2.play()

Explosion(alien.rect.topleft)

#检测无敌时间是否结束

if iamyourdaddy:

wait += time_passed_seconds

if wait > 1.5:

iamyourdaddy = False

wait = 0.0

#如果玩家处于重生中则不检测玩家碰撞

if not reloading:

#处理玩家与敌人的碰撞

for alien in pygame.sprite.spritecollide(player, aliens,True):

explosion_sound2.play()

Explosion(alien.rect.topleft)

if iamyourdaddy:

pass

else:

alarm_sound.play(2)

Explosion(player.rect.topleft)

Score.score += 1

Score.life -= 1

player.kill()

reloading = True

wait = 0.0

life -= 1

if not reloading:

#处理玩家与敌方子弹的碰撞

for shot in pygame.sprite.spritecollide(player, alien_shots, True):

explosion_sound1.play()

harm = shot.harm

if iamyourdaddy:

pass

elif not player.shoted_and_live(harm):

alarm_sound.play(2)

explosion_sound2.play()

Explosion(player.rect.topleft)

Score.life -= 1

player.kill()

reloading = True

wait = 0.0

life -= 1

#处理子弹与子弹的碰撞

if shot_id==4:

collide_dict = pygame.sprite.groupcollide(alien_shots,shots,True,False)

for alien_shot in collide_dict:

explosion_sound2.play()

Explosion(alien_shot.rect.topleft)

#死亡后重置玩家,生命数-1

if reloading:

wait += time_passed_seconds

if wait > reloading_time:

reloading = False

player = Player()

wait = 0.0

#进入无敌模式

iamyourdaddy = True

# 增加一颗新的星星

#stars.create_star(1)

#stars.move(time_passed_seconds)

#screen.fill((0, 0, 0))

# 绘制所有的星

#stars.draw(screen)

#screen.blit(image,(300,300))

all.draw(screen)

pygame.display.update()

#绘制结束画面

#设置字体

font = pygame.font.SysFont("文泉驿点阵正黑", 80)

end = font.render(u"YOU LOST!!!", True, (255,0,0))

screen.blit(end, (180, 270))

pygame.display.update()

time.sleep(2.5)

if __name__ == "__main__":

main()

测试画面:

以上是 pygame实现雷电游戏雏形开发 的全部内容, 来源链接: utcz.com/z/344468.html

回到顶部