gameutilモジュール

私が使ってるモジュール。
RyoN3さんによって書かれたモジュールでいまや欠かせません。
自分で一から書けとか言わないで。改造で精一杯なのです。
で、今後python+pygameの記事を書くときたぶん出てくるので、
ここに乗せておきます。
問題があったらすぐ消します。連絡してください。

# -*- coding:sjis -*-
"""雑多な自作ライブラリ

author:RyoN3
date  :04/20/2006
changed:ashiato45
date  :03/16/2008
The original was written by RyoN3.
I recommend you to read his text.
I changed this module a little.
If there is a trouble, I'll delete this module from my server.
RyoN3:http://www.halb-katze.jp/index.html
"""

import os,sys,textwrap, re
import pygame
from pygame.locals import *

# define name
N=1; E=2; W=4; S=8

# short name
flip = pygame.display.flip
get_event = pygame.event.get

# game utility functions
def init(size=(200,100), title='non title'):
	"""initialize all and make surface using pygame.init()"""
	pygame.init()
	scr = pygame.display.set_mode(size)
	scrRect = scr.get_rect()
	pygame.display.set_caption(title)
	return scr

#def load_image(filename, ckey=None):
#	"""あらゆるイメージをロードし、imageオブジェクトを返す。
#
#	filename:ファイル名
#	ckey:Colorkey設定。-1だと画像の左上ピクセルの色を拾う。"""
#	try:
#	    img = pygame.image.load(filename)
#	except pygame.error, message:
#	    print '画像を読み込めません', filename
#	    raise SystemExit, message
#	img = img.convert()
#	if ckey != None:
#	    if ckey == -1:
#	        ckey = img.get_at((0,0))
#	    img.set_colorkey(ckey, RLEACCEL)
#	return img

def load_image(name, colorkey=None):
	fullname = os.path.join('data', name)
	try:
		image=pygame.image.load(fullname)
	except pygame.error, message:
		print 'Cannot read image.'
		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,image.get_rect()

def load_font(size=24,name=None):
	"""フォントをセットする。name指定がなければMSゴシック。"""
	fontname = name or 'msgothic.ttc'
	# os check
	if sys.platform == 'win32':
	    syspath = os.path.join(os.environ['WINDIR'], "Fonts", fontname)
	    font = pygame.font.Font(syspath, size)
	else: # Macは知らん
	    syspath = os.path.join('/usr/X11R6/lib/X11/fonts', fontname)
	    font = pygame.font.Font(syspath, size)
	if font is None: font = pygame.font.Font(None, size)
	return font

def keydown(event, key):
	"""keyが押されているかの真偽を返す"""
	return event.type == KEYDOWN and event.key == key

def load_sound(name):
	"""サウンドを読み込んでオブジェクトを返す"""
	class NoneSound:
	    def play(self): pass
	if not pygame.mixer:
	    return NoneSound()
	fullname = os.path.join('data', name)
	try:
	    sound = pygame.mixer.Sound(fullname)
	except pygame.error, message:
	    print 'サウンドを読み込めません:', wav
	    raise SystemExit, message
	return sound

def image_rotate(image, img_rect, angle):
	"""画像を回転させる。回転後の画像は回転元画像に上書きしないように。"""
	center = img_rect.center # 元画像の中心位置を保存
	image = pygame.transform.rotate(image, angle)
	image_rect = image.get_rect()
	image_rect.center = center
	return image, image_rect

def get_reflect_angle(a, b):
	"""get_reflect_angle(assult_angle, wall_angle) -> double
	   calculate reflection angle"""
	if b >= 180: b -= 180
	return b * 2 - a

def islist(target):
	"""islist(object) -> bool
	   check type of object. if type is list, return True."""
	try: len(target)
	except: return False
	return True

def gcolliderect(group, rect):
	"""Check collide rect in BlitGroup"""
	crash = []
	rectgr = []
	for x in group:
	    rectgr.append(x.colrect)
	cl = rect.collidelistall(rectgr)
	for i in cl:
	    crash.append(group[i])
	return crash

def getviewlist(base, base_width, viewrect):
	"""マップ配列から自分の可視範囲の配列を作り直す

	base:元マップ
	base_width:元マップの横幅
	viewrect:可視範囲のRectオブジェ(配列値)"""
	
	retlist = []
	for i in range(viewrect.h):
	    for j in range(viewrect.w):
	        retlist.append(base[xy2x(j+viewrect.x, i+viewrect.y, base_width)])
	return retlist


def getDirection(oldrect, nowrect):
	"""return direction"""
	retstr = 0
	v = oldrect.top-nowrect.top
	h = oldrect.left-nowrect.left
	if h<0: retstr += E
	elif h>0: retstr += W
	if v<0: retstr += S
	elif v>0: retstr += N
	return retstr

def xy2x(x,y,w):
	"""2次元配列のインデックス位置をintに変換する"""
	return x+w*y

def x2xy(x,w):
	"""1次元配列を2次元配列のインデックスに分解する"""
	return (x%w, int(x/w))

