前几天看到自己四年前看过的文章,闲来无事,也做了一个玩玩
https://blog.csdn.net/abcdu472390947/article/details/84589224/
主类
'''
主程序入口
'''
import sys
import time
from collections import deque
import pygame
from MainMenu import main_menu_scr
def init():
pygame.init()
clock = pygame.time.Clock()
clock.tick(30)
screen = pygame.display.set_mode((1024, 512))
pygame.display.set_caption('TextRPG')
return screen
if __name__ == "__main__":
pages = deque()
addpages = {
}
screen = init()
main_menu = main_menu_scr(addpages)
pages.append(main_menu)
args = []
while len(pages)>0:
args = pages[-1].disp(screen, pages, addpages, args)
pygame.quit()
sys.exit()
主菜单
'''
主菜单类
'''
import pygame
from WorldMap import WorldMap_page
class main_menu_scr:
def __init__(self, addpages:dict) -> None:
addpages[self] = [WorldMap_page(addpages)]
pass
def disp(self, screen, pages, addpages:dict, *args):
options = ["开始游戏", "结束游戏"]
selected_option = 0
running = True
game_started = False
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
selected_option -= 1
elif event.key == pygame.K_DOWN:
selected_option += 1
elif event.key == pygame.K_SPACE:
if selected_option == 0 and not game_started:
# print("游戏开始了")
game_started = True
pages.append(addpages[self][0])
return
elif selected_option == 1:
running = False
selected_option %= len(options)
# 清屏
screen.fill((0, 0, 0))
# 显示主菜单
for i in range(len(options)):
if i == selected_option:
text = "-> " + options[i] + " <-"
color = (255, 255, 255) # 白色
else:
text = options[i]
color = (128, 128, 128) # 灰色
font = pygame.font.SysFont('simHei', 32) # 使用系统中可用的 "simHei" 字体
text_surface = font.render(text, True, color)
text_rect = text_surface.get_rect(center=(screen.get_size()[0]/2, screen.get_size()[1]/2 + i * 50))
screen.blit(text_surface, text_rect)
pygame.display.flip()
大地图
import random
import pygame
from Village import village_page
from Battle import BattleSrc
class WorldMap_page:
def __init__(self, addpages) -> None:
addpages[self] = [village_page(addpages), BattleSrc(addpages)]
# 读取地图文件
map_filename = "WorldMap.csv"
try:
with open(map_filename, "r") as file:
self.map_data = [line.strip().replace(",",'') for line in file.readlines()]
except FileNotFoundError:
print(f"Error: Cannot find file '{map_filename}'")
return
# 确定行数和列数
c = len(self.map_data)
r = len(self.map_data[0])
self.player_pos = [(x,y) for x in range(c) for y in range(r) if self.getmap((x,y))=="初"][0]
pass
def getmap(self, pos):
return self.map_data[pos[0]][pos[1]]
def disp(self, screen, pages, addpages:dict, pos)->list:
#初始化
# 设置单元大小和字体
unit_size = 32
font = pygame.font.SysFont('simHei', unit_size)
# 确定行数和列数
c = len(self.map_data)
r = len(self.map_data[0])
# 计算地图绘制区域的大小
map_area_width = r * unit_size
map_area_height = c * unit_size
# 计算地图绘制区域的左上角坐标
map_area_x = (screen.get_width() - map_area_width) // 2
map_area_y = (screen.get_height() - map_area_height) // 2
player_pos = self.player_pos # 初始化人物位置
#循环体
running = True
isMoved = False
while running:
# 位置处理
if isMoved and self.getmap(player_pos) == "村":
pages.append(addpages[self][0])
return [player_pos]
# 事件处理
if isMoved and random.randint(1, 16) == 1:
# 遇敌
pages.append(addpages[self][1])
return [player_pos]
isMoved = False
# 接受操作
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
exit()
elif event.type == pygame.KEYDOWN:
dirkeys = [pygame.K_UP,pygame.K_DOWN,pygame.K_LEFT,pygame.K_RIGHT]
movposs = [[-1,0],[1,0],[0,-1],[0,1]]
for i in range(len(dirkeys)):
if event.key != dirkeys[i]:
continue
newPos = [x+y for x,y in zip(player_pos,movposs[i])]
# print(newPos)
if not 0 <= newPos[0] < c or not 0<=newPos[1] <r:
print("出界")
break
if self.getmap(newPos) == "无":
print("无")
break
player_pos = newPos
self.player_pos = player_pos
isMoved = True
# 清屏
screen.fill((0, 0, 0))
# 绘制土黄区域作为地图背景
pygame.draw.rect(screen, (205, 133, 63), (map_area_x, map_area_y, map_area_width, map_area_height))
# 绘制
# 在黑色区域中绘制地图内容
for i in range(c):
for j in range(r):
char = self.map_data[i][j]
if char == "村":
text_surface = font.render(char, True, (255, 255, 255))
text_rect = text_surface.get_rect()
text_rect.topleft = (map_area_x + j * unit_size, map_area_y + i * unit_size)
screen.blit(text_surface, text_rect)
elif char == "无":
pygame.draw.rect(screen, (0, 0, 0), (map_area_x + j * unit_size, map_area_y + i * unit_size, unit_size, unit_size))
# 绘制人物位置
player_char = "♀"
text_surface = font.render(player_char, True, (255, 0, 0)) # 红色表示人物
text_rect = text_surface.get_rect()
text_rect.topleft = (map_area_x + player_pos[1] * unit_size, map_area_y + player_pos[0] * unit_size)
screen.blit(text_surface, text_rect)
pygame.display.flip()
战斗类
import pygame
from TextSys import dispText, WHITE, RED, GREEN
from Enemy import enemies
from Character import player
class BattleSrc:
def __init__(self, addpages:dict) -> None:
pass
def disp(self, screen:pygame.Surface, pages:list, addpages:dict, wmpos)->list:
#初始化
options = ["攻击","技能","物品","逃跑"]
selected_option = 0
actors = [player, enemies[0]]
actor = player
enemies[0].HP = enemies[0].MHP
#循环体
running = True
Texting = True
isReturn = False
text = f"野生的{enemies[0].name}出现了"
gif_image = pygame.image.load(r'resource\image\Slime\Slime_Front11.png')
original_width, original_height = gif_image.get_size()
gif_image = pygame.transform.scale(gif_image, (original_width * 8, original_height * 8))
# 控制闪烁效果的透明度
alpha = 255
alpha_direction = -2 # 透明度改变的方向和速度
while running:
#接受操作
for event in pygame.event.get():
if event.type == pygame.QUIT:
# running = False
pass
elif event.type == pygame.KEYDOWN:
if Texting:
if event.key == pygame.K_SPACE:
Texting = False
if isReturn:
pages.pop()
return [wmpos]
if actor == enemies:
# 敌方行动
damage = [enemies[0].attack if not player.armor else enemies[0].attack-player.armor.attack][0]
text = f"{enemies[0].name}对你造成了{damage}点伤害"
Texting = True
player.HP-=damage
actor = player
else:
if actor == player:
if event.key == pygame.K_UP:
selected_option -= 1
elif event.key == pygame.K_DOWN:
selected_option += 1
elif event.key == pygame.K_SPACE:
if selected_option == 0:
damage = [2 if not player.weapon else player.weapon.attack-enemies[0].defense][0]
text = f"你对{enemies[0].name}造成了{damage}点伤害"
Texting = True
enemies[0].HP-=damage
actor = enemies
selected_option %= len(options)
# 清屏
screen.fill((0, 0, 0))
# 绘制文本
dispText(screen, text, bottomleft=(128, 128*3), color=[(255, 255, 255) if Texting else (128, 128, 128)][0])
# 绘制己方状态
# 计算血量百分比
health_percentage = player.getHPpct()
# 绘制血量条
HPbarpos = (128*6,128*3)
health_bar_width = 200
health_bar_height = 20
health_bar_fill_width = int((health_percentage / 100) * health_bar_width)
health_bar_rect = pygame.Rect(HPbarpos[0], HPbarpos[1], health_bar_width, health_bar_height)
health_bar_fill_rect = pygame.Rect(HPbarpos[0], HPbarpos[1], health_bar_fill_width, health_bar_height)
pygame.draw.rect(screen, RED, health_bar_rect)
pygame.draw.rect(screen, GREEN, health_bar_fill_rect)
# 显示血量百分比
# font = pygame.font.SysFont(None, 30)
# # hptext = f"Health: {health_percentage}%"
# text_surface = font.render(hptext, True, WHITE)
# screen.blit(text_surface, (HPbarpos[0], HPbarpos[1]))
# 绘制敌方状态
# 计算血量百分比
health_percentage = enemies[0].getHPpct()
# 绘制敌方血量条
HPbarpos = (16*26,16*17)
health_bar_width = 200
health_bar_height = 20
health_bar_fill_width = int((health_percentage / 100) * health_bar_width)
health_bar_rect = pygame.Rect(HPbarpos[0], HPbarpos[1], health_bar_width, health_bar_height)
health_bar_fill_rect = pygame.Rect(HPbarpos[0], HPbarpos[1], health_bar_fill_width, health_bar_height)
pygame.draw.rect(screen, RED, health_bar_rect)
pygame.draw.rect(screen, GREEN, health_bar_fill_rect)
# 绘制行动选项
for i in range(len(options)):
optext = options[i]
if i == selected_option and not Texting:
color = (255, 255, 255) # 白色
else:
color = (128, 128, 128) # 灰色
dispText(screen, optext, bottomleft=(64, 64 + i * 64), color=color)
# 绘制敌方
alpha += alpha_direction
if alpha <= 0 or alpha >= 255:
alpha_direction *= -1
gif_image.set_alpha(alpha)
gif_rect = gif_image.get_rect()
gif_rect.center = (screen.get_size()[0] // 2, screen.get_size()[1] // 2-gif_image.get_height()/2)
screen.blit(gif_image, gif_rect)
# 死亡事件
if enemies[0].HP <= 0:
text = f"{enemies[0].name}倒下了"
Texting = True
isReturn = True
pygame.display.flip()
村庄类
from typing import Callable
import pygame
from TextSys import dispText
from WeaponShop import WeaponShopScr
class village_page:
def __init__(self, addpages:dict[Callable,list]) -> None:
addpages[self] = [WeaponShopScr(addpages)]
pass
def disp(self, screen, pages:list, addpages:dict, wmpos):
options = ["武器店", "防具店", "道具店", "旅馆", "离开村庄"]
selected_option = 0
# dispText(screen, "game start", center=(screen.get_width() // 2, screen.get_height() // 2))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
selected_option -= 1
elif event.key == pygame.K_DOWN:
selected_option += 1
elif event.key == pygame.K_SPACE:
if selected_option == 0:
pages.append(addpages[self][0])
return [wmpos]
elif selected_option == 4:
pages.pop()
return [wmpos]
selected_option %= len(options)
# 清屏
screen.fill((0, 0, 0))
# 显示主菜单
for i in range(len(options)):
text = options[i]
if i == selected_option:
color = (255, 255, 255) # 白色
else:
color = (128, 128, 128) # 灰色
dispText(screen, text, bottomleft=(0, 50 + i * 50), color=color)
pygame.display.flip()