8回目:pygameでゲームを作成する|マップを作る 主人公を歩かせる

前回はその場でキャラクターが足踏みするということをしました。

 

しかし、32×32の部分が黒くなってしまったのでまずはそこを治していきます。

 


# -*- coding: utf-8 -*- 
import pygame
from pygame.locals import*
import sys

(w,h)=(640,480)
RECT=Rect(0,0,w,h)

def load_image(filename):		#filenameからイメージを取得
 image=pygame.image.load(filename).convert_alpha()
# image.set_colorkey(000000)

 colorkey=image.get_at((0,0))
 image.set_colorkey(colorkey,RLEACCEL)

 if image.get_colorkey() is None:
  print("None")
 if image.get_colorkey() is not None:
  print("not None")
 
 return image

def split_image(image):	#画像を配列に分ける
 imageList=[]		#配列を作成
 for i in range(0,96,32):	#0~96を32ずつ進む(3回繰り返す)
  surface=pygame.Surface((32,32))	#カラのfurefacを作成
  surface.set_colorkey(000000)
  surface.blit(image,(0,0),(i,0,32,32))	#(0,0)は画像の左上の場所 iはimageのx座標、0はy座標、32がwidthとheight
  surface.convert_alpha()		#ピクセル形式を変更
  imageList.append(surface)	#imageListに加える

 return imageList

#----------------charaクラス----------------------------------------------------
class chara(pygame.sprite.Sprite):	#引数はSpirite.imageとSpirite.rect
 anime=12	#アニメーション速度
 frame=0
 def __init__(self,filename,x,y):	#filenameにSpirite.image、x,yにSpirite.rect
  pygame.sprite.Sprite.__init__(self,self.containers)
  self.images=split_image(load_image(filename))	#split_imageを呼び出し画像の配列をself.imagesに返す。
  self.image=self.images[0]			#最初の画像
  self.rect=self.image.get_rect(topleft=(x,y))	#self.imageの座標
 def update(self):
  self.frame+=1		#次のフレーム
  self.image=self.images[self.frame//self.anime%3]	#1/12/3=0,2/12/3=0…12/12/3=1 次のフレームに対応する配列番号
#↑//は整数の割り算 
#--------------------------------------------------------------------------------

def main():
 pygame.init()
 screen=pygame.display.set_mode(RECT.size)
 pygame.display.set_caption("キャラクターアニメーション")
 
 backImg=pygame.image.load("b.jpg").convert()
 
 spirit=pygame.sprite.RenderUpdates()	#pygame.sprite.RnderUpdates()を短くする
 chara.containers=spirit
 player=chara("c.png",100,100)		#charaクラスを呼び出す

 clock=pygame.time.Clock()
 while(1):
  clock.tick(60)	#1秒間に60回フレームが更新
  #screen.blit(backImg,(0,0))
  screen.fill((0,0,225))
  spirit.update()	#updateする(配列から新たに次の画像を取得)
  spirit.draw(screen)	#imageに格納されてある画像を出力
  pygame.display.update()

  for event in pygame.event.get():
   if event.type==QUIT:
    sys.exit()

if __name__=="__main__":
 main()

 

かなり試行錯誤して導きましたが、追加したのはこの一行です。

 


  surface.set_colorkey(000000)

 

これは「surfaceの黒い部分を透明化する」というものです。

 

000000は16進数で黒ですからね。

 

split_imageで新たに32×32のsurfaceを作成したときに、初期化の色が黒だったためそうなったのだと思います。

 

ということは、黒で作成した瞬間に黒を透明にすると、すべてが透明なsurfaceを作成することができます。

 

surface=pygame.Surface((32,32))を宣言した時点で透明化できるとよかったのですが、私には難しかったです。

 

まずは簡単なマップを作成する

RPGなどでは基本中の基本ですが、マップを作成していきます。

二次元配列を使って、マップを作成します。

ソースコード


# -*- coding:utf-8 -*-
import pygame
from pygame.locals import*
import sys

(w,h)=(640,480)
rect=Rect(0,0,w,h)
(TATE,YOKO)=(15,20)	#マップサイズ
GS=32	#一ますのサイズ

map=[	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],]

def image(filename):
 image=pygame.image.load(filename).convert_alpha()
 return image

def draw_map(screen):
 for i in range(TATE):	#縦回繰り返す
  for ix in range(YOKO):
   if map[i][ix]==0:
    screen.blit(MapImg,(ix*GS,i*GS))

