diff options
author | Joshua Minor <j@lux.vu> | 2007-12-22 16:12:29 (GMT) |
---|---|---|
committer | Joshua Minor <j@lux.vu> | 2007-12-22 16:12:29 (GMT) |
commit | fd70165074a14d1b2bed1d7c17558a3a80761719 (patch) | |
tree | f5593a504030b13609eae6f7d6f12c8fecb6b08e | |
parent | f60eebbdd6d4dd18619ad2d8dc6ad9141f9fc3fe (diff) |
Trying to sync git with actual files...
-rw-r--r-- | Maze.activity/.DS_Store | bin | 6148 -> 0 bytes | |||
-rw-r--r-- | Maze.activity/activity/activity-maze.svg | 4 | ||||
-rw-r--r-- | Maze.activity/activity/activity.info | 2 | ||||
-rw-r--r-- | Maze.activity/game.py | 79 | ||||
-rw-r--r-- | Maze.activity/olpcgames/__init__.pyc | bin | 0 -> 1336 bytes | |||
-rw-r--r-- | Maze.activity/olpcgames/canvas.pyc | bin | 0 -> 4253 bytes | |||
-rw-r--r-- | Maze.activity/player.py | 4 | ||||
-rwxr-xr-x | build | 3 | ||||
-rw-r--r-- | dist/Maze.xo | bin | 34323 -> 37958 bytes | |||
-rw-r--r-- | docs/HostingRequest.txt | 88 | ||||
-rw-r--r-- | docs/MazeActivity.gif | bin | 0 -> 67399 bytes | |||
-rw-r--r-- | docs/NOTES.txt | 92 |
12 files changed, 247 insertions, 25 deletions
diff --git a/Maze.activity/.DS_Store b/Maze.activity/.DS_Store Binary files differdeleted file mode 100644 index c8c7f65..0000000 --- a/Maze.activity/.DS_Store +++ /dev/null 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 Binary files differnew file mode 100644 index 0000000..4f2a40c --- /dev/null +++ b/Maze.activity/olpcgames/__init__.pyc diff --git a/Maze.activity/olpcgames/canvas.pyc b/Maze.activity/olpcgames/canvas.pyc Binary files differnew file mode 100644 index 0000000..dc37e8c --- /dev/null +++ b/Maze.activity/olpcgames/canvas.pyc 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): @@ -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 Binary files differindex 6d67bdc..ee9b075 100644 --- a/dist/Maze.xo +++ b/dist/Maze.xo 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 Binary files differnew file mode 100644 index 0000000..b5fb9cf --- /dev/null +++ b/docs/MazeActivity.gif 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) |