Last active
July 12, 2021 11:34
-
-
Save KatsumiKougen/0b339c070d797e0042390008a1a62817 to your computer and use it in GitHub Desktop.
Non-graphical turn-based combat game using Tkinter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random as r, tkinter as tk, namemaker, sys, time | |
from tkinter import ttk, messagebox as mb | |
if len(sys.argv) < 2: | |
raise OSError("Please enter a name, like this \"python3 battle.py [player_name]\"") | |
PLAYER_NAME = sys.argv[1] | |
BOSS_NAME = namemaker.randomName(4, "cv").capitalize() | |
BOSS_SPECIES = namemaker.randomName(r.randint(2, 5), "cvc").capitalize() | |
player_data = { | |
"maxhealth": 200, | |
"health": 200, | |
"atk": 21, | |
"def": 35, | |
} | |
boss_data = { | |
"maxhealth": 400, | |
"health": 400, | |
"atk": 34, | |
"def": 19 | |
} | |
win = tk.Tk() | |
win.title(f"{BOSS_NAME} emerges!") | |
win.geometry("500x500") | |
title = tk.Frame(master=win) | |
status = tk.Frame(master=win) | |
command = tk.Frame(master=win) | |
battle_lb = tk.Label( | |
master=title, | |
text=f"Get ready for rumble...!\n{PLAYER_NAME} vs {BOSS_NAME} the {BOSS_SPECIES}", | |
font=("Ubuntu", 13) | |
) | |
health_section = tk.Frame(master=status) | |
player = { | |
"name": tk.Label( | |
master=health_section, | |
text=PLAYER_NAME, | |
font=("Ubuntu Condensed", 14) | |
), | |
"health": ttk.Progressbar( | |
master=health_section, | |
mode="determinate", | |
orient=tk.HORIZONTAL, | |
length=280, | |
maximum=100 | |
) | |
} | |
boss = { | |
"name": tk.Label( | |
master=health_section, | |
text=BOSS_NAME, | |
font=("Ubuntu Condensed", 14) | |
), | |
"health": ttk.Progressbar( | |
master=health_section, | |
mode="determinate", | |
orient=tk.HORIZONTAL, | |
length=280, | |
maximum=100 | |
) | |
} | |
status_text = tk.Label( | |
master=status, | |
text=f"It is time to fight {BOSS_NAME}!\nChoose your move!", | |
fg="#ffffff", | |
bg="#000000", | |
font=("Ubuntu", 11) | |
) | |
def terminate_window(): | |
win.destroy() | |
def attack(): | |
if player_data["health"] < 20: | |
player["health"].step(0.1) | |
for button in command_button: | |
button["state"] = tk.DISABLED | |
status_text["text"] = f"{BOSS_NAME} defeats you!" | |
command = tk.Frame(master=win) | |
exit_button = tk.Button( | |
master=command, | |
text="Exit", | |
font=("Ubuntu", 14), | |
height=3, | |
width=9, | |
command=terminate_window | |
) | |
exit_button.grid(row=0, column=0) | |
command.grid(row=2, column=0) | |
elif boss_data["health"] < 20: | |
boss["health"].step(0.1) | |
for button in command_button: | |
button["state"] = tk.DISABLED | |
status_text["text"] = f"{BOSS_NAME} is defeated! You win!" | |
command = tk.Frame(master=win) | |
exit_button = tk.Button( | |
master=command, | |
text="Exit", | |
font=("Ubuntu", 14), | |
height=3, | |
width=9, | |
command=terminate_window | |
) | |
exit_button.grid(row=0, column=0) | |
command.grid(row=2, column=0) | |
else: | |
if r.choice((True, False, False, False)): | |
mb.showwarning( | |
title="Missed!", | |
message=f"{PLAYER_NAME} missed!" | |
) | |
else: | |
damage = abs(r.randint(12, 19) + player_data["atk"] - boss_data["def"]) | |
boss_data["health"] -= damage | |
mb.showwarning( | |
title="That hurts!", | |
message=f"{BOSS_NAME} deals {damage} {'point' if damage == 1 else 'points'} of damage!" | |
) | |
boss["health"]["value"] = (health_step("b")) | |
if r.choice((True, True, False, False)): | |
mb.showwarning( | |
title="Surprise!", | |
message=f"{BOSS_NAME} missed!" | |
) | |
else: | |
damage = abs(r.randint(10, 16) + boss_data["atk"] - player_data["def"]) | |
player_data["health"] -= damage | |
mb.showwarning( | |
title="Unbelievable!", | |
message=f"{PLAYER_NAME} deals {damage} {'point' if damage == 1 else 'points'} of damage!" | |
) | |
player["health"]["value"] = (health_step("p")) | |
command_button = [ | |
tk.Button( | |
master=command, | |
text="Fire attack", | |
font=("Ubuntu", 14), | |
height=3, | |
width=9, | |
command=attack | |
), | |
tk.Button( | |
master=command, | |
text="Water blast", | |
font=("Ubuntu", 14), | |
height=3, | |
width=9, | |
command=attack | |
), | |
tk.Button( | |
master=command, | |
text="Punch", | |
font=("Ubuntu", 14), | |
height=3, | |
width=9, | |
command=attack | |
), | |
tk.Button( | |
master=command, | |
text="Kick", | |
font=("Ubuntu", 14), | |
height=3, | |
width=9, | |
command=attack | |
), | |
] | |
def health_step(entity: str) -> float: | |
if entity in ("player", "p"): | |
return round(100*(player_data["health"]/player_data["maxhealth"]), 1) | |
elif entity in ("boss", "b"): | |
return round(100*(boss_data["health"]/boss_data["maxhealth"]), 1) | |
def init(): | |
battle_lb.grid(row=0, column=0) | |
for j, i in enumerate(("name", "health")): | |
player[i].grid(row=0, column=0+j) | |
boss[i].grid(row=1, column=0+j) | |
health_section.grid(row=0, column=0) | |
status_text.grid(row=1, column=0) | |
for i, r, c in zip(command_button, "0011", "0101"): | |
i.grid(row=int(r), column=int(c)) | |
title.grid(row=0, column=0) | |
status.grid(row=1, column=0) | |
command.grid(row=2, column=0) | |
player["health"].step(100-0.1) | |
boss["health"].step(100-0.1) | |
init() | |
win.mainloop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Requires
namemaker.py