def readmap(filename):
	"""改行で配置されたテキストをマップ配列に格納する"""
	maplist = []
	fp = file(filename)
	if fp is None: return None
	w,h = 0,0
	flg = False
	while 1:
	    tmp = fp.read(1)
	    if tmp == "": break # EOFなら終了
	    elif tmp != "\n":
	        if not flg: w += 1
	        maplist.append(int(tmp))
	    else: # tmp == "\n"
	        flg = True
	        h += 1
	fp.close()
	return w,h,maplist

def exit_check(event, inkey=None):
	"""終了チェック"""
	if event.type == QUIT:
	    return True
	if inkey is not None:
	    if keydown(event, inkey):
	        return True
	return False

# game utility classies
class TextRender:
	"""文字列描写統合クラス"""
	oldrect = None
	startproh = unicode("/[!%),.:;?]}¢°’”‰′″℃、。々〉》」』】〕ぁぃぅぇぉっゃゅょゎ゛゜ゝゞァィゥェォッャュョヮヵヶ・ーヽヾ!%),.:;?]}。」、・ァィゥェォャュョッー゙゚¢]/",
	                    "sjis")
	endproh = unicode("/[$([\{£\‘“〈《「『【〔$([{「£¥]/",
	                  "sjis")
	def __init__(self, font=None, color=None,
	             wrap=False, width=70, hanging=True):
	    """文字列描写の初期化を行う。

	    font   : 使用するフォント。省略時はMSゴシック
	    color  : フォントカラー。省略時は白(255,255,255)
	    warp   : 自動改行を行うか。省略時はFalse
	    width  : 1行の文字数。省略時は70文字
	    hanging: ぶら下がり指定。省略時はTrue"""
	    self.font = font or load_font()
	    self.color = color or (255,255,255)
	    self.wrapper = textwrap.TextWrapper()
	    self.wrapping = wrap
	    self.wrapper.width = width
	    self.hanging = hanging

	def draw(self, scr, textstr, pos=None):
	    self.oldrect = self.printscr(scr, textstr, pos)

	def clear(self, scr, bgd):
	    scr.blit(bgd, self.oldrect, self.oldrect)

	def printscr(self, scr, s, pos=None):
	    """printscr(surface, string, rect, bool) -> rect
	       blit strings with pygame.font.render"""
	    outstr = [] # 出力用テンポラリ
	    w = 0; h = 0 # 最終描写サイズ用
	    s = unicode(str(s),"sjis") # convert unicode
	    s = s.split("\n")
	    pos = pos or (0,0)
	    posrect = pygame.Rect(pos, scr.get_size())
	    x,y = posrect.topleft
	    if self.wrapping is True:
	        outstr = self._wrap(s)
	    else:
	        # wrapingが偽でも\n改行を見てるのでリスト化
	        outstr = s[:]
	    for tmp in outstr:
	        text = self.font.render(tmp, 0, self.color)
	        posrect.size = text.get_rect().size
	        scr.blit(text, posrect)
	        posrect.y += posrect.h # adding font height
	        w = max(posrect.w, w) # widthの最大値を取得
	        h += posrect.h # heightの累積値を取得
	    return pygame.Rect((x,y,w,h)) # 書き込んだ場所を全部返す。

	def _wrap(self, text):
	    # wrapingが真なら指定文字数で改行させる。
	    # unicodeなので全角半角関係なくwrap_width文字数
	    outstr = []
	    re1 = re.compile(self.endproh)
	    re2 = re.compile(self.startproh)
	    for i in text:
	        tmp = self.wrapper.wrap(i)
	        for j in tmp:
	            outstr.append(j)
	            if re2.search(j) is not None:
	                print "Match"
	            else:
	                print "No match"
	    print outstr

	    return outstr
	def size(self, s):
		return self.font.size(s)

class TextBoard(pygame.sprite.Sprite):
	def __init__(self, tr):
		pygame.sprite.Sprite.__init__(self)
		self.tr = tr
		self.render("")
	def _get_backnumber(self, n):
		leftdistance = n
		rightdistance = 255 - n
		if leftdistance > rightdistance:
			res = 0
		else:
			res = 255
		if res == n:
			return 255 - res
		else:
			return res
	def _get_othercolor(self, color):
		return tuple([self._get_backnumber(i) for i in color])
	def render(self, s):
		self.image = pygame.Surface(self.tr.size(str(s)))
		oc = self._get_othercolor(self.tr.color)
		self.image.fill(oc)
		self.image.set_colorkey(oc)
		try:
			self.rect.size = self.image.get_rect().size
		except AttributeError:
			self.rect = self.image.get_rect()

		self.tr.draw(self.image, str(s))

def quit(event):
	if event.type == QUIT:
		sys.exit(0)
	elif event.type == KEYDOWN and event.key == K_ESCAPE:
		sys.exit(0)
	    
def get_fontsize(fontname, maxheight, teststr, maxsize=24):
	c = range(1, maxsize+1)
	c.reverse()
	for i in c:
		f = load_font(i, fontname)
		h = f.size(teststr)[1]
		if h <= maxheight:
			return i
	return None

if __name__ == "__main__":
	pass