Design the \'game Millipede\' with python code. Do not use \'pygame\' or \'simpl
ID: 3865420 • Letter: D
Question
Design the 'game Millipede' with python code. Do not use 'pygame' or 'simplegui', use basic python 101 codes. Game should look similar to the image below which displays a 'Score', 'Lives' & option to get 'bonuses' when fired at enemies. (Please don't confuse it with the snake or pong game it's not it, google "Millipede game" for further reference of how it's supposed to be)
I have posted this question twice now & people keeps giving me a wrong answer just to make money or something so if you don't know the RIGHT answer PLEASE DON'T ANSWER I will report it like I have before.
Explanation / Answer
import os
import pygame
import random
import sys
DEBUG = False
class Game:
FRAME_RATE = 60
SCREEN_W = 360
SCREEN_H = 376
ARENA_W = 360
ARENA_H = 360
PLAYER_W = 360
PLAYER_H = 72
SCORE_W = 360
SCORE_H = 16
LIFE_BONUS = 20000
MAX_DDTS = 5
# delay times are in milliseconds
SLOW_DOWN_TIME_TTL = 5000
SLOW_DOWN_TIME_TTL_DT = 125
SWARM_STAGE_SPAWN_DELAY = 250
SPAWN_QUEUE_DELAY = 100
LEVEL_UP_DELAY = 1250
START_RANDOM_EVENT_DELAY = 1000
THE_NINTH_MILLIPEDE_DELAY = 750
BEE_SWARM = 0
DRAGONFLY_SWARM = 1
MOSQUITO_SWARM = 2
BEEDRAGONFLY_SWARM = 3
BEEDRAGONFLYMOSQUITO_SWARM = 4
SWARM_BONUS_INC = 100
SWARM_MAX_BONUS_POINTS = 1000
START_PLAYER_LIVES = 3
RANDOM_EVENT_FREQ = 50
def __init__(self):
max_columns = Game.SCREEN_W / MushroomField.MUSHROOM_WIDTH
pygame.init()
if not pygame.font: print "Warning: fonts disabled."
mixer_init = pygame.mixer.get_init()
if not mixer_init: print "Warning: mixer disabled."
if mixer_init:
print "Mixer available channels: ",
pygame.mixer.get_num_channels()
pygame.display.set_caption('Monsters and Mushrooms')
system_font = pygame.font.get_default_font()
self.font = pygame.font.SysFont( None, 24 )
# init joystick 0
num_joystick = pygame.joystick.get_count()
if num_joystick > 0:
joy = pygame.joystick.Joystick( num_joystick - 1 )
if not joy.init():
print "Warning: could not initialize joystick(s)"
# allocate backbuffer
size = Game.SCREEN_W, Game.SCREEN_H
#self.screen = pygame.display.set_mode(size,pygame.FULLSCREEN)
self.screen = pygame.display.set_mode(size)
self.background = pygame.Surface(size)
self.background.fill([0,0,0])
self.screen.blit(self.background, [0,0])
# initialize sounds
self.millipede_snd = load_sound("sounds/millipede.ogg")
self.player_missile_snd = load_sound("sounds/shot1.ogg")
self.player_hit_snd = load_sound("sounds/exp1.ogg")
self.ddt_snd = load_sound("sounds/exp2.ogg")
self.bee_snd = load_sound("sounds/bee1.ogg")
self.mosquito_snd = load_sound("sounds/fly.ogg")
self.spider_snd = load_sound("sounds/spider.ogg")
self.dragonfly_snd = load_sound("sounds/bee2.ogg")
# load main game static screens
self.title_img = load_image("images/title.png")
self.gameover_img = load_image("images/gameover.png")
self.paused_img = load_image("images/paused.png")
self.start_img = []
self.start_img.append(load_image("images/start0.png"))
self.start_img.append(load_image("images/start1.png"))
self.start_img.append(load_image("images/start2.png"))
self.init_vars()
def init_vars(self):
# init game objects
self.keys = [False, False, False, False, False]
self.score = 0
self.prev_score = 0
self.cur_level = 0
self.p_table_idx = 0
self.swarm_level = 0
self.player_lives = Game.START_PLAYER_LIVES
self.player_dead = False
self.slow_down_time = False
self.time_delay = 0
self.repeat_level = False
self.menu_delay = 0
self.level_up_delay = 0
self.clock = pygame.time.Clock()
self.cur_tick = 0
self.prev_tick = 0
self.spawn_queue = {
'bees' : 0,
'beetles' : 0,
'dragonflies' : 0,
'earwigs' : 0,
'inchworms' : 0,
'mosquitos' : 0,
'spiders' : 0,
'ttl' : 0
};
self.actionfn = self.main_menu_init
self.prev_actionfn = None
self.swarmfn = None
self.swarm_count = 0
self.swarm_launch_delay = 0
self.swarm_monster = None
self.swarm_monster_lst = None
self.swarm_points = 0
self.swarm_next_monster = 0
self.birthanddeathfn = None
self.player = Player(self)
self.players = pygame.sprite.Group()
self.playerMissile = PlayerMissile(self)
self.playerMissiles = pygame.sprite.Group()
self.playerMissiles.add( self.playerMissile )
self.popups = PopUps(self)
self.particles = Particles(self)
self.mushroom_field = MushroomField(self)
self.millipedes = []
self.spiders = pygame.sprite.Group()
self.bees = pygame.sprite.Group()
self.mosquitos = pygame.sprite.Group()
self.beetles = pygame.sprite.Group()
self.earwigs = pygame.sprite.Group()
self.dragonflies = pygame.sprite.Group()
self.inchworms = pygame.sprite.Group()
self.monsters = pygame.sprite.Group()
self.ddts = pygame.sprite.Group()
self.damaged_mushrooms = []
self.random_event_delay = 0
self.cur_level_random_event_delay = Game.START_RANDOM_EVENT_DELAY
self.p_table = (
(25,-1,-1,-1,-1,-1,-1),
(30,50,-1,52,-1,-1,54),
(35,52,54,58,-1,-1,62),
(40,54,56,60,-1,-1,64),
(45,56,58,64,66,68,74),
(50,58,60,66,68,70,76),
(50,60,62,68,70,72,78),
(50,62,64,70,72,74,80),
(50,64,68,76,80,84,92),
(50,66,70,78,82,86,94),
(50,68,72,80,84,88,96),
(50,70,76,84,88,92,98),
(50,70,78,86,92,98,100)
self.max_table = (
(2,0,0,0),
(2,1,1,1),
(2,1,1,1),
(3,1,1,1),
(3,2,1,1),
(4,2,1,1),
(4,2,1,1),
(5,3,2,2),
(5,4,2,2),
(6,5,2,2),
(6,6,2,2),
(7,7,2,2),
(8,8,2,2))
def game_reset(self):
"""Reset game variables."""
self.keys = [False, False, False, False, False]
self.score = 0
self.prev_score = 0
self.slow_down_time = False
self.time_delay = 0
self.menu_delay = 0
self.level_up_delay = 0
# swarm stage variables
self.swarmfn = None
self.swarm_count = 0
self.swarm_launch_delay = 0
self.swarm_monster = None
self.swarm_monster_lst = None
self.swarm_next_monster = 0
self.birthanddeathfn = None
# Reset the stop-watch timer.
self.cur_tick = 0
self.reset_ticks()
# reset spawn queue
self.spawn_queue_reset()
# random events
self.random_event_delay = 0
self.cur_level_random_event_delay = Game.START_RANDOM_EVENT_DELAY
# keep track of damaged mushrooms
self.damaged_mushrooms = []
#player info
self.score = 0
self.cur_level = 0
self.swarm_level = 0
self.player_lives = Game.START_PLAYER_LIVES
self.player_dead = False
self.slow_down_time = False
self.time_delay = 0
self.repeat_level = False
self.menu_delay = 0
self.level_up_delay = 0
self.clock = pygame.time.Clock()
self.cur_tick = 0
self.prev_tick = 0
for m in self.monsters:
m.kill()
self.ddts.empty()
self.mushroom_field.reset()
self.mushroom_field.populate_randomly()
# special events
self.the_ninth_millipede = False
self.scroll_mushroomfield_delay = 0
self.eight_spider_attack = False
def spawn_queue_reset(self):
"""Reset the spawn queue."""
self.spawn_queue['bees'] = 0
self.spawn_queue['beetles'] = 0
self.spawn_queue['dragonflies'] = 0
self.spawn_queue['earwigs'] = 0
self.spawn_queue['inchworms'] = 0
self.spawn_queue['mosquitos'] = 0
self.spawn_queue['spiders'] = 0
self.spawn_queue['ttl'] = self.get_ticks()
def level_reset(self):
"""Reset the current level."""
# remove all actors from the game
self.popups.clear()
self.players.empty()
self.playerMissiles.empty()
self.millipedes = []
for m in self.monsters:
m.kill()
for d in self.ddts:
if d.active:
d.kill()
self.spawn_queue_reset()
self.slow_down_time = False
self.player_dead = False
self.keys = [False, False, False, False, False]
def level_init(self):
"""Setup current level data."""
self.players.add( self.player )
self.playerMissile.reset()
self.playerMissiles.add( self.playerMissile )
def get_ticks(self):
"""Return game clock ticks."""
t = pygame.time.get_ticks()
dt = t - self.prev_tick
self.prev_tick = t
self.cur_tick += dt
return self.cur_tick
def one_up_and_eight_spiders(self):
"""check for 1-UP and 8 spider attack."""
event = False
n = self.prev_score % Game.LIFE_BONUS
m = self.score % Game.LIFE_BONUS
# m will be less than n should a 1-UP occur
if ((m-n) < 0):
event = True
self.player_lives += 1
# play player_1_up sound here...
if DEBUG:
print "PLAYER 1-UP!!!!!"
# check for 100,000 8 spider attack
n = self.prev_score % 100000
m = self.score % 100000
if ((m-n) < 0):
event = True
self.spawn_queue['spiders'] += 8
self.eight_spider_attack = True
if DEBUG:
print "Eight Spider Attack"
# prevent multiple 1-ups or multiple 8 spider attacks
if event:
self.prev_score = self.score
def reset_ticks(self):
"""Reset game tick counter. Must be called after a Pause."""
self.prev_tick = pygame.time.get_ticks()
def run(self):
"""Main game loop."""
while True:
self.actionfn()
def main(self):
"""Game run."""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.JOYAXISMOTION:
#print "move pad: ", event.joy, event.axis, event.value
if event.axis == 1:
if event.value == 0:
self.keys[2] = False
self.keys[3] = False
elif event.value == 1:
self.keys[3] = True
elif event.value == -1:
self.keys[2] = True
elif event.axis == 0:
if event.value == 0:
self.keys[0] = False
self.keys[1] = False
elif event.value == 1:
self.keys[1] = True
elif event.value == -1:
self.keys[0] = True
elif event.type == pygame.JOYBUTTONUP:
#print "button up: ", event.joy, event.button
if event.joy == 0 and event.button == 0:
self.keys[4] = False
elif event.type == pygame.JOYBUTTONDOWN:
#print "button down: ", event.joy, event.button
if event.joy == 0 and event.button == 0:
self.keys[4] = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
self.keys[0] = True
elif event.key == pygame.K_RIGHT:
self.keys[1] = True
elif event.key == pygame.K_UP:
self.keys[2] = True
elif event.key == pygame.K_DOWN:
self.keys[3] = True
elif (event.key == pygame.K_SPACE) or
(event.key == pygame.K_LCTRL):
self.keys[4] = True
elif event.key == pygame.K_ESCAPE:
sys.exit()
elif event.key == pygame.K_p:
self.prev_actionfn = self.actionfn
self.menu_delay = self.get_ticks()
self.actionfn = self.pause
pygame.mixer.pause()
elif event.key == pygame.K_m:
mushroom_field_print()
elif event.key == pygame.K_g:
(x, y) = game.player.rect.topleft
gx = x / MushroomField.MUSHROOM_WIDTH
gy = y / MushroomField.MUSHROOM_HEIGHT
print "Player position: (%d, %d) : (%d, %d)" %
(x, y, gx, gy)
elif event.key == pygame.K_0:
self.swarm_init(Game.BEE_SWARM)
elif event.key == pygame.K_1:
self.swarm_init(Game.DRAGONFLY_SWARM)
elif event.key == pygame.K_2:
self.swarm_init(Game.MOSQUITO_SWARM)
elif event.key == pygame.K_3:
self.swarm_init(Game.BEEDRAGONFLY_SWARM)
elif event.key == pygame.K_4:
self.swarm_init(Game.BEEDRAGONFLYMOSQUITO_SWARM)
elif event.key == pygame.K_l:
self.birthanddeathfn = self.birth_and_death_init
elif event.key == pygame.K_r:
self.mushroom_field.populate_randomly()
elif event.key == pygame.K_o:
self.mushroom_field.reset()
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
self.keys[0] = False
elif event.key == pygame.K_RIGHT:
self.keys[1] = False
elif event.key == pygame.K_UP:
self.keys[2] = False
elif event.key == pygame.K_DOWN:
self.keys[3] = False
elif event.key == pygame.K_SPACE or
(event.key == pygame.K_LCTRL):
self.keys[4] = False
# save current score -- used to check for player 1-UP
self.prev_score = self.score
class Millipede:
"""The Millipede."""
# size of each segment of the millipede
HEIGHT = -1
WIDTH = -1
frames = None
max_frames = 0
start_x = -1
start_y = -1
MAX_Y = -1
# Millipede moves 3 pixels per frame
MOVE_COUNT = 4
move_inc = 3
BODY_POINTS = 10
HEAD_POINTS = 100
MAX_SEGMENTS= 12
def __init__(self, game, num_segments=12, start_pos=None):
"""game - reference to game object
num_segments - starting number of segments
start_pos - tuple (x,y) screen coordinates
"""
self.game = game
if Millipede.frames == None:
Millipede.frames = []
Millipede.frames.append(load_image("sprites/millipede0.png"))
Millipede.frames.append(load_image("sprites/millipede1.png"))
Millipede.max_frames = len(Millipede.frames)
Millipede.HEIGHT = Millipede.frames[0].get_height()
Millipede.WIDTH = Millipede.frames[0].get_width()
Millipede.start_x = Game.ARENA_W / 2
Millipede.start_y = 0 - Millipede.HEIGHT
Millipede.MAX_Y = Game.ARENA_H - Game.PLAYER_H + Millipede.HEIGHT
self.image = Millipede.frames[0]
self.frame_delay = self.game.get_ticks()
self.cur_frame = 0
self.up = False
self.down = True
n = random.randint(0,10)
if n < 5:
self.left = True
self.right = False
else:
self.left = False
self.right = True
self.change_row = False
# max_y keeps track of max Y position of next row
# that the Millipede is heading to
self.max_y = 0
# pa_spawned indicates that the Millipede spawned in the player
# area
self.pa_spawned = False
self.poisoned = False
self.move_count = Millipede.MOVE_COUNT
if start_pos == None:
x = Millipede.start_x
y = Millipede.start_y
else:
x, y = start_pos
# millipede's body is an array of dictionaries
# representing each segment of the body
self.body = []
for i in range(0,num_segments):
# each segment of the millipede's body is
# represented by a dictionary which holds
# the segments position and heading
m = {}
if i == 0:
m['head'] = True
m['x_pos'] = x
m['y_pos'] = y
m['dx'] = 0
m['dy'] = 0
m['rect'] = pygame.Rect( x, y, Millipede.WIDTH, Millipede.HEIGHT )
y = y - Millipede.HEIGHT
self.body.append( m )
self.x_inc = 0
self.y_inc = Millipede.move_inc
self.set_waypoint( x, 0 )
def draw(self, buffer):
""" update animation ... """
dt = self.game.get_ticks() - self.frame_delay
if dt > 250:
self.frame_delay = self.game.get_ticks()
self.cur_frame += 1
if self.cur_frame == Millipede.max_frames:
self.cur_frame = 0
self.image = Millipede.frames[self.cur_frame]
for m in self.body:
buffer.blit( self.image, (m['x_pos'],m['y_pos']) )
def __change_row(self, head):
"""Move the Millipede up or down."""
if self.down:
x = head['x_pos']
y = head['y_pos'] + Millipede.HEIGHT
elif self.up:
x = head['x_pos']
y = head['y_pos'] - Millipede.HEIGHT
if y >= (Game.ARENA_H-Millipede.HEIGHT):
self.down = False
self.up = True
y = head['y_pos'] + Millipede.HEIGHT
self.max_y = Millipede.MAX_Y
# trigger Millipede spawn in player area
self.game.spawn_millipede_in_player_area()
if y < self.max_y:
self.down = True
self.up = False
y = head['y_pos'] - Millipede.HIEGHT
def move(self):
# move head & move body
head = self.body[0]
if not head:
return
if self.move_count > 0:
self.move_count -= 1
for m in self.body:
m['prev_x'] = m['x_pos']
m['prev_y'] = m['y_pos']
m['x_pos'] += m['dx']
m['y_pos'] += m['dy']
m['rect'].top = m['y_pos']
m['rect'].left = m['x_pos']
else:
# reset movement counter
self.move_count = Millipede.MOVE_COUNT
# used to see if we need to change rows and/or alternate
# direction of movement
alternate_dir = False
random_dir = False
x = head['x_pos']
y = head['y_pos']
# was moving left
if self.left and not self.change_row:
if head['x_pos'] > 0:
x = head['x_pos'] - Millipede.WIDTH
y = head['y_pos']
elif head['x_pos'] == 0:
self.change_row = True
# was moving right
elif self.right and not self.change_row:
x_max = Game.ARENA_W - Millipede.WIDTH
if head['x_pos'] < x_max:
x = head['x_pos'] + Millipede.WIDTH
y = head['y_pos']
elif head['x_pos'] == x_max:
self.change_row = True
# change rows up or down if needed
if self.change_row:
if self.down:
x = head['x_pos']
y = head['y_pos'] + Millipede.HEIGHT
elif self.up:
x = head['x_pos']
y = head['y_pos'] - Millipede.HEIGHT
if y >= (Game.ARENA_H-Millipede.HEIGHT):
random_dir = True
self.down = False
self.up = True
y = head['y_pos'] + Millipede.HEIGHT
self.max_y = Millipede.MAX_Y
# trigger Millipede spawn in player area
self.game.spawn_millipede_in_player_area()
# Millipede is no longer poisoned when it
# reaches the bottom of the player area
if self.poisoned:
self.poisoned = False
if y < self.max_y:
self.down = True
self.up = False
y = head['y_pos'] - Millipede.HEIGHT
if not self.poisoned:
self.change_row = False
alternate_dir = True
# at this point the movement way point has been set
# need to see if we can move into the desired grid point
# check for mushroom collision
collision = self.game.mushroom_field.millipede_collision(x, y)
if not self.poisoned and not self.pa_spawned and collision:
# collision has occured, change millipede direction
# and move up or down a row depending on which way we
# are going.
# did we hit a poisoned mushroom?
if self.game.mushroom_field.is_poisoned(x, y):
# poison the Millipede and make dive down
if DEBUG:
print "MILLIPEDE POISONED!!!!"
self.poisoned = True
alternate_dir = False
self.down = True
self.up = False
self.change_row = True
# make normal an Millipedes which spawned in player
# area
if self.pa_spawned:
self.pa_spawned = False
# alternate between left/right movement
if alternate_dir:
#n = random.randint(0,10)
if self.left:
self.left = False
self.right = True
else:
self.left = True
self.right = False
# make Millipede more eratic if in player area
if random_dir:
n = random.randint(0,10)
if n < 5:
self.left = True
self.right = False
else:
self.left = False
self.right = True
# keep track of head's current position before
# waypoint change -- this is used by the body
# to keep it moving along.
#
# move the head and propagate the waypoint change(s)
# to the body
#
self.set_waypoint( x, y )
def set_waypoint(self, x, y):
"""set target position for Millipede to move towards."""
# need to handle special case where both dy and y are negative
# ie. we are just starting to move into the board
x0 = x
y0 = y
for m in self.body:
x1 = m['x_pos']
y1 = m['y_pos']
if (y0 < 0) or (m['y_pos'] < 0):
m['dx'] = 0
m['dy'] = Millipede.move_inc
else:
dx = x0 - m['x_pos']
dy = y0 - m['y_pos']
if dx > 0:
m['dx'] = Millipede.move_inc
elif dx < 0:
m['dx'] = -Millipede.move_inc
else:
m['dx'] = 0
if dy > 0:
m['dy'] = Millipede.move_inc
elif dy < 0:
m['dy'] = -Millipede.move_inc
else:
m['dy'] = 0
x0 = x1
y0 = y1
def collision(self, rect):
"""check for collision against other sprite."""
m_rect = pygame.Rect(0,0,Millipede.WIDTH,Millipede.HEIGHT)
hit = False
for m in self.body:
m_rect.left = m['x_pos']
m_rect.top = m['y_pos']
if m_rect.colliderect( rect ):
self.game.stop_ninth_millipede()
hit = True
fx = m['x_pos'] / MushroomField.MUSHROOM_WIDTH
fy = m['y_pos'] / MushroomField.MUSHROOM_WIDTH
self.game.mushroom_field.add_mushroom( fx, fy )
"""
split the millipede body at segment where collision
occurrs and create a new instance of millipede
"""
index = self.body.index( m )
n = len(self.body)
# determine score
if index == 0:
self.game.score += Millipede.HEAD_POINTS
self.game.popups.add(
m['x_pos'],
m['y_pos'],
Millipede.HEAD_POINTS)
else:
self.game.score += Millipede.BODY_POINTS
# split Millipede if it has segments
if n > 1:
# make millipede dive down if split
self.change_row = True
# split body into two parts
n -= 1
body0 = self.body[0:index]
index += 1
body1 = self.body[index:n]
if (len(body0) == 0) and (len(body1) == 0):
self.game.millipedes.remove(self)
break
if body0 != []:
self.body = body0
n = len(body1)
if n > 0:
child = Millipede(self.game, -1)
child.body = body1
self.set_child_state( child )
self.game.millipedes.append( child )
else:
self.body = body1
else:
# nothing of the Millipede remains kill it
self.game.millipedes.remove( self )
break
return hit
def go_left(self):
"""make Millipede (which spawned in player area) go left."""
self.change_row = False
self.up = False
self.down = True
self.left = True
self.right = False
self.pa_spawned = True
def go_right(self):
"""make Millipede (which spawned in player area) go right."""
self.change_row = False
self.up = False
self.down = True
self.left = False
self.right = True
self.pa_spawned = True
def set_child_state(self, child):
""" copy some parent state variables to the child."""
child.move_count = self.move_count
child.change_row = True
child.max_y = self.max_y
child.up = self.up
child.down = self.down
child.left = not self.right
child.right = not self.left
if __name__=='__main__':
game = Game()
game.run()
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.