Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoshua Minor <j@lux.vu>2007-12-22 16:12:29 (GMT)
committer Joshua Minor <j@lux.vu>2007-12-22 16:12:29 (GMT)
commitfd70165074a14d1b2bed1d7c17558a3a80761719 (patch)
treef5593a504030b13609eae6f7d6f12c8fecb6b08e
parentf60eebbdd6d4dd18619ad2d8dc6ad9141f9fc3fe (diff)
Trying to sync git with actual files...
-rw-r--r--Maze.activity/.DS_Storebin6148 -> 0 bytes
-rw-r--r--Maze.activity/activity/activity-maze.svg4
-rw-r--r--Maze.activity/activity/activity.info2
-rw-r--r--Maze.activity/game.py79
-rw-r--r--Maze.activity/olpcgames/__init__.pycbin0 -> 1336 bytes
-rw-r--r--Maze.activity/olpcgames/canvas.pycbin0 -> 4253 bytes
-rw-r--r--Maze.activity/player.py4
-rwxr-xr-xbuild3
-rw-r--r--dist/Maze.xobin34323 -> 37958 bytes
-rw-r--r--docs/HostingRequest.txt88
-rw-r--r--docs/MazeActivity.gifbin0 -> 67399 bytes
-rw-r--r--docs/NOTES.txt92
12 files changed, 247 insertions, 25 deletions
diff --git a/Maze.activity/.DS_Store b/Maze.activity/.DS_Store
deleted file mode 100644
index c8c7f65..0000000
--- a/Maze.activity/.DS_Store
+++ /dev/null
Binary files differ
diff --git a/Maze.activity/activity/activity-maze.svg b/Maze.activity/activity/activity-maze.svg
index b612407..cb2cad0 100644
--- a/Maze.activity/activity/activity-maze.svg
+++ b/Maze.activity/activity/activity-maze.svg
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
- <!ENTITY fill_color "#000000">
- <!ENTITY stroke_color "#FFFFFF">
+ <!ENTITY fill_color "#FFFFFF">
+ <!ENTITY stroke_color "#000000">
]>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="50px" height="50px" viewBox="0 0 50 50" enable-background="new 0 0 50 50" xml:space="preserve">
diff --git a/Maze.activity/activity/activity.info b/Maze.activity/activity/activity.info
index f322a03..818c1fb 100644
--- a/Maze.activity/activity/activity.info
+++ b/Maze.activity/activity/activity.info
@@ -3,5 +3,5 @@ name = Maze
service_name = vu.lux.olpc.Maze
class = activity.MazeActivity
icon = activity-maze
-activity_version = 2
+activity_version = 3
show_launcher = yes
diff --git a/Maze.activity/game.py b/Maze.activity/game.py
index 3c2216b..1c7a6e0 100644
--- a/Maze.activity/game.py
+++ b/Maze.activity/game.py
@@ -81,15 +81,26 @@ class MazeGame:
self.aspectRatio = canvas_size[0] / float(canvas_size[1])
# start with a small maze
- self.start_time = int(time.time())
- self.maze = Maze(self.start_time, int(9*self.aspectRatio), 9)
+ self.start_time = time.time()
+ self.maze = Maze(int(self.start_time), int(9*self.aspectRatio), 9)
self.reset()
self.frame = 0
+
+ self.font = pygame.font.Font(None, 30)
+
+ # support arrow keys, game pad arrows and game pad buttons
+ self.upkeys = (pygame.K_UP, pygame.K_KP8, pygame.K_KP9)
+ self.downkeys = (pygame.K_DOWN, pygame.K_KP2, pygame.K_KP3)
+ self.leftkeys = (pygame.K_LEFT, pygame.K_KP4, pygame.K_KP7)
+ self.rightkeys = (pygame.K_RIGHT, pygame.K_KP6, pygame.K_KP1)
+ self.allkeys = self.upkeys + self.downkeys + self.leftkeys + self.rightkeys
def reset(self):
"""Reset the game state. Everyone starts in the top-left.
The goal starts in the bottom-right corner."""
self.running = True
+ self.start_time = time.time()
+ self.finish_time = None
for player in self.players.values():
player.reset()
self.goal = (self.maze.width-2, self.maze.height-2)
@@ -125,19 +136,19 @@ class MazeGame:
self.harder()
elif event.key == pygame.K_MINUS:
self.easier()
- elif event.key == pygame.K_UP:
+ elif event.key in self.upkeys:
self.localplayer.direction=(0,-1)
if len(self.players)>1:
mesh.broadcast("move:%d,%d,%d,%d" % (self.localplayer.position[0], self.localplayer.position[1], self.localplayer.direction[0], self.localplayer.direction[1]))
- elif event.key == pygame.K_DOWN:
+ elif event.key in self.downkeys:
self.localplayer.direction=(0,1)
if len(self.players)>1:
mesh.broadcast("move:%d,%d,%d,%d" % (self.localplayer.position[0], self.localplayer.position[1], self.localplayer.direction[0], self.localplayer.direction[1]))
- elif event.key == pygame.K_LEFT:
+ elif event.key in self.leftkeys:
self.localplayer.direction=(-1,0)
if len(self.players)>1:
mesh.broadcast("move:%d,%d,%d,%d" % (self.localplayer.position[0], self.localplayer.position[1], self.localplayer.direction[0], self.localplayer.direction[1]))
- elif event.key == pygame.K_RIGHT:
+ elif event.key in self.rightkeys:
self.localplayer.direction=(1,0)
if len(self.players)>1:
mesh.broadcast("move:%d,%d,%d,%d" % (self.localplayer.position[0], self.localplayer.position[1], self.localplayer.direction[0], self.localplayer.direction[1]))
@@ -206,6 +217,11 @@ class MazeGame:
# won't have their maps yanked out from under them when someone new joins.
self.maze = Maze(seed, width, height)
self.reset()
+ elif message.startswith("finish:"):
+ # someone finished the maze
+ elapsed = float(message[7:])
+ player.elapsed = elapsed
+ self.markPointDirty(player.position)
else:
# it was something I don't recognize...
print "Message from %s: %s" % (player.nick, message)
@@ -213,27 +229,20 @@ class MazeGame:
def arrowKeysPressed(self):
keys = pygame.key.get_pressed()
- return keys[pygame.K_UP] or keys[pygame.K_DOWN] or keys[pygame.K_LEFT] or keys[pygame.K_RIGHT]
+ for key in self.allkeys:
+ if keys[key]:
+ return True
+ return False
def run(self):
"""Run the main loop of the game."""
# lets draw once before we enter the event loop
self.draw()
pygame.display.flip()
- #clock = pygame.time.Clock()
+ clock = pygame.time.Clock()
while self.running:
self.frame += 1
- # is there anything to animate?
- movement = False
- for player in self.players.values():
- if player.direction != (0,0):
- movement = True
- break
- if not movement:
- # then wait for the next event
- # so we don't waste power
- self.processEvent(pygame.event.wait())
# process all queued events
for event in pygame.event.get():
self.processEvent(event)
@@ -244,8 +253,7 @@ class MazeGame:
pygame.display.flip()
# don't animate faster than about 20 frames per second
# this keeps the speed reasonable and limits cpu usage
- pygame.time.wait(1000/20)
- #clock.tick(20) doesn't play nice when we use pygame.event.wait()
+ clock.tick(20)
def harder(self):
"""Make a new maze that is harder than the current one."""
@@ -277,6 +285,7 @@ class MazeGame:
def animate(self):
"""Animate one frame of action."""
+
for player in self.players.values():
oldposition = player.position
newposition = player.animate(self.maze)
@@ -286,8 +295,17 @@ class MazeGame:
if player == self.localplayer:
self.maze.map[player.previous[0]][player.previous[1]] = self.maze.SEEN
if newposition == self.goal:
- self.harder()
-
+ self.finish()
+
+ if self.finish_time is not None and time.time() > self.finish_time+5:
+ self.harder()
+
+ def finish(self):
+ self.finish_time = time.time()
+ self.localplayer.elapsed = self.finish_time - self.start_time
+ if len(self.players)>1:
+ mesh.broadcast("finish:%.2f" % (self.localplayer.elapsed))
+
def draw(self):
"""Draw the current state of the game.
This makes use of the dirty rectangle to reduce CPU load."""
@@ -335,6 +353,23 @@ class MazeGame:
# draw the local player last so he/she will show up on top
self.drawPlayer(self.localplayer)
+ # draw the elapsed time for each player that has finished
+ finishedPlayers = filter(lambda p: p.elapsed is not None, self.players.values())
+ finishedPlayers.sort(lambda a,b: cmp(a.elapsed,b.elapsed))
+ y = 0
+ for player in finishedPlayers:
+ fg, bg = player.colors
+ text = "%3.2f - %s" % (player.elapsed, player.nick)
+ textimg = self.font.render(text, 1, fg)
+ textwidth, textheight = self.font.size(text)
+ rect = pygame.Rect(8, y+4, textwidth, textheight)
+ bigrect = rect.inflate(16,8)
+ pygame.draw.rect(self.screen, bg, bigrect, 0)
+ pygame.draw.rect(self.screen, fg, bigrect, 2)
+ self.screen.blit(textimg, rect)
+
+ y += bigrect.height + 4
+
# clear the dirty rect so nothing will be drawn until there is a change
self.dirtyRect = None
diff --git a/Maze.activity/olpcgames/__init__.pyc b/Maze.activity/olpcgames/__init__.pyc
new file mode 100644
index 0000000..4f2a40c
--- /dev/null
+++ b/Maze.activity/olpcgames/__init__.pyc
Binary files differ
diff --git a/Maze.activity/olpcgames/canvas.pyc b/Maze.activity/olpcgames/canvas.pyc
new file mode 100644
index 0000000..dc37e8c
--- /dev/null
+++ b/Maze.activity/olpcgames/canvas.pyc
Binary files differ
diff --git a/Maze.activity/player.py b/Maze.activity/player.py
index 0c55fc0..d582dac 100644
--- a/Maze.activity/player.py
+++ b/Maze.activity/player.py
@@ -14,8 +14,12 @@ class Player:
self.direction = (0,0)
self.position = (1,1)
self.previous = (1,1)
+ self.elapsed = None
def animate(self, maze):
+ # if the player finished the maze, then don't move
+ if self.elapsed is not None:
+ self.direction=(0,0)
if self.direction == (0,0):
return self.position
if self.canGo(self.direction, maze):
diff --git a/build b/build
new file mode 100755
index 0000000..cf75a04
--- /dev/null
+++ b/build
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+zip -r dist/Maze.xo Maze.activity && scp dist/Maze.xo luxvu@lux.vu:public_html/olpc/
diff --git a/dist/Maze.xo b/dist/Maze.xo
index 6d67bdc..ee9b075 100644
--- a/dist/Maze.xo
+++ b/dist/Maze.xo
Binary files differ
diff --git a/docs/HostingRequest.txt b/docs/HostingRequest.txt
new file mode 100644
index 0000000..52a7af9
--- /dev/null
+++ b/docs/HostingRequest.txt
@@ -0,0 +1,88 @@
+1. Project name : Maze
+2. Existing website, if any : http://lux.vu/blog/2007/12/11/one-maze-per-child/
+3. One-line description : A multiplayer maze game.
+
+4. Longer description : A multiplayer maze game that uses the olpcgames
+ : module and pygame.
+ :
+ :
+
+5. URLs of similar projects :
+
+6. Committer list
+ Please list the maintainer (lead developer) as the first entry. Only list
+ developers who need to be given accounts so that they can commit to your
+ project's code repository, or push their own. There is no need to list
+ non-committer developers.
+
+ Username Full name SSH2 key URL E-mail
+ -------- --------- ------------ ------
+ #1 jminor Joshua Minor j@lux.vu
+ #2
+ #3
+ ...
+
+ If any developers don't have their SSH2 keys on the web, please attach them
+ to the application e-mail.
+
+7. Preferred development model
+
+ [X] Central tree. Every developer can push his changes directly to the
+ project's git tree. This is the standard model that will be familiar to
+ CVS and Subversion users, and that tends to work well for most projects.
+
+ [ ] Maintainer-owned tree. Every developer creates his own git tree, or
+ multiple git trees. He periodically asks the maintainer to look at one
+ or more of these trees, and merge changes into the maintainer-owned,
+ "main" tree. This is the model used by the Linux kernel, and is
+ well-suited to projects wishing to maintain a tighter control on code
+ entering the main tree.
+
+ If you choose the maintainer-owned tree model, but wish to set up some
+ shared trees where all of your project's committers can commit directly,
+ as might be the case with a "discussion" tree, or a tree for an individual
+ feature, you may send us such a request by e-mail, and we will set up the
+ tree for you.
+
+8. Set up a project mailing list:
+
+ [ ] Yes, named after our project name
+ [ ] Yes, named ______________________
+ [X] No
+
+ When your project is just getting off the ground, we suggest you eschew
+ a separate mailing list and instead keep discussion about your project
+ on the main OLPC development list. This will give you more input and
+ potentially attract more developers to your project; when the volume of
+ messages related to your project reaches some critical mass, we can
+ trivially create a separate mailing list for you.
+
+ If you need multiple lists, let us know. We discourage having many
+ mailing lists for smaller projects, as this tends to
+ stunt the growth of your project community. You can always add more lists
+ later.
+
+9. Commit notifications
+
+ [ ] Notification of commits to the main tree should be e-mailed to the list
+ we chose to create above
+ [ ] A separate mailing list, <projectname>-git, should be created for commit
+ notifications
+ [X] No commit notifications, please
+
+10. Shell accounts
+
+ As a general rule, we don't provide shell accounts to developers unless
+ there's a demonstrated need. If you have one, please explain here, and
+ list the usernames of the committers above needing shell access.
+
+11. Translation
+ [X] Set up the laptop.org Pootle server to allow translation commits to be made
+ [ ] Translation arrangements have already been made at _______________
+
+12. Notes/comments:
+ This game might fill the role of a Maze Game Template as mentioned
+here: http://wiki.laptop.org/go/Game_templates Also, there is no text in the game
+by design, so only the title of the activity would need to be translated. I have
+only tested it under emulation.
+
diff --git a/docs/MazeActivity.gif b/docs/MazeActivity.gif
new file mode 100644
index 0000000..b5fb9cf
--- /dev/null
+++ b/docs/MazeActivity.gif
Binary files differ
diff --git a/docs/NOTES.txt b/docs/NOTES.txt
new file mode 100644
index 0000000..32f8981
--- /dev/null
+++ b/docs/NOTES.txt
@@ -0,0 +1,92 @@
+Idea:
+ A maze game for the XO laptop.
+
+Basics:
+ Use the arrow keys to move around a maze.
+ When you get to the goal, jump to a harder maze.
+
+Collaboration:
+ Multiple players can play on the same maze.
+ The first one to the goal "wins"
+ When one player reaches the end, all players jump to the next maze.
+
+Enhancements:
+ Show XO buddy icons instead of colored dots (only for easy mazes, when icons are large).
+ Measure time-to-goal and rank players to formalize the winning condition.
+ Separate easy/hard from small/large maze.
+ Easy mazes could have extra holes punched in them to make for multiple solutions.
+ Different maze-building algorithms
+ Adjust random direction choice to favor twisty vs straight hallways
+ Add larger rooms
+ Bonus items could be sprinkled around the maze.
+ Speed up self/opponents
+ Slow down self/opponents
+ Punch extra holes
+ Move some walls - make sure there is still a valid solution
+ Teleport
+ Keys/locked doors
+ Toggle switches/doors
+ Enemies
+ Block you
+ Eat you
+ Players could block/eat each other.
+ This might require adding a "facing" to control who eats who.
+ Players could draw their own maps
+ Save, load, share
+ Would have to xfer whole map, not just random seed
+ Add multiple floors with ramps, ladders, pits, etc.
+ Add a light source at each player that reveals the map as you travel through it.
+ Add a fog that slowly fades areas you have seen already.
+
+
+
+ self.icon = self.iconFromBuddy(buddy)
+
+def iconFromBuddy(self, buddy):
+ data = buddy.props.icon
+ fn = "/tmp/buddy.icon.jpg"
+ f = open(fn,"w")
+ f.write(data)
+ f.close()
+ # class StringFile:
+ # def __init__(self, data):
+ # self.data = data
+ # def read(bytes=None):
+ # if bytes is None:
+ # bytes = len(self.data)
+ # d = self.data[:bytes]
+ # self.data = self.data[bytes:]
+ # return d
+ # return pygame.image.load(StringFile(data)).convert_alpha()
+ img = pygame.image.load(fn)
+ img.convert_alpha()
+ return img
+
+
+
+
+ icon = CanvasIcon(
+ icon_name='computer-xo',
+ xo_color=XoColor(buddy.props.color))
+ print icon
+ #print icon.get_pixbuf()
+ print icon.get_image()
+
+
+
+
+ icon = player.icon
+ if icon:
+ pygame.display.get_surface().blit(icon, rect)
+ else:
+
+
+
+
+
+ # self.img = self.readSVG(
+ # file = rsvg.Handle(filename)
+ # (w,h,w2,h2) = file.get_dimension_data()
+ # srf = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
+ # file.render_cairo(cairo.Context(srf))
+ # return surface.CairoSurface(srf)