pygame.init()
screen=pygame.display.set_mode((w,h))
pygame.display.set_caption("マップを作成")
 
Img=image("c.png")
MapImg=image("d.png")
while(1): 
 draw_map(screen)
 screen.blit(Img,(0,0))
 pygame.display.update()
 for event in pygame.event.get():
  if event.type==QUIT:
   sys.exit()


 

これでマップの作成と、キャラクターの配置はできました。

 

ついでに移動を付けるとこんな感じになります。

 


# -*- coding:utf-8 -*-
import pygame
from pygame.locals import*
import sys

(w,h)=(640,480)
rect=Rect(0,0,w,h)
(TATE,YOKO)=(15,20)	#マップサイズ
GS=32	#一ますのサイズ

map=[	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],]

def image(filename):
 image=pygame.image.load(filename).convert_alpha()
 return image

def draw_map(screen):
 for i in range(TATE):	#縦回繰り返す
  for ix in range(YOKO):
   if map[i][ix]==0:
    screen.blit(MapImg,(ix*GS,i*GS))
    print (i*GS,ix*GS)

pygame.init()
screen=pygame.display.set_mode((w,h))
pygame.display.set_caption("マップを作成")
 
Img=image("c.png")
Img_rect=Img.get_rect()
MapImg=image("d.png")
while(1): 
 pressed_keys = pygame.key.get_pressed()
 if pressed_keys[K_LEFT]:
    Img_rect.move_ip(-32, 0)
 if pressed_keys[K_RIGHT]:
    Img_rect.move_ip(32, 0)
 if pressed_keys[K_UP]:
    Img_rect.move_ip(0, -32)
 if pressed_keys[K_DOWN]:
    Img_rect.move_ip(0, 32)
 Img_rect = Img_rect.clamp(rect)

 draw_map(screen)
 screen.blit(Img,Img_rect)
 pygame.display.update()
 for event in pygame.event.get():
  if event.type==QUIT:
   sys.exit()


 

主人公は常に前を向いていますが、移動することができました。

 

一枚の画像のように見えるかもしれませんが、ちゃんと32×32ピクセルの画像を出力しているんですよ?

 

足踏み主人公の作成

ソースコード


# -*- coding:utf-8 -*-
import pygame
from pygame.locals import*
import sys

(w,h)=(640,480)
rect=Rect(0,0,w,h)
(TATE,YOKO)=(15,20)	#マップサイズ
GS=32	#一ますのサイズ

map=[	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],]

def image(filename):
 image=pygame.image.load(filename).convert_alpha()
 return image

def split(image):
 imageList=[]
 for i in range(0,96,GS):	#GSは32
  surface=pygame.Surface((GS,GS))
  surface.blit(image,(0,0),(i,0,GS,GS))
  surface.set_colorkey(000000)
  surface.convert_alpha()
  imageList.append(surface)
 return imageList

def draw_map(screen):
 for i in range(TATE):	#縦回繰り返す
  for ix in range(YOKO):
   if map[i][ix]==0:
    screen.blit(MapImg,(ix*GS,i*GS))

pygame.init()
screen=pygame.display.set_mode((w,h))
pygame.display.set_caption("マップを作成")
 
ImgList=split(image("c.png"))
MapImg=image("d.png")

(x,y)=(0,0)
anime=24
frame=0

clock=pygame.time.Clock()

while(1): 
 clock.tick(60)

 frame+=1
 Img=ImgList[frame//anime%3]

 pressed_keys = pygame.key.get_pressed()
 if pressed_keys[K_LEFT]:
    x-=1
 if pressed_keys[K_RIGHT]:
    x+=1
 if pressed_keys[K_UP]:
    y-=1
 if pressed_keys[K_DOWN]:
    y+=1
 
 Img_rect=(x*GS,y*GS,GS,GS)

 draw_map(screen)
 screen.blit(Img,Img_rect)
 pygame.display.update()
 for event in pygame.event.get():
  if event.type==QUIT:
   sys.exit()


これで足踏み主人公の作成ができました。

 

かに歩きしかできない状態です。

 

まとめ

マップを作成できると、ゲームという感じがしますね。

 

次回は、かに歩きではなく普通に歩けるようなソースコードを作成したいと思います。

 

参考サイト

マップを作る