pygame實(shí)現(xiàn)雷電游戲雛形開發(fā)
本文實(shí)例為大家分享了pygame實(shí)現(xiàn)雷電游戲開發(fā)代碼,供大家參考,具體內(nèi)容如下
源代碼:
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)):
'''創(chuàng)建一個(gè)或多個(gè)星星,顏色可選'''
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):
'''移動(dòng)星星并過濾'''
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):
'''將星星畫到指定圖像對(duì)象'''
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):
'''移動(dòng),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參數(shù)為子彈射出的方向角度,以12點(diǎn)鐘方向?yàn)?度,逆時(shí)針增大'''
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):
'''
敵方子彈類
為了對(duì)象分組專為敵人的子彈使用一個(gè)新類,并定制子彈射速
'''
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):
'''常規(guī)子彈'''
Shot(pos, 0, shot_id)
class Alien(pygame.sprite.Sprite):
'''通用敵人類'''
#默認(rèn)速度表,速度為像素/秒
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 ]
#用于射擊的時(shí)間計(jì)算
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):
'''爆炸類'''
#用于存儲(chǔ)爆炸圖像每幀的坐標(biāo)
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 = "文泉驛點(diǎn)陣正黑"):
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 *
#默認(rèn)星空的速度
default_stars_speed = (50, 300)
#子彈種數(shù)和當(dāng)前子彈ID,以及對(duì)應(yīng)的子彈大小、發(fā)射頻率(個(gè)/秒)
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):
'''在指定圖像上生成一些星星并移動(dòng),繪制'''
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轉(zhuǎn)換'''
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)
#加載各種資源數(shù)據(jù)
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])
#為各種游戲?qū)ο蠓纸M,all組存儲(chǔ)了所有游戲?qū)ο?
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()
#玩家生命數(shù),重載標(biāo)志和重載時(shí)間
life = 3
reloading = False
reloading_time = 1.5
Score.score = 0
Score.life = life
score = Score()
all.add(score)
#無敵標(biāo)志,重生后需要進(jìn)入一段無敵時(shí)間
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)
#若不是上下則恢復(fù)默認(rèn)速度
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]:
#第二個(gè)參數(shù)為射出角度,以12點(diǎn)鐘方向?yàn)?度逆時(shí)針變大
#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()
#隨機(jī)生成敵人,不同敵人血量不同
n = randint(0,100)
if n==1:
Alien(1,3)
elif n==2:
Alien(2,5)
elif n==3:
Alien(3,5)
#處理玩家子彈與敵方的碰撞,碰撞字典鍵為第一個(gè)組的對(duì)象,值為第二個(gè)組的對(duì)象列表
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)
#檢測(cè)無敵時(shí)間是否結(jié)束
if iamyourdaddy:
wait += time_passed_seconds
if wait > 1.5:
iamyourdaddy = False
wait = 0.0
#如果玩家處于重生中則不檢測(cè)玩家碰撞
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)
#死亡后重置玩家,生命數(shù)-1
if reloading:
wait += time_passed_seconds
if wait > reloading_time:
reloading = False
player = Player()
wait = 0.0
#進(jìn)入無敵模式
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()
#繪制結(jié)束畫面
#設(shè)置字體
font = pygame.font.SysFont("文泉驛點(diǎn)陣正黑", 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()
測(cè)試畫面:

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- pygame游戲之旅 游戲中添加顯示文字
- pygame游戲之旅 python和pygame安裝教程
- python和pygame實(shí)現(xiàn)簡(jiǎn)單俄羅斯方塊游戲
- Python使用pygame模塊編寫俄羅斯方塊游戲的代碼實(shí)例
- Python基于pygame實(shí)現(xiàn)的font游戲字體(附源碼)
- python基于pygame實(shí)現(xiàn)響應(yīng)游戲中事件的方法(附源碼)
- 用Python寫飛機(jī)大戰(zhàn)游戲之pygame入門(4):獲取鼠標(biāo)的位置及運(yùn)動(dòng)
- pygame學(xué)習(xí)筆記(6):完成一個(gè)簡(jiǎn)單的游戲
相關(guān)文章
python numpy.power()數(shù)組元素求n次方案例
這篇文章主要介紹了python numpy.power()數(shù)組元素求n次方案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-03-03
Python?第三方opencv庫實(shí)現(xiàn)圖像分割處理
這篇文章主要介紹了Python?第三方opencv庫實(shí)現(xiàn)圖像分割處理,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06
Python實(shí)現(xiàn)提高運(yùn)行速度的技巧分享
這篇文章主要為大家詳細(xì)介紹了Python實(shí)現(xiàn)提高運(yùn)行速度的相關(guān)技巧,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以跟隨小編一起了解一下2023-06-06
Python控制臺(tái)輸出俄羅斯方塊的方法實(shí)例
這篇文章主要給大家介紹了關(guān)于Python控制臺(tái)輸出俄羅斯方塊的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
基于Python實(shí)現(xiàn)簡(jiǎn)單學(xué)生管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了基于Python實(shí)現(xiàn)簡(jiǎn)單學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07
Python學(xué)習(xí)之Django的管理界面代碼示例
這篇文章主要介紹了Python學(xué)習(xí)之Django的管理界面代碼示例,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-02-02
Python實(shí)現(xiàn)堡壘機(jī)模式下遠(yuǎn)程命令執(zhí)行操作示例
這篇文章主要介紹了Python實(shí)現(xiàn)堡壘機(jī)模式下遠(yuǎn)程命令執(zhí)行操作,結(jié)合實(shí)例形式分析了Python堡壘機(jī)模式執(zhí)行遠(yuǎn)程命令的原理與相關(guān)操作技巧,需要的朋友可以參考下2019-05-05

