기본 콘텐츠로 건너뛰기

라벨이 python인 게시물 표시

파이썬(python) 의 System Random

 보통 사용하는 random 함수는 완전한 랜덤 함수가 아닌 공식에 의해서 만들어지는 유사 랜덤값 입니다. 따라서 seed 가 동일하면 난수의 값도 동일하게 출력 됩니다. 오늘 kotlin 에 대해서 보다 보니 secure random 이라는게 있더군요. os 의 내부 값을 이용해서 랜덤 값을 얻기 때문에 더욱 완전한 랜덤값을 얻게 됩니다.  그래서 파이썬에도 방법이 있지 않을까 검색해 보니 바로 있더군요.(이걸 왜 못봤지...?? ㅜ.ㅜ) 그래서 아주 간단히 테스트 해 봤습니다.  >>> import random >>> random.Random(1).random() 0.13436424411240122 >>> random.Random(1).random() 0.13436424411240122 >>> random.SystemRandom(1).random() 0.6490113165803764 >>> random.SystemRandom(1).random() 0.1295135574954781 >>> random.SystemRandom(1).random() 0.7727918191932017 문서의 내용을 간단히 말하자면...SystemRandom 에 넣어주는 seed 값은 아무 의미가 없다고 합니다. OS 에서 random값을 얻기 때문입니다. 리눅스의 경우는 /dev/random, /dev/urandom 등에서 얻는 모양인데 자세한건 잘 모르겠습니다. ^^; 위의 테스트 한 내용을 보면 그냥 Random(1) 으로 같은 시드값을 준 경우엔 random 값이 동일한걸 알 수 있습니다. SystemRandom 에서도 seed 를 '1' 로 동일하게 넣어 주었으나 시드값을 무시하고 각기 다른 랜덤값이 출력되는 걸 볼 수 있습니다. >>> i=[i for i in range(1,20)] >>> i [1, 2, 3, 4, 5,...

[pygame] Cannon 게임프로젝트 7 - 사운드

 게임에서 사운드는 배경음악과 효과음 2가지가 있습니다. 이를 위해 pygame 에선 mixer 라이브러리를 제공합니다. > 사운드 기능을 사용하기 전에 해야 할 일은 초기화 입니다.  pygame.mixer.init 라는 함수가 있어 설정값을 주고 초기화 할 수있지만, 보통은 pygame.init() 를 사용하여 한번에 여러 라이브러리를 초기화 하는게 간단하고 편하기 때문에 보통 초기화는 다음과 같은 방법을 씁니다. pygame.mixer.pre_init(44100,-16,2,512)   pygame.init()    pygame.init() 전에 pre_init 로 초기화시 사용할 초기값을 미리 설정해 주는 것 입니다. 맨 마지막 인수가 buffer 값인데 예전에는 512 로 해 주지 않으면 효과음에 지연이 생겨서 넣어 줬던 것인데 최근 pygame 문서를 보면 기본값이 512 로 바뀌었더군요. 따라서 pre_init 를 해주지 않아도 될지도 모르겠지만 pygame 버전에 따른 차이가 생길 수 있으니 저는 그냥 명시적으로 넣어줍니다.    1. 배경음악 pygame.mixer.music 의 사용법은 간단합니다. pygame.mixer.music.load('bg.ogg') pygame.mixer.music.play() 하면 됩니다. load 함수에 리턴값 없이 그냥 저렇게 쓰면 됩니다. play 함수는 play(3) 처럼 반복 재생회수를 넣어줄 수 있으며 -1 이면 계속 반복 재생합니다. https://www.pygame.org/docs/ref/music.html  그 외에 다른 함수들은 위의 링크를 보면 됩니다. 영어 단어만 봐도 대충 무슨 함수인지 알 수 있습니다. rewind, stop, pause 같은 함수들입니다. 다만 몇가지만 설명해 드리자면....  > pygame.mixer.queue('xxx.ogg')  위의 queue 함수는 지금 재생...

[pygame] Cannon 게임 프로젝트 6 - 총알 발사

 제작로그 6 - 총알 발사, Vector2 클래스의 이용 위 스크린샷은 게임에서 쓰이는 대포의 모습입니다.  대포는 빨간색으로 표시해 놓은곳을 중심으로 좌우로 90도씩 회전하도록 되어 있습니다. 이를 위해서는 2가지를 해결해야 합니다. 첫째는 대포를 중심을 기준으로 회전시켜야 했습니다. 이에 대해선 제 블로그에 pygame 의 회전을 다룬 다른 포스팅이 있는데 그걸 참고 하시면 됩니다. 링크 둘째는 총알을 발사했을때 특정 각도로 총알을 움직여야 하는 것이었습니다. 보통은 이런 경우 삼각함수를 이용해야 할테지만 pygame 에는 Vector2 라는 클래스가 있어서 이걸 이용할 수 있습니다.  다만 저도 아직 Vector2 클래스를 완전히 다 이해한 것은 아닙니다. 대충 보고 제가 필요한 부분만 이용한 것이라 더 간단한 방법이 있을 수 있음을 미리 알려드립니다. > 우선 Vector2 클래스에 대해 간단히 설명하겠습니다. Vector2 클래스는 죄표를 쉽게 다룰 수 있는 클래스 입니다.  예를 들어 (1,1) 에서 (1,100) 으로 공을 계속 1 만큼 이동시키는 건 매우 간단합니다. y 좌표에 계속 1 을 더하면 됩니다.  그런데 (10,10) 에서 (100,200) 으로 공을 1만큼 이동 시키려면 어떻게 해야 할까요? x,y 값에 각각 얼마씩을 더해줘야 할까요? 이걸 Vector2 클래스를 이용하면 별다른 수학적 계산 없이 할 수 있습니다. >>> a = pygame.math.Vector2(10,10) >>> b = pygame.math.Vector2(100,200) >>> c = b - a >>> c <Vector2(90, 190)> >>> d = c.normalize() >>> d <Vector2(0.428086, 0.903738)> 위에 보시면 아시겠지만 Vector 끼리 연산이 가능합니...

[pygame] Cannon 게임 프로젝트 5 - 스프라이트 충돌 체크

 제작로그 5 - 스프라이트 충돌 체크 기본 스프라이트의 충돌체크 방법은 몇가지가 있는데요. 여기서는 mask 방식의 충돌체크만 설명하겠습니다.  사각형과 원 방식의 충돌체크는 충돌을 판단하는 기준만 다를뿐 기본적으로 비슷한 함수를 사용하기 때문에 뒤에 아주 간단히 설명 하겠습니다. > mask 충돌체크를 하기 위해선 기본적으로 이미지를 로딩할때 convert_alpha() 를 사용해야 합니다. robot_image = pygame.image.load('images/robot.png').convert_alpha() 위의 문장과 같이 이미지를 로드해야 합니다.  > 또 한가지 조건은 sprite 클래스에 mask 란 변수를 만들고 mask 데이터를 넣어 줘야 합니다.  class Robot(pygame.sprite.Sprite):     def __init__(self,img,x,y):         super().__init__()         self.image = img    #스프라이트 이미지 surface         self.rect = img.get_rect()  #이미지 rect 구해서 저장         self.rect.center = (x,y)    #캐릭터 위치좌표         self.x = x         self.y = y         self.mask = pyga...

python3 변수를 복사하기

>>> for j in range(10): ...     random.seed() ...     for i in range(6): ...         num.append(random.randint(0,9)) ...     num_col.append(num) ...     num.clear() ... >>> num_col [[], [], [], [], [], [], [], [], [], []] 위의 소스는 랜덤값 6개를 만들어 리스트를 만들고 그 값을 num_col 리스트에 추가 합니다. 하지만 결과는 아무값도 들어가지 않습니다. 왜냐 하면 그 아래 num.clear() 때문입니다.  프로그램을 배우신 분이라면 당연히 아시겠지만....num_col 에는 num 의 값이 들어가는게 아니라 주소값이 들어 가기 때문입니다. > 원하는 결과를 얻는 방법은 2가지가 있습니다.  for j in range(10):     random.seed()     for i in range(6):         num.append(random.randint(0,9))     num_col.append(num)     num=[] 위와 같이 num.clear() 대신 num=[] 같이 새로운 값을 할당해 버리면 됩니다. 그러면 새로운 객체가 생성되고 num 의 주소값이 바뀌기 때문에 저 위와 같은 문제가 없습니다.  > 또 한가지 방법이 copy 명령을 써서 변수를 복사 하는 겁니다.  import random import cop...

[pygame] Cannon 게임 프로젝트 4 - 스프라이트 기본

 제작로그 4 - 스프라이트 기본  스프라이트는 화면에 움직이는 오브젝트들(캐릭터들?) 이라고 생각하면 됩니다. 제가 만드는 게임이라면 총알이라던가 적 캐릭터라던가 하는것들입니다.  pygame 에는 스프라이트 클래스가 준비되어 있고 중요한 기능중 하나는 캐릭터 간의 충돌체크 입니다.  충돌체크는 다음에 다루기로 하고 여기서는 간단히 스프라이트 이용의 기본 내용만 보겠습니다.  import pygame from robot import *   SCREEN_X = 800    #게임창 x 크기 SCREEN_Y = 600    #게임창 y 크기   screen = pygame.display.set_mode((SCREEN_X,SCREEN_Y)) #게임 윈도우 생성 background = pygame.Surface(screen.get_size())        #게임 화면을 그릴 surface pygame.init() #pygame 초기화 robot_image = pygame.image.load('robot.png').convert_alpha() #이미지를 로드하고 변환 robot_image = pygame.transform.scale(robot_image,(40,40)) #이미지의 크기 변환 robot = Robot(robot_image,300,300)    #Robot 스프라이트 객체 생성 done=True   while done:        #이 루프를 벗어나면 게임이 종료됨     ev = pygame.event.get()     for event in ev:         ...

[pygame] Cannon 게임 프로젝트 3 - 텍스트 표시

 제작 로그 3 - 화면에 텍스트 표시  pygame에서 모든 이미지는 surface 에 그려집니다. surface 는 이미지를 그리는 도화지 같은 것이라고 생각하시면 됩니다.  게임이 표시되는 화면도 surface 이고 화면에 표시되는 이미지도 읽어들이면 surface 객체로 생성됩니다.  따라서 텍스트도 surface 로 만들어져서 화면에 표시됩니다. 화면에 텍스트를 표시하기 위해서는... 1. font = pygame.font.SysFont("notosanscjkkr",30) 2. text_start = font.render("게임을 시작하려면 's' 키를 누르세요.",True,(0,255,0)) 3. background.blit(text_start,(150,300)) 위의 3 과정을 거칩니다.  1번은 폰트 객체를 생성하는 것 입니다.  2번은 텍스트가 표시된 Surface 를 만드는 것이고요. 3번은 화면에 표시되는 Surface 에 텍스트 이미지가 들어간 Surface 를 복사해 넣는 것입니다. 이 3번은 이전에 이야기 했던 while 문(게임의 메인루프)에 작성해야 합니다.  각 순서에 대한 자세한 설명은 아래에서 하나씩 하겠습니다. > 1번 폰트객체의 생성방법은 2가지가 있습니다.  첫째는 위와 같이 system 폰트를 이용하는 방법이고요.  두번째는 직접 폰트 파일을 읽어들여서 사용하는 방법입니다.   *시스템 폰트란 OS 에 등록되어 있는 폰트를 말합니다. 이 경우는 등록된 이름만 알면 위의 예처럼 바로 사용할 수 있습니다. 시스템이 등록된 폰트는 pygame 의 font 객체의 get_fonts() 함수로 구할 수 있습니다.  *폰트파일을 직접 읽어들이는 방법은 외부에서 다운받은 ".ttf " 파일을 직접 읽어들여 사용합니다. 이 경우는 게임을 배포한다면 폰트의 라이센스에 주의 해야 합니다.  파일을 실행파일과 같은 디렉토...

blogger 에서 highlight js 사용시 python 의 주석부분 에서의 문제

 제 블로그에 게시하는 소스 코드를 보기 좋게 할 목적으로 highlight js 를 설치 했습니다. 그런데 문제가 있더군요.    보시면 아시겠지만 뭔가 이상합니다. 주석문인 # 이후로 하이라이트 기능이 제대로 동작하지 않고 있습니다. 검색을 해 본 결과 html 태그의 br 때문이라고 합니다. 블로그에 소스를 복사해 넣을때 html 모드에서가 아닌 일반모드에서 복사해 넣으면 줄바꿈인 br 태그가 붙는데 그것 때문에 생기는 문제입니다. 해결 방법은 2가지 인데 .... 1. 소스코드를 붙여 넣을때 html 모드로 전환해서 붙여넣는 방법 2. highlight js 의 설정을 바꾸는 방법 일반 에디트 모드에서 소스코드를 붙여 넣는 방식을 사용하려면 2번째 방법을 써야 합니다. 저는 2번째 방식을 쓰기로 했습니다. 이 경우는 블로그 스킨의 html 소스 수정기능을 이용해서 다음 문장을 추가 해 넣어야 합니다. <script>hljs.configure({useBR: true});</script> 대충 내용은 줄바꿈 태그인 br 을 사용하겠다는 겁니다.  제 경우는 아무래도 일반 에디터 상태에서 편집을 하는게 더 쉬울거 같아서 이 방법을 쓰기로 했습니다.  추가 하는 곳은 highlight js 를 로드하기 전에 넣어주면 됩니다.  <script>hljs.initHighlightingOnLoad();</script> 블로그 스킨 html 소스에서 위의 문장 앞에 복사해 넣으시면 됩니다. 결과는 다음과 같습니다. 하이라이트 기능이 잘 작동되고 있습니다. > 참고로.... 위와 같이 br 태그를 사용하게 설정하면 1번과 같이 html 상태에서 복사해 넣은 소스는 줄바꿈 없이 1줄로 나오기 때문에 두 방법은 공존해서 사용할 수가 없습니다. 한가지를 선택해야 합니다. 

[pygame] Cannon 게임 프로젝트 2 - 기본 구조와 키보드, 마우스 처리

 제작로그 2 - pygame 의 기본구조  import pygame   SCREEN_X = 800    #게임창 x 크기 SCREEN_Y = 600    #게임창 y 크기   screen = pygame.display.set_mode((SCREEN_X,SCREEN_Y)) #게임 윈도우 생성 background = pygame.Surface(screen.get_size())        #게임 화면을 그릴 surface   done=True   while done:        #이 루프를 벗어나면 게임이 종료됨     ev = pygame.event.get()     for event in ev:         if event.type ==pygame.QUIT:     #창의 종료버튼이 눌렸을때 게임종료             done = False              if event.type == pygame.MOUSEBUTTONUP:             pass         if event.type == pygame.MOUSEMOTION:    #마우스를 움직이고 있음   ...

[pygame] Cannon 게임 프로젝트 1 - 프롤로그

제작로그 1 - 프롤로그  예전 부터 pygame 을 한번 사용해 보고 싶었습니다만...여러 이유로 진행이 안됐었는데 이번에 천천히 진행해 보고 있습니다.     현재 대략 진행중인 상태입니다.  이 게임은 예전에 제가 8비트 Apple 컴퓨터를 구입했을때 받은 디스켓에 들어있던 게임 중 하나였는데 오래되서 정확히 기억은 안나지만 대충 기억을 되살려 비슷하게 만들어 보았습니다. 게임의 규칙은 매우 간단해서 낙하산을 타고 내려오는 적들(제 경우는 로봇군단으로 설정)을 아래의 무기(대포)로 땅에 내려오기 전에 맞추면 되는 게임입니다.  모두 4기의 로봇이 땅에 착지하면 대포는 폭파되어 게임이 끝나고요. 대포가 있는 저 사각형 위는 한대라도 착지 하면 게임은 끝납니다. 대략적인 구현은 끝난 상태인데요. 제가 pygame 을 처음 다뤄보고, 원래 pygame 을 완전히 파악하고 진행하는게 아니라 공부 겸 해서 진행하는 프로젝트였고 그러다 보니 처음부터 치밀하게 구상해서 코딩을 하지 않았기 때문에 소스가 전혀 정리가 안되는 상태고 맘에 안듭니다만 기록을 남겨두지 않으면 또 까맣게 잊어버릴게 분명하기에 간단히 정리해 기록해 둘 생각입니다.  다음에는 조금 나아 지겠죠. 아마도요....ㅎㅎ  현재 로봇이나 대포의 폭파 표현등을 어떻게 할지를 고민중입니다. 이런 연출(?)은 해본적이 없어서....사운드도 좀 넣어야 되고....

pygame 에서 이미지 회전하는 방법

 pygame 에서 transform.rotate 를 사용해서 이미지를 회전시켜 보면 생각과는 달리 요상하게 회전합니다.    따라서 이를 해결해 보고자 검색해 보다 다음 링크를 찾았습니다. https://stackoverflow.com/questions/4183208/how-do-i-rotate-an-image-around-its-center-using-pygame/54714144 위 링크를 보면 파이게임의 이미지 회전이 왜 그렇게 이상한지 알 수 있고 답변하신 분이 blitRotate 라는 함수를 만들어 놓아서 이용할 수 있습니다.  제 소스에 가져와서 테스트를 해 봤는데 제 생각대로 회전 하더군요.  def blitRotate(image, pos, originPos, angle):       #calcaulate the axis aligned bounding box of the rotated image     w, h       = image.get_size()     box        = [pygame.math.Vector2(p) for p in [(0, 0), (w, 0), (w, -h), (0, -h)]]     box_rotate = [p.rotate(angle) for p in box]     min_box    = (min(box_rotate, key=lambda p: p[0])[0], min(box_rotate, key=lambda p: p[1])[1])     max_box    = (max(box_rotate, key=lambda p: p[0])[0], max...

파이썬에서 자료형을 파일로 저장하기

리스트,  튜플, 딕셔너리 같은 자료형을 파일로 저장하는 방법을 적어 보겠습니다. 예전에는 pickle 이라는 것도 썼었지만 지금은 다른 방법을 권하더군요. 그중 json 을 사용하는 방법을 적어 볼까 합니다. 간단히 대화형 인터프리터를 이용해서 사용해 보겠습니다. >>> i = [2,4,6,8,10] >>> i [2, 4, 6, 8, 10] >>> import json >>> with open('list.json','w') as f: ...     json.dump(i,f) >>> i=[] >>> i [] >>> with open('list.json','r') as f: ...     i=json.load(f) ... >>> i [2, 4, 6, 8, 10]  간단히 리스트 i 에 값을 넣고 json 을 이용해 list.json 파일로 기록한 다음 변수를 초기화 하고 저장된 파일을 읽어들이는 예제 입니다.  자료형을 매우 간단히 파일로 저장할 수 있습니다. 실제 파일을 텍스트 에디터로 읽어보면  [2, 4, 6, 8, 10] 위와 같이 기록되어 있습니다. > 딕셔너리도 위와 똑같이 사용가능합니다.  >>> i={'ip':'192.168.100.50','port':'6790'} >>> i {'ip': '192.168.100.50', 'port': '6790'} >>> import json >>> with open('dict.json','w') as f: ...     json.dump(i,f) >>> i=[] >>> i [] >...

파이썬에서 랜덤값 사용방법

random은  파이썬에서 랜덤한 숫자를 얻기 위해 사용하는 모듈입니다. 간단히 사용법을 정리해 봤습니다. 1. random.seed() 컴퓨터에서 생성하는 랜덤값은 엄밀히 말하면 완전 랜덤은 아닙니다. 계산식에 의해서 만드는 유사 랜덤 값입니다. 따라서 seed 에 들어가는 숫자가 동일하면 나오는 랜덤 값도 동일합니다.  별도로 파이썬에선 위 명령을 주지 않아도 import 될때 현재 시간이 seed 가 되어서 적용되지만 원한다면 명시적으로 seed 를 호출할 수 있습니다. seed 에 원하는 숫자를 인자로 사용할 수 있으며 만일 위처럼 인자를 넣지 않을 경우 seed 는 현재시간을 사용합니다. 2. random.random()       0.0 <= x < 1.0 사이의 값을 출력합니다. 3. random.uniform(a.4, b.7)      a.4 <= x < b.7  사이의 값을 출력합니다. 4. random.randrange(b)      0 <= x < b 사이의 정수를 출력합니다. 5. random.randrange(a,b)      a <= x < b  사이의 정수를 출력합니다. 6. random.randint(a,b)      a <= x <= b  사이의 정수를 출력합니다. >>> import random >>> random.random() 0.3594656143224264 >>> random.uniform(3.5,4.2) 3.6876359136188914 >>> random.randrange(8,10) 8 >>> random.randint(5,10) 6   위와 같이 사...

파이썬에서 print 문 사용형식 정리

 파이썬에서 문자 출력 방법에 대해 정리해 보겠습니다. 다른 언어 쓰다가 쓰려면 매번 헷갈려서... 가장 최근에 새로 생긴 문법부터 소개 하겠습니다. 대화형 인터프리터 환경에서 간단히 확인 가능합니다. > >>> x=1 >>> y=5 >>> print(f"x+y={x+y}") x+y=6 >>>print(f"x={x}") x=1  문자열 앞에 f 를 넣고 프린트 할 변수를 {} 안에 넣으면 되는 무척 간단한 문법입니다 > >>> print("x = %d, y = %d" % (x,y)) x = 1, y = 5   예전 C 언어등에서 사용했던 방식과 비슷한 방식 입니다.  > >>> print("x={0}, y={1}".format(x,y)) x=1, y=5 >>> print("x={}, y={}".format(x,y)) x=1, y=5 format 문을 이용하는 방법입니다. 괄호({}) 안에 숫자로 format 문의 첫번째 인자, 두번째 인자등을 선택합니다. 숫자없이 괄호만 쓸 경우 차례대로 대입됩니다. >  >>> print("a","b","c","d") a b c d >>> print("a","b","c","d",sep=',') a,b,c,d print 문에서 ',' 로 여러문자를 print 하면 빈칸으로 구분되는데 이를 다른 문자로 바꾸는 방법입니다. 여기서는 보이는것 처럼 ',' 로 바꿔봤습니다. > print(x,end=',') print(y) 파이썬에서 print 문은 인쇄하고 줄바꿈을 합니다. 만일...

tkinter 콤보박스 간단사용예

 tkinter 의 간단한 콤보박스 사용예입니다.  콤보박스에서 컬러를 선택하면 그 아래 Label 의 배경색이 변합니다.  그 아래 Progressbar 는 그냥 심심해서(?) 넣어 본것 입니다. indeterminate 모드로 넣은 것인데 indeterminate 모드는 정확한 진행정도를 나타내는게 아니라 그냥 진행중이라는걸 표시하는 것입니다. 진행바가 그냥 좌우로 움직이기만 합니다.  from tkinter import * from tkinter.ttk import * from tkinter.messagebox import *   class Application(Frame):     def __init__(self, master=None):         super().__init__(master)         self.master = master         self.pack(side="top")         self.create_widgets()       def create_widgets(self):         self.cb = Combobox(width=10,value=['white','blue','yellow','black','red'])         self.cb.current(0)         self.cb.bind("<<ComboboxSelected>>", self.chan...

파이썬(Python) 온라인 이북

 파이썬을 공부하기 좋은 온라인 책입니다.  https://wikidocs.net/book/1 점프 투 파이썬 이라는 책으로 오프라인으로도 판매되고 있고요.  ebook 을 주문하실 수도 있으며, 온라인으로 그냥 보실 수도 있습니다.  제 경우는 예전에 오프라인으로 구입했었는데 그 당시 책은 2.x 기반이었고 온라인에서도 2.x 기반이었지만 최근에는 3.x 버전이 나온 지 오래 되었기 때문에 위 강좌 내용도 3.x 기반으로 완전히 개편되어 있습니다. 저 사이트 wikidocs 에는 위 책 말고도 여러 무료 서적이 있으니 한번 확인해 보시면 도움이 되실 겁니다. 

tkinter 기본 위젯 사용예

  그냥 tkinter 가 어떻게 쓰이는지 기본적인 작동을 하도록 만들어 본 것 입니다. 기본 골격은 파이썬 도큐먼트에 있는 예제 소스에서 가져왔고 거기에 살을 좀 붙였습니다. 가장 많이 쓰는 Label 과 버튼, 에디트 컨트롤의 기본적인 사용예 입니다. import tkinter as tk from tkinter import ttk from tkinter import messagebox class Application(ttk.Frame):     def __init__(self, master=None):         super().__init__(master)         self.master = master         self.pack(side="top")         self.create_widgets()     def create_widgets(self):         style = ttk.Style()        #style 설정         style.configure("BW.TLabel", foreground="black", background="white")                  self.l1 = ttk.Label(text = "Label1", style = "BW.TLabel")    ...