Browse files

update to new lib2d (still unstable)

  • Loading branch information...
1 parent 9f40043 commit d8e90e57fe80a0e454b46a23d0f4ebe60384e455 @bitcraft committed Oct 30, 2012
Showing with 205 additions and 10,522 deletions.
  1. +0 −35 client.py
  2. +43 −0 docs/TODO
  3. +1 −1 lib2d/__init__.py
  4. +0 −1 lib2d/client/__init__.py
  5. +0 −189 lib2d/client/banner.py
  6. +0 −57 lib2d/client/buttons.py
  7. +0 −31 lib2d/client/client.py
  8. +0 −309 lib2d/client/cmenu.py
  9. +0 −29 lib2d/client/game.py
  10. +0 −87 lib2d/client/gamestate.py
  11. +0 −114 lib2d/client/gfx.py
  12. +0 −385 lib2d/client/gui.py
  13. +0 −289 lib2d/client/menu.py
  14. +0 −1 lib2d/client/net/__init__.py
  15. +0 −51 lib2d/client/net/communicate.py
  16. +0 −11 lib2d/client/net/errors.py
  17. +0 −136 lib2d/client/net/netbase.py
  18. +0 −158 lib2d/client/net/socket-2.py
  19. +0 −36 lib2d/client/net/tcp.py
  20. +0 −180 lib2d/client/playerinput.py
  21. +0 −16 lib2d/client/signals.py
  22. +0 −326 lib2d/client/statedriver.py
  23. +0 −120 lib2d/client/subpixelsurface.py
  24. +0 −450 lib2d/client/tilemap.py
  25. +0 −37 lib2d/client/waitscreen.py
  26. +0 −1 lib2d/common/__init__.py
  27. +0 −503 lib2d/common/avatar.py
  28. +0 −270 lib2d/common/bbox.py
  29. +0 −2,468 lib2d/common/configobj.py
  30. +0 −36 lib2d/common/encodings.py
  31. +0 −97 lib2d/common/fov.py
  32. +0 −323 lib2d/common/gameobject.py
  33. +0 −226 lib2d/common/los.py
  34. +0 −381 lib2d/common/objects.py
  35. +0 −246 lib2d/common/packets.py
  36. +0 −397 lib2d/common/quadtree.py
  37. +0 −252 lib2d/common/rect.py
  38. +0 −159 lib2d/common/res.py
  39. +0 −73 lib2d/common/temporal.py
  40. +0 −332 lib2d/common/vec.py
  41. +10 −5 lib2d/pathfinding/astar.py
  42. +0 −723 lib2d/server/area.py
  43. +4 −0 pytmx/__init__.py
  44. +0 −89 pytmx/maputils.py
  45. +124 −800 pytmx/tmxloader.py
  46. +23 −23 pytmx/tmxloader3.py
  47. +0 −69 utilities/chop.py
