Jul-23-2018, 12:57 AM
I'm working on refining my strategy for writing a game. I would like to know what you lot think about it. Hoping you'll point out the flaws, and let me know what you think.
I'm working on a project like Asteroids, there's not much to the game, you can fly around, shoot at rocks and try not to get killed. If a rock hits the craft its game over. If the craft goes off the screen I want the autopilot to get the craft back on the screen. I been finding the process of implementing a realistic autopilot challenging. Here are some of the steps it goes through:
- Turn the craft around in the opposite direction that its flying in.
- Apply the thruster to come to a complete stop.
- Turn the craft to point at the center of the screen.
- Apply thrusters at the right time to glide the craft back on the screen.
To make it more realistic the routines can't just keep looping until the task was done because I want the game to do other things like refresh the screen. I orginally achieved 65% of this with block if statements, but decided things were growing and it was starting to look untidy and hard to manage. I like to make things easy, so I thought what if I created a list of tasks to achieve the same thing, wouldn't that be easier?
PS. The AutoPilot class is a work-in-progress, an idea I have for how I would like handle the steps needed to achieve a goal, like returning a craft that has gone off the screen and returning it the centre of the screen.
I'm working on a project like Asteroids, there's not much to the game, you can fly around, shoot at rocks and try not to get killed. If a rock hits the craft its game over. If the craft goes off the screen I want the autopilot to get the craft back on the screen. I been finding the process of implementing a realistic autopilot challenging. Here are some of the steps it goes through:
- Turn the craft around in the opposite direction that its flying in.
- Apply the thruster to come to a complete stop.
- Turn the craft to point at the center of the screen.
- Apply thrusters at the right time to glide the craft back on the screen.
To make it more realistic the routines can't just keep looping until the task was done because I want the game to do other things like refresh the screen. I orginally achieved 65% of this with block if statements, but decided things were growing and it was starting to look untidy and hard to manage. I like to make things easy, so I thought what if I created a list of tasks to achieve the same thing, wouldn't that be easier?
PS. The AutoPilot class is a work-in-progress, an idea I have for how I would like handle the steps needed to achieve a goal, like returning a craft that has gone off the screen and returning it the centre of the screen.
def enum(*args): # --------------------------------------------------------------------------- # Used to create enumate values. # # Example: # fruits =enum("APPLES", "ORANGES", "PEARS") # if fruits.APPLES ==fruits.ORANGES: # print("they're the same.") # # --------------------------------------------------------------------------- enums =dict(zip(args, range(len(args)))) return type('Enum', (), enums) # enum() -------------------------------------------------------------------- class MemSpace: pass # MemSpace ------------------------------------------------------------------ class Task: _list =[] statuses =enum("WAITING", "INIT", "RUNNING", "COMPLETED") def __init__(self): self.var =MemSpace() self.status =Task.statuses.WAITING Task._list.append(self) # __init__() ------------------------------------------------------------ @staticmethod def all_routines(): # Debug information. print("\n\nTASK LIST INFORMATION") print("-------------------------") for cp in Task._list: print(" name:", cp.var.name) print(" - status =", status_text(cp.status)) print("...\n\n") # _. # Run all the active routines. for cp in Task._list: cp.routine() # _. # --- Delete Completed Tasks --- something_running =False index =0 while index <len(Task._list): deleted_a_task =False cp =Task._list[index] if cp.status ==Task.statuses.COMPLETED: # We don't need this Task # anymore, delete it from our list. Task._list.pop(index) # Reset the search to start from # the top again because we messed # with the ordinal positions of # the list. deleted_a_task =True elif not cp.status ==Task.statuses.WAITING: # We can presume that task must # be initialising or running. something_running =True if not deleted_a_task: index +=1 if not something_running: # Looks like there's nothing # running, start the first task # we come across. Task.start_next() # all_routines() ----------------------------------------------------- @staticmethod def start_next(): # Looks at the list and starts the next Task. if len(Task._list) >0: # There's a task in the list. Task._list[0].status =Task.statuses.INIT # _start_next() --------------------------------------------------------- def routine(self): const =Task.statuses if not self.status in (const.WAITING, const.COMPLETED): self.var.routine(self) # routine() --------------------------------------------------------- # Task ------------------------------------------------------------------- class AutoPilot: @staticmethod def turn_craft_oaf(active_Task): # Turn the craft in the opposite angle of flight. var =active_Task.var print("\nRoutine 'turn_craft_oaf' called.") active_Task.status =Task.statuses.COMPLETED active_Task.owner ="Alan" # turn_craft_oaf() ------------------------------------------------------ @staticmethod def stationary_position(active_Task): var =active_Task.var print("\nRoutine 'stationary_position' called.") try: if var.cntr >= 2: active_Task.status =Task.statuses.COMPLETED print("\nTask 'stationary_position' has changed its status to COMPLETED.") except AttributeError: # Assume the counter was never set, # start it off at 0. var.cntr =0 var.cntr +=1 # stationary_position() ------------------------------------------------- # AutoPilot ----------------------------------------------------------------- def status_text(status_id): if status_id ==Task.statuses.WAITING: status_msg ="WAITING" elif status_id ==Task.statuses.INIT: status_msg ="INIT" elif status_id ==Task.statuses.RUNNING: status_msg ="RUNNING" elif status_id ==Task.statuses.COMPLETED: status_msg ="COMPLETED" else: status_msg ="UnKnown" return status_msg # status_text() ------------------------------------------------------------- # Create a task to turn the craft. my_task =Task() my_task.var.name ="Turn" my_task.var.target_angle =90 my_task.var.current_angle =10 my_task.var.routine =AutoPilot.turn_craft_oaf my_task.status =Task.statuses.INIT # _. # Create a task to bring the craft to a complete stop. my_task =Task() my_task.var.name ="Stationary" my_task.var.routine =AutoPilot.stationary_position # _. # Simulate the routines being run inside a large # game routine that's moving sprites around and # updating the screen. for x in range(5): # Run any additional tasks that might have # been created. Task.all_routines() # Perform animation tasks. # ... # Refresh the screen image. # ...
Output:TASK LIST INFORMATION
-------------------------
name: Turn
- status = INIT
name: Stationary
- status = WAITING
...
Routine 'turn_craft_oaf' called.
TASK LIST INFORMATION
-------------------------
name: Stationary
- status = INIT
...
Routine 'stationary_position' called.
TASK LIST INFORMATION
-------------------------
name: Stationary
- status = INIT
...
Routine 'stationary_position' called.
TASK LIST INFORMATION
-------------------------
name: Stationary
- status = INIT
...
Routine 'stationary_position' called.
Task 'stationary_position' has changed its status to COMPLETED.
TASK LIST INFORMATION
-------------------------
...
>>>