#!/usr/bin/env python # -*- coding: utf-8 -*- import pygame from pygame.locals import * import sys import os SCR_RECT = Rect(0, 0, 640, 480) GS = 32 DOWN,LEFT,RIGHT,UP = 0,1,2,3 def main(): pygame.init() screen = pygame.display.set_mode(SCR_RECT.size) pygame.display.set_caption(u"PyRPG 08 マップのロード") # マップチップをロード Map.images[0] = load_image("grass.png") # 草地 Map.images[1] = load_image("water.png") # 水 # マップとプレイヤー作成 map = Map("test") player = Player("player", (1,1), DOWN) clock = pygame.time.Clock() while True: clock.tick(60) player.update() map.draw(screen) player.draw(screen) pygame.display.update() for event in pygame.event.get(): if event.type == QUIT: sys.exit() if event.type == KEYDOWN and event.key == K_ESCAPE: sys.exit() # プレイヤーの移動処理 if event.type == KEYDOWN and event.key == K_DOWN: player.move(DOWN, map) if event.type == KEYDOWN and event.key == K_LEFT: player.move(LEFT, map) if event.type == KEYDOWN and event.key == K_RIGHT: player.move(RIGHT, map) if event.type == KEYDOWN and event.key == K_UP: player.move(UP, map) def load_image(filename, colorkey=None): filename = os.path.join("data", filename) try: image = pygame.image.load(filename) except pygame.error, message: print "Cannot load image:", filename raise SystemExit, message image = image.convert() if colorkey is not None: if colorkey is -1: colorkey = image.get_at((0,0)) image.set_colorkey(colorkey, RLEACCEL) return image def split_image(image): """128x128のキャラクターイメージを32x32の16枚のイメージに分割 分割したイメージを格納したリストを返す""" imageList = [] for i in range(0, 128, GS): for j in range(0, 128, GS): surface = pygame.Surface((GS,GS)) surface.blit(image, (0,0), (j,i,GS,GS)) surface.set_colorkey(surface.get_at((0,0)), RLEACCEL) surface.convert() imageList.append(surface) return imageList class Map: images = [None] * 256 # マップチップ(番号->イメージ) def __init__(self, name): self.name = name self.row = -1 # 行数 self.col = -1 # 列数 self.map = [] # マップデータ(2次元リスト) self.load() def draw(self, screen): """マップを描画する""" for r in range(self.row): for c in range(self.col): screen.blit(self.images[self.map[r][c]], (c*GS,r*GS)) def is_movable(self, x, y): """(x,y)は移動可能か?""" # マップ範囲内か? if x < 0 or x > self.col-1 or y < 0 or y > self.row-1: return False # マップチップは移動可能か? if self.map[y][x] == 1: # 水は移動できない return False return True def load(self): """ファイルからマップをロード""" file = os.path.join("data", self.name + ".map") # テキスト形式のマップを読み込む fp = open(file) lines = fp.readlines() row_str, col_str = lines[0].split() # 行数と列数 self.row, self.col = int(row_str), int(col_str) for line in lines[1:]: line = line.rstrip() self.map.append([int(x) for x in list(line)]) fp.close() class Player: animcycle = 24 # アニメーション速度 frame = 0 def __init__(self, name, pos, dir): self.name = name # プレイヤー名(ファイル名と同じ) self.images = split_image(load_image("%s.png" % name)) self.image = self.images[0] # 描画中のイメージ self.x, self.y = pos[0], pos[1] # 座標(単位:マス) self.rect = self.image.get_rect(topleft=(self.x*GS, self.y*GS)) self.direction = dir def update(self): # キャラクターアニメーション(frameに応じて描画イメージを切り替える) self.frame += 1 self.image = self.images[self.direction*4+self.frame/self.animcycle%4] def move(self, dir, map): """プレイヤーを移動""" if dir == DOWN: self.direction = DOWN if map.is_movable(self.x, self.y+1): self.y += 1 self.rect.top += GS elif dir == LEFT: self.direction = LEFT if map.is_movable(self.x-1, self.y): self.x -= 1 self.rect.left -= GS elif dir == RIGHT: self.direction = RIGHT if map.is_movable(self.x+1, self.y): self.x += 1 self.rect.left += GS elif dir == UP: self.direction = UP if map.is_movable(self.x, self.y-1): self.y -= 1 self.rect.top -= GS def draw(self, screen): screen.blit(self.image, self.rect) if __name__ == "__main__": main()