diff --git a/blocks.py b/blocks.py new file mode 100644 index 0000000..1041817 --- /dev/null +++ b/blocks.py @@ -0,0 +1,240 @@ +import pygame +import os +import lib.constants as constants +from lib.gameregistry import GameRegistry +from lib.block import Block +from lib.inventory import Inventory +dy_blocks={} + +def make_block(klass_name,name,clear=False,drops=False): + def blk_init(): + pass + def init(self,x,y,screen): + Block.__init__(self,x,y,screen) + self.setTextureName(name) + self.clear=clear + self.drops=drops + self.unlocalisedName=name + attr_table={ + "unlocalisedName":name, + "__init__":init, + "init":blk_init, + } + klass=type(klass_name,(Block,),attr_table) + GameRegistry.registerBlock(klass,name) + Block.registerTexture(name) + glob=globals() + glob[klass_name]=klass + global dy_blocks + dy_blocks[klass_name]=name + return klass + +make_block("BlockStone","stone") +make_block("BlockTree","tree",False,("wood",8)) +make_block("BlockGrass","grass",True) +make_block("BlockWood","wood") +make_block("BlockCoal","coal_ore") +GameRegistry.registerFuel("coal_ore",8) +make_block("BlockIron","iron_ore") +make_block("ItemIronIngot","iron_ingot",False) +#make_block("ItemCoal","coal",False) +# class BlockDoor(Block): +# unlocalisedName="door" +# openDoor=pygame.image.load(os.path.join("tiles","door_open.png")) +# +# @classmethod +# def init(cls): +# GameRegistry.registerBlock(cls,cls.unlocalisedName) +# Block.registerTexture(cls.unlocalisedName) +# +# def __init__(self,x,y,screen): +# Block.__init__(self,x,y,screen) +# self.setTextureName(BlockDoor.unlocalisedName) +# self.unlocalisedName=BlockDoor.unlocalisedName +# +# def interact(self,inv): +# self.clear=not self.clear +# pygame.mixer.Sound("door.ogg").play().set_volume(0.2) +# +# def getTexture(self): +# if self.clear: +# return BlockDoor.openDoor +# else: +# return False +# +# def interactData(self): +# return {"clear":self.clear} +# +# def loadData(self,data): +# self.clear=data["clear"] +# +# class BlockWorkbench(Block): +# unlocalisedName="workbench" +# +# @classmethod +# def init(cls): +# GameRegistry.registerBlock(cls,cls.unlocalisedName) +# Block.registerTexture(cls.unlocalisedName) +# +# def __init__(self,x,y,screen): +# Block.__init__(self,x,y,screen) +# self.setTextureName(BlockWorkbench.unlocalisedName) +# self.unlocalisedName=BlockWorkbench.unlocalisedName +# self.inv=Inventory() +# +# def interact(self,inv): +# selected=inv.selected +# if selected!="": +# inv.remove(selected) +# self.inv.addTile(selected,1) +# else: +# if self.inv.inv in GameRegistry.recipes.values(): +# out="" +# for outp,reqs in GameRegistry.recipes.items(): +# if self.inv.inv==reqs: +# out=outp +# break +# inv.addTile(out,1) +# self.inv.clear() +# +# def interactData(self): +# return {"inv":self.inv} +# +# def loadData(self,data): +# self.inv=data["inv"] +# +# class BlockFurnace(Block): +# unlocalisedName="furnace" +# frames=[] +# +# @classmethod +# def init(cls): +# GameRegistry.registerBlock(cls,cls.unlocalisedName) +# Block.registerTexture(cls.unlocalisedName) +# for i in range(3): +# path=os.path.join("animation",cls.unlocalisedName,"{}.png".format(i)) +# img=pygame.image.load(path) +# cls.frames.append(img) +# +# def __init__(self,x,y,screen): +# Block.__init__(self,x,y,screen) +# self.setTextureName(BlockFurnace.unlocalisedName) +# self.unlocalisedName=BlockFurnace.unlocalisedName +# self.frameno=0 +# self.forward=True +# self.burn=False +# self.count=0 +# self.inp="" +# self.inp_amount=0 +# self.outp="" +# self.outp_amount=0 +# self.fuel="" +# self.fuel_amount=0 +# self.fuel_num=0 +# self.originator=True +# +# def interact(self,inv): +# sel=inv.selected +# if sel!="": +# if sel in GameRegistry.fuels.keys(): +# if self.fuel!="" and sel!=self.fuel: +# return +# self.fuel=sel +# self.fuel_num=GameRegistry.fuels[sel] +# self.fuel_amount+=1 +# if self.inp!="": +# if self.burn==False: +# self.fuel_amount-=1 +# self.burn=True +# else: +# if self.inp!="" and sel!=self.inp: +# return +# if not sel in GameRegistry.smelting.keys(): +# return +# self.inp_amount+=1 +# self.inp=sel +# if self.burn==False and self.fuel!="": +# self.fuel_amount-=1 +# self.burn=True +# inv.remove(sel) +# else: +# if self.outp!="": +# inv.addTile(self.outp,self.outp_amount) +# self.outp="" +# self.outp_amount=0 +# self.originator=True +# +# def getTexture(self): +# if self.burn: +# self.count+=1 +# if self.count==10: +# self.update() +# self.count=0 +# img=BlockFurnace.frames[self.frameno] +# if self.forward: +# self.frameno+=1 +# if self.frameno>2: +# self.frameno=1 +# self.forward=False +# else: +# self.frameno-=1 +# if self.frameno<0: +# self.frameno=1 +# self.forward=True +# return img +# else: +# return False +# self.mp_upd=True +# +# def update(self): +# self.fuel_num-=1 +# if self.inp=="": +# self.burn=False +# return +# if self.fuel_num<=0: +# if self.fuel_amount<=0: +# self.burn=False +# self.fuel="" +# return +# else: +# self.fuel_amount-=1 +# self.fuel_num=GameRegistry.fuels[self.fuel] +# if self.inp!="": +# if self.inp in GameRegistry.smelting: +# self.inp_amount-=1 +# self.outp=GameRegistry.smelting[self.inp] +# self.outp_amount+=1 +# if self.inp_amount<=0: +# self.inp="" +# if self.originator: +# self.mp_upd=True +# +# def loadData(self,data): +# self.frameno=data["frameno"] +# self.forward=data["forward"] +# self.burn=data["burn"] +# self.count=data["count"] +# self.inp=data["inp"] +# self.inp_amount=data["inp_amount"] +# self.outp=data["outp"] +# self.outp_amount=data["outp_amount"] +# self.fuel=data["fuel"] +# self.fuel_amount=data["fuel_amount"] +# self.fuel_num=data["fuel_num"] +# self.originator=False +# +# def interactData(self): +# self.mp_upd=False +# return { +# "frameno":self.frameno, +# "forward":self.forward, +# "burn":self.burn, +# "count":self.count, +# "inp":self.inp, +# "inp_amount":self.inp_amount, +# "outp":self.outp, +# "outp_amount":self.outp_amount, +# "fuel":self.fuel, +# "fuel_amount":self.fuel_amount, +# "fuel_num":self.fuel_num +# } diff --git a/client.py b/client.py new file mode 100644 index 0000000..69c0cb2 --- /dev/null +++ b/client.py @@ -0,0 +1,67 @@ +import pygame +import os +import random +import sys +import select +import socket +import pickle +import lib.constants as constants +from lib.gameregistry import GameRegistry +from lib.map import Map +from lib.character import Character +from lib.block import Block +from lib.player import Player +from lib.player_img import PlayerImg +from time import sleep +import pprint +import blocks + +pygame.init() +screen=pygame.display.set_mode((constants.WINDWIDTH,constants.WINDHEIGHT)) + +running=True +move=False +direction=None +key_to_dir={ + pygame.K_UP:"up", + pygame.K_DOWN:"down", + pygame.K_LEFT:"left", + pygame.K_RIGHT:"right" +} + +map=Map(screen,None,0) +map.tiles={} +player=Player(0,0,map,screen,"PJHT","player_local") +player.direction="up" + +while running: + for event in pygame.event.get(): + if event.type==pygame.QUIT: + running=False + if event.type==pygame.KEYDOWN: + if event.key in key_to_dir.keys(): + move=True + direction=key_to_dir[event.key] + elif event.type==pygame.KEYUP: + move=False + player.frame=1 + key_states = pygame.key.get_pressed() + if key_states[pygame.K_UP]==1: + move=True + direction="up" + elif key_states[pygame.K_DOWN]==1: + move=True + direction="down" + elif key_states[pygame.K_LEFT]==1: + move=True + direction="left" + elif key_states[pygame.K_RIGHT]==1: + move=True + direction="right" + if move: + player.move(direction) + screen.fill([0,0,0]) + map.draw(player.x,player.y) + player.draw() + pygame.display.flip() + sleep(0.1) diff --git a/lib/__init__.py b/lib/__init__.py new file mode 100644 index 0000000..d1eb679 --- /dev/null +++ b/lib/__init__.py @@ -0,0 +1,2 @@ +from . import block,constants,gameregistry,map,character,inventory,player,player_img +__all__=["block","gameregistry","map","character","inventory","player","player_img"] diff --git a/lib/block.py b/lib/block.py new file mode 100644 index 0000000..4c5cb84 --- /dev/null +++ b/lib/block.py @@ -0,0 +1,53 @@ +from pygame.sprite import Sprite +import pygame.image +import os +from time import sleep +from . import constants +class Block(Sprite): + textures={} + background=pygame.image.load(os.path.join("tiles","{}.png".format(constants.BACKGROUND))) + @classmethod + def init(cls): + subclasses=cls.__subclasses__() + for klass in subclasses: + klass.init() + + def __init__(self,x,y,screen): + super().__init__() + self.x=x + self.y=y + self.screen=screen + self.tname=None + self.clear=False + self.unlocalisedName="" + self.drops=False + self.mp_upd=False + + def draw(self,x,y): + if self.tname==None: + raise Exception("No texture name for block. Did you forget to call setTextureName()?".format()) + self.screen.blit(Block.background,(x*constants.TILESIZE,y*constants.TILESIZE)) + texture=self.getTexture() + if texture==False: + texture=Block.textures[self.tname] + self.screen.blit(texture,(x*constants.TILESIZE,y*constants.TILESIZE)) + def setTextureName(self,name): + if not name in Block.textures.keys(): + raise Exception("{} is not a valid texture. Did you forget to call registerTexture(\"{}\")?".format(name,name)) + self.tname=name + + @classmethod + def registerTexture(cls,name): + Block.textures[name]=pygame.image.load(os.path.join("tiles","{}.png".format(name))) + + def interact(self,inv): + pass + + def getTexture(self): + return False + + def interactData(self): + return None + + def loadData(self,data): + pass diff --git a/lib/character.py b/lib/character.py new file mode 100644 index 0000000..91df30c --- /dev/null +++ b/lib/character.py @@ -0,0 +1,53 @@ +from pygame.sprite import Sprite +import pygame.image +import os +from . import constants +class Character(Sprite): + @staticmethod + def loadFrames(type): + frames={} + dirs=["up","down","left","right"] + num_frames=3 + for direction in dirs: + frame_array=[0,0,0] + i=0 + while i2: + self.frame=0 + tile=self.map.tileAt(self.x,self.y) + if not tile.clear: + self.x=old_x + self.y=old_y diff --git a/lib/constants.py b/lib/constants.py new file mode 100644 index 0000000..d39dcac --- /dev/null +++ b/lib/constants.py @@ -0,0 +1,12 @@ +TILESIZE=16 +MAPWIDTH=64 +MAPHEIGHT=64 +PORTHEIGHT=32 +PORTWIDTH=32 +EXTRAROWS=1 +CENTERX=15 +CENTERY=15 +WINDWIDTH=PORTWIDTH*TILESIZE +WINDHEIGHT=(PORTHEIGHT+EXTRAROWS)*TILESIZE +BACKGROUND="grass" +FONTSIZE=30 diff --git a/lib/gameregistry.py b/lib/gameregistry.py new file mode 100644 index 0000000..cfcf95a --- /dev/null +++ b/lib/gameregistry.py @@ -0,0 +1,25 @@ +class GameRegistry: + block_classes={} + recipes={} + smelting={} + fuels={} + + @classmethod + def registerBlock(cls,klass,name): + if not klass in cls.block_classes.keys(): + cls.block_classes[name]=klass + + @classmethod + def registerCrafting(cls,reqs,result): + if not result in cls.recipes.keys(): + cls.recipes[result]=reqs + + @classmethod + def registerSmelting(cls,inp,outp): + if not inp in cls.smelting.keys(): + cls.smelting[inp]=outp + + @classmethod + def registerFuel(cls,name,amount): + if not name in cls.fuels.keys(): + cls.fuels[name]=amount diff --git a/lib/inventory.py b/lib/inventory.py new file mode 100644 index 0000000..f2a3fe6 --- /dev/null +++ b/lib/inventory.py @@ -0,0 +1,51 @@ +class Inventory: + def __init__(self): + self.inv={} + self.selected="" + + def addTile(self,name,amount): + if name in self.inv.keys(): + self.inv[name]+=amount + else: + self.inv[name]=amount + self.selected=name + + def remove(self,name,num=1): + if not name in self.inv: + raise Exception("No {} in inventory".format(name)) + amount=self.inv[name] + amount-=num + if amount<0: + raise Exception("Attempted to remove more {} than avalible".format(name)) + self.inv[name]=amount + if amount==0: + del self.inv[name] + self.selected="" + + def selPrev(self): + newsel="" + for item, count in self.inv.items(): + if item==self.selected: + break + newsel=item + if newsel!="": + self.selected=newsel + + def clearSel(self): + self.selected="" + + def selNext(self): + newsel="" + ok_next=False + for item, count in self.inv.items(): + if ok_next: + newsel=item + break + if item==self.selected: + ok_next=True + if newsel!="": + self.selected=newsel + + def clear(self): + self.inv={} + self.selected="" diff --git a/lib/map.py b/lib/map.py new file mode 100644 index 0000000..462a89c --- /dev/null +++ b/lib/map.py @@ -0,0 +1,97 @@ +import pygame +import random +from pygame.sprite import Group +from . import block,gameregistry +from . import constants +from .gameregistry import GameRegistry +from .block import Block +import pickle +class Map: + def __init__(self,screen,sock=None,uid=None): + super().__init__() + self.tiles={} + self.screen=screen + self.sock=sock + self.uid=uid + + def send_str(self,sock,str): + sock.send((str+"\n").encode("utf-8")) + + def recvall(self,sock): + BUFF_SIZE=4096 + data=b'' + while True: + part=sock.recv(BUFF_SIZE) + data+=part + if len(part)constants.MAPWIDTH-1: + return False + if x<0: + return False + if y>constants.MAPHEIGHT-1: + return False + if y<0: + return False + return (x,y) + + def interact(self): + coords=self.facingTile() + if coords==False: + return + tile=self.map.tileAt(coords[0],coords[1]) + name=tile.unlocalisedName + if name=="grass": + to_place=self.inv.selected + if to_place=="": + return + self.map.tiles[(coords[0],coords[1])]=None + self.map.addTile(to_place,coords[0],coords[1]) + self.inv.remove(to_place) + else: + tile.interact(self.inv) + + def attack(self): + coords=self.facingTile() + if coords==False: + return + tile=self.map.tileAt(coords[0],coords[1]) + name=tile.unlocalisedName + if name=="grass": + return + self.map.tiles[(coords[0],coords[1])]=None + self.map.addTile("grass",coords[0],coords[1]) + if tile.drops==False: + self.inv.addTile(name,1) + else: + drop=tile.drops[0] + amount=tile.drops[1] + self.inv.addTile(drop,amount) + + def draw(self): + oldx=self.x + oldy=self.y + self.x=constants.CENTERX + self.y=constants.CENTERY + super().draw() + self.x=oldx + self.y=oldy diff --git a/lib/player_img.py b/lib/player_img.py new file mode 100644 index 0000000..a732dfe --- /dev/null +++ b/lib/player_img.py @@ -0,0 +1,33 @@ +from pygame.sprite import Sprite +import pygame.image +import os +import lib.constants as constants +class PlayerImg(Sprite): + @staticmethod + def loadFrames(type): + frames={} + dirs=["up","down","left","right"] + num_frames=3 + for direction in dirs: + frame_array=[0,0,0] + i=0 + while i