SCREEN_SIZE = (640, 480)
ANT_COUNT=5
import pygame
from pygame.locals import *
from random import randint, choice
from gameobjects.vector2 import Vector2
class World(object):
def __init__(self):
self.entities = {}
self.entity_id = 0
'''self.background = pygame.surface.Surface(SCREEN_SIZE).convert() '''
def add_entity(self, entity):
self.entities[self.entity_id] = entity
entity.id = self.entity_id
self.entity_id += 1
def remove_entity(self, entity):
del self.entities[entity.id]
def get(self, entity_id):
if entity_id in self.entities:
return self.entities[entity_id]
else:
return None
def process(self, time_passed):
time_passed_seconds = time_passed / 1000.0
for entity in self.entities.values():
entity.process(time_passed_seconds)
def render(self, surface):
'''surface.blit(self.background, (0, 0))'''
background_image_filename='grass.jpg'
background=pygame.image.load(background_image_filename).convert()
surface.blit(background,(0,0))
for entity in self.entities.itervalues():
entity.render(surface)
def get_close_entity(self, name, location, range=100.):
location = Vector2(*location)
for entity in self.entities.itervalues():
if entity.name == name:
distance = location.get_distance_to(entity.location)
if distance < range:
return entity
return None
class State(object):
def __init__(self, name):
self.name = name
def do_actions(self):
pass
def check_conditions(self):
pass
def entry_actions(self):
pass
def exit_actions(self):
pass
class StateMachine(object):
def __init__(self):
self.states = {}
self.active_state = None
def add_state(self, state):
self.states[state.name] = state
def think(self):
if self.active_state is None:
return
self.active_state.do_actions()
new_state_name = self.active_state.check_conditions()
if new_state_name is not None:
self.set_state(new_state_name)
def set_state(self, new_state_name):
if self.active_state is not None:
self.active_state.exit_actions()
self.active_state = self.states[new_state_name]
self.active_state.entry_actions()
class AntStateExploring(State):
def __init__(self, ant):
State.__init__(self, "exploring")
self.ant = ant
def random_destination(self):
w, h = SCREEN_SIZE
self.ant.destination = Vector2(randint(0, w), randint(0, h))
def do_actions(self):
if randint(1, 20) == 1:
self.random_destination()
def check_conditions(self):
spider = self.ant.world.get_close_entity("spider", self.ant.location)
if spider is not None:
if self.ant.location.get_distance_to(spider.location) < 100.:
self.ant.spider_id = spider.id
return "hunting"
return None
def entry_actions(self):
self.ant.speed = 120. + randint(-30, 30)
self.random_destination()
class AntStateHunting(State):
def __init__(self, ant):
State.__init__(self, "hunting")
self.ant = ant
self.got_kill = False
def do_actions(self):
spider = self.ant.world.get(self.ant.spider_id)
if spider is None:
return
self.ant.destination = spider.location
if self.ant.location.get_distance_to(spider.location) < 15.:
if randint(1, 5) == 1:
spider.health=spider.health-self.ant.attack
if spider.health <= 0:
spider.speed = 0.
self.ant.world.remove_entity(spider)
self.got_kill = True
self.ant.exp=self.ant.level+spider.lenhealth
if self.ant.exp>10:
self.ant.level=self.ant.level+1
self.ant.exp=0
self.ant.attack=self.ant.attack+1
spider.speed = 140
def check_conditions(self):
if self.got_kill:
return "exploring"
spider = self.ant.world.get(self.ant.spider_id)
if spider is None:
return "exploring"
return None
def entry_actions(self):
self.speed = 160. + randint(0, 50)
def exit_actions(self):
self.got_kill = False
class GameEntity(object):
def __init__(self, world, name, image):
self.world = world
self.name = name
self.image = image
self.location = Vector2(0, 0)
self.destination = Vector2(0, 0)
self.speed = 0.
self.brain = StateMachine()
self.id = 0
def render(self, surface):
x, y = self.location
w, h = self.image.get_size()
surface.blit(self.image, (x-w/2, y-h/2))
def process(self, time_passed):
self.brain.think()
if self.speed > 0. and self.location != self.destination:
vec_to_destination = self.destination - self.location
distance_to_destination = vec_to_destination.get_length()
heading = vec_to_destination.get_normalized()
travel_distance = min(distance_to_destination, time_passed * self.speed)
self.location += travel_distance * heading
class Ant(GameEntity):
def __init__(self, world, image):
GameEntity.__init__(self, world, "ant", image)
exploring_state = AntStateExploring(self)
hunting_state = AntStateHunting(self)
self.brain.add_state(exploring_state)
self.brain.add_state(hunting_state)
self.level=0
self.exp=0
self.attack=randint(1,10)
def render(self, surface):
GameEntity.render(self, surface)
x, y = self.location
w, h = self.image.get_size()
bar_x = x - 12
bar_y = y + h/2
surface.fill( (150, 30, 50), (bar_x, bar_y, self.level, 5))
class Spider(GameEntity):
def __init__(self, world, image):
GameEntity.__init__(self, world, "spider", image)
self.health = randint(10,40)
self.lenhealth = self.health
self.speed = 50. + randint(-20, 20)
def render(self, surface):
GameEntity.render(self, surface)
x, y = self.location
w, h = self.image.get_size()
bar_x = x - 12
bar_y = y + h/2
surface.fill( (255, 0, 0), (bar_x, bar_y, self.lenhealth , 4))
surface.fill( (0, 255, 0), (bar_x, bar_y, self.health, 4))
def process(self, time_passed):
x, y = self.location
if x > SCREEN_SIZE[0] + 2:
self.world.remove_entity(self)
return
GameEntity.process(self, time_passed)
def run():
pygame.init()
screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
w, h = SCREEN_SIZE
clock = pygame.time.Clock()
ant_image = pygame.image.load("ant.png").convert_alpha()
spider_image = pygame.image.load("spider.png").convert_alpha()
world = World()
for ant_no in xrange(ANT_COUNT):
ant = Ant(world, ant_image)
ant.location = Vector2(randint(0, w), randint(0, h))
ant.brain.set_state("exploring")
world.add_entity(ant)
while True:
for event in pygame.event.get():
if event.type == QUIT:
return
time_passed = clock.tick(30)
for event in pygame.event.get():
if event.type == QUIT:
return
time_passed = clock.tick(30)
if randint(1, 100) == 1:
spider = Spider(world, spider_image)
spider.location = Vector2(-50, randint(0, h))
spider.destination = Vector2(w+50, randint(0, h))
world.add_entity(spider)
world.process(time_passed)
world.render(screen)
pygame.display.update()
if __name__ == "__main__":
run()
用pygame寫遊戲 螞蟻打蜘蛛俠 並升級
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.