在python整個語言系統學完以後,我得知了Pygame這個擴充套件,發現相當的好用,所以在個人興趣下寫了小遊戲(還沒徹底寫完)作為學習.
視窗大小:1200×600
遊戲基本內容:使用一個類似馬里奧的小人,進行類似飛機大戰形式的躲子彈遊戲:
大致py檔案分類:
box類:類似馬里奧箱子那種,可以站立
bullet類:boss發射的子彈
hinder類:障礙物類,從螢幕的左右兩邊發射火球,擊中後主角死亡
part類:主人公類
road類:地面類,(emmmmmm本來可以不要這個,不知道咋的就加上了)
boss類:就是boss類
game_function:儲存遊戲的主要判定函數等等
main_cycle:遊戲主函數部分
setting類:儲存遊戲的設定等等
from time import sleep
import pygame
from settings import Settings
from part import Part
from BOSS import BOSS
from road import Road
from box import Box
import game_function as gf
from pygame.sprite import Group
import datetime
def run():
pygame.init()
game_setting=Settings()
screen = pygame.display.set_mode((game_setting.screen_width, game_setting.screen_height))
pygame.display.set_caption("茄理奧")
box = Box(game_setting, screen)
road = Road(game_setting, screen)
boss = BOSS(screen,game_setting)
part = Part(game_setting, screen,box,road)
hinders=Group()
hinder1s = Group()
bullets = Group()
# dt = datetime.datetime.now()
gf.create_fleet(game_setting, screen, hinders)
gf.create_fleet1(game_setting, screen, hinder1s)
gf.create_bullet(game_setting,screen,bullets,boss)
# gf.create_bullet(game_setting,screen,bullets,boss)
while True:
# 監聽
gf.check_events(part)
part.update()
boss.update()
hinders.update()
hinder1s.update()
bullets.update()
for hinder in hinders.copy():
if hinder.rect.bottom >550 or hinder.rect.top<0 or hinder.rect.left<0 or hinder.rect.right>1200:
hinders.remove(hinder)
if len(hinders)<1:
hinders.remove(hinder)
gf.create_fleet(game_setting, screen, hinders)
for hinder1 in hinder1s.copy():
if hinder1.rect.bottom > 550 or hinder1.rect.top < 0 or hinder1.rect.left < 0 or hinder1.rect.right > 1500:
hinder1s.remove(hinder1)
if len(hinder1s) < 1:
hinder1s.remove(hinder1)
gf.create_fleet1(game_setting, screen, hinder1s)
for bullet in bullets.copy():
if bullet.rect.bottom > 550 or bullet.rect.top < 0 or bullet.rect.left < 0 or bullet.rect.right > 1200:
bullets.remove(bullet)
if len(bullets) < 5:
bullets.remove(bullet)
gf.create_bullet(game_setting, screen, bullets,boss)
gf.update_screen(game_setting, screen, part,hinders,boss,bullets,road,box,hinder1s)
run()
#因為後面程式碼越寫越亂,本來好多東西應該放在設定類裡面,請大家別學習這種行為
import pygame
class Settings(object):
"""儲存遊戲中所有的設定類"""
def __init__(self):
"""初始化遊戲設定"""
#螢幕設定
self.screen_width = 1200
self.screen_height =600
self.bg_img =pygame.image.load("image/backgroud.jpg")
self.img1 = pygame.transform.scale(self.bg_img, (1200, 553))
self.a = 1
self.part_speed_factor = 3
self.time = 5
self.boss_speed_factor = 1.5
import pygame,sys,random
from hinder import Hinder
from hinder1 import Hinder1
from bullet import BULLET
def check_keydown_events(event,part):
if event.key == pygame.K_RIGHT:
part.moving_right = True
part.direction = True
if event.key == pygame.K_LEFT:
part.moving_left = True
part.direction = False
if event.key == pygame.K_UP:
part.isjump = True
def check_keyup_events(event,part):
if event.key == pygame.K_RIGHT:
part.moving_right = False
if event.key == pygame.K_LEFT:
part.moving_left = False
def check_events(part):
"""響應按鍵和滑鼠事件"""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event,part)
elif event.type ==pygame.KEYUP:
check_keyup_events(event,part)
def update_screen(game_setting,screen,part,hinders,boss,bullets,road,box,hinder1s):
"""更新螢幕上的影象"""
#每次呼叫時都回圈繪製螢幕
screen.blit(game_setting.img1,(0,0)) #在遊戲視窗上顯示背景圖片,背景圖片比遊戲視窗大,否則視窗周邊將用黑邊填充
# screen.fill(255,0,0)
part.blitme()
hinders.draw(screen)
boss.blitim()
road.blitme()
box.blitme()
hinder1s.draw(screen)
bullets.draw(screen)
for hinder in hinders:
part.part_hinder_collide(hinder)
for hinder1 in hinders:
part.part_hinder_collide(hinder1)
# part.Ispeng()
for bullet in bullets:
part.part_bullet_collide(bullet)
#繪製螢幕課件(測試)
pygame.display.flip()
def create_fleet(game_setting, screen,hinders):
for hinder_number in range(1):
hinder=Hinder(game_setting, screen)
hinder.x=0
hinder.y =random.randint(0,500)
hinder.rect.x=hinder.x
hinders.add(hinder)
def create_fleet1(game_setting, screen,hinder1s):
for hinder1_number in range(1):
hinder1=Hinder1(game_setting, screen)
hinder1.x=1180
hinder1.y =random.randint(0,500)
hinder1.rect.x=hinder1.x
hinder1s.add(hinder1)
def create_bullet(game_setting,screen,bullets,boss):
for bullet_number in range(10):
bullet = BULLET(game_setting,screen)
bullet.x = boss.rect.centerx
bullet.y = boss.rect.bottom
bullet.rect.x = bullet.x
bullets.add(bullet)
from time import sleep
import pygame
class Part():
def __init__(self, game_setting, screen,box,road):
"""設定角色的初始化位置"""
self.road=road
self.box = box
self.screen = screen
self.game_setting = game_setting
# 載入角色影象,並獲得他的外解矩形位置
self.image = pygame.image.load("image/part_0.png")
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
# 將新繪製的角色放在螢幕底部中間
self.rect.centerx = self.screen_rect.centerx-200
self.rect.centery = self.screen_rect.bottom-100
# 在屬性中儲存小數值
self.center = float(self.rect.centerx)
self.center2 = float(self.rect.centery)
# # 移動標誌
self.moving_right = False
self.moving_left = False
self.moving_top = False
self.moving_bottom = False
self.isjump=False
self.direction=True#角色圖片的朝向
self.ispeng=False
self.isdie=False
def jump(self):
if self.game_setting.time >= -5 and not(self.isdie):
a = self.game_setting.a # 前半段減速上跳
if self.game_setting.time < 0:
a = -self.game_setting.a # 後半段加速下落
self.center2 -= 0.5 * a * (self.game_setting.time ** 2) # 勻加速直線運動的位移公式
if self.center2 < 60:
self.center2 = 60 # 防止跳出邊界
if self.center2 > self.road.rect.top - 110:
self.center2 = self.road.rect.top - 110 # 防止跳出邊界
self.game_setting.time -= 0.1
else:
a = self.game_setting.a
self.isjump = False
self.game_setting.time = 5
def update(self):
"""根據移動標誌調整角色的位置"""
# 更新角色的center值,不是rect
if not(self.isjump) and not(self.isdie) :
if not (self.ispeng):
if self.moving_right and self.rect.right < self.screen_rect.right:
self.center += self.game_setting.part_speed_factor
if self.moving_left and self.rect.left > 0:
self.center -= self.game_setting.part_speed_factor
if self.center2 != self.road.rect.top-50:
self.center2 = self.road.rect.top-50
else:
if self.moving_right and self.rect.right < self.screen_rect.right:
self.center += self.game_setting.part_speed_factor
if self.moving_left and self.rect.left > 0:
self.center -= self.game_setting.part_speed_factor
if not(self.isjump) and self.isdie:
if not (self.ispeng):
if self.center2 != self.road.rect.top:
self.center2 = self.road.rect.top
if self.isjump:
if self.moving_right and self.rect.right < self.screen_rect.right:
self.center += self.game_setting.part_speed_factor
if self.moving_left and self.rect.left > 0:
self.center -= self.game_setting.part_speed_factor
self.jump()
# 根據self.center 更新 rect
self.rect.centerx = self.center
self.rect.centery = self.center2
if self.isjump==True and not(self.isdie):
self.image = pygame.image.load("image/part_1.png")
if self.isjump==False and not(self.isdie):
self.image = pygame.image.load("image/part_0.png")
if self.isjump==False and self.moving_left==True and not(self.isdie):
self.image = pygame.image.load("image/part_4.png")
if self.isjump==False and self.moving_right==True and not(self.isdie):
self.image = pygame.image.load("image/part_4.png")
if self.isjump==False and self.moving_right==False and self.moving_left==False and not(self.isdie):
self.image = pygame.image.load("image/part_0.png")
if self.isdie:
self.image = pygame.image.load("image/part_die.png")
def blitme(self):
"""在指定位置繪製角色"""
img1 = pygame.transform.flip(self.image, True, False)
if self.direction==False:
self.screen.blit(img1, self.rect)
else:
self.screen.blit(self.image, self.rect)
def part_hinder_collide(self, hinders):
if pygame.Rect.colliderect(pygame.Rect(self.rect.x+35, self.rect.y, 50, 80), pygame.Rect(hinders.rect.x+122, hinders.rect.y+88, 60, 60)):
self.isdie = True
def part_bullet_collide(self, bullets):
if pygame.Rect.colliderect(pygame.Rect(self.rect.x+35, self.rect.y, 50, 80), pygame.Rect(bullets.rect.x, bullets.rect.y, 22, 22)):
self.isdie = True
import pygame
class Road():
def __init__(self, game_setting, screen):
"""設定角色的初始化位置"""
self.screen = screen
self.game_setting = game_setting
# 載入角色影象,並獲得他的外解矩形位置
self.image = pygame.image.load("image/road.png")
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
self.rect.centery = 710
self.img1 = pygame.transform.scale(self.image, (1200, 47))
# 在屬性中儲存小數值
self.center1 = float(self.rect.centerx)
self.center2 = float(self.rect.centery)
def blitme(self):
"""在指定位置繪製角色"""
self.screen.blit(self.img1, self.rect)
#箱子還沒範例化出來,後續會寫
import pygame
class Box():
def __init__(self, game_setting, screen):
"""設定角色的初始化位置"""
self.screen = screen
self.game_setting = game_setting
# 載入角色影象,並獲得他的外解矩形位置
self.image = pygame.image.load("image/box.png")
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
# 將新繪製的角色放在螢幕底部中間
self.rect.centerx = self.screen_rect.centerx + 200
self.rect.centery = 470
self.img1=pygame.transform.scale(self.image,(200,40))
import pygame
#boss類
class BOSS():
def __init__(self, screen, game_setting):
# 初始化BOSS並設定初始位置
self.screen = screen
self.game_setting = game_setting
# 載入BOSS影象
self.image = pygame.image.load("image/boss.png")
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
# 讓BOSS出生在螢幕頂側
self.rect.centerx = self.screen_rect.centerx
self.rect.top = self.screen_rect.top
# 在boss屬性中儲存小數值
self.center = float(self.rect.centerx)
# 移動標誌
self.moving_right = True
def update(self):
if self.moving_right:
if self.center < self.screen_rect.right:
self.center += self.game_setting.boss_speed_factor
else:
self.center -= self.game_setting.boss_speed_factor
self.moving_right = False
else:
if self.center > self.screen_rect.left:
self.center -= self.game_setting.boss_speed_factor
self.moving_right = False
else:
self.center += self.game_setting.boss_speed_factor
self.moving_right = True
# # # 根據self.center跟新rect
self.rect.centerx = self.center
# 指定位置繪製BOSS
def blitim(self):
img1 = pygame.transform.flip(self.image, True, False)
if self.moving_right==False:
self.screen.blit(img1, self.rect)
else:
self.screen.blit(self.image, self.rect)
import pygame,random
from pygame.sprite import Sprite
class BULLET(Sprite):
def __init__(self,game_setting,screen):
#初始化子彈位置
super(BULLET, self).__init__()
self.screen = screen
self.game_setting = game_setting
#載入子彈影象,
self.image = pygame.image.load("image/bullet.png")
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
#讓子彈出生在boss圖下
# self.rect.x = self.boss.rect.centerx
# self.rect.y = self.boss.rect.bottom
# 在屬性中儲存小數值
self.rect.x = self.rect.width
self.rect.y = self.rect.height
# 在屬性中儲存小數值
self.x = float(self.rect.x)
self.y = float(self.rect.y)
# 設定子彈速度
self.speed_factor_Y = random.randint(-5, 5)
self.speed_factor_X = random.randint(-3,3)
def update(self):
self.x += self.speed_factor_X
self.y += self.speed_factor_Y
self.rect.y = self.y
self.rect.x = self.x
# def blitme(self):
# """在指定位置繪製角色"""
# self.screen.blit(self.image, self.rect)
import pygame,random
from pygame.sprite import Sprite
class Hinder(Sprite):
def __init__(self, game_setting, screen):
"""設定角色的初始化位置"""
super(Hinder,self).__init__()
self.screen = screen
self.game_setting = game_setting
# 載入角色影象,並獲得他的外解矩形位置
self.image = pygame.image.load("image/hinder.png")
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
# 將新繪製的角色放在螢幕底部中間
self.rect.x = self.rect.width
self.rect.y = self.rect.height
# 在屬性中儲存小數值
self.x = float(self.rect.x)
self.y = float(self.rect.y)
#設定子彈速度
self.speed_factor_Y = random.randint(1,2)
self.speed_factor_X = random.randint(2,4)
def update(self):
self.x += self.speed_factor_X
self.y +=self.speed_factor_Y
self.rect.y=self.y
self.rect.x=self.x
# def blitme(self):
# """在指定位置繪製角色"""
# self.screen.blit(self.image, self.rect)
ps:為了省事,我直接寫了個hinder1類,實際上直接用hinder在範例化一個就可以了,但是把生成位置寫死了,改起來很簡單,但是我有點懶:所以
import pygame,random
from pygame.sprite import Sprite
class Hinder1(Sprite):
def __init__(self, game_setting, screen):
"""設定角色的初始化位置"""
super(Hinder1,self).__init__()
self.screen = screen
self.game_setting = game_setting
# 載入角色影象,並獲得他的外解矩形位置
self.image = pygame.image.load("image/hinder1.png")
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
# 將新繪製的角色放在螢幕底部中間
self.rect.x = self.rect.width
self.rect.y = self.rect.height
# 在屬性中儲存小數值
self.x = float(self.rect.x)
self.y = float(self.rect.y)
#設定子彈速度
self.speed_factor_Y = random.randint(1,2)
self.speed_factor_X = random.randint(-4,-2)
def update(self):
self.x += self.speed_factor_X
self.y +=self.speed_factor_Y
self.rect.y=self.y
self.rect.x=self.x
# def blitme(self):
# """在指定位置繪製角色"""
# self.screen.blit(self.image, self.rect)
程式碼完成的很草率,有很多地方還能優化,死亡畫面和計分都沒加
後續完成: 功能(boss血量,主人公血量,死亡畫面,等)
函數(程式碼整合優化,主人公攻擊boss,計分,等)
#程式碼完成:
@by本人
main_cycle,game_function,part,settings,部分整合
@by Siranyu
boss,bullet,部分整合
@by 小zhang
hinder,hinder1,road,box