Boxhead herschapen in Python uit BenR op Vimeo.
Er is een fantastisch onderhoudend computerspel genaamd Boxhead, waar in wezen u en/of een tweede persoon bestrijden hordes Zombies en duivels aanvallen met verschillende wapens. Voor een computer wetenschap klasse dit jaar die ik neem, was het laatste project om opnieuw een computerspel in Python met Tkinter. Boxhead leek de logische keuze, en ik over het opnieuw instellen. Ik hoop dat u geniet van wat het geworden tot nu toe en ik hoop toe te voegen meer wapens, niveau met de objecten en een tweede speler in de toekomst.Vanaf nu kan Boxhead alleen vechten met een pistool en mijnen, maar het zou geweldig zijn om te beschikken over shotgun en raketten.
Voel je vrij om te kopiëren van de code en het zelf spelen of het toevoegen van wapens. Houd enkel in mening dat het programma en beelden binnen dezelfde map moeten worden gehouden en de beelden zijn in submappen. Bijvoorbeeld zijn de Boxhead beelden in een aparte map dan de Zombie-beelden. De Zombies gaan in de "zombies" submap, duivels in "duivels", boxhead in "boxhead" en mijn/bloed/duivel aanval (gele bol) in "spel elementen".
De besturingselementen voor verkeer bevinden "WASD", pauze "p", VN-pauze "o", schakelen tussen wapens "i" en "u". Bovenal echter is "ruimte" vuur.
Als u wilt spelen het spel alle van de beelden moest gaan samen met de code beschikbaar zijn hier samen met de code.
# Boxhead # By Ben Rothschild # Boxhead - a copy of the original game made in Python with Tkinter # Last Edit 12/14/2012 from Tkinter import * import random import time import math Window_Height = 550 # set the window height and width Window_Width = 800 X_Window_Buffer = 40 Y_Window_Buffer = 40 canvas = Canvas(highlightthickness=0, height=Window_Height, width=Window_Width) canvas.master.title("Boxhead") canvas.pack() Main = canvas.create_rectangle(0,0,Window_Width,Window_Height,fill="#EBDCC7", belowThis = None) # create the base color similar to that of the Boxhead game pic = PhotoImage(width=Window_Width, height=Window_Height) canvas.create_image(0,0,image=pic,anchor=NW) Zombie_Dict_Made = False # have the Zombies and Boxhead been created? boxhead_made = False Run_Game = True New_Level = False B_move_length = 2 # Some the game attributes that change and are used for the initial setup. Most would be better in a central Game Class Zombie_per_move = .5 Devil_move = 1 direction = 1 shot_duration = .01 Zombie_Buffer = 30 kill_zone = 15 Number_of_Zombies = 5 total_devil_attacks = 0 blood_marks = 0 number_of_mines = 0 global pause_game # pause the game if 'P' is pressed or start it up if 'O' is pressed pause_game = False Mines_Dict = {} # holds all of the mines Zombie_Dict = {} # Where the Zombies are kept - elements are deleted as Boxhead shoots them Devil_Dict = {} # same as Zombie_Dict but for Devils Dead_Zombie_List = [] Devil_Attack_Dict = {} # The spheres that the Devils can attack with class Edge_limits(object): """Tells limits in x any y direction to objects so that they don't run off of the game screen""" def __init__(self): self.x_start = 2*X_Window_Buffer - 20 self.y_start = 3*Y_Window_Buffer -35 self.x_end = Window_Width - X_Window_Buffer - 20 self.y_end = Window_Height - Y_Window_Buffer - 20 class Buffer(object): """The edge buffers for the game""" def __init__ (self,x_start,y_start,x_end,y_end,fill): canvas.create_rectangle(x_start,y_start,x_end,y_end,fill = fill) left_buffer = Buffer(0,0,(X_Window_Buffer),(Y_Window_Buffer+Window_Height), "Black") # create all of the buffer images right_buffer = Buffer((X_Window_Buffer+Window_Width),0,(Window_Width-(X_Window_Buffer)),((2*Y_Window_Buffer)+Window_Height), "Black") top_buffer = Buffer(0,0,(Window_Width-X_Window_Buffer),Y_Window_Buffer,"Black") bottom_buffer = Buffer(0,(Window_Height-Y_Window_Buffer),Window_Width,Window_Height,"Black") class Blood(object): """What happens when you kill something. It create a blood spot on the coordinates of the killed Zombie(s) / Devil(s) They are deleted at the beginning of each new level""" def __init__(self,x,y): global base_for_blood self.image = PhotoImage(file = "images/game_elements/blood.gif") self.blood_spot = canvas.create_image(x,y,image = self.image) canvas.tag_lower(self.blood_spot) canvas.tag_lower(Main) class MINE(object): """ The mines class. Watch where you step""" def __init__(self,x,y): self.photo = PhotoImage(file = "images/game_elements/mine.gif") self.image = canvas.create_image(x,y,image = self.photo) # Create a black rectangle for the mine image canvas.tag_lower(self.image) canvas.tag_lower(Main) self.destroy = False self.x = x self.y = y def explode(self): """Determine if a Zombie or Devil is close enought to set of the mine. If that is True then it tests to see whether any Zombie or Devil in the greater surrounding area should be killed""" destroy_zombie = [] destroy_devil = [] self.exploded = False for the_zombie in Zombie_Dict: Zombie = Zombie_Dict[the_zombie] if abs(self.x - Zombie.x) 0: # If the velocity in that direction is not 0 it adds 1 to the speed so that it is faster than the Devil who shot it. self.x_vel += .75 if self.x_vel 0: self.y_vel += .75 if self.y_vel = game_limit.x_end) and self.x_vel > 0: # Can boxhead move in that direction or will he strike the edge of the game self.x_vel = 0 if self.x = game_limit.y_end) and self.y_vel > 0: self.y_vel = 0 elif self.y self.shoot_y_end and abs(Zombie.x - self.shoot_x_start) self.shoot_y_start and Zombie.y self.shoot_x_end and abs(Zombie.y - self.shoot_y_start) self.shoot_x_start and Zombie.x self.shoot_y_end and abs(Zombie.x - self.shoot_x_start) self.shoot_y_start and Zombie.y self.shoot_x_end and abs(Zombie.y - self.shoot_y_start) self.shoot_x_start and Zombie.x 0: mine = MINE(self.x,self.y) Mines_Dict[number_of_mines] = mine number_of_mines +=1 self.mine_count -=1 else: pass canvas.update() def key(self,key): """Look at the input from the keyboard and adjust Boxhead accordingly. Movement = WASD Fire = Space Pistol = I Mines = U Pause = P Unpause = O""" global press,pause_game press = key if press == 'w': self.x_vel = 0 self.y_vel = -B_move_length self.direction = 1 if press == 's': self.x_vel = 0 self.y_vel = B_move_length self.direction = 2 if press == 'a': self.x_vel = -B_move_length self.y_vel = 0 self.direction = 3 if press == 'd': self.x_vel = B_move_length self.y_vel = 0 self.direction = 4 if press == 'space': self.fire_gun() if press == 'p': pause_game = True if press == 'o': pause_game = False if press == 'i': self.gun = "Pistol" self.ammo = 'Infinte' if press == 'u': self.gun = 'Mines' self.ammo = self.mine_count def shoot_coords(self,x_start,y_start,x_end,y_end): """Help to adjust the coordinates based on where to shoot from each direction""" self.shoot_x_start = x_start self.shoot_y_start = y_start self.shoot_x_end = x_end self.shoot_y_end = y_end class Zombie(object): """ZOMBIES. Nothing like a bunch of Zombies that chase you around. Boxhead is faster then Zombies, but Zombies can move diagonally""" def __init__(self): self.zup = PhotoImage(file = "images/zombies/zup.gif") # there are 8 directions that Zombies can move in self.zdown = PhotoImage(file = "images/zombies/zdown.gif") self.zleft = PhotoImage(file = "images/zombies/zleft.gif") self.zright = PhotoImage(file = "images/zombies/zright.gif") self.zrightup = PhotoImage(file = "images/zombies/zrightup.gif") self.zrightdown = PhotoImage(file = "images/zombies/zrightdown.gif") self.zleftup = PhotoImage(file = "images/zombies/zleftup.gif") self.zleftdown = PhotoImage(file = "images/zombies/zleftdown.gif") self.x = random.randrange(game_limit.x_start,(game_limit.x_end-(game_limit.x_end / 2))) # create Zombies in the left half of the arena self.y = random.randrange(game_limit.y_start,game_limit.y_end) self.direction = 1 self.zombie = canvas.create_image(self.x,self.y, image = self.zup) self.alive = True self.distance_to_b = 0 self.attacked = False def move(self,target): """This function like Boxhead1.move tests to see whether the Zombie will hit the edge of the game, but also tests to see whether the Zombie will collide with another Zombie in front of it. This helps avoid having all of the Zombies stack up on top of each other and froming one really dense Zombie. That is what the really long line of code below is testing""" global boxhead1 which_zombie = 0 collision = False self.x_vel = 0 self.y_vel = 0 for which_zombie in Zombie_Dict: test_self = Zombie_Dict[which_zombie] if abs(self.x - boxhead1.x) - abs(boxhead1.x - test_self.x) > 0 and abs(self.x - boxhead1.x) - abs(boxhead1.x - test_self.x) 0 and abs(self.y - boxhead1.y) - abs(boxhead1.y - test_self.y) target.x: self.x_vel= -Zombie_per_move elif self.x == target.x: self.x_vel = 0 if self.x >= Window_Width - 25: # x coords self.x_vel = -Zombie_per_move if self.x target.y: self.y_vel = -Zombie_per_move elif self.y == target.y: self.y_vel = 0 if self.y >= Window_Height - 25:# y coords self.y_vel = -Zombie_per_move if self.y 0 and self.x_vel == 0: canvas.itemconfigure(self.zombie, image = self.zdown) if self.x_vel 0 and self.y_vel == 0: canvas.itemconfigure(self.zombie, image = self.zright) if self.y_vel > 0 and self.x_vel > 0: canvas.itemconfigure(self.zombie, image = self.zrightdown) if self.y_vel 0: canvas.itemconfigure(self.zombie, image = self.zrightup) if self.y_vel > 0 and self.x_vel 0 and abs(self.x - boxhead1.x) - abs(boxhead1.x - test_self.x) 0 and abs(self.y - boxhead1.y) - abs(boxhead1.y - test_self.y) target.x: self.x_vel= -Devil_move elif self.x == target.x: self.x_vel = 0 if self.x >= Window_Width - 25: # x coords self.x_vel = -Devil_move if self.x target.y: self.y_vel = -Devil_move elif self.y == target.y: self.y_vel = 0 if self.y >= Window_Height - 25:# y coords self.y_vel = -Devil_move if self.y 0 and self.x_vel == 0: canvas.itemconfigure(self.devil, image = self.ddown) if self.x_vel 0 and self.y_vel == 0: canvas.itemconfigure(self.devil, image = self.dright) if self.y_vel > 0 and self.x_vel > 0: canvas.itemconfigure(self.devil, image = self.drightdown) if self.y_vel 0: canvas.itemconfigure(self.devil, image = self.drightup) if self.y_vel > 0 and self.x_vel 45: d_attack = Zombie_Attack(self.x,self.y,self.x_vel,self.y_vel) Devil_Attack_Dict[total_devil_attacks] = d_attack total_devil_attacks +=1 self.attack_fire = 0 else: self.attack_fire +=1 def key_press(event): """This function passes all of the key presses to the Boxhead1.key function for further analysis""" global pause_game press = event.keysym boxhead1.key(press) if press == 'o': pause_game = False def init_game_parts(): """ This builds all of the inital game elements that are only created once regardless of the number of levels. For example it creates the score board""" global up, down, right, left global down global right global left global current_shot global game_limit global score_board global boxhead1 global Zombie_Dict global game_limit up = Shot() down = Shot() left = Shot() right = Shot() current_shot = Shot() game_limit = Edge_limits() boxhead1 = Boxhead() score_board = Stats() def new_level(): """For every new level all of the Devils and Zombies have been killed so new ones need to be created. Each time 70% more Zombies are added""" build_zombie = 0 build_devil = 0 for i in range(Number_of_Zombies): z = Zombie() Zombie_Dict[build_zombie] = z build_zombie+=1 for i in range(int(Number_of_Zombies / 5)): D = Devil() Devil_Dict[build_devil] = D build_devil +=1 def main_loop(): """The central function for the game. There are 2 while loops. The inner one is only broken for a new level and the outer while loop is only broken if boxhead dies and the game is over""" global New_Level,Run_Game,Zombie_Dict,Dead_Zombie_List,Number_of_Zombies,boxhead1 init_game_parts() # create all of the game images like the edge buffers while Run_Game == True: global Blood_Dict Blood_Dict = {} # create a new empty blood dictionary if boxhead1.health ", key_press) canvas.pack() canvas.mainloop()