View
35 client.py
@@ -1,35 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Runs the frontend for the lib2d client.
-Based on the Tkinter.
-
-not complete.
-"""
-
-from Tkinter import *
-
-
-class AddServerDialog():
- def __init__(self, master):
- frame = Frame(master)
- frame.pack()
-
-
-class Frontend(object):
-
- def __init__(self, master):
- frame = Frame(master)
- frame.pack()
-
- self.button_quit = Button(frame, text="Quit")
- self.button_quit.pack()
-
- self.button_addserver = Button(frame, text="Add Server")
- self.button_addserver.pack()
-
-
-root = Tk()
-app = Frontend(root)
-
-root.mainloop()
View
43 docs/TODO
@@ -104,6 +104,9 @@ real-time nature and strategy will have to be a mix of options
should be enough npcs and variety so that poor decisions will not have huge consequences for the player.
+no nps:
+ botting, zerging
+
may require another rewrite with the following kept in mind:
all objects must be able to be loaded and unladed at any moment
any change to state should emit a signal, even if nobody wants to listen
@@ -138,3 +141,43 @@ Quadtree:
+ Great for static geometry
- Slow add/remove of nodes
+
+alternative setting: 2300's.
+civilization has been destroyed by biological warfare
+pockets of citizens have basic communities
+proliferation of 'ancient' technologies are in common use:
+ steam engines
+ bi-planes and other simple craft
+ wind/solar/water power
+ locomotives
+knowledge of old ways of life and technology is common, but the number of people is too low to support advanced technology.
+cities are completely uninhabitable, overrun with zombie-like humans
+
+core mechanics:
+ botting/zerging is encouraged
+ economy is open (ala eve online)
+ interface allows for control of multiple characters
+ gameplay is limited by AP, per player (good/bad?)
+ no npcs!
+ game objects can be crafted and manipulated
+
+game structure:
+ players are able to create quests-like conditions for other players
+ this can be hunting type missions, assasinations, bounties, or cash
+ players run stores, inns, and other rpg-like foundations
+
+players are encouraged to settle areas by populating them with characters (alts)
+game is hybrid turn based/real time, like urban dead
+players gain experience to get access to alts
+interface uses a pane of statuses (ala facebook) with options:
+ <player> wants to buy X, etc
+
+alts can be commanded from high level (return to home, give X to X, etc)
+
+
+with enough players, no real aliances are needed
+players have reputation that follows them and is easily found
+no concepts of chat lobbies
+languages can be learned and used
+zerging as a mechanic gives one player a much more broad view of the world
+
View
2 lib2d/__init__.py
@@ -1 +1 @@
-
+from fsa import fsa
View
1 lib2d/client/__init__.py
@@ -1 +0,0 @@
-
View
189 lib2d/client/banner.py
@@ -1,189 +0,0 @@
-"""
-Copyright 2010, 2011 Leif Theden
-
-This file is part of lib2d.
-
-lib2d is free software: you can redistribute it
-and/or modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation, either version 3 of
-the License, or (at your option) any later version.
-
-lib2d is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with lib2d. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-from lib2d.common import res
-
-from pygame import Color
-import pygame
-import os
-
-
-pygame.font.init()
-
-class TextBanner(object):
- """
- Wrapper around Pygame's Font class
-
- Loading fonts in pygame can be slow, and to make up for it,
- this class caches fonts returned from pygame and can make
- multiple renders faster. It also includes some hacks
- to make blitting pretty
- """
-
- def __init__(self, text, color=[0,0,0], size=12, font=None):
- super(TextBanner, self).__init__()
-
- self._font_size = size
- self._text = text
- self._color = color
- self._rect = pygame.rect.Rect(0,0,0,0)
-
- if font == None:
- font = res.defaultFont()
- self._font = pygame.font.Font(font, size)
- self._font_name = font
-
- else:
- if isinstance(font, str):
- fullpath = res.fontPath(font)
- self.set_font(fullpath)
- else:
- self._font = font
- self._font_name = font
-
- self.dirty = 1
-
- def get_text(self):
- return self._text
-
- def set_text(self, text):
- self._text = text
- self.dirty = 1
-
- text = property(get_text, set_text)
-
- def get_font(self):
- return self._font
-
- def set_font(self, font=None):
- if font == None:
- font = default_font
- self._font = pygame.font.Font(font, self.font_size)
- self._font_name = font
- self.dirty = 1
-
- font = property(get_font, set_font)
-
- def get_font_size(self):
- return self._font_size
-
- def set_font_size(self, size):
- self._font_size = size
- self.dirty = 1
-
- font_size = property(get_font_size, set_font_size)
-
- def get_color(self):
- return self._color
-
- def set_color(self, color):
- self._color = Color(*color)
- self.dirty = 1
-
- color = property(get_color, set_color)
-
- @property
- def image(self):
- if self.dirty:
- self.render()
- return self._image
-
- @property
- def rect(self):
- if self.dirty:
- self.render()
- return self._rect
-
- def render(self, bkg=None, alpha=False):
- try:
- if alpha == True:
- self._image = self.font.render(self.text, True, self._color).convert_alpha()
- elif bkg == None:
- self._image = self.font.render(self.text, False, self._color).convert()
- else:
- self._image = self.font.render(self.text, True, self._color, bkg).convert()
- self._image.set_colorkey(bkg)
- self._rect.size = self._image.get_rect().size
- return self._image
- except AttributeError:
- print "font not set correctly"
- raise
-
- self.dirty = 0
-
-class OutlineTextBanner(TextBanner):
- colorkey = (90,0,0)
- border = 3
- border_color = (0,0,0)
-
- def render(self, bkg=None, alpha=False):
- try:
- # render the font once to determine the size needed for our scratch surface
- image = self.font.render(self.text, True, self._color)
-
- # this is our scratch surface
- s = pygame.Surface(image.get_size())
-
- # we need to fanagle the image a bit to make sure colorkey surfaces work
- if not alpha:
- s.fill(self.colorkey)
- s.set_colorkey(self.colorkey)
-
- # choose the font for the banner. it must be smaller than the original size
- if self._font_name == None:
- inner_font = pygame.font.Font(default_font, self.font_size - 4)
- else:
- inner_font = pygame.font.Font(self._font_name, self.font_size - 4)
-
- # render the text for the border
-
- text = inner_font.render(self.text, False, self.border_color)
-
- # build a border for the text by blitting it in a circle
- for x in xrange(self.border + 2):
- for y in xrange(self.border + 2):
- s.blit(text, (x, y))
-
- # render the innner portion of the banner
- text = inner_font.render(self.text, False, self._color)
-
- # blit the text over the border
- s.blit(text, (2,2))
-
- self._image = s.convert()
- self._rect.size = self._image.get_rect().size
-
- return self._image
- except AttributeError:
- print "font not set correctly"
- raise
-
-class RetroOutlineTextBanner(OutlineTextBanner):
- """
- Outlined text banner, but stretches out the image to give it
- a look not unlike 80's era fonts that have rectangluar pixels
- """
-
- def render(self, bkg=None, alpha=True):
- super(RetroOutlineTextBanner, self).render(bkg, alpha)
-
- w, h = self.image.get_size()
- self._image = pygame.transform.scale(self._image, (int(w/2), h))
- self._image = pygame.transform.scale(self._image, (w, h)).convert()
-
View
57 lib2d/client/buttons.py
@@ -1,57 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Button Constants
-
-# movement
-BUTTON_LEFT = 64
-BUTTON_RIGHT = 128
-BUTTON_UP = 256
-BUTTON_DOWN = 512
-
-
-# for fighting style games
-BUTTON_PUNCH = 7 # don't assign controls to this -- for interal use
-BUTTON_LOW_PUNCH = 1
-BUTTON_MED_PUNCH = 2
-BUTTON_HI_PUNCH = 4
-
-BUTTON_KICK = 56 # don't assign controls to this -- for interal use
-BUTTON_LOW_KICK = 8
-BUTTON_MED_KICK = 16
-BUTTON_HI_KICK = 32
-
-BUTTON_GUARD = 2048
-
-
-# misc
-BUTTON_NULL = 0 # virtual button to handle state changes w/hold buttons
-BUTTON_FORWARD = 4096
-BUTTON_BACK = 8192
-BUTTON_PAUSE = 1024
-BUTTON_MENU = 1024
-BUTTON_SELECT = 4096
-
-BUTTONUP = 1 # after being released
-BUTTONHELD = 2 # when button is down for more than one check
-BUTTONDOWN = 4 # will only be this value on first check
-
-P1_UP = 1
-P1_DOWN = 2
-P1_LEFT = 4
-P1_RIGHT = 8
-P1_ACTION1 = 16
-P1_ACTION2 = 32
-P1_ACTION3 = 64
-P1_ACTION4 = 128
-P1_X_RETURN = 256
-P1_Y_RETURN = 512
-
-
-P2_UP = 1
-P2_DOWN = 2
-P2_LEFT = 4
-P2_RIGHT = 8
-P2_ACTION1 = 16
-P2_ACTION2 = 32
-
-KEYNAMES = {1:"up", 2:"down", 4:"left", 8:"right", 16:"action0", 32:"action1"}
View
31 lib2d/client/client.py
@@ -1,31 +0,0 @@
-from lib2d.client.net.tcp import TCPClient
-from lib2d.common.packets import make_packet
-
-
-
-class Client(object):
- """
- connects to a server and allows the player to play
- """
-
-
- version = 1
-
- def __init__(self, user, passwd, addr, port):
- self.user = user
- self.passwd = passwd
- self.connect()
-
-
- def connect(self):
- self.conn = TCPClient()
- self.conn.connect("127.0.0.1", 25565)
-
-
- def login(self):
- packet = make_packet("login",
- protocol=self.version,
- username=self.user,
- password=self.passwd)
-
- self.conn.send_data(packet)
View
309 lib2d/client/cmenu.py
@@ -1,309 +0,0 @@
-"""
-Copyright 2010-2012 Leif Theden
-
-
-This file is part of lib2d.
-
-lib2d is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-lib2d is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with lib2d. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-from lib2d.common import res
-from lib2d.client.banner import OutlineTextBanner, TextBanner
-
-import pygame
-from pygame.locals import *
-
-
-
-class OutlineMenuItem(OutlineTextBanner):
- def __init__(self, t, cb, c, s, f):
- self.callback = cb
- self.disabled = False
- super(OutlineMenuItem, self).__init__(text=t, color=c, size=s, font=f)
-
-
-class MenuItem(TextBanner):
- def __init__(self, t, cb, c, s, f):
- self.callback = cb
- self.disabled = False
- super(MenuItem, self).__init__(text=t, color=c, size=s, font=f)
-
-
-class cMenu():
-
- move_sound = res.loadSound("bump0.wav")
- select_sound = res.loadSound("select1.wav")
-
- def __init__(self, rect, h_pad, v_pad, orientation, number, button_list,
- font=None, font_size=32, banner_style="outline", callback=None):
-
- ## menu items
- self.menu_items = [] # List of menu items
- self.font = font # Font to use
- self.font_size = font_size
-
- self.rect = pygame.Rect(rect) # Top left corner (of surface)
- self.change_number = number # new row/col #
- self.orientation = orientation
- self.horizontal_padding = h_pad
- self.vertical_padding = v_pad
-
- self.selection = 0 # The currently selected button
- self.u_color = (230,230,230) # Color for unselected text
- self.s_color = (255,50,10) # Color for selected text
-
- self.centered = False # True if the menu is centered
- self.update_buttons = False # True if the positions of the
- # buttons need to be updated
-
- # the callback will call a function with the current selection as the
- # first argument. useful if you want to track state of the menu in a
- # sane way. you could constantly poll, selection, but this is better.
- self.callback = callback
-
- self.banner_style = banner_style # type of font to use
- self.dirty = True
-
- # This dictionary contains the alignment orientation of the buttons
- # related to each other. It shifts the button within the bounds of
- # 'max_width' and 'max_height' in the self.position_items() method.
- self.alignment = {'vertical' :'top',
- 'horizontal':'left'}
-
-
- [ self.add_button(self.create_button(*i[:2])) for i in button_list ]
- self.update_buttons = True
-
- def disable(self, i):
- """
- disable a specific option
-
- the option will be shown, but cannot be selected
- """
-
- self.menu_items[i].disabled = True
- self.update_buttons = True
-
-
- def enable(self, i):
- """
- enable a specific option
- """
-
- self.menu_items[i].disabled = False
- self.update_buttons = True
-
- def add_button(self, button):
- self.menu_items.append(button)
-
- def draw(self, surface):
- if self.update_buttons:
- self.position_items()
- self.render()
- self.update_buttons = False
-
- [ surface.blit(b.image, b.rect) for b in self.menu_items ]
-
- @property
- def drawables(self):
- return self.menu_items
-
- def render(self):
- # grey-out disabled menu items
- for b in self.menu_items:
- if b.disabled:
- b.color = (80,80,80)
- else:
- b.render()
- self.dirty = True
-
- def set_padding(self, h_pad, v_pad):
- self.horizontal_padding = h_pad
- self.vertical_padding = v_pad
- self.update_buttons = True
-
- def set_orientation(self, new_orientation):
- if new_orientation == 'vertical' or new_orientation == 'horizontal':
- self.orientation = new_orientation
- self.update_buttons = True
- else:
- print 'WARNING: cMenu.set_orientation: Invalid argument '\
- 'new_orientation (value: %d)' % new_orientation
-
- def set_font(self, font):
- self.font = font
- [ item.set_font(font) for item in self.menu_items ]
-
- def set_alignment(self, v_align, h_align):
- if v_align in ['top', 'center', 'bottom']:
- self.alignment['vertical'] = v_align
- if h_align in ['left', 'center', 'right']:
- self.alignment['horizontal'] = h_align
- self.update_buttons = True
-
- def remove_buttons(self, indexList):
- for index in indexList:
- if len(self.menu_items) > 1:
- self.menu_items.pop(index)
- self.update_buttons = True
-
- def create_button(self, text, callback, color=None):
- if color == None:
- color = self.u_color
-
- if self.banner_style == "outline":
- new_button = OutlineMenuItem(text, callback, color, self.font_size, self.font)
- else:
- new_button = MenuItem(text, callback, color, self.font_size, self.font)
-
- return new_button
-
- def position_items(self):
- width = 0
- height = 0
- max_width = 0
- max_height = 0
- counter = 0
-
- x_loc = self.rect.left
- y_loc = self.rect.top
-
- # Get the maximum width and height of the surfaces
- for item in self.menu_items:
- max_width = max(item.rect.width, max_width)
- max_height = max(item.rect.height, max_height)
-
- # Position the button in relation to each other
- for item in self.menu_items:
- # Vertical Alignment
- if self.alignment['vertical'] == 'top':
- offset_height = 0
- elif self.alignment['vertical'] == 'center':
- offset_height = (max_height - item.rect.height)/2
- elif self.alignment['vertical'] == 'bottom':
- offset_height = (max_height - item.rect.height)
-
- # Horizontal Alignment
- if self.alignment['horizontal'] == 'left':
- offset_width = 0
- elif self.alignment['horizontal'] == 'center':
- offset_width = (max_width - item.rect.width)/2
- elif self.alignment['horizontal'] == 'right':
- offset_width = (max_width - item.rect.width)
-
- # Move the button location slightly based on the alignment offsets
- x_loc += offset_width
- y_loc += offset_height
-
- # Assign the location of the button
- item.rect.topleft = (x_loc, y_loc)
-
- # Take the alignment offsets away after the button position has been
- # assigned so that the new button can start fresh again
- x_loc -= offset_width
- y_loc -= offset_height
-
- # Add the width/height to the position based on the orientation of the
- # menu. Add in the padding.
- if self.orientation == 'vertical':
- y_loc += max_height + self.vertical_padding
- else:
- x_loc += max_width + self.horizontal_padding
-
-
- def handle_event(self, event):
- if event.type != KEYDOWN: return
- key = event.key
-
- o = self.orientation
- s = self.selection
- n = self.change_number
-
- d = 0
-
- if key == K_DOWN:
- self.move_sound.stop()
- self.move_sound.play()
- if (o == 'vertical') and ((s + 1) % n != 0):
- d = 1
- elif o == 'horizontal':
- d = n
- elif key == K_UP:
- self.move_sound.stop()
- self.move_sound.play()
- if (o == 'vertical') and ((s) % n != 0):
- d = -1
- elif o == 'horizontal':
- d = -n
- elif key == K_RIGHT:
- self.move_sound.stop()
- self.move_sound.play()
- if o == 'vertical':
- d = n
- elif (o == 'horizontal') and ((s + 1) % n != 0):
- d = 1
- elif key == K_LEFT:
- self.move_sound.stop()
- self.move_sound.play()
- if o == 'vertical':
- d = -n
- elif (o == 'horizontal') and ((s) % n != 0):
- d = -1
- elif key == K_RETURN:
- #self.select_sound.play()
- return [None], self.menu_items[self.selection].callback()
-
- self.check_disabled(d)
-
- if self.selection >= len(self.menu_items):
- self.selection = len(self.menu_items) -1
-
- elif self.selection < 0:
- self.selection = 0
-
- if s != self.selection:
- self.menu_items[self.selection].color = self.s_color
- self.menu_items[s].color = self.u_color
- if not self.callback == None:
- self.callback(self.selection)
-
- return None
-
- def check_disabled(self, d=0):
- try:
- if self.menu_items[self.selection + d].disabled:
- if self.selection + d == 0:
- self.selection = 0
- self.check_disabled(1)
-
- elif self.selection + d == len(self.menu_items) - 1:
- self.selection = len(self.menu_items) - 1
- self.check_disabled(-1)
-
- else:
- if d < 0:
- d -= 1
- else:
- d += 1
-
- self.check_disabled(d)
- else:
- self.selection += d
- except:
- return
-
- def ready(self, start=0):
- self.selection = start
- self.check_disabled()
- self.menu_items[self.selection].color = self.s_color
View
29 lib2d/client/game.py
@@ -1,29 +0,0 @@
-#!/usr/bin/env python
-
-from lib2d.client.statedriver import driver as sd
-from lib2d.client import gfx
-import pygame
-
-
-class Game(object):
- def __init__(self):
- self.config = {}
- pygame.init()
- pygame.mixer.init()
- gfx.init()
- self.sd = sd
- self.sd.set_parent(self)
-
- def load_config(self, location):
- pass
-
- def get_config(self):
- return self.config
-
- def get_screen(self):
- return gfx.screen
-
- def start(self):
- pass
-
-
View
87 lib2d/client/gamestate.py
@@ -1,87 +0,0 @@
-class GameState(object):
- """
- Game states are a logical way to break up distinct portions of a game.
- """
-
- def __init__(self):
- """
- Called when object is instanced.
-
- Not a good idea to load large objects here since it is possible
- that the state is simply instanced and placed in a queue. It would
- be wasteful.
-
- Ideally, any initialization will be handled in activate() since
- that is the point when assets will be required.
- """
-
- self.activated = False
-
-
- def activate(self):
- """
- Called when focus is given to the state for the first time
- """
-
- pass
-
-
- def reactivate(self):
- """
- Called with focus is given to the state again
- """
-
- pass
-
-
- def deactivate(self):
- """
- Called when focus is being lost
- """
-
- pass
-
-
- def terminate(self):
- """
- Called when the state is no longer needed
- The state will be lost after this is called
- """
-
- pass
-
-
- def draw(self, surface):
- """
- Called when state can draw to the screen
- """
-
- pass
-
-
- def handle_event(self, event):
- """
- Called when there is a lib2d or pygame event to process
-
- Better to use handle_command() or handle_commandlist()
- for player input
- """
-
- pass
-
-
- def handle_command(self, command):
- """
- Called when there is an input command to process
- """
-
- pass
-
-
- def handle_commandlist(self, cmdlist):
- """
- Called when there are multiple input commands to process
- This is more effecient that handling them one at a time
- """
-
- pass
View
114 lib2d/client/gfx.py
@@ -1,114 +0,0 @@
-"""
-Copyright 2010, 2011 Leif Theden
-
-
-This file is part of lib2d.
-
-lib2d is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-lib2d is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with lib2d. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-from lib2d.common.vec import Vec2d
-
-from pygame.transform import scale, scale2x
-from pygame.display import flip
-import pygame, os.path, pprint
-
-
-
-"""
-a few utilities for making retro looking games by scaling the screen
-and providing a few functions for handling screen changes
-
-"""
-
-DEBUG = False
-
-def debug(text):
- if DEBUG: sys.stdout.write(text)
-
-
-pixelize = None
-pix_scale = 1
-screen_dim = None
-buffer_dim = None
-screen = None
-screen_surface = None
-update_display = None
-double_buffer = False
-hwsurface = False
-#surface_flags = pygame.FULLSCREEN
-surface_flags = 0
-
-
-
-def hardware_checks():
- """
- TODO: Do some tests to see if we can reliably use hardware sprites
- """
-
- pass
-
-
-def init():
- global screen_dim
-
- # determine if we can use hardware accelerated surfaces or not
- pygame.display.set_caption("robots!")
-
-# is it redundant to have a pygame buffer, and one for pixalization? maybe...
-
-def update_display_scaled2x(dirty):
- scale2x(screen, screen_surface)
- flip()
-
-def update_display_scaled(dirty):
- scale(screen, screen_dim, screen_surface)
- flip()
-
-def set_screen(dim, scale=1, transform=None):
-
- global pixelize, pix_scale, buffer_dim, screen, update_display, screen_surface, screen_dim
-
- screen_dim = Vec2d(dim)
-
- if transform == "scale2x" or transform == "scale":
- set_scale(scale, transform)
-
- elif transform == None:
- pixelize = False
- pixel_buffer = None
- pix_scale = 1
- buffer_dim = None
- update_display = pygame.display.update
- screen_surface = pygame.display.set_mode(screen_dim, surface_flags)
- screen = screen_surface
-
-def set_scale(scale, transform="scale"):
- from pygame.surface import Surface
-
- global pixelize, pix_scale, buffer_dim, screen, update_display, screen_surface, screen_dim
-
- if transform == "scale2x":
- pix_scale = 2
- update_display = update_display_scaled2x
- elif transform == "scale":
- pix_scale = scale
- update_display = update_display_scaled
-
- pixelize = True
- buffer_dim = tuple([ int(i / pix_scale) for i in screen_dim ])
- screen_surface = pygame.display.set_mode(screen_dim, surface_flags)
- screen = Surface(buffer_dim, surface_flags)
- #screen_surface = pygame.display.set_mode(screen_dim)
-
View
385 lib2d/client/gui.py
@@ -1,385 +0,0 @@
-from lib2d.common import res
-
-import pygame
-from math import ceil
-from itertools import product
-from pygame import Surface, Rect, RLEACCEL
-
-
-
-class GraphicBox(object):
- """
- Generic class for drawing graphical boxes
-
- load it, then draw it wherever needed
- """
-
- def __init__(self, filename, hollow=False):
- self.hollow = hollow
-
- image = res.loadImage(filename, colorkey=True)
- iw, self.th = image.get_size()
- self.tw = iw / 9
- names = "nw ne sw se n e s w c".split()
- tiles = [ image.subsurface((i*self.tw, 0, self.tw, self.th))
- for i in range(9) ]
-
- if self.hollow:
- ck = tiles[8].get_at((0,0))
- [ t.set_colorkey(ck, RLEACCEL) for t in tiles ]
-
- self.tiles = dict(zip(names, tiles))
- self.background = self.tiles['c'].get_at((0,0))
-
-
- def draw(self, surface, rect):
- ox, oy, w, h = Rect(rect)
-
- for x in range(self.tw+ox, w-self.tw+ox, self.tw):
- surface.blit(self.tiles['n'], (x, oy))
- surface.blit(self.tiles['s'], (x, h-self.th+oy))
-
- for y in range(self.th+oy, h-self.th+oy, self.th):
- surface.blit(self.tiles['w'], (w-self.tw+ox, y))
- surface.blit(self.tiles['e'], (ox, y))
-
- if not self.hollow:
- p = product(range(self.tw+ox, w-self.tw+ox, self.tw),
- range(self.th+oy, h-self.th+oy, self.th))
-
- [ surface.blit(self.tiles['c'], (x, y)) for x, y in p ]
-
- surface.blit(self.tiles['nw'], (ox, oy))
- surface.blit(self.tiles['ne'], (w-self.tw+ox, oy))
- surface.blit(self.tiles['se'], (ox, h-self.th+oy))
- surface.blit(self.tiles['sw'], (w-self.tw+ox, h-self.th+oy))
-
-
-# draw some text into an area of a surface
-# automatically wraps words
-# returns any text that didn't get blitted
-def drawText(surface, text, color, rect, font=None, aa=False, bkg=None):
- rect = Rect(rect)
- y = rect.top
- lineSpacing = -2
- maxWidth = 0
- maxHeight = 0
-
- if font == None:
- fullpath = pygame.font.get_default_font()
- font = pygame.font.Font(fullpath, 12)
-
- # get the height of the font
- fontHeight = font.size("Tg")[1]
-
- # for very small fonts, turn off antialiasing
- if fontHeight < 16:
- aa=0
- bkg=None
-
-
- while text:
- i = 1
-
- # determine if the row of text will be outside our area
- if y + fontHeight > rect.bottom:
- break
-
- # determine maximum width of line
-
- while font.size(text[:i])[0] < rect.width and i < len(text):
- if text[i] == "\n":
- text = text[:i] + text[i+1:]
- break
- i += 1
- else:
- # if we've wrapped the text, then adjust the wrap to the last word
- if i < len(text):
- i = text.rfind(" ", 0, i) + 1
-
- # render the line and blit it to the surface
- if bkg:
- image = font.render(text[:i], 1, color, bkg)
- image.set_colorkey(bkg)
- else:
- image = font.render(text[:i], aa, color)
-
- surface.blit(image, (rect.left, y))
- y += fontHeight + lineSpacing
-
- # remove the text we just blitted
- text = text[i:]
-
- return text
-
-
-def renderOutlineText(text, color, border, fontFilename, size,
- colorkey=(128,128,0)):
-
- font = pygame.font.Font(fontFilename, size+4)
- image = pygame.Surface(font.size(text), pygame.SRCALPHA)
- inner = pygame.font.Font(fontFilename, size - 4)
- outline = inner.render(text, 2, border)
- w, h = image.get_size()
- ww, hh = outline.get_size()
- cx = w/2-ww/2
- cy = h/2-hh/2
- for x in xrange(-3,3):
- for y in xrange(-3,3):
- image.blit(outline, (x+cx, y+cy))
- image.blit(inner.render(text, 1, color), (cx,cy))
- return image
-
-
-class ScrollingTextPanel(object):
- """
- Area that can display text and maintains a buffer
- """
-
- def __init__(self, rect, maxlen):
- self.rect = rect
- self.maxlen = maxlen
- self.background = (0,0,0)
-
- def add(self, text):
- if len(self.text) == maxlen:
- self.text.popleft()
-
- self.text.append(text)
-
- def draw(self, surface):
- for line in self.text:
- banner = TextBanner(line, size=self.text_size)
- surface.blit(banner.render(self.background), (x,y))
- y += banner.font.size(line)[1]
-
-
-class VisualTimer(object):
- """
- Display a timer
- """
-
- def __init__(self, finish, rect=None, color=(255,255,255)):
- self.time = 0
- self.finish = float(finish)
-
- if rect == None:
- rect = Rect(0,0,100,16)
-
- self.rect = Rect(rect)
-
- self.size = self.rect.width
- self.color = color
-
- self.image = Surface(self.rect.size)
- self.finished = 0
-
- def set_alarm(self, time):
- self.finish = float(time)
- self.reset()
-
- def reset(self):
- self.time = 0
- self.finished = 0
-
- def update(self, time):
- if self.finished: return
-
- time += self.time
-
- if time <= self.finish:
- self.time = time
- else:
- self.finished = 1
-
- def draw(self, surface):
- if not self.finished:
- self.render()
-
- surface.blit(self.image, self.rect.topleft)
-
- def render(self):
- i = ceil(self.size * (self.time / self.finish))
-
- w, h = self.rect.size
- self.image.lock()
-
- self.image.fill((32,32,32))
- self.image.fill(self.color, (0,0,i,self.rect.height))
-
- #Make the corners look pretty
- self.image.fill((0,0,0), (0,0,1,1))
- self.image.fill((0,0,0), (w-1,0,1,1))
- self.image.fill((0,0,0), (w-1,h-1,1,1))
- self.image.fill((0,0,0), (0,h-1,1,1))
-
- self.image.unlock()
-
-
-"""
-Misc. software cursor.
-"""
-
-from pygame.locals import *
-from pygame.rect import Rect
-from pygame.transform import flip
-import pygame
-
-
-
-class Cursor(object):
- """
- Cursor base class that has a shadow and flips while moving
- """
- def __init__(self, image, hotspot=(0,0)):
- """
- surface = Global surface to draw on
- cursor = surface of cursor (needs to be specified when enabled!)
- hotspot = the hotspot for your cursor
- """
- self.enabled = 0
- self.image = None
- self.shadow = None
- self.hotspot = hotspot
- self.bg = None
- self.offset = 0,0
- self.old_pos = 0,0
- self.direction = 0
- self.do_flip = False
-
- if image:
- self.setImage(image, hotspot)
-
-
- def enable(self):
- """
- Enable the GfxCursor (disable normal pygame cursor)
- """
- raise NotImplementedError
-
-
- def disable(self):
- """
- Disable the GfxCursor (enable normal pygame cursor)
- """
- raise NotImplementedError
-
-
- def make_shadow(self):
- # generate an image for use as a shadow
- # this is a kludge
- self.shadow = self.image.copy()
- colorkey = self.image.get_at((0,0))
- self.shadow.set_colorkey(colorkey)
- for x in xrange(self.image.get_rect().width):
- for y in xrange(self.image.get_rect().height):
- if not self.shadow.get_at((x, y)) == colorkey:
- self.shadow.set_at((x, y), (0,0,0))
- self.shadow.convert()
- self.shadow.set_alpha(60)
-
-
- def setImage(self, image, hotspot=(0,0)):
- """
- Set a new cursor surface
- """
- self.image = image
- self.offset = hotspot
- self.image.set_alpha(200)
- self.make_shadow()
- if self.direction == 1:
- self.do_flip = True
-
-
- def setHotspot(self,pos):
- """
- Set a new hotspot for the cursor
- """
- self.hide()
- self.offset = pos
-
-
- def draw(self, surface):
- if self.enabled:
- if self.do_flip:
- self.image = flip(self.image, True, False)
- if not self.shadow == None:
- self.shadow = flip(self.shadow, True, False)
- self.do_flip = False
-
- pos=[self.old_pos[0]-self.offset[0],self.old_pos[1]-self.offset[1]]
-
- if not self.shadow == None:
- surface.blit(self.shadow,(pos[0]+2, pos[1]+2))
- surface.blit(self.image,pos)
-
-
- def setPos(self, pos):
- if self.direction == 0:
- if self.old_pos[0] > pos[0]:
- if self.do_flip == False:
- self.direction = 1
- self.do_flip = True
-
- else:
- if self.old_pos[0] < pos[0]:
- if self.do_flip == False:
- self.direction = 0
- self.do_flip = True
-
- self.old_pos = pos[:]
-
-
- def setFlip(self, flip):
- """
- The cursor can optionally flip left or right depending on the
- direction it is moving. This is a neat-o effect for the hand cursor.
- """
- self.do_flip = bool(flip)
-
-
-class MouseCursor(Cursor):
- """
- Replaces the normal pygame mouse cursor with any bitmap cursor
- """
-
- def enable(self):
- """
- Enable the GfxCursor (disables normal pygame cursor)
- """
- if not self.image or self.enabled: return
- pygame.mouse.set_visible(0)
- self.enabled = 1
-
-
- def disable(self):
- """
- Disable the GfxCursor (enables normal pygame cursor)
- """
- if self.enabled:
- pygame.mouse.set_visible(1)
- self.enabled = 0
-
-
-class KeyCursor(Cursor):
- """
- A cursor that can be controlled by keys
- (not complete)
- """
-
- def enable(self):
- """
- Enable the GfxCursor
- """
- if not self.image or self.enabled: return
- self.enabled = 1
-
-
- def disable(self):
- """
- Disable the GfxCursor
- """
- if self.enabled:
- self.enabled = 0
-
-
View
289 lib2d/client/menu.py
@@ -1,289 +0,0 @@
-import res
-
-import pygame
-from pygame.locals import *
-
-
-
-class OutlineMenuItem(OutlineTextBanner):
- def __init__(self, t, cb, c, s, f):
- self.callback = cb
- self.disabled = False
- super(OutlineMenuItem, self).__init__(text=t, color=c, size=s, font=f)
-
-
-class MenuItem(TextBanner):
- def __init__(self, t, cb, c, s, f):
- self.callback = cb
- self.disabled = False
- super(MenuItem, self).__init__(text=t, color=c, size=s, font=f)
-
-
-class cMenu():
-
- move_sound = res.loadSound("bump0.wav")
- select_sound = res.loadSound("select1.wav")
-
- def __init__(self, rect, h_pad, v_pad, orientation, number, button_list,
- font=None, font_size=32, banner_style="outline", callback=None):
-
- ## menu items
- self.menu_items = [] # List of menu items
- self.font = font # Font to use
- self.font_size = font_size
-
- self.rect = rect # Top left corner (of surface)
- self.change_number = number # new row/col #
- self.orientation = orientation
- self.horizontal_padding = h_pad
- self.vertical_padding = v_pad
-
- self.selection = 0 # The currently selected button
- self.u_color = (230,230,230) # Color for unselected text
- self.s_color = (255,50,10) # Color for selected text
-
- self.centered = False # True if the menu is centered
- self.update_buttons = False # True if the positions of the
- # buttons need to be updated
-
- # the callback will call a function with the current selection as the
- # first argument. useful if you want to track state of the menu in a
- # sane way. you could constantly poll, selection, but this is better.
- self.callback = callback
-
- self.banner_style = banner_style # type of font to use
- self.dirty = True
-
- # This dictionary contains the alignment orientation of the buttons
- # related to each other. It shifts the button within the bounds of
- # 'max_width' and 'max_height' in the self.position_items() method.
- self.alignment = {'vertical' :'top',
- 'horizontal':'left'}
-
-
- [ self.add_button(self.create_button(*i[:2])) for i in button_list ]
- self.update_buttons = True
-
- def disable(self, i):
- """
- disable a specific option
-
- the option will be shown, but cannot be selected
- """
-
- self.menu_items[i].disabled = True
- self.update_buttons = True
-
-
- def enable(self, i):
- """
- enable a specific option
- """
-
- self.menu_items[i].disabled = False
- self.update_buttons = True
-
- def add_button(self, button):
- self.menu_items.append(button)
-
- def draw(self, surface):
- if self.update_buttons:
- self.position_items()
- self.render()
- self.update_buttons = False
-
- [ surface.blit(b.image, b.rect) for b in self.menu_items ]
-
- @property
- def drawables(self):
- return self.menu_items
-
- def render(self):
- # grey-out disabled menu items
- for b in self.menu_items:
- if b.disabled:
- b.color = (80,80,80)
- else:
- b.render()
- self.dirty = True
-
- def set_padding(self, h_pad, v_pad):
- self.horizontal_padding = h_pad
- self.vertical_padding = v_pad
- self.update_buttons = True
-
- def set_orientation(self, new_orientation):
- if new_orientation == 'vertical' or new_orientation == 'horizontal':
- self.orientation = new_orientation
- self.update_buttons = True
- else:
- print 'WARNING: cMenu.set_orientation: Invalid argument '\
- 'new_orientation (value: %d)' % new_orientation
-
- def set_font(self, font):
- self.font = font
- [ item.set_font(font) for item in self.menu_items ]
-
- def set_alignment(self, v_align, h_align):
- if v_align in ['top', 'center', 'bottom']:
- self.alignment['vertical'] = v_align
- if h_align in ['left', 'center', 'right']:
- self.alignment['horizontal'] = h_align
- self.update_buttons = True
-
- def remove_buttons(self, indexList):
- for index in indexList:
- if len(self.menu_items) > 1:
- self.menu_items.pop(index)
- self.update_buttons = True
-
- def create_button(self, text, callback, color=None):
- if color == None:
- color = self.u_color
-
- if self.banner_style == "outline":
- new_button = OutlineMenuItem(text, callback, color, self.font_size, self.font)
- else:
- new_button = MenuItem(text, callback, color, self.font_size, self.font)
-
- return new_button
-
- def position_items(self):
- width = 0
- height = 0
- max_width = 0
- max_height = 0
- counter = 0
-
- x_loc = self.rect.left
- y_loc = self.rect.top
-
- # Get the maximum width and height of the surfaces
- for item in self.menu_items:
- max_width = max(item.rect.width, max_width)
- max_height = max(item.rect.height, max_height)
-
- # Position the button in relation to each other
- for item in self.menu_items:
- # Vertical Alignment
- if self.alignment['vertical'] == 'top':
- offset_height = 0
- elif self.alignment['vertical'] == 'center':
- offset_height = (max_height - item.rect.height)/2
- elif self.alignment['vertical'] == 'bottom':
- offset_height = (max_height - item.rect.height)
-
- # Horizontal Alignment
- if self.alignment['horizontal'] == 'left':
- offset_width = 0
- elif self.alignment['horizontal'] == 'center':
- offset_width = (max_width - item.rect.width)/2
- elif self.alignment['horizontal'] == 'right':
- offset_width = (max_width - item.rect.width)
-
- # Move the button location slightly based on the alignment offsets
- x_loc += offset_width
- y_loc += offset_height
-
- # Assign the location of the button
- item.rect.topleft = (x_loc, y_loc)
-
- # Take the alignment offsets away after the button position has been
- # assigned so that the new button can start fresh again
- x_loc -= offset_width
- y_loc -= offset_height
-
- # Add the width/height to the position based on the orientation of the
- # menu. Add in the padding.
- if self.orientation == 'vertical':
- y_loc += max_height + self.vertical_padding
- else:
- x_loc += max_width + self.horizontal_padding
-
-
- def handle_event(self, event):
-
- if event.type != KEYDOWN: return
- key = event.key
-
- o = self.orientation
- s = self.selection
- n = self.change_number
-
- d = 0
-
- if key == K_DOWN:
- self.move_sound.stop()
- self.move_sound.play()
- if (o == 'vertical') and ((s + 1) % n != 0):
- d = 1
- elif o == 'horizontal':
- d = n
- elif key == K_UP:
- self.move_sound.stop()
- self.move_sound.play()
- if (o == 'vertical') and ((s) % n != 0):
- d = -1
- elif o == 'horizontal':
- d = -n
- elif key == K_RIGHT:
- self.move_sound.stop()
- self.move_sound.play()
- if o == 'vertical':
- d = n
- elif (o == 'horizontal') and ((s + 1) % n != 0):
- d = 1
- elif key == K_LEFT:
- self.move_sound.stop()
- self.move_sound.play()
- if o == 'vertical':
- d = -n
- elif (o == 'horizontal') and ((s) % n != 0):
- d = -1
- elif key == K_RETURN:
- #self.select_sound.play()
- return [None], self.menu_items[self.selection].callback()
-
- self.check_disabled(d)
-
- if self.selection >= len(self.menu_items):
- self.selection = len(self.menu_items) -1
-
- elif self.selection < 0:
- self.selection = 0
-
- if s != self.selection:
- self.menu_items[self.selection].color = self.s_color
- self.menu_items[s].color = self.u_color
- if not self.callback == None:
- self.callback(self.selection)
-
- return None
-
- def check_disabled(self, d=0):
- try:
- if self.menu_items[self.selection + d].disabled:
- if self.selection + d == 0:
- self.selection = 0
- self.check_disabled(1)
-
- elif self.selection + d == len(self.menu_items) - 1:
- self.selection = len(self.menu_items) - 1
- self.check_disabled(-1)
-
- else:
- if d < 0:
- d -= 1
- else:
- d += 1
-
- self.check_disabled(d)
- else:
- self.selection += d
- except:
- return
-
- def ready(self, start=0):
- self.selection = start
- self.check_disabled()
- self.menu_items[self.selection].color = self.s_color
View
1 lib2d/client/net/__init__.py
@@ -1 +0,0 @@
-from netbase import *
View
51 lib2d/client/net/communicate.py
@@ -1,51 +0,0 @@
-from errors import *
-import zlib
-
-def EncodeData(data,compress):
- data = pickle.dumps(data)
- if compress != False:
- data = zlib.compress(data,compress)
- length = str(len(data))
- length = ("0"*(8-len(length)))+length
- return length,data
-
-
-def DecodeData(data):
- try:data = pickle.loads(data)
- except:data = pickle.loads(zlib.decompress(data))
- return data
-
-
-def SendData(sock,data,compress,includelength=False,address=None):
- length,data = EncodeData(data,compress)
- if includelength: data = length + data
- if len(data) > 1024: print "Warning: packets are big."
- try:
- if address != None:
- sock.sendto(data,address)
- else:
- sock.send(data)
- except:
- sock.close()
- raise SocketError("Connection is broken; data could not be sent!")
-
-
-def ReceiveData(sock):
- try:
- length = int(sock.recv(8))
- data = sock.recv(length)
- except:
- sock.close()
- raise SocketError("Connection is broken; data could not be received!")
- data = DecodeData(data)
- return data
-
-
-def ReceiveDataUDP(sock,size=1024):
- try:
- data, address = sock.recvfrom(size)
- except:
- sock.close()
- raise SocketError("Connection is broken; data could not be received!")
- data = DecodeData(data)
- return data, address
View
11 lib2d/client/net/errors.py
@@ -1,11 +0,0 @@
-class PickleError(Exception):
- def __init__(self,errormess):self.errormess = errormess
- def __str__(self):return repr(self.errormess)
-
-class ServerError(Exception):
- def __init__(self,errormess):self.errormess = errormess
- def __str__(self):return repr(self.errormess)
-
-class SocketError(Exception):
- def __init__(self,errormess):self.errormess = errormess
- def __str__(self):return repr(self.errormess)
View
136 lib2d/client/net/netbase.py
@@ -1,136 +0,0 @@
-import socket,select,sys,time
-from errors import *
-from communicate import SendData, ReceiveData, ReceiveDataUDP
-
-
-
-class TCPServer():
- def __init__(self):
- self.sending_socket = None
-
- def input_func(self,sock,host,port,address):pass
- def output_func(self,sock,host,port,address):pass
- def connect_func(self,sock,host,port):pass
- def client_connect_func(self,sock,host,port,address):pass
- def client_disconnect_func(self,sock,host,port,address):pass
- def quit_func(self,host,port):pass
-
- def connect(self,host,port):
- self.host = host
- self.port = port
- try:
- self.unconnected_socket = socket.socket()
- self.unconnected_socket.bind((self.host,self.port))
- self.unconnected_socket.listen(5)
- except:
- self.unconnected_socket.close()
- raise ServerError("Only one instance of the server on port "+str(self.port)+" may run at one time!")
- self.connect_func(self.unconnected_socket,self.host,self.port)
- self.connected_sockets = []
- self.socketaddresses = {}
-
- def remove_socket(self,sock):
- address = self.socketaddresses[sock]
- self.client_disconnect_func(sock,self.host,self.port,address)
- self.connected_sockets.remove(sock)
- def serve_forever(self):
- self.looping = True
- while self.looping:
- input_ready,output_ready,except_ready = select.select([self.unconnected_socket]+self.connected_sockets,[],[])
- for sock in input_ready:
- if sock == self.unconnected_socket:
- #init socket
- connected_socket, address = sock.accept()
- self.connected_sockets.append(connected_socket)
- self.socketaddresses[connected_socket] = address
- self.client_connect_func(connected_socket,self.host,self.port,address)
- else:
- try:
- data = ReceiveData(sock)
- address = self.socketaddresses[sock]
- self.input_func(sock,self.host,self.port,address)
- except:
- data = "client quit"
- if data != None:
- if data == "client quit":
- self.remove_socket(sock)
- continue
- self.sending_socket = sock
- self.handle_data(data)
-
- def handle_data(self,data):
- pass
- def send_data(self,data,compress=False):
- try:
- SendData(self.sending_socket,data,compress,includelength=True)
- address = self.socketaddresses[self.sending_socket]
- self.output_func(self.sending_socket,self.host,self.port,address)
- except:
- self.remove_socket(self.sending_socket)
-
- def quit(self):
- for s in self.connected_sockets: s.close()
- self.quit_func(self.host,self.port)
-
-
-class UDPServer():
- def __init__(self):
- self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-
- def input_func(self,sock,host,port,address):pass
- def output_func(self,sock,host,port,address):pass
- def connect_func(self,sock,host,port):pass
- def quit_func(self,host,port):pass
-
- def connect(self,host,port):
- self.host = host
- self.port = port
- try:
- self.socket.bind((host, port))
- except:
- self.socket.close()
- raise ServerError("Only one instance of the server on port "+str(self.port)+" may run at one time!")
- self.connect_func(self.socket,self.host,self.port)
- def serve_forever(self):
- self.looping = True
- while self.looping:
- data,self.lastaddress = ReceiveDataUDP(self.socket)
- self.input_func(self.socket,self.host,self.port,self.lastaddress)
- self.handle_data(data)
- def handle_data(self,data):
- pass
- def send_data(self,data,compress=False):
- try:
- SendData(self.socket,data,compress,address=self.lastaddress)
- self.output_func(self.socket,self.host,self.port,self.lastaddress)
- except:
- pass
- #client disconnected
-
- def quit(self):
- self.socket.close()
- self.quit_func(self.host,self.port)
-
-
-class UDPClient:
- def __init__(self):
- pass
- def connect(self,host,port):
- self.host = host
- self.port = port
- self.socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
- self.socket.connect((self.host,self.port))
-
- def send_data(self,data,compress=False):
- SendData(self.socket,data,compress)
- def wait_for_data(self):
- input_ready,output_ready,except_ready = select.select([self.socket],[],[])
- return ReceiveDataUDP(self.socket)[0]
- def check_for_data(self):
- input_ready,output_ready,except_ready = select.select([self.socket],[],[],0.001)
- if len(input_ready) > 0:
- return ReceiveDataUDP(self.socket)[0]
-
- def quit(self):
- self.socket.close()
View
158 lib2d/client/net/socket-2.py
@@ -1,158 +0,0 @@
-import socket,select,sys,time
-from errors import *
-from communicate import SendData, ReceiveData, ReceiveDataUDP
-
-class TCPServer():
- def __init__(self):
- self.sending_socket = None
-
- def input_func(self,sock,host,port,address):pass
- def output_func(self,sock,host,port,address):pass
- def connect_func(self,sock,host,port):pass
- def client_connect_func(self,sock,host,port,address):pass
- def client_disconnect_func(self,sock,host,port,address):pass
- def quit_func(self,host,port):pass
-
- def connect(self,host,port):
- self.host = host
- self.port = port
- try:
- self.unconnected_socket = socket.socket()
- self.unconnected_socket.bind((self.host,self.port))
- self.unconnected_socket.listen(5)
- except:
- self.unconnected_socket.close()
- raise ServerError("Only one instance of the server on port "+str(self.port)+" may run at one time!")
- self.connect_func(self.unconnected_socket,self.host,self.port)
- self.connected_sockets = []
- self.socketaddresses = {}
-
- def remove_socket(self,sock):
- address = self.socketaddresses[sock]
- self.client_disconnect_func(sock,self.host,self.port,address)
- self.connected_sockets.remove(sock)
- def serve_forever(self):
- self.looping = True
- while self.looping:
- input_ready,output_ready,except_ready = select.select([self.unconnected_socket]+self.connected_sockets,[],[])
- for sock in input_ready:
- if sock == self.unconnected_socket:
- #init socket
- connected_socket, address = sock.accept()
- self.connected_sockets.append(connected_socket)
- self.socketaddresses[connected_socket] = address
- self.client_connect_func(connected_socket,self.host,self.port,address)
- else:
- try:
- data = ReceiveData(sock)
- address = self.socketaddresses[sock]
- self.input_func(sock,self.host,self.port,address)
- except:
- data = "client quit"
- if data != None:
- if data == "client quit":
- self.remove_socket(sock)
- continue
- self.sending_socket = sock
- self.handle_data(data)
-
- def handle_data(self,data):
- pass
- def send_data(self,data,compress=False):
- try:
- SendData(self.sending_socket,data,compress,includelength=True)
- address = self.socketaddresses[self.sending_socket]
- self.output_func(self.sending_socket,self.host,self.port,address)
- except:
- self.remove_socket(self.sending_socket)
-
- def quit(self):
- for s in self.connected_sockets: s.close()
- self.quit_func(self.host,self.port)
-
-class UDPServer():
- def __init__(self):
- self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-
- def input_func(self,sock,host,port,address):pass
- def output_func(self,sock,host,port,address):pass
- def connect_func(self,sock,host,port):pass
- def quit_func(self,host,port):pass
-
- def connect(self,host,port):
- self.host = host
- self.port = port
- try:
- self.socket.bind((host, port))
- except:
- self.socket.close()
- raise ServerError("Only one instance of the server on port "+str(self.port)+" may run at one time!")
- self.connect_func(self.socket,self.host,self.port)
- def serve_forever(self):
- self.looping = True
- while self.looping:
- data,self.lastaddress = ReceiveDataUDP(self.socket)
- self.input_func(self.socket,self.host,self.port,self.lastaddress)
- self.handle_data(data)
- def handle_data(self,data):
- pass
- def send_data(self,data,compress=False):
- try:
- SendData(self.socket,data,compress,address=self.lastaddress)
- self.output_func(self.socket,self.host,self.port,self.lastaddress)
- except:
- pass
- #client disconnected
-
- def quit(self):
- self.socket.close()
- self.quit_func(self.host,self.port)
-
-class TCPClient:
- def __init__(self):
- pass
- def connect(self,host,port):
- self.host = host
- self.port = port
- try:
- self.socket = socket.socket()
- self.socket.connect((self.host,self.port))
- except:
- self.socket.close()
- raise SocketError("The connection could not be opened. It must be created first with a server object.")
-
- def send_data(self,data,compress=False):
- SendData(self.socket,data,compress,includelength=True)
- def wait_for_data(self):
- input_ready,output_ready,except_ready = select.select([self.socket],[],[])
- return ReceiveData(self.socket)
- def check_for_data(self):
- input_ready,output_ready,except_ready = select.select([self.socket],[],[],0.001)
- if len(input_ready) > 0:
- return ReceiveData(self.socket)
-
- def quit(self):
- self.socket.close()
-
-class UDPClient:
- def __init__(self):
- pass
- def connect(self,host,port):
- self.host = host
- self.port = port
- self.socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
- self.socket.connect((self.host,self.port))
-
- def send_data(self,data,compress=False):
- SendData(self.socket,data,compress)
- def wait_for_data(self):
- input_ready,output_ready,except_ready = select.select([self.socket],[],[])
- return ReceiveDataUDP(self.socket)[0]
- def check_for_data(self):
- input_ready,output_ready,except_ready = select.select([self.socket],[],[],0.001)
- if len(input_ready) > 0:
- return ReceiveDataUDP(self.socket)[0]
-
- def quit(self):
- self.socket.close()
View
36 lib2d/client/net/tcp.py
@@ -1,36 +0,0 @@
-import socket, select
-
-
-
-class TCPClient:
- def __init__(self):
- pass
-
-
- def connect(self, host, port):
- self.host = host
- self.port = port
- self.socket = socket.create_connection((self.host, self.port))
-
-
- def send_data(self, data):
- try:
- self.socket.send(data)
- except:
- raise
- self.sock.close()
-
-
- def wait_for_data(self):
- input_ready,output_ready,except_ready = select.select([self.socket],[],[])
- return ReceiveData(self.socket)
-
-
- def check_for_data(self):
- input_ready,output_ready,except_ready = select.select([self.socket],[],[],0.001)
- if len(input_ready) > 0:
- return ReceiveData(self.socket)
-
-
- def quit(self):
- self.socket.close()
View
180 lib2d/client/playerinput.py
@@ -1,180 +0,0 @@
-"""
-this provides an abstraction between pygame's inputs and input handling.
-events will be translated into a format that the game will handle. this
-provides an way to deal with multiple inputs and reconfiguring keys at runtime.
-
-provides a couple nice features:
- inputs can be reconfigured during runtime, without changing game code
- inputs can be changed during runtime: want a joystick? no problem
- input commands keep track of buttons being held as well
-
-When processing the pygame event queue, be sure to check events against the
-processEvent() method.
-"""
-
-from pygame.locals import *
-from buttons import *
-import pygame
-
-
-
-class PlayerInput(object):
- def processEvent(self, event):
- """
- Determine state by checking a pygame event
- """
- raise NotImplementedError
-
-
- def getState(self):
- """
- Return a list of buttons that have been pressed or held since
- last time input was checked
- """
- raise NotImplementedError
-
-
-
-class KeyboardPlayerInput(PlayerInput):
- default_p1 = {
- K_UP: P1_UP,
- K_DOWN: P1_DOWN,
- K_LEFT: P1_LEFT,
- K_RIGHT: P1_RIGHT,
- K_q: P1_ACTION1,
- K_w: P1_ACTION2,
- K_e: P1_ACTION3,
- K_r: P1_ACTION4}
-
- default_p2 = {
- K_w: P2_UP,
- K_s: P2_DOWN,
- K_a: P2_LEFT,
- K_d: P2_RIGHT,
- K_r: P2_ACTION1,
- K_t: P2_ACTION2}
-
- def __init__(self, keymap=None):
-
- if keymap == None:
- self.keymap = KeyboardPlayerInput.default_p1
- self.rev_keymap = dict((v,k) for k, v in self.keymap.iteritems())
- self.held = []
-
-
- def getState(self):
- """
- return a list of keys that are being held down
- """
-
- return [ (self.__class__, key, ) for key in self.held ]
-
-
- def processEvent(self, event):
-
- try:
- key = self.keymap[event.key]
- except (KeyError, AttributeError):
- return None
-
- if event.type == KEYDOWN:
- if event.key in self.held:
- state = BUTTONHELD
- else:
- state = BUTTONDOWN
- self.held.append(key)
-
- elif event.type == KEYUP:
- state = BUTTONUP
- try:
- self.held.remove(key)
- except:
- pass
-
- if ( key == P1_LEFT):
- if self.rev_keymap[P1_RIGHT] in self.held:
- return self.__class__, P1_RIGHT, BUTTONDOWN
-
- if ( key == P1_RIGHT):
- if self.rev_keymap[P1_LEFT] in self.held:
- return self.__class__, P1_LEFT, BUTTONDOWN
-
- if ( key == P1_UP):
- if self.rev_keymap[P1_DOWN] in self.held:
- return self.__class__, P1_DOWN, BUTTONDOWN
-
- if ( key == P1_DOWN):
- if self.rev_keymap[P1_UP] in self.held:
- return self.__class__, P1_UP, BUTTONDOWN
-
- return self.__class__, key, state
-
-
-
-
-
-class JoystickPlayerInput(PlayerInput):
- default_p1 = {
- None: P1_UP,
- None: P1_DOWN,
- None: P1_LEFT,
- None: P1_RIGHT,
- 13: P1_ACTION1,
- 14: P1_ACTION2}
-
- def __init__(self, keymap=None):
- # make sure pygame's joystick stuff is up
- pygame.joystick.init()
- self.jsNumber = 0
- self.js = pygame.joystick.Joystick(self.jsNumber)
- self.js.init()
- self.deadzone = float(0.12)
-
- if keymap == None:
- self.keymap = JoystickPlayerInput.default_p1
-
- def processEvent(self, event):
- try:
- if event.joy != self.jsNumber: return
- except AttributeError:
- return
-
- if event.type == JOYAXISMOTION:
- # left - right axis
- if event.axis == 0:
- if abs(event.value) > self.deadzone:
- v = abs(event.value) + self.deadzone
- if v > 1: v = 1.0
-
- if event.value < 0:
- return self.__class__, P1_LEFT, v
- else:
- return self.__class__, P1_RIGHT, v
- else:
- return self.__class__, P1_LEFT, 0.0
-
- # up - down axis
- if event.axis == 1:
- if abs(event.value) > self.deadzone:
- v = abs(event.value) + self.deadzone
- if v > 1.0: v = 1.0
-
- if event.value < 0:
- return self.__class__, P1_UP, v
- else:
- return self.__class__, P1_DOWN, v
- else:
- return self.__class__, P1_UP, 0.0
-
- elif event.type == JOYBUTTONDOWN:
- try:
- return self.__class__, self.keymap[event.button], 1.0
- except KeyError:
- pass
-
- elif event.type == JOYBUTTONUP:
- try:
- return self.__class__, self.keymap[event.button], 0.0
- except KeyError:
- pass
-
View
16 lib2d/client/signals.py
@@ -1,16 +0,0 @@
-from lib2d.common.dispatch import Signal, receiver
-
-"""
-Define signals used in Lib2d here
-"""
-
-# signals used in area.py
-bodyRelMove = Signal(providing_args=["body", "position", "force"])
-bodyAbsMove = Signal(providing_args=["body", "position", "force"])
-bodyWarp = Signal(providing_args=["body", "area"])
-emitSound = Signal(providing_args=["filename", "position"])
-
-# signals relevant for the engine
-timeSignal = Signal(providing_args=["time"])
-drawSignal = Signal(providing_args=["surface"])
-inputSignal = Signal(providing_args=["driver", "args"])
View
326 lib2d/client/statedriver.py
@@ -1,326 +0,0 @@
-"""
-Copyright 2010, 2011, 2012 Leif Theden
-
-
-This file is part of lib2d.
-
-lib2d is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-lib2d is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with lib2d. If not, see <http://www.gnu.org/licenses/>.
-"""
-
-import gfx
-import pygame
-from playerinput import KeyboardPlayerInput
-from collections import deque
-from itertools import cycle, islice
-from pygame.locals import *
-
-
-"""
-player's input doesn't get checked every loop. it is checked
-every 15ms and then handled. this prevents the game logic
-from dealing with input too often and slowing down rendering.
-"""
-
-target_fps = 30
-
-
-inputs = []
-inputs.append(KeyboardPlayerInput())
-
-
-def flush_cmds(cmds):
- pass
-
-
-class StatePlaceholder(object):
- """
- holds a ref to a state
-
- when found in the queue, will be instanced
- """
-
- def __init__(self, klass):
- self.klass = klass
-
- def activate(self):
- pass
-
- def deactivate(self):
- pass
-
-
-class StateDriver(object):
- """
- A state driver controls what is displayed and where input goes.
-
- A state is a logical way to break up "modes" of use for a game.
- For example, a title screen, options screen, normal play, pause,
- etc.
- """
-
- def __init__(self, parent=None):
- self.parent = parent
- self._states = deque()
-
- if parent != None:
- self.reload_screen()
-
-
- def get_size(self):
- """
- Return the size of the surface that is being drawn on.
-
- * This may differ from the size of the window or screen if the display
- is set to scale.
- """
-
- return self.parent.get_screen().get_size()
-
-
- def get_screen(self):
- ""