Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/game1
diff options
context:
space:
mode:
authorMateu Batle <mateu.batle@collabora.co.uk>2010-10-27 17:40:28 (GMT)
committer Mateu Batle <mateu.batle@collabora.co.uk>2010-10-27 17:40:28 (GMT)
commit0018a9e211ebbe74d371339a70edc0d36c4fc99f (patch)
treeddfd93d0713c615ed70dbf869747b55b94791af8 /game1
Initial import of game1 and game2 in math quwy
Diffstat (limited to 'game1')
-rwxr-xr-xgame1/__init__.py11
-rwxr-xr-xgame1/collectgame.py72
-rwxr-xr-xgame1/constants.py35
-rwxr-xr-xgame1/newhighscore.py36
-rwxr-xr-xgame1/player.py118
-rwxr-xr-xgame1/resources.py25
-rwxr-xr-xgame1/score.py25
-rwxr-xr-xgame1/tiledtmxloader.py1058
-rwxr-xr-xgame1/tracktmx.py166
9 files changed, 1546 insertions, 0 deletions
diff --git a/game1/__init__.py b/game1/__init__.py
new file mode 100755
index 0000000..ccb5cd6
--- /dev/null
+++ b/game1/__init__.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+from collectgame import *
+from constants import *
+#from newhighscore import *
+from player import *
+from resources import *
+from score import *
+from tiledtmxloader import *
+#from track import *
+from tracktmx import *
+
diff --git a/game1/collectgame.py b/game1/collectgame.py
new file mode 100755
index 0000000..24ca67b
--- /dev/null
+++ b/game1/collectgame.py
@@ -0,0 +1,72 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+import pygame
+import usmpgames
+from player import *
+from tracktmx import *
+from score import *
+from resources import *
+from gettext import gettext as _
+
+class CollectGame(usmpgames.ApplicationState):
+
+ def __init__(self, game_mode, next_state = None, background = None):
+ usmpgames.ApplicationState.__init__(self, next_state, background)
+ self.game_mode = game_mode
+
+ def entering_state(self, fromStack):
+ usmpgames.ApplicationState.entering_state(self, fromStack)
+ if (not fromStack) :
+ self.track = Track()
+ self.player = Player(self.game_mode)
+ self.score = Score(self.player)
+ #music_background.play(-1)
+
+ def exiting_state(self, fromStack):
+ #music_background.stop()
+ self.next_state().clear_all()
+ self.next_state().add_htmltext(
+ _(""" <b>Felicidades</b>\n\nHas conseguido %d puntos""") % self.player.score,
+ color = (0, 255, 0, 0),
+ pos = (660, 260),
+ rectsize = (380, 390),
+ fontsize = 22,
+ font = "arial");
+
+ def input(self, ms):
+ events = pygame.event.get()
+ # Now the main event-processing loop
+ if events:
+ for event in events:
+ if event.type == pygame.QUIT:
+ self.set_running( False )
+ elif event.type == pygame.KEYDOWN:
+ if event.key == pygame.K_ESCAPE:
+ self.set_running( False )
+ elif event.key == pygame.K_LEFT or event.key == ord('a') or event.key == K_KP4 or event.key== K_KP7:
+ self.player.moveLeft()
+ elif event.key == pygame.K_RIGHT or event.key == ord('d') or event.key == K_KP6 or event.key== K_KP1:
+ self.player.moveRight()
+ elif event.key == pygame.K_DOWN or event.key == ord('s') or event.key == K_KP2 or event.key== K_KP3:
+ self.player.moveForward()
+ elif event.key == pygame.K_UP or event.key == ord('w') or event.key == K_KP8 or event.key== K_KP9:
+ self.player.moveBack()
+
+ def simulation(self, ms):
+ self.player.update(ms)
+ offsety = self.player.getOffsetY()
+ if self.track.endOfTrack(offsety) :
+ self.go_to_next_state()
+ self.player.checkCollision(self.track)
+
+ def pre_render(self, ms):
+ self.screen().fill( (110,183,251))
+ usmpgames.ApplicationState.pre_render(self, ms)
+
+ def render(self, ms):
+ offsety = self.player.getOffsetY()
+ if not self.track.endOfTrack(offsety) :
+ self.track.draw(self.screen(), offsety)
+ self.player.draw(self.screen())
+ self.score.draw(self.screen())
diff --git a/game1/constants.py b/game1/constants.py
new file mode 100755
index 0000000..79f0d62
--- /dev/null
+++ b/game1/constants.py
@@ -0,0 +1,35 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from pygame import *
+
+# Screen size, by default the XO screen size resolution
+screen_size = [1200, 900]
+# Size of the tile
+tile_size = [screen_size[0]/16, screen_size[0]/16]
+# Size of the sprite (player)
+sprite_size = tile_size
+
+# Maximum speed for the player
+max_speed = (screen_size[0] / 3, screen_size[1] / 8)
+
+horizon_y = screen_size[0]/18
+horizon_x = horizon_y
+
+# Acceleration to use when changing speed
+accel = (max_speed[0] / 3, max_speed[1] / 8)
+
+# Number of tiles in the screen
+num_tiles_sc = [screen_size[0] / tile_size[0], (screen_size[1] - horizon_y) / tile_size[1]]
+
+# Friction value in y axis
+friction_y = max_speed[1] / 100
+
+# Friction value in x axis
+friction_x = max_speed[0] / 1
+
+# Minimum speed value in y axis
+min_speed_y = max_speed[1] / 2
+
+# Minimum speed value in x axis
+min_speed_x = max_speed[0] / 20
diff --git a/game1/newhighscore.py b/game1/newhighscore.py
new file mode 100755
index 0000000..25eeeca
--- /dev/null
+++ b/game1/newhighscore.py
@@ -0,0 +1,36 @@
+import pygame, highScores,pares,impares,logging,os
+from highScores import *
+from pygame.locals import *
+h = HighScore()
+
+class newhighscore():
+
+
+ def __init__(self):
+ newScore = 0
+ global item
+ item = h.loadscores()
+ global scorew
+ scorew = []
+ i=0
+ for i in range(len(item)):
+ scorew.append(item[i][0])
+ print scorew
+ def main(self,newscore):
+ newenter = False
+ for score in scorew[:len(item)]:
+ if score < newscore :
+ newenter = True
+ if newenter == True:
+ item.append((newscore,os.getlogin()))
+ h.savescores(item)
+ else:
+ print "nooooo"
+
+ LOG_FILENAME='Esquiador.log'
+
+ log = logging.getLogger( 'EsquiadorRun' )
+ #log.setLevel( logging.DEBUG )
+ if __name__=="__main__":
+ logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG)
+ main()
diff --git a/game1/player.py b/game1/player.py
new file mode 100755
index 0000000..9199397
--- /dev/null
+++ b/game1/player.py
@@ -0,0 +1,118 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# kinds of tiles
+# - navigable
+# - flags: even / odd
+# - obstacle
+# - enemy
+
+from pygame import *
+from pygame.locals import *
+from constants import *
+from resources import *
+
+class Player(sprite.Sprite):
+
+ def __init__(self, game_mode):
+ sprite.Sprite.__init__(self)
+ self.pos_wc = [screen_size[0] / 2, 0]
+ self.speed = [0, min_speed_y]
+ self.image = player_image_normal
+ self.image_ticks = 0
+ self.rect_sc = self.image.get_rect()
+ self.rect_sc.topleft = [self.pos_wc[0], horizon_y]
+ self.score = 0
+ self.game_mode = game_mode
+
+ def update(self, milliseconds):
+ self.speed[1] -= friction_y
+ if (self.speed[1] < min_speed_y):
+ self.speed[1] = min_speed_y
+ self.pos_wc[0] += self.speed[0] * (milliseconds / 1000.0)
+ self.pos_wc[1] += self.speed[1] * (milliseconds / 1000.0)
+ if self.pos_wc[0] < 0:
+ self.pos_wc[0] = 0
+ elif self.pos_wc[0] > screen_size[0] - sprite_size[0]:
+ self.pos_wc[0] = screen_size[0] - sprite_size[0]
+ self.rect_sc.topleft = [self.pos_wc[0], horizon_y]
+
+ def moveLeft(self):
+ self.speed[0] -= accel[0]
+ self.speed[0] = min(self.speed[0], max_speed[0])
+
+ def moveRight(self):
+ self.speed[0] += accel[0]
+ self.speed[0] = min(self.speed[0], max_speed[0])
+
+ def moveForward(self):
+ self.speed[1] += accel[1]
+ self.speed[1] = min(self.speed[1], max_speed[1])
+
+ def moveBack(self):
+ self.speed[1] -= accel[1]
+ self.speed[1] = min(-self.speed[1], -max_speed[1])
+
+ def getPos(self):
+ return self.pos_wc
+
+ def getOffsetY(self):
+ return self.pos_wc[1]
+
+ def getRectWC(self):
+ return Rect(self.pos_wc, sprite_size)
+
+ def draw(self, screen):
+ screen.blit(self.image, self.rect_sc)
+
+ def checkCollision(self, track):
+
+ rect_wc = self.getRectWC()
+
+ collisionTile = track.collidesWith(rect_wc)
+ if track.isNotNavigable(collisionTile) :
+ """ frena mas """
+ self.speed[1] = 0
+ self.speed[0] = 0
+ self.image = player_image_impact
+ self.image_ticks = 25
+ #sound_collide.play()
+ elif track.isDanger(collisionTile) :
+ self.speed[1] = 0
+ self.speed[0] = 0
+ self.score -= 10
+ self.image = player_image_impact_hard
+ self.image_ticks = 25
+ sound_danger.play()
+ elif track.isNavigable(collisionTile) :
+ if (self.image_ticks > 0):
+ self.image_ticks -= 1
+ else:
+ self.image = player_image_normal
+ elif type(collisionTile) == int:
+ num = collisionTile
+ if(self.game_mode =='impares'):
+ if (num % 2) == 1 :
+ self.score += 20
+ self.image = player_image_happy
+ self.image_ticks = 15
+ sound_good_choice.play()
+ else:
+ self.score -= 5
+ self.image = player_image_sad
+ self.image_ticks = 25
+ sound_bad_choice.play()
+ elif self.game_mode =='pares':
+ if (num % 2) == 0 :
+ self.score += 20
+ self.image = player_image_happy
+ self.image_ticks = 15
+ sound_good_choice.play()
+ else:
+ self.score -= 5
+ self.image = player_image_sad
+ self.image_ticks = 15
+ sound_bad_choice.play()
+
+ if self.score <=0:
+ self.score=0
diff --git a/game1/resources.py b/game1/resources.py
new file mode 100755
index 0000000..f620892
--- /dev/null
+++ b/game1/resources.py
@@ -0,0 +1,25 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+from pygame import *
+from constants import *
+
+# Images used for the player
+player_image_normal = transform.scale( image.load("data/quwy.png"), sprite_size)
+player_image_happy = transform.scale( image.load("data/quwy_happy.png"), sprite_size)
+player_image_sad = transform.scale( image.load("data/quwy_sad.png"), sprite_size)
+player_image_impact = transform.scale( image.load("data/quwy_impact.png"), sprite_size)
+player_image_impact_hard = transform.scale( image.load("data/quwy_impact_hard.png"), sprite_size)
+
+# Sounds
+music_background = None
+sound_good_choice = mixer.Sound('./data/sounds/yujui_short.ogg')
+sound_bad_choice = mixer.Sound('./data/sounds/oops.ogg')
+sound_danger = mixer.Sound('./data/sounds/ohoo.ogg')
+sound_collide = mixer.Sound('./media/sounds/gameover.wav')
+#music_background = mixer.Sound('./media/sounds/menumusic.ogg')
+#sound_good_choice = mixer.Sound('./media/sounds/aplause.ogg')
+#sound_bad_choice = mixer.Sound('./media/sounds/gameover.wav')
+#sound_danger = mixer.Sound('./media/sounds/gameover.wav')
+#sound_collide = mixer.Sound('./media/sounds/gameover.wav')
+sound_game_over = mixer.Sound('./media/sounds/gameover.wav')
diff --git a/game1/score.py b/game1/score.py
new file mode 100755
index 0000000..58e239b
--- /dev/null
+++ b/game1/score.py
@@ -0,0 +1,25 @@
+#Actividad Esquiador
+#Archivo: score.py
+#Descripcion: Clase que maneja el puntaje del juego
+#
+
+import pygame
+from pygame import *
+from pygame.locals import *
+from constants import *
+from gettext import gettext as _
+#fuente = pygame.font.Font("./media/fuentes/space age.ttf", 25)
+
+class Score():
+
+ def __init__(self, player):
+ self.player = player
+ self.font = pygame.font.SysFont("Arial", 50)
+ pass
+
+ def draw(self, screen):
+ score = _("PUNTAJE: %05d") % self.player.score
+ surface = self.font.render(score, 1, (0,0,0))
+ rect = surface.get_rect()
+ screen.blit(surface, rect)
+
diff --git a/game1/tiledtmxloader.py b/game1/tiledtmxloader.py
new file mode 100755
index 0000000..4647484
--- /dev/null
+++ b/game1/tiledtmxloader.py
@@ -0,0 +1,1058 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+u"""
+TileMap loader for python for Tiled, a generic tile map editor
+from http://mapeditor.org/ .
+It loads the \*.tmx files produced by Tiled.
+"""
+
+__version__ = u'$Id$'
+__author__ = u'DR0ID_ @ 2009'
+
+if __debug__:
+ import sys
+ sys.stdout.write(u'%s loading ... \n' % (__name__))
+ import time
+ _start_time = time.time()
+
+#-------------------------------------------------------------------------------
+
+
+import sys
+from xml.dom import minidom, Node
+import base64
+import gzip
+import StringIO
+import os.path
+#import codecs
+
+# TODO: ideas: save indexed_tiles as {type:data} so no image loader is needed
+# user would have to write its own image loading
+# different types would be : {gid : ('img_parts', (margin, spacing, path, tile_w, tile_h, colorkey))}
+# {gid : ('img_path', ('C:/...', colorkey)}
+# {gid : ('file_like', (file_like_obj, colorkey))}
+#
+# maybe use cStringIO instead of StringIO
+
+#-------------------------------------------------------------------------------
+class IImageLoader(object):
+ u"""
+ Interface for image loading. Depending on the framework used the
+ images have to be loaded differently.
+ """
+
+ def load_image(self, filename, colorkey=None): # -> image
+ u"""
+ Load a single image.
+
+ :Parameters:
+ filename : string
+ Path to the file to be loaded.
+ colorkey : tuple
+ The (r, g, b) color that should be used as colorkey (or magic color).
+ Default: None
+
+ :rtype: image
+
+ """
+ raise NotImplementedError(u'This should be implemented in a inherited class')
+
+ def load_image_file_like(self, file_like_obj, colorkey=None): # -> image
+ u"""
+ Load a image from a file like object.
+
+ :Parameters:
+ file_like_obj : file
+ This is the file like object to load the image from.
+ colorkey : tuple
+ The (r, g, b) color that should be used as colorkey (or magic color).
+ Default: None
+
+ :rtype: image
+ """
+ raise NotImplementedError(u'This should be implemented in a inherited class')
+
+ def load_image_parts(self, filename, margin, spacing, tile_width, tile_height, colorkey=None): #-> [images]
+ u"""
+ Load different tile images from one source image.
+
+ :Parameters:
+ filename : string
+ Path to image to be loaded.
+ margin : int
+ The margin around the image.
+ spacing : int
+ The space between the tile images.
+ tile_width : int
+ The width of a single tile.
+ tile_height : int
+ The height of a single tile.
+ colorkey : tuple
+ The (r, g, b) color that should be used as colorkey (or magic color).
+ Default: None
+
+ Luckily that iteration is so easy in python::
+
+ ...
+ w, h = image_size
+ for y in xrange(margin, h, tile_height + spacing):
+ for x in xrange(margin, w, tile_width + spacing):
+ ...
+
+ :rtype: a list of images
+ """
+ raise NotImplementedError(u'This should be implemented in a inherited class')
+
+#-------------------------------------------------------------------------------
+class ImageLoaderPygame(IImageLoader):
+ u"""
+ Pygame image loader.
+
+ It uses an internal image cache. The methods return Surface.
+
+ :Undocumented:
+ pygame
+ """
+
+
+ def __init__(self):
+ self.pygame = __import__('pygame')
+ self._img_cache = {} # {name: surf}
+
+ def load_image(self, filename, colorkey=None):
+ img = self._img_cache.get(filename, None)
+ if img is None:
+ img = self.pygame.image.load(filename)
+ self._img_cache[filename] = img
+ if colorkey:
+ img.set_colorkey(colorkey)
+ return img
+
+ def load_image_part(self, filename, x, y, w, h, colorkey=None):
+ source_rect = self.pygame.Rect(x, y, w, h)
+ img = self._img_cache.get(filename, None)
+ if img is None:
+ img = self.pygame.image.load(filename)
+ self._img_cache[filename] = img
+ img_part = self.pygame.Surface((w, h), 0, img)
+ img_part.blit(img, (0, 0), source_rect)
+ if colorkey:
+ img_part.set_colorkey(colorkey)
+ return img_part
+
+ def load_image_parts(self, filename, margin, spacing, tile_width, tile_height, colorkey=None): #-> [images]
+ source_img = self._img_cache.get(filename, None)
+ if source_img is None:
+ source_img = self.pygame.image.load(filename)
+ self._img_cache[filename] = source_img
+ w, h = source_img.get_size()
+ images = []
+ for y in xrange(margin, h, tile_height + spacing):
+ for x in xrange(margin, w, tile_width + spacing):
+ img_part = self.pygame.Surface((tile_width, tile_height), 0, source_img)
+ img_part.blit(source_img, (0, 0), self.pygame.Rect(x, y, tile_width, tile_height))
+ if colorkey:
+ img_part.set_colorkey(colorkey)
+ images.append(img_part)
+ return images
+
+ def load_image_file_like(self, file_like_obj, colorkey=None): # -> image
+ # pygame.image.load can load from a path and from a file-like object
+ # that is why here it is redirected to the other method
+ return self.load_image(file_like_obj, colorkey)
+
+#-------------------------------------------------------------------------------
+class ImageLoaderPyglet(IImageLoader):
+ u"""
+ Pyglet image loader.
+
+ It uses an internal image cache. The methods return some form of
+ AbstractImage. The resource module is not used for loading the images.
+
+ Thanks to HydroKirby from #pyglet to contribute the ImageLoaderPyglet and the pyglet demo!
+
+ :Undocumented:
+ pyglet
+ """
+
+
+ def __init__(self):
+ self.pyglet = __import__('pyglet')
+ self._img_cache = {} # {name: image}
+
+ def load_image(self, filename, colorkey=None, fileobj=None):
+ img = self._img_cache.get(filename, None)
+ if img is None:
+ if fileobj:
+ img = self.pyglet.image.load(filename, fileobj, self.pyglet.image.codecs.get_decoders("*.png")[0])
+ else:
+ img = self.pyglet.image.load(filename)
+ self._img_cache[filename] = img
+ return img
+
+ def load_image_part(self, filename, x, y, w, h, colorkey=None):
+ img = self._img_cache.get(filename, None)
+ if img is None:
+ img = self.pyglet.image.load(filename)
+ self._img_cache[filename] = img
+ img_part = image.get_region(x, y, w, h)
+ return img_part
+
+
+ def load_image_parts(self, filename, margin, spacing, tile_width, tile_height, colorkey=None): #-> [images]
+ source_img = self._img_cache.get(filename, None)
+ if source_img is None:
+ source_img = self.pyglet.image.load(filename)
+ self._img_cache[filename] = source_img
+ images = []
+ # Reverse the map column reading to compensate for pyglet's y-origin.
+ for y in xrange(source_img.height - tile_height, margin - tile_height,
+ -tile_height - spacing):
+ for x in xrange(margin, source_img.width, tile_width + spacing):
+ #img_part = source_img.get_region(x, y, tile_width, tile_height)
+ img_part = source_img.get_region(x, y - spacing, tile_width, tile_height)
+ images.append(img_part)
+ return images
+
+ def load_image_file_like(self, file_like_obj, colorkey=None): # -> image
+ # pyglet.image.load can load from a path and from a file-like object
+ # that is why here it is redirected to the other method
+ return self.load_image(file_like_obj, colorkey, file_like_obj)
+
+#-------------------------------------------------------------------------------
+class TileMap(object):
+ u"""
+
+ The TileMap holds all the map data.
+
+ :Ivariables:
+ orientation : string
+ orthogonal or isometric or hexagonal or shifted
+ tilewidth : int
+ width of the tiles (for all layers)
+ tileheight : int
+ height of the tiles (for all layers)
+ width : int
+ width of the map (number of tiles)
+ height : int
+ height of the map (number of tiles)
+ version : string
+ version of the map format
+ tile_sets : list
+ list of TileSet
+ properties : dict
+ the propertis set in the editor, name-value pairs, strings
+ pixel_width : int
+ width of the map in pixels
+ pixel_height : int
+ height of the map in pixels
+ layers : list
+ list of TileLayer
+ map_file_name : dict
+ file name of the map
+ object_groups : list
+ list of :class:MapObjectGroup
+ indexed_tiles : dict
+ dict containing {gid : (offsetx, offsety, surface} if load() was called
+ when drawing just add the offset values to the draw point
+ indexed_tiles_tileset: dict
+ dict containing {gid : layer_name }
+ named_layers : dict of string:TledLayer
+ dict containing {name : TileLayer}
+ named_tile_sets : dict
+ dict containing {name : TileSet}
+
+ """
+
+
+ def __init__(self):
+# This is the top container for all data. The gid is the global id (for a image).
+# Before calling convert most of the values are strings. Some additional
+# values are also calculated, see convert() for details. After calling
+# convert, most values are integers or floats where appropriat.
+ u"""
+ The TileMap holds all the map data.
+ """
+ # set through parser
+ self.orientation = None
+ self.tileheight = 0
+ self.tilewidth = 0
+ self.width = 0
+ self.height = 0
+ self.version = 0
+ self.tile_sets = [] # TileSet
+ self.layers = [] # WorldTileLayer <- what order? back to front (guessed)
+ self.indexed_tiles = {} # {gid: (offsetx, offsety, image}
+ self.indexed_tiles_tileset = {} # {gid: tileset_name }
+ self.object_groups = []
+ self.properties = {} # {name: value}
+ # additional info
+ self.pixel_width = 0
+ self.pixel_height = 0
+ self.named_layers = {} # {name: layer}
+ self.named_tile_sets = {} # {name: tile_set}
+ self.map_file_name = ""
+ self._image_loader = None
+
+ def convert(self):
+ u"""
+ Converts numerical values from strings to numerical values.
+ It also calculates or set additional data:
+ pixel_width
+ pixel_height
+ named_layers
+ named_tile_sets
+ """
+ self.tilewidth = int(self.tilewidth)
+ self.tileheight = int(self.tileheight)
+ self.width = int(self.width)
+ self.height = int(self.height)
+ self.pixel_width = self.width * self.tilewidth
+ self.pixel_height = self.height * self.tileheight
+ for layer in self.layers:
+ self.named_layers[layer.name] = layer
+ layer.opacity = float(layer.opacity)
+ layer.x = int(layer.x)
+ layer.y = int(layer.y)
+ layer.width = int(layer.width)
+ layer.height = int(layer.height)
+ layer.pixel_width = layer.width * self.tilewidth
+ layer.pixel_height = layer.height * self.tileheight
+ layer.visible = bool(int(layer.visible))
+ for tile_set in self.tile_sets:
+ self.named_tile_sets[tile_set.name] = tile_set
+ tile_set.spacing = int(tile_set.spacing)
+ tile_set.margin = int(tile_set.margin)
+ for img in tile_set.images:
+ if img.trans:
+ img.trans = (int(img.trans[:2], 16), int(img.trans[2:4], 16), int(img.trans[4:], 16))
+ for obj_group in self.object_groups:
+ obj_group.x = int(obj_group.x)
+ obj_group.y = int(obj_group.y)
+ obj_group.width = int(obj_group.width)
+ obj_group.height = int(obj_group.height)
+ for map_obj in obj_group.objects:
+ map_obj.x = int(map_obj.x)
+ map_obj.y = int(map_obj.y)
+ map_obj.width = int(map_obj.width)
+ map_obj.height = int(map_obj.height)
+
+ def load(self, image_loader):
+ u"""
+ loads all images using a IImageLoadermage implementation and fills up
+ the indexed_tiles dictionary.
+ The image may have per pixel alpha or a colorkey set.
+ """
+ self._image_loader = image_loader
+ for tile_set in self.tile_sets:
+ # do images first, because tiles could reference it
+ for img in tile_set.images:
+ if img.source:
+ self._load_image_from_source(tile_set, img)
+ else:
+ tile_set.indexed_images[img.id] = self._load_image(img)
+ # tiles
+ for tile in tile_set.tiles:
+ for img in tile.images:
+ if not img.content and not img.source:
+ # only image id set
+ indexed_img = tile_set.indexed_images[img.id]
+ self.indexed_tiles[int(tile_set.firstgid) + int(tile.id)] = (0, 0, indexed_img)
+ self.indexed_tiles_tileset[int(tile_set.firstgid) + int(tile.id)] = tile_set.name
+ else:
+ if img.source:
+ self._load_image_from_source(tile_set, img)
+ else:
+ indexed_img = self._load_image(img)
+ self.indexed_tiles[int(tile_set.firstgid) + int(tile.id)] = (0, 0, indexed_img)
+ self.indexed_tiles_tileset[int(tile_set.firstgid) + int(tile.id)] = tile_set.name
+
+ def _load_image_from_source(self, tile_set, a_tile_image):
+ # relative path to file
+ img_path = os.path.join(os.path.dirname(self.map_file_name), a_tile_image.source)
+ tile_width = int(self.tilewidth)
+ tile_height = int(self.tileheight)
+ if tile_set.tileheight:
+ tile_width = int(tile_set.tilewidth)
+ if tile_set.tilewidth:
+ tile_height = int(tile_set.tileheight)
+ offsetx = 0
+ offsety = 0
+# if tile_width > self.tilewidth:
+# offsetx = tile_width
+ if tile_height > self.tileheight:
+ offsety = tile_height - self.tileheight
+ idx = 0
+ for image in self._image_loader.load_image_parts(img_path, \
+ tile_set.margin, tile_set.spacing, tile_width, tile_height, a_tile_image.trans):
+ self.indexed_tiles[int(tile_set.firstgid) + idx] = (offsetx, -offsety, image)
+ self.indexed_tiles_tileset[int(tile_set.firstgid) + idx] = tile_set.name
+ idx += 1
+
+ def _load_image(self, a_tile_image):
+ img_str = a_tile_image.content
+ if a_tile_image.encoding:
+ if a_tile_image.encoding == u'base64':
+ img_str = decode_base64(a_tile_image.content)
+ else:
+ raise Exception(u'unknown image encoding %s' % a_tile_image.encoding)
+ sio = StringIO.StringIO(img_str)
+ new_image = self._image_loader.load_image_file_like(sio, a_tile_image.trans)
+ return new_image
+
+ def decode(self):
+ u"""
+ Decodes the TileLayer encoded_content and saves it in decoded_content.
+ """
+ for layer in self.layers:
+ layer.decode()
+#-------------------------------------------------------------------------------
+
+
+class TileSet(object):
+ u"""
+ A tileset holds the tiles and its images.
+
+ :Ivariables:
+ firstgid : int
+ the first gid of this tileset
+ name : string
+ the name of this TileSet
+ images : list
+ list of TileImages
+ tiles : list
+ list of Tiles
+ indexed_images : dict
+ after calling load() it is dict containing id: image
+ indexed_tiles : dict
+ after calling load() it is a dict containing
+ gid: (offsetx, offsety, image) , the image corresponding to the gid
+ spacing : int
+ the spacing between tiles
+ marging : int
+ the marging of the tiles
+ properties : dict
+ the propertis set in the editor, name-value pairs
+ tilewidth : int
+ the actual width of the tile, can be different from the tilewidth of the map
+ tilehight : int
+ the actual hight of th etile, can be different from the tilehight of the map
+
+ """
+
+ def __init__(self):
+ self.firstgid = 0
+ self.name = None
+ self.images = [] # TileImage
+ self.tiles = [] # Tile
+ self.indexed_images = {} # {id:image}
+ self.indexed_tiles = {} # {gid: (offsetx, offsety, image} <- actually in map data
+ self.spacing = 0
+ self.margin = 0
+ self.properties = {}
+ self.tileheight = 0
+ self.tilewidth = 0
+
+#-------------------------------------------------------------------------------
+
+class TileImage(object):
+ u"""
+ An image of a tile or just an image.
+
+ :Ivariables:
+ id : int
+ id of this image (has nothing to do with gid)
+ format : string
+ the format as string, only 'png' at the moment
+ source : string
+ filename of the image. either this is set or the content
+ encoding : string
+ encoding of the content
+ trans : tuple of (r,g,b)
+ the colorkey color, raw as hex, after calling convert just a (r,g,b) tuple
+ properties : dict
+ the propertis set in the editor, name-value pairs
+ image : TileImage
+ after calling load the pygame surface
+ """
+
+ def __init__(self):
+ self.id = 0
+ self.format = None
+ self.source = None
+ self.encoding = None # from <data>...</data>
+ self.content = None # from <data>...</data>
+ self.image = None
+ self.trans = None
+ self.properties = {} # {name: value}
+
+#-------------------------------------------------------------------------------
+
+class Tile(object):
+ u"""
+ A single tile.
+
+ :Ivariables:
+ id : int
+ id of the tile gid = TileSet.firstgid + Tile.id
+ images : list of :class:TileImage
+ list of TileImage, either its 'id' or 'image data' will be set
+ properties : dict of name:value
+ the propertis set in the editor, name-value pairs
+ """
+
+ def __init__(self):
+ self.id = 0
+ self.images = [] # uses TileImage but either only id will be set or image data
+ self.properties = {} # {name: value}
+
+#-------------------------------------------------------------------------------
+
+class TileLayer(object):
+ u"""
+ A layer of the world.
+
+ :Ivariables:
+ x : int
+ position of layer in the world in number of tiles (not pixels)
+ y : int
+ position of layer in the world in number of tiles (not pixels)
+ width : int
+ number of tiles in x direction
+ height : int
+ number of tiles in y direction
+ pixel_width : int
+ width of layer in pixels
+ pixel_height : int
+ height of layer in pixels
+ name : string
+ name of this layer
+ opacity : float
+ float from 0 (full transparent) to 1.0 (opaque)
+ decoded_content : list
+ list of graphics id going through the map::
+
+ e.g [1, 1, 1, ]
+ where decoded_content[0] is (0,0)
+ decoded_content[1] is (1,0)
+ ...
+ decoded_content[1] is (width,0)
+ decoded_content[1] is (0,1)
+ ...
+ decoded_content[1] is (width,height)
+
+ usage: graphics id = decoded_content[tile_x + tile_y * width]
+ content2D : list
+ list of list, usage: graphics id = content2D[x][y]
+
+ """
+
+ def __init__(self):
+ self.width = 0
+ self.height = 0
+ self.x = 0
+ self.y = 0
+ self.pixel_width = 0
+ self.pixel_height = 0
+ self.name = None
+ self.opacity = -1
+ self.encoding = None
+ self.compression = None
+ self.encoded_content = None
+ self.decoded_content = []
+ self.visible = True
+ self.properties = {} # {name: value}
+ self.content2D = None
+
+ def decode(self):
+ u"""
+ Converts the contents in a list of integers which are the gid of the used
+ tiles. If necessairy it decodes and uncompresses the contents.
+ """
+ s = self.encoded_content
+ if self.encoded_content:
+ if self.encoding:
+ if self.encoding == u'base64':
+ s = decode_base64(s)
+ else:
+ raise Exception(u'unknown data encoding %s' % (self.encoding))
+ if self.compression:
+ if self.compression == u'gzip':
+ s = decompress_gzip(s)
+ else:
+ raise Exception(u'unknown data compression %s' %(self.compression))
+ else:
+ raise Exception(u'no encoded content to decode')
+ self.decoded_content = []
+ for idx in xrange(0, len(s), 4):
+ val = ord(str(s[idx])) | (ord(str(s[idx + 1])) << 8) | \
+ (ord(str(s[idx + 2])) << 16) | (ord(str(s[idx + 3])) << 24)
+ self.decoded_content.append(val)
+ # generate the 2D version
+ self._gen_2D()
+
+ def _gen_2D(self):
+ self.content2D = []
+ # generate the needed lists
+ for xpos in xrange(self.width):
+ self.content2D.append([])
+ # fill them
+ for xpos in xrange(self.width):
+ for ypos in xrange(self.height):
+ self.content2D[xpos].append(self.decoded_content[xpos + ypos * self.width])
+
+ def pretty_print(self):
+ num = 0
+ for y in range(int(self.height)):
+ s = u""
+ for x in range(int(self.width)):
+ s += str(self.decoded_content[num])
+ num += 1
+ print s
+#-------------------------------------------------------------------------------
+
+
+class MapObjectGroup(object):
+ u"""
+ Group of objects on the map.
+
+ :Ivariables:
+ x : int
+ the x position
+ y : int
+ the y position
+ width : int
+ width of the bounding box (usually 0, so no use)
+ height : int
+ height of the bounding box (usually 0, so no use)
+ name : string
+ name of the group
+ objects : list
+ list of the map objects
+
+ """
+
+ def __init__(self):
+ self.width = 0
+ self.height = 0
+ self.name = None
+ self.objects = []
+ self.x = 0
+ self.y = 0
+ self.properties = {} # {name: value}
+
+#-------------------------------------------------------------------------------
+
+class MapObject(object):
+ u"""
+ A single object on the map.
+
+ :Ivariables:
+ x : int
+ x position relative to group x position
+ y : int
+ y position relative to group y position
+ width : int
+ width of this object
+ height : int
+ height of this object
+ type : string
+ the type of this object
+ image_source : string
+ source path of the image for this object
+ image : :class:TileImage
+ after loading this is the pygame surface containing the image
+ """
+ def __init__(self):
+ self.name = None
+ self.x = 0
+ self.y = 0
+ self.width = 0
+ self.height = 0
+ self.type = None
+ self.image_source = None
+ self.image = None
+ self.properties = {} # {name: value}
+
+#-------------------------------------------------------------------------------
+def decode_base64(in_str):
+ u"""
+ Decodes a base64 string and returns it.
+
+ :Parameters:
+ in_str : string
+ base64 encoded string
+
+ :returns: decoded string
+ """
+ return base64.decodestring(in_str)
+
+#-------------------------------------------------------------------------------
+def decompress_gzip(in_str):
+ u"""
+ Uncompresses a gzip string and returns it.
+
+ :Parameters:
+ in_str : string
+ gzip compressed string
+
+ :returns: uncompressed string
+ """
+ # gzip can only handle file object therefore using StringIO
+ copmressed_stream = StringIO.StringIO(in_str)
+ gzipper = gzip.GzipFile(fileobj=copmressed_stream)
+ s = gzipper.read()
+ gzipper.close()
+ return s
+
+#-------------------------------------------------------------------------------
+def printer(obj, ident=''):
+ u"""
+ Helper function, prints a hirarchy of objects.
+ """
+ import inspect
+ print ident + obj.__class__.__name__.upper()
+ ident += ' '
+ lists = []
+ for name in dir(obj):
+ elem = getattr(obj, name)
+ if isinstance(elem, list) and name != u'decoded_content':
+ lists.append(elem)
+ elif not inspect.ismethod(elem):
+ if not name.startswith('__'):
+ if name == u'data' and elem:
+ print ident + u'data = '
+ printer(elem, ident + ' ')
+ else:
+ print ident + u'%s\t= %s' % (name, getattr(obj, name))
+ for l in lists:
+ for i in l:
+ printer(i, ident + ' ')
+
+#-------------------------------------------------------------------------------
+class TileMapParser(object):
+ u"""
+ Allows to parse and decode map files for 'Tiled', a open source map editor
+ written in java. It can be found here: http://mapeditor.org/
+ """
+
+ def _build_tile_set(self, tile_set_node, world_map):
+ tile_set = TileSet()
+ self._set_attributes(tile_set_node, tile_set)
+ for node in self._get_nodes(tile_set_node.childNodes, u'image'):
+ self._build_tile_set_image(node, tile_set)
+ for node in self._get_nodes(tile_set_node.childNodes, u'tile'):
+ self._build_tile_set_tile(node, tile_set)
+ self._set_attributes(tile_set_node, tile_set)
+ world_map.tile_sets.append(tile_set)
+
+ def _build_tile_set_image(self, image_node, tile_set):
+ image = TileImage()
+ self._set_attributes(image_node, image)
+ # id of TileImage has to be set!! -> Tile.TileImage will only have id set
+ for node in self._get_nodes(image_node.childNodes, u'data'):
+ self._set_attributes(node, image)
+ image.content = node.childNodes[0].nodeValue
+ tile_set.images.append(image)
+
+ def _build_tile_set_tile(self, tile_set_node, tile_set):
+ tile = Tile()
+ self._set_attributes(tile_set_node, tile)
+ for node in self._get_nodes(tile_set_node.childNodes, u'image'):
+ self._build_tile_set_tile_image(node, tile)
+ tile_set.tiles.append(tile)
+
+ def _build_tile_set_tile_image(self, tile_node, tile):
+ tile_image = TileImage()
+ self._set_attributes(tile_node, tile_image)
+ for node in self._get_nodes(tile_node.childNodes, u'data'):
+ self._set_attributes(node, tile_image)
+ tile_image.content = node.childNodes[0].nodeValue
+ tile.images.append(tile_image)
+
+ def _build_layer(self, layer_node, world_map):
+ layer = TileLayer()
+ self._set_attributes(layer_node, layer)
+ for node in self._get_nodes(layer_node.childNodes, u'data'):
+ self._set_attributes(node, layer)
+ layer.encoded_content = node.lastChild.nodeValue
+ world_map.layers.append(layer)
+
+ def _build_world_map(self, world_node):
+ world_map = TileMap()
+ self._set_attributes(world_node, world_map)
+ if world_map.version != u"1.0":
+ raise Exception(u'this parser was made for maps of version 1.0, found version %s' % world_map.version)
+ for node in self._get_nodes(world_node.childNodes, u'tileset'):
+ self._build_tile_set(node, world_map)
+ for node in self._get_nodes(world_node.childNodes, u'layer'):
+ self._build_layer(node, world_map)
+ for node in self._get_nodes(world_node.childNodes, u'objectgroup'):
+ self._build_object_groups(node, world_map)
+ return world_map
+
+ def _build_object_groups(self, object_group_node, world_map):
+ object_group = MapObjectGroup()
+ self._set_attributes(object_group_node, object_group)
+ for node in self._get_nodes(object_group_node.childNodes, u'object'):
+ tiled_object = MapObject()
+ self._set_attributes(node, tiled_object)
+ for img_node in self._get_nodes(node.childNodes, u'image'):
+ tiled_object.image_source = img_node.attributes[u'source'].nodeValue
+ object_group.objects.append(tiled_object)
+ world_map.object_groups.append(object_group)
+
+ #-- helpers --#
+ def _get_nodes(self, nodes, name):
+ for node in nodes:
+ if node.nodeType == Node.ELEMENT_NODE and node.nodeName == name:
+ yield node
+
+ def _set_attributes(self, node, obj):
+ attrs = node.attributes
+ for attr_name in attrs.keys():
+ setattr(obj, attr_name, attrs.get(attr_name).nodeValue)
+ self._get_properties(node, obj)
+
+
+ def _get_properties(self, node, obj):
+ props = {}
+ for properties_node in self._get_nodes(node.childNodes, u'properties'):
+ for property_node in self._get_nodes(properties_node.childNodes, u'property'):
+ try:
+ props[property_node.attributes[u'name'].nodeValue] = property_node.attributes[u'value'].nodeValue
+ except KeyError:
+ props[property_node.attributes[u'name'].nodeValue] = property_node.lastChild.nodeValue
+ obj.properties.update(props)
+
+
+ #-- parsers --#
+ def parse(self, file_name):
+ u"""
+ Parses the given map. Does no decoding nor loading the data.
+ :return: instance of TileMap
+ """
+ #dom = minidom.parseString(codecs.open(file_name, "r", "utf-8").read())
+ dom = minidom.parseString(open(file_name, "rb").read())
+ for node in self._get_nodes(dom.childNodes, 'map'):
+ world_map = self._build_world_map(node)
+ break
+ world_map.map_file_name = os.path.abspath(file_name)
+ world_map.convert()
+ return world_map
+
+ def parse_decode(self, file_name):
+ u"""
+ Parses the map but additionally decodes the data.
+ :return: instance of TileMap
+ """
+ world_map = TileMapParser().parse(file_name)
+ world_map.decode()
+ return world_map
+
+ def parse_decode_load(self, file_name, image_loader):
+ u"""
+ Parses the data, decodes them and loads the images using the image_loader.
+ :return: instance of TileMap
+ """
+ world_map = self.parse_decode(file_name)
+ world_map.load(image_loader)
+ return world_map
+
+#-------------------------------------------------------------------------------
+def demo_pygame(file_name):
+ pygame = __import__('pygame')
+
+ # parser the map
+ world_map = TileMapParser().parse_decode(file_name)
+ # init pygame and set up a screen
+ pygame.init()
+ pygame.display.set_caption("tiledtmxloader - " + file_name)
+ screen_width = min(1024, world_map.pixel_width)
+ screen_height = min(768, world_map.pixel_height)
+ screen = pygame.display.set_mode((screen_width, screen_height))
+
+ # load the images using pygame
+ world_map.load(ImageLoaderPygame())
+ #printer(world_map)
+
+ # an example on how to access the map data and draw an orthoganl map
+ # draw the map
+ assert world_map.orientation == "orthogonal"
+
+ running = True
+ dirty = True
+ # cam_offset is for scrolling
+ cam_offset_x = 0
+ cam_offset_y = 0
+ # mainloop
+ while running:
+ # eventhandling
+ events = [pygame.event.wait()]
+ events.extend(pygame.event.get())
+ for event in events:
+ dirty = True
+ if event.type == pygame.QUIT:
+ running = False
+ elif event.type == pygame.KEYDOWN:
+ if event.key == pygame.K_ESCAPE:
+ running = False
+ elif event.key == pygame.K_DOWN:
+ cam_offset_y -= world_map.tileheight
+ elif event.key == pygame.K_UP:
+ cam_offset_y += world_map.tileheight
+ elif event.key == pygame.K_LEFT:
+ cam_offset_x += world_map.tilewidth
+ elif event.key == pygame.K_RIGHT:
+ cam_offset_x -= world_map.tilewidth
+
+ # draw the map
+ if dirty:
+ dirty = False
+ for layer in world_map.layers[:]:
+ if layer.visible:
+ idx = 0
+ # loop over all tiles
+ for ypos in xrange(0, layer.height):
+ for xpos in xrange(0, layer.width):
+ # add offset in number of tiles
+ x = (xpos + layer.x) * world_map.tilewidth
+ y = (ypos + layer.y) * world_map.tileheight
+ # get the gid at this position
+ img_idx = layer.content2D[xpos][ypos]
+ idx += 1
+ if img_idx:
+ # get the actual image and its offset
+ offx, offy, screen_img = world_map.indexed_tiles[img_idx]
+ # only draw the tiles that are relly visible (speed up)
+ if x >= cam_offset_x - 3 * world_map.tilewidth and x + cam_offset_x <= screen_width + world_map.tilewidth\
+ and y >= cam_offset_y - 3 * world_map.tileheight and y + cam_offset_y <= screen_height + 3 * world_map.tileheight:
+ if screen_img.get_alpha():
+ screen_img = screen_img.convert_alpha()
+ else:
+ screen_img = screen_img.convert()
+ if layer.opacity > -1:
+ #print 'per surf alpha', layer.opacity
+ screen_img.set_alpha(None)
+ alpha_value = int(255. * float(layer.opacity))
+ screen_img.set_alpha(alpha_value)
+ screen_img = screen_img.convert_alpha()
+ # draw image at right position using its offset
+ screen.blit(screen_img, (x + cam_offset_x + offx, y + cam_offset_y + offy))
+ # map objects
+ for obj_group in world_map.object_groups:
+ goffx = obj_group.x
+ goffy = obj_group.y
+ if goffx >= cam_offset_x - 3 * world_map.tilewidth and goffx + cam_offset_x <= screen_width + world_map.tilewidth \
+ and goffy >= cam_offset_y - 3 * world_map.tileheight and goffy + cam_offset_y <= screen_height + 3 * world_map.tileheight:
+ for map_obj in obj_group.objects:
+ size = (map_obj.width, map_obj.height)
+ if map_obj.image_source:
+ surf = pygame.image.load(map_obj.image_source)
+ surf = pygame.transform.scale(surf, size)
+ screen.blit(surf, (goffx + map_obj.x + cam_offset_x, goffy + map_obj.y + cam_offset_y))
+ else:
+ r = pygame.Rect((goffx + map_obj.x + cam_offset_x, goffy + map_obj.y + cam_offset_y), size)
+ pygame.draw.rect(screen, (255, 255, 0), r, 1)
+ # simple pygame
+ pygame.display.flip()
+
+#-------------------------------------------------------------------------------
+
+def demo_pyglet(file_name):
+ """Loads and views a map using pyglet.
+
+ Holding the arrow keys will scroll along the map.
+ Holding the left shift key will make you scroll faster.
+ Pressing the escape key ends the application.
+ """
+
+ import pyglet
+ from pyglet.gl import glTranslatef, glLoadIdentity
+
+ world_map = TileMapParser().parse_decode(file_name)
+ # delta is the x/y position of the map view.
+ # delta is a list because the scoping is different for immutable types.
+ # This list can be used within the update method.
+ delta = [0.0, 0.0]
+ window = pyglet.window.Window()
+
+ @window.event
+ def on_draw():
+ window.clear()
+ # Reset the "eye" back to the default location.
+ glLoadIdentity()
+ # Move the "eye" to the current location on the map.
+ glTranslatef(delta[0], delta[1], 0.0)
+ batch.draw()
+
+ keys = pyglet.window.key.KeyStateHandler()
+ window.push_handlers(keys)
+ world_map.load(ImageLoaderPyglet())
+
+ def update(dt):
+ speed = 3.0 + keys[pyglet.window.key.LSHIFT] * 6.0
+ if keys[pyglet.window.key.LEFT]:
+ delta[0] += speed
+ if keys[pyglet.window.key.RIGHT]:
+ delta[0] -= speed
+ if keys[pyglet.window.key.UP]:
+ delta[1] -= speed
+ if keys[pyglet.window.key.DOWN]:
+ delta[1] += speed
+
+ # Generate the graphics for every visible tile.
+ batch = pyglet.graphics.Batch()
+ groups = []
+ sprites = []
+ for group_num, layer in enumerate(world_map.layers[:]):
+ if layer.visible is False:
+ continue
+ groups.append(pyglet.graphics.OrderedGroup(group_num))
+ for xtile in range(layer.width):
+ for ytile in range(layer.height):
+ image_id = layer.content2D[xtile][ytile]
+ if image_id:
+ # o_x and o_y are offsets. They are not helpful here.
+ o_x, o_y, image_file = world_map.indexed_tiles[image_id]
+ # To compensate for pyglet's upside-down y-axis, the
+ # Sprites are placed in rows that are backwards compared
+ # to what was loaded into the map. The "max - current"
+ # formula does this reversal.
+ sprites.append(pyglet.sprite.Sprite(image_file,
+ xtile * world_map.tilewidth,
+ layer.pixel_height - (ytile+1) * world_map.tileheight,
+ batch=batch, group=groups[group_num]))
+
+ pyglet.clock.schedule_interval(update, 1.0 / 60.0)
+ pyglet.app.run()
+
+
+#-------------------------------------------------------------------------------
+def main():
+
+ args = sys.argv[1:]
+ if len(args) != 2:
+ #print 'usage: python test.py mapfile.tmx [pygame|pyglet]'
+ print('usage: python %s your_map.tmx [pygame|pyglet]' % \
+ os.path.basename(__file__))
+ return
+
+ if args[1] == 'pygame':
+ demo_pygame(args[0])
+ elif args[1] == 'pyglet':
+ demo_pyglet(args[0])
+ else:
+ print 'missing framework, usage: python test.py mapfile.tmx [pygame|pyglet]'
+ sys.exit(-1)
+
+#-------------------------------------------------------------------------------
+
+if __name__ == '__main__':
+ main()
+
+
+if __debug__:
+ _dt = time.time() - _start_time
+ sys.stdout.write(u'%s loaded: %fs \n' % (__name__, _dt))
diff --git a/game1/tracktmx.py b/game1/tracktmx.py
new file mode 100755
index 0000000..8867942
--- /dev/null
+++ b/game1/tracktmx.py
@@ -0,0 +1,166 @@
+# -*- coding: utf-8 -*-
+
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""
+
+There are 4 types of tiles:
+
+1) Navigable materials (lowercase letter) like grass, dirt
+2) Non-navigable materials (uppercase letter) like Water, Plant, Rock, Tree, trunK
+3) Dangerous materials (numbers) like black cuy (2) and owl (1)
+4) Goals (symbols) like apples (#), oranges ($)
+
+"""
+
+import sys
+import random
+import pygame
+import glob
+import os.path
+from pygame import *
+from pygame.locals import *
+from constants import *
+from resources import *
+from tiledtmxloader import *
+
+class Track():
+
+ def __init__(self):
+ self.numbers_image = {}
+ self.numbers_number = {}
+ self.touched = {}
+ self.load()
+
+ def load(self, filename = "./tracks/track1.tmx"):
+ self.world_map = TileMapParser().parse_decode(filename)
+ self.world_map.load(ImageLoaderPygame())
+ assert self.world_map.orientation == "orthogonal"
+
+ def endOfTrack(self, offset = 0):
+ return False
+
+ def draw(self, screen, offset = 0):
+ # cam_offset is for scrolling
+ cam_offset_x = 0
+ cam_offset_y = -offset
+ screen_width = screen_size[0]
+ screen_height = screen_size[1]
+ # draw the map
+ for layer in self.world_map.layers[:]:
+ if layer.visible:
+ idx = 0
+ # loop over all tiles
+ for ypos in xrange(0, layer.height):
+ for xpos in xrange(0, layer.width):
+ # add offset in number of tiles
+ x = (xpos + layer.x) * self.world_map.tilewidth
+ y = (ypos + layer.y) * self.world_map.tileheight
+ # get the gid at this position
+ img_idx = layer.content2D[xpos][ypos]
+ material = self.world_map.indexed_tiles_tileset[img_idx]
+ idx += 1
+ if img_idx:
+ # get the actual image and its offset
+ offx, offy, screen_img = self.world_map.indexed_tiles[img_idx]
+ # only draw the tiles that are relly visible (speed up)
+ if x >= cam_offset_x - 3 * self.world_map.tilewidth and x + cam_offset_x <= screen_width + self.world_map.tilewidth\
+ and y >= cam_offset_y - 3 * self.world_map.tileheight and y + cam_offset_y <= screen_height + 3 * self.world_map.tileheight:
+ """
+ if screen_img.get_alpha():
+ screen_img = screen_img.convert_alpha()
+ else:
+ screen_img = screen_img.convert()
+ if layer.opacity > -1:
+ #print 'per surf alpha', layer.opacity
+ screen_img.set_alpha(None)
+ alpha_value = int(255. * float(layer.opacity))
+ screen_img.set_alpha(alpha_value)
+ screen_img = screen_img.convert_alpha()
+ """
+ # draw image at right position using its offset
+ screen.blit(screen_img, (x + cam_offset_x + offx, y + cam_offset_y + offy + horizon_y))
+ if material == "goals":
+ surface = self.getTextSurface(xpos, ypos, img_idx)
+ screen.blit(surface, (x + cam_offset_x + offx + 10, y + cam_offset_y + offy + horizon_y + 10))
+
+ """
+ # map objects
+ for obj_group in world_map.object_groups:
+ goffx = obj_group.x
+ goffy = obj_group.y
+ if goffx >= cam_offset_x - 3 * world_map.tilewidth and goffx + cam_offset_x <= screen_width + world_map.tilewidth \
+ and goffy >= cam_offset_y - 3 * world_map.tileheight and goffy + cam_offset_y <= screen_height + 3 * world_map.tileheight:
+ for map_obj in obj_group.objects:
+ size = (map_obj.width, map_obj.height)
+ if map_obj.image_source:
+ surf = pygame.image.load(map_obj.image_source)
+ surf = pygame.transform.scale(surf, size)
+ screen.blit(surf, (goffx + map_obj.x + cam_offset_x, goffy + map_obj.y + cam_offset_y))
+ else:
+ r = pygame.Rect((goffx + map_obj.x + cam_offset_x, goffy + map_obj.y + cam_offset_y), size)
+ pygame.draw.rect(screen, (255, 255, 0), r, 1)
+ """
+
+ def getTextSurface(self, xtile, ytile, object):
+ if self.numbers_image.has_key( (xtile, ytile) ):
+ return self.numbers_image[(xtile, ytile)]
+ if (object % 2) == 1:
+ number = random.randint(0,49) * 2 + 1
+ elif (object % 2) == 0:
+ number = random.randint(0,49) * 2
+ afont = pygame.font.SysFont("droidsans", 44)
+ text = afont.render(str(number), 1, (255,255,255))
+ self.numbers_number[(xtile, ytile)] = number
+ self.numbers_image[(xtile, ytile)] = text
+ return text
+
+ def getTileNumberWC(self, x_wc, y_wc):
+ return [x_wc / tile_size[0], y_wc / tile_size[1]]
+
+ def getTileRectWC(self, x_wc, y_wc):
+ tile_rect = Rect()
+ tile_rect.top = y_wc / tile_size[1]
+ tile_rect.left = x_wc / tile_size[0]
+ tile_rect.width = tile_size[0]
+ tile_rect.height = tile_size[1]
+
+ def getTileType(self, tilex, tiley):
+ return self.lines[tiley][tilex]
+
+ def collidesWith(self, rect, justCheck = False):
+ """ check collision """
+ xtilemin, ytilemin = self.getTileNumberWC(rect.left, rect.top)
+ xtilemax, ytilemax = self.getTileNumberWC(rect.right, rect.bottom)
+ retmaterial = "navegable"
+ for layer in self.world_map.layers[:]:
+ for tiley in range(ytilemin, ytilemax + 1):
+ for tilex in range(xtilemin, xtilemax + 1):
+ img_idx = layer.content2D[tilex][tiley]
+ material = self.world_map.indexed_tiles_tileset[img_idx]
+ if self.isGoal(material):
+ if not self.touched.has_key ( (tilex, tiley) ):
+ if not justCheck:
+ self.touched[ (tilex,tiley) ] = True
+ return self.numbers_number[(tilex, tiley)]
+ if self.isDanger(material):
+ if not self.touched.has_key ( (tilex, tiley) ):
+ if not justCheck:
+ self.touched[ (tilex,tiley) ] = True
+ return material
+ if self.isNotNavigable(material):
+ retmaterial = material
+ return retmaterial
+
+ def isNavigable(self, tile):
+ return tile == "navegable"
+
+ def isNotNavigable(self, tile):
+ return tile == "nonavegable"
+
+ def isDanger(self, tile):
+ return tile == "enemies"
+
+ def isGoal(self, tile):
+ return tile == "goals"