Python小游戲
? 在python整個語言系統學完以后,我得知了Pygame這個擴展,發現相當的好用,所以在個人興趣下寫了小游戲(還沒徹底寫完)作為學習.
游戲整體設計
? 視窗大小:1200×600
? 游戲基本內容:使用一個類似馬里奧的小人,進行類似飛機大戰形式的躲子彈游戲:
? 大致py檔案分類:
? box類:類似馬里奧箱子那種,可以站立
? bullet類:boss發射的子彈
? hinder類:障礙物類,從螢屏的左右兩邊發射火球,擊中后主角死亡
? part類:主人公類
? road類:地面類,(emmmmmm本來可以不要這個,不知道咋的就加上了)
? boss類:就是boss類
? game_function:儲存游戲的主要判定函式等等
? main_cycle:游戲主函式部分
? setting類:儲存游戲的設定等等
代碼塊
main_cycle.py:
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()
settings.py:
#因為后面代碼越寫越亂,本來好多東西應該放在設定類里面,請大家別學習這種行為
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
game_function.py:
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)
part.py:
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
road.py:
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)
box.py :
#箱子還沒實體化出來,后續會寫
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))
boss.py:
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)
bullet.py:
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)
hinder.py:
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在實體化一個就可以了,但是把生成位置寫死了,改起來很簡單,但是我有點懶:所以
hinder1.py:
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
?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/172473.html
標籤:其他
上一篇:2020.09.19【省選組】模擬 gmoj 3983. 乾坤大挪移
下一篇:BigDecimal 精度問題
