前言
halo,包子們晚上好
很久沒有更新啦,主要是小編這邊最近有點小忙
今天給大家整一個簡易版本的王者榮耀
有法師,射手,坦克,輔助
支持雙人游戲喲
快跟你的小伙伴一起玩耍吧
相關(guān)文件
關(guān)注小編,私信小編領(lǐng)取喲!
當然別忘了一件三連喲~~
源碼點擊藍色字體領(lǐng)取
開發(fā)工具
Python版本:3.7.8
相關(guān)模塊:
pygame模塊;
setting模塊;
re模塊;
以及一些python自帶的模塊。
環(huán)境搭建
安裝Python并添加到環(huán)境變量,pip安裝需要的相關(guān)模塊即可。
模塊介紹
- main.py 程序入口,進行游戲內(nèi)容的初始化及主循環(huán)。
- game_event.py 處理輸入事件,生成和更新物體狀態(tài)的方法。
- live.py 玩家操控人物的屬性和行為。
- enemy.py 游戲中的敵人的屬性和行為。
- gameui.py 游戲過程中的信息的顯示。
- startupui.py 游戲啟動界面的按鈕等組件的顯示。
- rigidbody.py 模擬物體碰撞產(chǎn)生的位移。
- effect.py包含人物和敵人產(chǎn)生的攻擊物體的更新和顯示。
- setting.py 從外部加載圖片,匯總游戲中各類屬性的定義。
效果展示
游戲主頁
三個模式,四大人物選擇,大家不要看這個玩意不咋好看,小編只有這個能力畫出這個玩意
游戲中
我們選擇了法師,妲己,可能有點潦草的妲己,希望大家不要噴我,哈哈哈
游戲結(jié)束
四大人物
輔助:孫斌
射手:后羿
上單:猴子
法師:妲己
可以認出來就行啦,哈哈哈哈文章來源:http://www.zghlxwxcb.cn/news/detail-766746.html
部分代碼展示
游戲初始化和主函數(shù)
源碼領(lǐng)取加群:494958217
'''
程序主函數(shù),匯總其它模塊輸出游戲窗口
'''
import pygame
import os.path
import csv
import setting as set
import live
import game_event
import gameui as gi
import startupui as si
#程序主函數(shù)
def run_game():
#初始化pygame庫
pygame.init()
#創(chuàng)建時鐘對象(控制幀率)
clock=pygame.time.Clock()
#實例化設(shè)置類,用于導入游戲設(shè)置
setting=set.Setting()
#設(shè)置游戲窗口
screen=pygame.display.set_mode((setting.screen_width,setting.screen_height))
pygame.display.set_caption(setting.screen_caption)
#設(shè)置不同的組,用于分別處理各種物品間的關(guān)系
#玩家組
group_player=pygame.sprite.Group()
#玩家的攻擊組
group_attack=pygame.sprite.Group()
#敵人組
group_enemy=pygame.sprite.Group()
#敵人的攻擊組
group_enemy_attack=pygame.sprite.Group()
#實例化ui對象
#showinfo用于在游戲內(nèi)顯示人物血條等信息
showinfo=gi.Info(setting,screen)
#人物選擇按鈕
yi_button=si.MonkeyKingButton(screen,setting)
monkey_button=si.YiButton(screen,setting)
fox_button=si.FoxButton(screen,setting)
bin_button=si.BinButton(screen,setting)
#游戲開始界面的按鈕
pve_button=si.PVEButton(screen,setting)
pvp_button=si.PVPButton(screen,setting)
endless_button=si.EndlessButton(screen,setting)
control_button=si.ControlButton(screen,setting)
memory_button=si.RecordButton(screen,setting)
cooling_button=si.CoolingButton(screen,setting)
#游戲背景
select_button=si.SelectButton(screen,setting)
win_button=si.WinButton(screen,setting)
dead_button=si.DeadButton(screen,setting)
#玩家當前選擇的人物標記
player_button_1=si.PlayerButton1(screen,setting)
player_button_2=si.PlayerButton2(screen,setting)
#空白按鈕
none_button=si.NoneButton(screen,setting)
#空白圖像
none_info=gi.ExInfo(screen,none_button,setting.introduce_none)
#介紹按鈕作用的圖像
pve_info=gi.ExInfo(screen,pve_button,setting.introduce_pve)
pvp_info=gi.ExInfo(screen,pvp_button,setting.introduce_pvp)
endless_info=gi.ExInfo(screen,endless_button,setting.introduce_endless)
control_info=gi.ExInfo(screen,control_button,setting.introduce_control)
record_info=gi.ExInfo(screen,memory_button,setting.introduce_record)
cooling_info=gi.ExInfo(screen,cooling_button,setting.introduce_cooling)
#按鈕組(繪制時,在前的按鈕會被在后的按鈕覆蓋)
buttons=[select_button,yi_button,monkey_button,fox_button,bin_button,
pve_button,pvp_button,endless_button,
cooling_button,control_button,memory_button,
dead_button,win_button]
#標簽按鈕組
choose_buttons=[player_button_1,player_button_2]
#介紹按鈕作用的圖像組
button_info_dict={none_button:none_info,pve_button:pve_info,pvp_button:pvp_info,
endless_button:endless_info,control_button:control_info,
memory_button:record_info,cooling_button:cooling_info}
#當前顯示的圖像列表
info_label=[]
#存儲模擬剛體運動的列表
rigidbody_list=[]
#玩家實例,初始化為戰(zhàn)士
player_1=live.MonkeyKing(setting,screen)
player_2=live.MonkeyKing(setting,screen)
if not os.path.exists(setting.record_path):
#如果游戲記錄文件不存在就新創(chuàng)建一個
with open(setting.record_path,'w',newline="") as f:
writer=csv.writer(f)
header=["Time","Mode","Winner","1st Score","2st Score","Duration(s)","1st Player","2nd Player","isCooling"]
writer.writerow(header)
#游戲主循環(huán)
while True:
#繪制背景
screen.blit(setting.screen_surface_background,(0,0))
#設(shè)置游戲幀率
clock.tick(setting.fps)
#檢測鍵盤鼠標事件
game_event.check_event(setting,screen,group_player,group_attack,group_enemy,
group_enemy_attack,buttons,showinfo,button_info_dict,info_label)
#更新當前選擇人物的標簽
game_event.update_choose(setting,buttons,choose_buttons)
#游戲運行,非玩家對抗模式
if (setting.game_active and (setting.game_mode==0 or setting.game_mode==2)):
#人物初始化
if(not setting.isinit):
if setting.player_1!=None:
player_1=setting.player_1
group_player.add(player_1)
if setting.player_2!=None:
player_2=setting.player_2
group_player.add(player_2)
setting.isinit=True
#游戲計時器
setting.timer+=1
#更新玩家
group_player.update()
#生成敵人
game_event.generate_enemies(setting,group_enemy,screen)
#更新敵人,玩家的攻擊,敵人的攻擊,玩家狀態(tài)等
game_event.update_enemies(setting,showinfo,screen,group_player,group_enemy,group_attack,group_enemy_attack)
game_event.update_attacks(setting,screen,group_attack,group_enemy,rigidbody_list)
game_event.update_enemy_attacks(setting,screen,group_player,group_enemy_attack,rigidbody_list)
game_event.update_state(setting,showinfo)
game_event.update_rigidbody(setting,rigidbody_list)
#勝利條件
if setting.timer>=60*setting.fps and not group_enemy.spritedict and setting.game_mode==0:
game_event.game_win(setting,showinfo,group_enemy,group_attack,group_enemy_attack)
setting.timer=0
#失敗條件
if setting.isinit and ((setting.player_1!=None and setting.health_1<=0) or (setting.player_2!=None and setting.health_2<=0)):
game_event.game_dead(setting,showinfo,group_enemy,group_attack,group_enemy_attack)
setting.timer=0
#玩家對抗模式
elif setting.game_active and setting.game_mode==1:
#人物初始化
if(not setting.isinit):
if setting.player_1!=None and setting.player_2!=None:
player_1=setting.player_1
group_player.add(player_1)
player_2=setting.player_2
group_player.add(player_2)
setting.isinit=True
#游戲計時器
setting.timer+=1
#更新玩家
player_1.update()
player_2.update()
#更新玩家的攻擊,信息顯示和物理模擬
game_event.update_attacks_pvp(setting,screen,group_attack,rigidbody_list)
game_event.update_state(setting,showinfo)
game_event.update_rigidbody(setting,rigidbody_list)
#玩家1勝利條件
if setting.isinit and setting.health_2<=0:
setting.score_1+=1
game_event.game_win(setting,showinfo,group_enemy,group_attack,group_enemy_attack)
setting.timer=0
#玩家2勝利條件
if setting.isinit and setting.health_1<=0:
setting.score_2+=1
game_event.game_win(setting,showinfo,group_enemy,group_attack,group_enemy_attack)
setting.timer=0
#根據(jù)上述更新的結(jié)果繪制整個游戲窗口
game_event.update_screen(setting,screen,group_player,group_attack,group_enemy,group_enemy_attack,
showinfo,buttons,info_label,choose_buttons)
#運行游戲
run_game()
游戲啟動界面的按鈕等組件的顯示。
源碼領(lǐng)取加群:494958217
'''
startupui模塊定義了在游戲啟動界面的各類ui組件外觀
Button類為模塊中其它類的父類,雖然叫button但不包括事件處理,只定義了圖像和布局(點擊事件的處理在game_event模塊中)
Button類提供一個draw()實例方法繪制自身
子類 SelectButton WinButton DeadButton 作為界面背景(選人、勝利、失?。?子類 MonkeyKingButton YiButton FoxButton BinButton 作為選人按鈕
其它子類為啟動界面的各類功能按鈕,包括開始特定模式的游戲,開關(guān)冷卻等
'''
import pygame.font
import pygame.draw
class Button():
"""按鈕基類"""
def __init__(self,screen,setting):
#窗口和設(shè)置屬性
self.screen=screen
self.screen_rect=screen.get_rect()
self.setting=setting
#按鈕的長寬
self.width = 120
self.height = 50
#按鈕背景和字體顏色
self.button_color = (40, 200, 0)
self.text_color = (255, 255, 255)
#默認字體
self.font = pygame.font.SysFont(None, 50)
#布局
self.rect = pygame.Rect(0, 0, self.width, self.height)
self.rect.center = self.screen_rect.center
def draw(self):
"""渲染方法"""
self.screen.blit(self.surface, self.rect)
class MonkeyKingButton(Button):
"""戰(zhàn)士按鈕"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=self.setting.surface_none
self.rect = pygame.Rect((0,0),(200,380))
class FoxButton(Button):
"""法師按鈕"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=self.setting.surface_none
self.rect = pygame.Rect((200,0),(200,380))
class BinButton(Button):
"""輔助按鈕"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=self.setting.surface_none
self.rect = pygame.Rect((400,0),(200,380))
class YiButton(Button):
"""射手按鈕"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=self.setting.surface_none
self.rect = pygame.Rect((600,0),(200,380))
class SelectButton(Button):
"""人物選擇界面"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=self.setting.screen_surface_select
self.rect = self.surface.get_rect()
class WinButton(Button):
"""勝利界面"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=self.setting.screen_surface_win
self.rect = self.surface.get_rect()
class DeadButton(Button):
"""失敗界面"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=setting.screen_surface_dead
self.rect = self.surface.get_rect()
class PVEButton(Button):
"""普通模式按鈕"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=setting.button_pve_surface
self.rect=self.surface.get_rect()
self.rect.center=(400,100)
class PVPButton(Button):
"""玩家對抗按鈕"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=setting.button_pvp_surface
self.rect=self.surface.get_rect()
self.rect.center=(400,200)
class EndlessButton(Button):
"""無盡模式按鈕"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=setting.button_endless_surface
self.rect=self.surface.get_rect()
self.rect.center=(400,300)
class PlayerButton1(Button):
"""玩家1人物選擇標記"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=setting.player_1_surface
self.rect=self.surface.get_rect()
self.rect.center=(1000,1000)
class PlayerButton2(Button):
"""玩家2人物選擇標記"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=setting.player_2_surface
self.rect=self.surface.get_rect()
self.rect.center=(1000,1000)
class NoneButton(Button):
"""空白按鈕"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=setting.surface_none
self.rect=self.surface.get_rect()
self.rect.center=(1000,1000)
self.rect.size=(1,1)
class CoolingButton(Button):
"""技能冷卻按鈕"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=setting.button_cooling_surface_0
self.surface_=setting.button_cooling_surface_1
self.rect=self.surface.get_rect()
self.rect.center=(70,360)
def draw(self):
"""根據(jù)技能狀態(tài)繪制按鈕"""
if self.setting.iscooling:
self.screen.blit(self.surface, self.rect)
else:
self.screen.blit(self.surface_, self.rect)
class ControlButton(Button):
"""控制按鈕"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=setting.button_control_surface
self.rect=self.surface.get_rect()
self.rect.center=(740,390)
class RecordButton(Button):
"""記錄按鈕"""
def __init__(self,screen,setting):
super().__init__(screen,setting)
self.surface=setting.button_memory_surface
self.rect=self.surface.get_rect()
self.rect.center=(70,420)
游戲中的敵人的屬性和行為。
源碼領(lǐng)取加群:494958217
import pygame
import random
import effect
from pygame.sprite import Sprite
class Enemy(Sprite):
"""敵人的基類"""
def __init__(self,setting,screen,surface,generate_point,health,speed,action_interval,attack_interval,weight,score):
super().__init__()
#基本變量
self.screen=screen
self.setting=setting
self.screen_rect=screen.get_rect()
#移動速度
self.speed=speed
#重設(shè)移動方向間隔
self.action_interval=action_interval
#攻擊間隔
self.attack_interval=attack_interval
#重量
self.weight=weight
#死亡后玩家獲取的得分
self.score=score
#選擇一名玩家人物作為目標
if setting.player_1!=None and setting.player_2!=None:
target=[setting.player_1,setting.player_2]
self.player=random.choice(target)
elif setting.player_1!=None:
self.player=setting.player_1
else:
self.player=setting.player_2
#以一個隨機時刻開始移動和攻擊計時器
self.action_timer=random.randint(0,int(action_interval))
self.attack_timer=random.randint(0,int(attack_interval))
#是否還存活
self.isalive=True
#是否是近戰(zhàn)
self.ismelee=False
#近戰(zhàn)攻擊生成次數(shù)
self.melee_count=1
#朝向(-1朝左,1朝右)
self.forward=-1
#圖像
self.surface=surface
self.surface_flip=pygame.transform.flip(self.surface,True,False)
#布局
self.rect=self.surface.get_rect()
#出生位置
self.rect.center=generate_point
#生命屬性
self.max_health=health
self.health=self.max_health
#生命條布局
self.health_rect_background=pygame.Rect(self.rect.centerx-10,self.rect.centery-30,50,20)
self.health_rect=pygame.Rect(self.rect.centerx-10,self.rect.centery-30,self.health/self.max_health*50,20)
#移動方向
self.direction_x=0.0
self.direction_y=0.0
def update(self):
"""更新狀態(tài)"""
self.flip()
self.auto_move()
self.update_health_ui()
def draw(self):
"""繪制圖像"""
if self.forward==-1:
self.screen.blit(self.surface,self.rect)
else:
self.screen.blit(self.surface_flip,self.rect)
#繪制生命條
pygame.draw.rect(self.screen,(200,200,200),self.health_rect_background)
pygame.draw.rect(self.screen,(30,30,30),self.health_rect)
def flip(self):
"""更新當前朝向"""
if (self.rect.centerx-self.player.rect.centerx)>=0:
self.forward=-1
else:
self.forward=1
def update_health_ui(self,x=-25,y=-40,width=50,height=10):
"""更新血量ui"""
self.health_rect_background=pygame.Rect(self.rect.centerx+x,self.rect.centery+y,width,height)
self.health_rect=pygame.Rect(self.rect.centerx+x,self.rect.centery+y,self.health/self.max_health*width,height)
def auto_move(self):
"""自主更新位置"""
pass
class Mage(Enemy):
"""小法師"""
def __init__(self,setting,screen):
super().__init__(setting,screen,setting.enemy_mage_surface,setting.enemy_genrate_point,
setting.enemy_mage_health,setting.enemy_mage_move_speed,setting.enemy_mage_action_interval,
setting.enemy_mage_attack_interval,setting.enemy_mage_weight,setting.enemy_mage_score)
self.rect.centery+=random.randint(-150,150)
def auto_move(self):
"""上下隨機移動"""
if(self.action_timer<=0):
self.direction_x=0
self.direction_y=random.uniform(-2,2)
#重置計時器
self.action_timer=self.action_interval
elif(self.action_timer%2==0):
#移動不能超出窗口
if self.rect.left > 0 and self.direction_x<0:
self.rect.centerx+=self.direction_x*self.speed
if self.rect.right < self.screen_rect.right and self.direction_x>0:
self.rect.centerx+=self.direction_x*self.speed
if self.rect.bottom < self.screen_rect.bottom and self.direction_y>0:
self.rect.centery+=self.direction_y*self.speed
if self.rect.top > 0 and self.direction_y<0:
self.rect.centery+=self.direction_y*self.speed
self.action_timer-=1
else:
self.action_timer-=1
def auto_attack(self):
"""返回攻擊物"""
return effect.EnemyFireBall(self.setting,self.screen,self.player,self)
class Warrior(Enemy):
"""小戰(zhàn)士"""
def __init__(self,setting,screen):
super().__init__(setting,screen,setting.enemy_warrior_surface,setting.enemy_genrate_point,
setting.enemy_warrior_health,setting.enemy_warrior_move_speed,setting.enemy_warrior_action_interval,
setting.enemy_warrior_attack_interval,setting.enemy_warrior_weight,setting.enemy_warrior_score)
self.ismelee=True
self.rect.centerx+=random.randint(-100,0)
self.rect.centery+=random.randint(-120,120)
def auto_move(self):
"""朝向目標玩家移動"""
if(self.action_timer<=0):
if self.player.rect.centerx-self.rect.centerx<=0:
self.direction_x=random.uniform(-2,-1)
else:
self.direction_x=random.uniform(1,2)
if self.player.rect.centery-self.rect.centery<=0:
self.direction_y=random.uniform(-2,-1)
else:
self.direction_y=random.uniform(1,2)
#重置計時器
self.action_timer=self.action_interval
elif(self.action_timer%2==0):
#移動不能超出窗口
if self.rect.left > 0 and self.direction_x<0:
self.rect.centerx+=self.direction_x*self.speed
if self.rect.right < self.screen_rect.right and self.direction_x>0:
self.rect.centerx+=self.direction_x*self.speed
if self.rect.bottom < self.screen_rect.bottom and self.direction_y>0:
self.rect.centery+=self.direction_y*self.speed
if self.rect.top > 0 and self.direction_y<0:
self.rect.centery+=self.direction_y*self.speed
self.action_timer-=1
else:
self.action_timer-=1
def auto_attack(self):
return effect.EnemyCollide(self.setting,self.screen,self.player,self)
class Artillery(Enemy):
"""小炮兵"""
def __init__(self,setting,screen):
super().__init__(setting,screen,setting.enemy_artillery_surface,setting.enemy_genrate_point,
setting.enemy_artillery_health,setting.enemy_artillery_move_speed,setting.enemy_artillery_action_interval,
setting.enemy_artillery_attack_interval,setting.enemy_artillery_weight,setting.enemy_artillery_score)
self.rect.centery+=random.randint(-200,200)
def auto_move(self):
"""遠離玩家移動"""
if(self.action_timer<=0):
if self.player.rect.centerx-self.rect.centerx<=0:
self.direction_x=random.uniform(1,2)
else:
self.direction_x=random.uniform(-2,-1)
if self.player.rect.centery-self.rect.centery<=0:
self.direction_y=random.uniform(1,2)
else:
self.direction_y=random.uniform(-2,-1)
#重置計時器
self.action_timer=self.action_interval
elif(self.action_timer%2==0):
#移動不能超出窗口
if self.rect.left > 0 and self.direction_x<0:
self.rect.centerx+=self.direction_x*self.speed
if self.rect.right < self.screen_rect.right and self.direction_x>0:
self.rect.centerx+=self.direction_x*self.speed
if self.rect.bottom < self.screen_rect.bottom and self.direction_y>0:
self.rect.centery+=self.direction_y*self.speed
if self.rect.top > 0 and self.direction_y<0:
self.rect.centery+=self.direction_y*self.speed
self.action_timer-=1
else:
self.action_timer-=1
def auto_attack(self):
return effect.EnemyTargetBall(self.setting,self.screen,self.player,self)
class Overlord(Enemy):
"""大宿主"""
def __init__(self,setting,screen):
super().__init__(setting,screen,setting.enemy_overlord_surface,setting.enemy_genrate_point,
setting.enemy_overlord_health,setting.enemy_overlord_move_speed,setting.enemy_overlord_action_interval,
setting.enemy_overlord_attack_interval,setting.enemy_overlord_weight,setting.enemy_overlord_score)
self.rect.centerx-=random.randint(0,300)
#眼睛的圖像
self.eye_surface=setting.enemy_eye_surface
self.eye_rect=self.eye_surface.get_rect()
self.eye_rect.center=self.rect.center
#半徑的平方
self.radius=12**2
def eye_move(self):
"""眼睛移動向玩家"""
move_x=0
move_y=0
if self.player.rect.centerx-self.rect.centerx>=0:
move_x+=1
else:
move_x-=1
if self.player.rect.centery-self.rect.centery>=0:
move_y+=1
else:
move_y-=1
#計算和圓心的距離
delta_x=((self.eye_rect.centerx+move_x)-self.rect.centerx)
delta_y=((self.eye_rect.centery+move_y)-self.rect.centery)
#如果超出半徑,則往回移動,否則朝目標移動
if (delta_x**2+delta_y**2)<self.radius:
self.eye_rect.centerx+=move_x
self.eye_rect.centery+=move_y
else:
if delta_x<=0:
self.eye_rect.centerx+=1
else:
self.eye_rect.centerx-=1
if delta_y<=0:
self.eye_rect.centery+=1
else:
self.eye_rect.centery-=1
def update(self):
"""更新狀態(tài)"""
self.flip()
self.eye_move()
self.update_health_ui(y=-100,x=-50,width=100,height=15)
def auto_attack(self):
"""隨機選擇一種攻擊返回"""
i=random.randint(0,1)
if i==0:
return effect.EnemyRingAttack(self.setting,self.screen,self.player,self)
else:
return effect.EnemyShoot(self.setting,self.screen,self.player,self)
def draw(self):
"""繪制自身和眼睛"""
super().draw()
self.screen.blit(self.eye_surface,self.eye_rect)
總結(jié)
源碼有點多,所以就不都給大家展示啦
需要源碼的小伙伴看文章末尾找到小編領(lǐng)取哈文章來源地址http://www.zghlxwxcb.cn/news/detail-766746.html
到了這里,關(guān)于【Python游戲】Python實現(xiàn)低配版王者榮耀,除了沒有打野啥都有,你確定不心動嘛?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!