헤더파일

랜덤 유닛 디펜스 - 파이썬 2D 게임 본문

포트폴리오 정리

랜덤 유닛 디펜스 - 파이썬 2D 게임

헤더파일 2019. 8. 15. 16:28

개발 환경

 

  • 파이썬
  • SDL 라이브러리

게임소개

 

  • 유닛을 뽑아서 성벽을 지키는 게임입니다.
  • 여러 유닛을 조합하여 더 좋은 유닛으로 만들 수 있습니다.
  • 5개의 스테이지, 26가지 유닛을 만들 수 있습니다.

 

 


게임 특징

 

타일맵


Tiled 프로그램으로 만든 JSON 데이터를 읽어와서 맵을 그립니다.  Tile 이미지를 Tileset으로 구성하고 타일맵 데이터를 이용하여 해당 위치에 이미지를 그립니다. 적은 이미지 리소스로 다양한 맵을 만들 수 있고 Layer를 나눠 겹친 사물도 표현할 수 있습니다.

class TileMap:


    def load(self, name):
        f = open(name)
        info = json.load(f)
        f.close()
        self.__dict__.update(info)
        print(self.tilesets[0])
        self.tile_set = load_tile_set(self.tilesets[0]['source'])
        self.firstgid = self.tilesets[0]['firstgid']
        self.data = self.layers[0]['data']
        new_data = []
        for row in reversed(range(self.height)):
            new_data.append(self.data[row * self.width: row * self.width + self.width])
        self.data = new_data
        
    def clip_draw_to_origin(self, l, b, w, h, dx, dy):
        tl = l // self.tilewidth
        tb = b // self.tileheight
        tw = (l + w) // self.tilewidth - tl + 1
        th = (b + h) // self.tileheight - tb + 1
        lo = l % self.tilewidth
        bo = b % self.tileheight
        for x in range(tl, min(tl + tw, self.width)):
            for y in range(tb, min(tb + th, self.height)):
                self.tile_set.tile_images[self.data[y][x] - self.firstgid].\
                    draw_to_origin((x - tl) * self.tilewidth - lo, (y - tb) * self.tileheight - bo)
        					...
class TileSet:

    def __init__(self):
        self.firstgid = 0

    def load(self, file_name):
        f = open(file_name)

        data = json.load(f)
        f.close()
        self.__dict__.update(data)
        print(self.__dict__)
        self.base_image = load_image(self.image)
        self.tile_images = []
        for i in range(self.tilecount):
            col, row = i % self.columns, i // self.columns
            left = col * self.tilewidth
            bottom = self.base_image.h - (row + 1) * self.tileheight
            image = self.base_image.clip_image(left, bottom,
                                               self.tilewidth, self.tileheight)
            self.tile_images.append(image)
						...

 

텍스쳐 인스턴싱


각 텍스쳐를 한번만 만들어서 보관하고 다시 그릴때는 위치만 지정해서 그리게 하여 각 객체마다 텍스쳐를 만들 필요가 없게 했습니다.

class Effect:

    def __init__(self):
        					...
                            
        self.explosionImage = load_image(r'resource\effect\e1.png'),load_image(r'resource\effect\e2.png')
        self.beamHitImage = load_image(r'resource\effect\r1.png'),load_image(r'resource\effect\r2.png'),load_image(r'resource\effect\r3.png')
        self.beamImage = (load_image(r'resource\effect\l3.png'), load_image(r'resource\effect\l4.png')),(load_image(r'resource\effect\l3.png'), load_image(r'resource\effect\l4.png')),(load_image(r'resource\effect\l5.png'), load_image(r'resource\effect\l6.png'))
     def Draw(self,frameTime):
     				...
                    
    	 for enemy in self.enemyList:
                    self.effectManager.Draw(enemy.x, enemy.y, ally.effectType)
                    
                    		...

 JSON 데이터 활용


각 유닛데이터를 JSON형태로 만들고 보관하여 수정 및 적용이 코드상에서 이루어지지 않게 했습니다.

[
    {"effectType":0,"attackPoint":10,"attackSound":0} ,
    {"effectType":0,"attackPoint":20,"attackSound":0} ,
    {"effectType":0,"attackPoint":30,"attackSound":0} ,
    {"effectType":1,"attackPoint":40,"attackSound":2} ,
    {"effectType":1,"attackPoint":50,"attackSound":0} ,
    {"effectType":1,"attackPoint":60,"attackSound":2} ,
    {"effectType":2,"attackPoint":90,"attackSound":0} ,
    {"effectType":2,"attackPoint":100,"attackSound":1} ,
    {"effectType":2,"attackPoint":110,"attackSound":1} ,
				...
]
Comments