Implement vim-style (j/k) and curses-style (ctrl+n/p) menu controls

pull/1/head
Jake Funke 2017-03-16 20:01:08 +00:00
parent 948adec959
commit b2d1c62323
2 changed files with 32 additions and 24 deletions

View File

@ -36,7 +36,7 @@ from menu_screen import *
# - create rarer species by diff gens # - create rarer species by diff gens
# - if neighbor plant dies, node will be removed from list # - if neighbor plant dies, node will be removed from list
# #
# build ascii trees # build ascii plant art
# Make it fun to keep growing after seed level (what is reward for continuing # Make it fun to keep growing after seed level (what is reward for continuing
# instead of starting over? # instead of starting over?
@ -89,6 +89,13 @@ class Plant(object):
10: 'cannabis', 10: 'cannabis',
11: 'pansy', 11: 'pansy',
12: 'iris', 12: 'iris',
13: 'agave',
14: 'ficus',
15: 'lichen',
16: 'sage',
17: 'snapdragon',
18: 'columbine',
19: 'brugmansia',
} }
mutation_dict = { mutation_dict = {
@ -138,8 +145,8 @@ class Plant(object):
# Constructor # Constructor
self.plant_id = str(uuid.uuid4()) self.plant_id = str(uuid.uuid4())
# TODO: change from debug # TODO: change from debug
self.life_stages = (10, 20, 30, 40, 50) # self.life_stages = (10, 20, 30, 40, 50)
# self.life_stages = (3600, (3600*24)*3, (3600*24)*10, (3600*24)*20, (3600*24)*30) self.life_stages = (3600*24, (3600*24)*3, (3600*24)*10, (3600*24)*20, (3600*24)*30)
self.stage = 0 self.stage = 0
self.mutation = 0 self.mutation = 0
self.species = random.randint(0,len(self.species_dict)-1) self.species = random.randint(0,len(self.species_dict)-1)
@ -222,7 +229,7 @@ class Plant(object):
# Create plant mutation # Create plant mutation
# TODO: when out of debug this needs to be set to high number (1000 # TODO: when out of debug this needs to be set to high number (1000
# even maybe) # even maybe)
CONST_MUTATION_RARITY = 2000 # Increase this # to make mutation rarer (chance 1 out of x) CONST_MUTATION_RARITY = 3000 # Increase this # to make mutation rarer (chance 1 out of x)
mutation_seed = random.randint(1,CONST_MUTATION_RARITY) mutation_seed = random.randint(1,CONST_MUTATION_RARITY)
if mutation_seed == CONST_MUTATION_RARITY: if mutation_seed == CONST_MUTATION_RARITY:
# mutation gained! # mutation gained!
@ -275,11 +282,6 @@ class Plant(object):
def life(self): def life(self):
# I've created life :) # I've created life :)
# TODO: change out of debug
# TODO: variable stages of life
# day = 3600*24
# life_stages = (1*day, 2*day, 3*day, 4*day, 5*day)
# leave this untouched bc it works for now
while True: while True:
time.sleep(1) time.sleep(1)
if not self.dead: if not self.dead:
@ -291,14 +293,15 @@ class Plant(object):
if self.mutate_check(): if self.mutate_check():
1==1 1==1
if self.water_check(): if self.water_check():
# Do something
1==1 1==1
if self.dead_check(): if self.dead_check():
# Do something else
1==1 1==1
# TODO: event check # TODO: event check
class DataManager(object): class DataManager(object):
# handles user data, puts a .botany dir in user's home dir (OSX/Linux) # handles user data, puts a .botany dir in user's home dir (OSX/Linux)
# TODO: windows... lol
user_dir = os.path.expanduser("~") user_dir = os.path.expanduser("~")
botany_dir = os.path.join(user_dir,'.botany') botany_dir = os.path.join(user_dir,'.botany')
game_dir = os.path.dirname(os.path.realpath(__file__)) game_dir = os.path.dirname(os.path.realpath(__file__))
@ -338,8 +341,7 @@ class DataManager(object):
autosave_thread.start() autosave_thread.start()
def death_check_update(self,this_plant): def death_check_update(self,this_plant):
# .1 second updates to minimize race condition # .1 second updates and lock to minimize race condition
# TODO: improve how this is handled to eliminate race condition
while True: while True:
is_dead = this_plant.dead_check() is_dead = this_plant.dead_check()
if is_dead: if is_dead:

View File

@ -1,7 +1,6 @@
import curses, os, traceback, threading, time, datetime, pickle, operator, random import curses, os, traceback, threading, time, datetime, pickle, operator, random
class CursedMenu(object): class CursedMenu(object):
#TODO: create a side panel with log of events..?
#TODO: name your plant #TODO: name your plant
'''A class which abstracts the horrors of building a curses-based menu system''' '''A class which abstracts the horrors of building a curses-based menu system'''
def __init__(self, this_plant, this_garden_file_path): def __init__(self, this_plant, this_garden_file_path):
@ -65,8 +64,6 @@ class CursedMenu(object):
def draw(self): def draw(self):
# Draw the menu and lines # Draw the menu and lines
# TODO: this needs to either display the default menu screen or the
# garden/leaderboard thing
# TODO: display refresh is hacky. Could be more precise # TODO: display refresh is hacky. Could be more precise
self.screen.refresh() self.screen.refresh()
try: try:
@ -162,15 +159,21 @@ class CursedMenu(object):
user_in = self.screen.getch() # Gets user input user_in = self.screen.getch() # Gets user input
except Exception as e: except Exception as e:
self.__exit__() self.__exit__()
# DEBUG KEYS
# self.screen.addstr(1, 1, str(user_in), curses.A_NORMAL)
# self.screen.refresh()
# Resize sends curses.KEY_RESIZE, update display
if user_in == curses.KEY_RESIZE:
self.maxy,self.maxx = self.screen.getmaxyx()
self.screen.clear()
self.screen.refresh()
# enter and exit Keys are special cases # enter and exit Keys are special cases
if user_in == 10: if user_in == 10:
return self.options[self.selected] return self.options[self.selected]
if user_in == 27: if user_in == 27:
return self.options[-1] return self.options[-1]
if user_in == curses.KEY_RESIZE:
self.maxy,self.maxx = self.screen.getmaxyx()
self.screen.clear()
self.screen.refresh()
# this is a number; check to see if we can set it # this is a number; check to see if we can set it
if user_in >= ord('1') and user_in <= ord(str(min(9,len(self.options)+1))): if user_in >= ord('1') and user_in <= ord(str(min(9,len(self.options)+1))):
@ -178,9 +181,11 @@ class CursedMenu(object):
return return
# increment or Decrement # increment or Decrement
if user_in == curses.KEY_DOWN: # down arrow down_keys = [curses.KEY_DOWN, 14, 106]
up_keys = [curses.KEY_UP, 16, 107]
if user_in in down_keys: # down arrow
self.selected += 1 self.selected += 1
if user_in == curses.KEY_UP: # up arrow if user_in in up_keys: # up arrow
self.selected -=1 self.selected -=1
self.selected = self.selected % len(self.options) self.selected = self.selected % len(self.options)
return return
@ -344,16 +349,17 @@ class CursedMenu(object):
# load data # load data
# format data # format data
if self.infotoggle != 1: if self.infotoggle != 1:
# TODO: clear the bar first
# TODO: when garden grows this won't clear everything. # TODO: when garden grows this won't clear everything.
output_string = clear_bar * 8 # for example if there are 9 people in garden it won't clear all
# of them
output_string = clear_bar * (self.maxy - 15)
for y, line in enumerate(output_string.splitlines(), 2): for y, line in enumerate(output_string.splitlines(), 2):
self.screen.addstr(y+12, 2, line) self.screen.addstr(y+12, 2, line)
self.screen.refresh() self.screen.refresh()
output_string = self.get_plant_description(this_plant) output_string = self.get_plant_description(this_plant)
self.infotoggle = 1 self.infotoggle = 1
else: else:
output_string = clear_bar * 4 output_string = clear_bar * 3
self.infotoggle = 0 self.infotoggle = 0
for y, line in enumerate(output_string.splitlines(), 2): for y, line in enumerate(output_string.splitlines(), 2):