Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

551 lines (482 sloc) 16.469 kb
# Nubcake Farms
# A simple farming game geared towards learning the basics of PyGame.
VERSION = "Alpha 0.1"
try:
import sys
import random
import math
import time
import os
import getopt
import pygame
from socket import *
from pygame.locals import *
except ImportError, err:
print "couldn't load module. %s" % (err)
sys.exit(2)
spritelist = []
objectlist = []
hudspritelist = []
scenerylist = []
fences = []
plots = []
plants = []
def time_in_ms():
return int(round(time.time() * 1000))
def load_img(subdir, name):
""" Load image and return image object"""
if subdir != None:
fullname = os.path.join('images', subdir, name)
else:
fullname = os.path.join('images', name)
try:
image = pygame.image.load(fullname)
if image.get_alpha() is None:
image = image.convert()
else:
image = image.convert_alpha()
except pygame.error, message:
print 'Cannot load image:', fullname
raise SystemExit, message
return image
def update_hud_text():
font = pygame.font.SysFont('calibri', 14)
textpos_base = pygame.Rect((0, 0), (64, 12))
seeds_text = font.render(str(farmer.seeds), 1, (0, 0, 0))
seeds_textpos = pygame.Rect((0, 0), (seeds_text.get_width(), seeds_text.get_height()))
seeds_textpos.centerx = textpos_base.move(14, 85).centerx
seeds_textpos.centery = textpos_base.move(14, 85).centery
hud.blit(seeds_text, seeds_textpos)
wheat_text = font.render(str(farmer.wheat), 1, (0, 0, 0))
wheat_textpos = pygame.Rect((0, 0), (wheat_text.get_width(), wheat_text.get_height()))
wheat_textpos.centerx = textpos_base.move(14 + 82, 85).centerx
wheat_textpos.centery = textpos_base.move(14 + 82, 85).centery
hud.blit(wheat_text, wheat_textpos)
water_text = font.render(str(farmer.water) + "/" + str(farmer.water_max), 1, (0, 0, 0))
water_textpos = pygame.Rect((0, 0), (water_text.get_width(), water_text.get_height()))
water_textpos.centerx = textpos_base.move(14 + 82*2, 85).centerx
water_textpos.centery = textpos_base.move(14 + 82*2, 85).centery
hud.blit(water_text, water_textpos)
gold_text = font.render(str(farmer.gold), 1, (0, 0, 0))
gold_textpos = pygame.Rect((0, 0), (gold_text.get_width(), gold_text.get_height()))
gold_textpos.centerx = textpos_base.move(14 + 82*3, 85).centerx
gold_textpos.centery = textpos_base.move(14 + 82*3, 85).centery
hud.blit(gold_text, gold_textpos)
def update_shop_text():
font = pygame.font.SysFont('calibri', 20)
textpos_base = pygame.Rect((0, 0), (160, 20))
seed_text_color = (0,0,0)
wheat_text_color = (0,0,0)
leave_text_color = (0,0,0)
if shop.selection == 0:
seed_text_color = (120,120,230)
elif shop.selection == 1:
wheat_text_color = (120,120,230)
elif shop.selection == 2:
leave_text_color = (120,120,230)
spacer = 0
for line in shop.selections[0]:
buy_seeds_text = font.render(line, 1, seed_text_color)
buy_seeds_textpos = pygame.Rect((10, 60+spacer), (buy_seeds_text.get_width(), buy_seeds_text.get_height()))
shopinterface.blit(buy_seeds_text, buy_seeds_textpos)
spacer += 24
spacer = 0
for line in shop.selections[1]:
buy_wheat_text = font.render(line, 1, wheat_text_color)
buy_wheat_textpos = pygame.Rect((10, 140+spacer), (buy_wheat_text.get_width(), buy_wheat_text.get_height()))
shopinterface.blit(buy_wheat_text, buy_wheat_textpos)
spacer += 24
leave_text = font.render(shop.selections[2], 1, leave_text_color)
leave_textpos = pygame.Rect((10, 225), (leave_text.get_width(), leave_text.get_height()))
shopinterface.blit(leave_text, leave_textpos)
class Farmer(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self) #call Sprite intializer
self.farmerpic_left = load_img('farmer', 'farmer_left.png')
self.farmerpic_right = load_img('farmer', 'farmer_right.png')
self.farmerpic_up = load_img('farmer', 'farmer_up.png')
self.farmerpic_down = load_img('farmer', 'farmer_down.png')
self.image = self.farmerpic_down
screen = pygame.display.get_surface()
self.area = screen.get_rect()
self.rect = self.image.get_rect()
self.seeds = 2
self.wheat = 0
self.water = 0
self.water_max = 1
self.gold = 0
def update(self):
pass
def interact(self):
checkspot = self.rect.move((-64 * (self.facing == 'left') + 64 * (self.facing == 'right')), (-64 * (self.facing == 'up') + 64 * (self.facing == 'down'))) # Determines the block the farmer is facing
found_object = checkspot.collidelist(objectlist)
found_plant = checkspot.collidelist(plants)
if found_object != -1 and found_plant == -1:
entity = objectlist[found_object]
if entity.__class__.__name__ == 'Plot':
plot = entity
if plot.state == 'dry' and self.water > 0:
plot.wet()
self.water -= 1
elif plot.state == 'wet' and self.seeds > 0:
plant = Wheat_Plant(checkspot.left, checkspot.top)
self.seeds -= 1
elif entity.__class__.__name__ == 'Well':
well = entity
self.water = self.water_max
elif entity.__class__.__name__ == 'Shop':
shop = entity
shop.open()
elif entity.__class__.__name__ == 'WateringCan':
wateringcan = entity
self.water_max = 4
wateringcan.kill()
hud_sprites = allhudsprites.sprites()
for sprite in hud_sprites:
if sprite.name == "Watering Can":
sprite.image = load_img('HUD', 'watering_can_large.png')
objectlist.remove(wateringcan)
elif found_plant != -1:
plant = plants[found_plant]
if plant.stage == 4:
plant.harvest()
def move(self, direction):
if direction == "up":
newpos = self.rect.move(0, -64)
self.image = self.farmerpic_up
self.facing = "up"
elif direction == "down":
newpos = self.rect.move(0, 64)
self.image = self.farmerpic_down
self.facing = "down"
elif direction == "left":
newpos = self.rect.move(-64, 0)
self.image = self.farmerpic_left
self.facing = "left"
elif direction == "right":
newpos = self.rect.move(64, 0)
self.image = self.farmerpic_right
self.facing = "right"
if newpos.collidelistall(objectlist) != []: newpos = self.rect
if newpos.collidelistall(scenerylist) != []: newpos = self.rect
newpos = self.check_bounds(newpos)
self.rect = newpos
def check_bounds(self, newpos):
if newpos.left < self.area.left:
newpos.left = self.area.left
if newpos.right > self.area.right:
newpos.right = self.area.right
if newpos.top < self.area.top:
newpos.top = self.area.top
if newpos.bottom > self.area.bottom:
newpos.bottom = self.area.bottom
return newpos
class Fence(pygame.sprite.Sprite):
def __init__(self, x, y):
self.fence_ = load_img('fence', 'fence_.png')
self.fence_u = load_img('fence', 'fence_u.png')
self.fence_d = load_img('fence', 'fence_d.png')
self.fence_l = load_img('fence', 'fence_l.png')
self.fence_r = load_img('fence', 'fence_r.png')
self.fence_ud = load_img('fence', 'fence_ud.png')
self.fence_ul = load_img('fence', 'fence_ul.png')
self.fence_ur = load_img('fence', 'fence_ur.png')
self.fence_dl = load_img('fence', 'fence_dl.png')
self.fence_dr = load_img('fence', 'fence_dr.png')
self.fence_lr = load_img('fence', 'fence_lr.png')
self.fence_udl = load_img('fence', 'fence_udl.png')
self.fence_udr = load_img('fence', 'fence_udr.png')
self.fence_ulr = load_img('fence', 'fence_ulr.png')
self.fence_dlr = load_img('fence', 'fence_dlr.png')
self.fence_udlr = load_img('fence', 'fence_udlr.png')
pygame.sprite.Sprite.__init__(self)
self.image = self.fence_
self.rect = self.image.get_rect()
self.rect.topleft = x, y
fences.append(self)
def assign_image(self):
imagename = "fence_"
if self.rect.move(0, -64).collidelistall(fences) != []: imagename = imagename + "u"
if self.rect.move(0, 64).collidelistall(fences) != []: imagename = imagename + "d"
if self.rect.move(-64, 0).collidelistall(fences) != []: imagename = imagename + "l"
if self.rect.move(64, 0).collidelistall(fences) != []: imagename = imagename + "r"
exec('self.image = self.%s' % imagename)
class Plot(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.dry_img = load_img('plot', 'plot_dry.png')
self.wet_img = load_img('plot', 'plot_wet.png')
self.image = self.dry_img
self.rect = self.image.get_rect()
self.rect.topleft = x, y
self.state = 'dry'
self.occupied = False
self.wettime = current_time - 15000
plots.append(self)
def dry(self):
self.state = 'dry'
self.image = self.dry_img
def wet(self):
self.state = 'wet'
self.image = self.wet_img
self.wettime = current_time
def update(self):
if current_time - 15000 >= self.wettime and self.state == 'wet' and not self.occupied:
self.dry()
def occupy(self):
self.occupied = True
def unoccupy(self):
self.occupied = False
class Well(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = load_img('scenery', 'well.png')
self.rect = self.image.get_rect()
self.rect.topleft = x, y
class WateringCan(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = load_img('HUD', 'watering_can_large.png')
self.rect = self.image.get_rect()
self.rect.topleft = x, y
class HUD_Sprite(pygame.sprite.Sprite):
def __init__(self, img, x, y, name):
pygame.sprite.Sprite.__init__(self)
self.name = name
self.image = img
self.rect = self.image.get_rect()
self.rect.topleft = x, y
hudspritelist.append(self)
class Wheat_Plant(pygame.sprite.Sprite):
def __init__(self, x, y):
self.stage_1_img = load_img('plot\\wheat', 'wheat_1.png')
self.stage_2_img = load_img('plot\\wheat', 'wheat_2.png')
self.stage_3_img = load_img('plot\\wheat', 'wheat_3.png')
self.stage_4_img = load_img('plot\\wheat', 'wheat_4.png')
pygame.sprite.Sprite.__init__(self)
self.image = self.stage_1_img
self.rect = self.image.get_rect()
self.rect.topleft = x, y
self.start_time = current_time
self.growthtime = self.get_growth_time()
self.stage = 1
plants.append(self)
allplants.add(self)
objectlist[self.rect.collidelist(objectlist)].occupy()
def get_growth_time(self):
return 5000 + random.randint(0, 5000) # Returns a random amount of time between 5 and 10 seconds
def update(self):
if self.stage < 4:
if time_in_ms() - self.growthtime >= self.start_time:
self.grow()
def grow(self):
self.stage += 1
exec('self.image = self.stage_%d_img' % (self.stage))
self.growthtime = self.get_growth_time()
self.start_time = current_time
def harvest(self):
objectlist[self.rect.collidelist(objectlist)].dry()
objectlist[self.rect.collidelist(objectlist)].unoccupy()
self.kill()
plants.remove(self)
farmer.wheat += 1
class Shop(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self)
self.image = load_img('scenery', 'shop.png')
self.rect = self.image.get_rect()
self.rect.topleft = x, y
self.active = False
self.selections = [["", # This first group is the seed purchase text
""],
["", # This second group is the wheat selling text
""],
""] # This last string is the leaving text
self.maxseeds = 0
self.selection = 0
def open(self):
self.update()
self.active = True
self.selection = 0
def close(self):
self.active = False
def update(self):
self.maxseeds = int(farmer.gold/2)
self.selections = [["Buy %d seeds" % (self.maxseeds),
"This will cost %d gold" % (self.maxseeds * 2)],
["Sell %d wheat" % (farmer.wheat),
"You will gain %d gold" % (farmer.wheat * 3)],
"Leave shop (Esc)"]
def up_selection(self):
self.selection -= 1
if self.selection < 0:
self.selection = 2
def down_selection(self):
self.selection += 1
if self.selection > 2:
self.selection = 0
def make_selection(self):
if self.selection == 0: # If the player wishes to buy seeds (all or none, for now)
farmer.gold -= self.maxseeds * 2
farmer.seeds += self.maxseeds
self.update()
elif self.selection == 1: # If the player wishes to sell wheat (all or none, for now)
farmer.gold += farmer.wheat * 3
farmer.wheat = 0
self.update()
elif self.selection == 2: # If the player wishes to leave the shop
self.close()
def main():
# Initialize screen
pygame.init()
screen = pygame.display.set_mode((640, 640))
pygame.display.set_caption('Nubcake Farms')
global current_time
current_time = time_in_ms()
# Initialize clock
global clock
clock = pygame.time.Clock()
# Generate grassy background
bgimage1 = load_img("grass", "grass1.png")
bgimage2 = load_img("grass", "grass2.png")
bgimage3 = load_img("grass", "grass3.png")
background = pygame.Surface(screen.get_size())
background = background.convert()
for y in range(10):
for x in range(10):
exec('image = bgimage%d' % random.randint(1,3))
background.blit(image, (64*x, 64*y))
# Generate HUD
global hud
hud = pygame.Surface((340, 112))
hud.convert()
hudimage = load_img("hud", "hud.png")
hud.blit(hudimage, (0, 0))
hud_seeds = HUD_Sprite(load_img('hud', 'wheat_seeds.png'), 17, 16, "Seeds")
hud_wheat = HUD_Sprite(load_img('hud', 'wheat.png'), 98, 16, "Wheat")
hud_watering_can = HUD_Sprite(load_img('hud', 'watering_can_small.png'), 179, 16, "Watering Can")
hud_coin = HUD_Sprite(load_img('hud', 'coin.png'), 260, 16, "Gold")
global allhudsprites
allhudsprites = pygame.sprite.RenderPlain(hudspritelist)
# Generate Shop Interface
global shopinterface
shopinterface = pygame.Surface((192, 256))
shopinterface.convert()
shopinterfaceimage = load_img("hud", "shop.png")
shopinterface.blit(shopinterfaceimage, (0, 0))
# Generate sprites/objects
global farmer
farmer = Farmer()
fencenum = 1
plotnum = 1
blockx = 0
blocky = 0
level = open('data/level.txt', 'r')
spritelist.append(farmer)
for line in level:
for char in line:
if char == 'F':
exec('fence%i = Fence(blockx, blocky)' % fencenum)
exec('scenerylist.append(fence%i)' % fencenum)
fencenum += 1
elif char == 'L':
exec('plot%i = Plot(blockx, blocky)' % plotnum)
exec('objectlist.append(plot%i)' % plotnum)
plotnum += 1
elif char == 'W':
well = Well(blockx, blocky)
objectlist.append(well)
elif char == 'S':
global shop
shop = Shop(blockx, blocky)
objectlist.append(shop)
elif char == 'C':
wateringcan = WateringCan(blockx, blocky)
objectlist.append(wateringcan)
elif char == 'P':
farmer.rect.topleft = (blockx, blocky)
blockx += 64
blocky += 64
blockx = 0
for fence in fences:
fence.assign_image()
global allsprites
global allobjects
global allscenery
allsprites = pygame.sprite.RenderPlain(spritelist)
allobjects = pygame.sprite.RenderPlain(objectlist)
allscenery = pygame.sprite.RenderPlain(scenerylist)
global allplants
allplants = pygame.sprite.Group()
# Blit everything to the screen
screen.blit(background, (0, 0))
allobjects.draw(screen)
allsprites.draw(screen)
screen.blit(hud, (150, 520))
pygame.display.flip()
# Event loop
while 1:
# Update current time
current_time = time_in_ms()
# Check for input
for event in pygame.event.get():
if event.type == QUIT:
return
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
if shop.active:
shop.close()
else:
return
elif event.key == K_UP:
if shop.active:
shop.up_selection()
else:
farmer.move("up")
elif event.key == K_DOWN:
if shop.active:
shop.down_selection()
else:
farmer.move("down")
elif event.key == K_LEFT:
if shop.active:
pass
else:
farmer.move("left")
elif event.key == K_RIGHT:
if shop.active:
pass
else:
farmer.move("right")
elif event.key == K_SPACE:
if shop.active:
shop.make_selection()
else:
farmer.interact()
elif event.key == K_TAB:
pass
# Update actively updated objects
for plant in allplants:
plant.update()
for plot in plots:
plot.update()
# Update the game area
screen.blit(background, (0, 0))
allobjects.draw(screen)
allsprites.draw(screen)
allscenery.draw(screen)
allplants.draw(screen)
# Update the HUD
screen.blit(hud, (150, 520))
hud.blit(hudimage, (0, 0))
allhudsprites.draw(hud)
update_hud_text()
# Show the shop, if it is active
if shop.active:
screen.blit(shopinterface, (224, 144))
shopinterface.blit(shopinterfaceimage, (0, 0))
update_shop_text()
pass
# Render everything
pygame.display.flip()
if __name__ == '__main__': main()
Jump to Line
Something went wrong with that request. Please try again.