-
[내배캠] Python으로 오락실 게임만들기 ft.나도코딩, pygame내일배움캠프/과제 2022. 8. 9. 23:18
제가 사용한 이미지들입니다.
기존 강의인 공 부쉬기 게임에 이미지와 약간의 기능을 추가하였습니다.
변경 사항 및 추가 기능
- 이미지 변경
- 점프 기능
- 방향에 따른 이미지 변경
- 필살기, 횟수 설정
- 필살기 횟수 표시
import pygame import os ###################################################################### pygame.init() # 반드시 필요 초기화 작업 # screen size screen_width = 640 screen_height = 480 screen = pygame.display.set_mode((screen_width,screen_height)) #title pygame.display.set_caption('Save the earth Son') #FPS clock = pygame.time.Clock() ##################################################################### # 1. 사용자 게임 초기화 (배경화면, 게임 이미지, 케릭터 좌표, FPS속도, 폰트 등) current_path = os.path.dirname(__file__) image_path = os.path.join(current_path, "images") background = pygame.image.load(os.path.join(image_path, 'background.png')) # character create character = pygame.image.load(os.path.join(image_path, 'character.png')) character_size = character.get_rect().size character_width = character_size[0] character_height = character_size[1] character_x_pos = screen_width//2 - character_width//2 character_y_pos = screen_height - character_height # 얼마나 움직일지 변수 설정 x_to = 0 y_to = 0 foot = 5 #무기 생성 weapon = pygame.image.load(os.path.join(image_path, 'weapon.png')) weapon_size = weapon.get_rect().size weapon_width = weapon_size[0] # 여러개의 무기가 들어올 것이기에 리스트로 무기 각각의 위치를 받을 예정 weapons = [] weapon_speed = 10 #원기옥 필살기 유무와 횟수, 속도 one_exis = False one_cnt = 1 one_speed = 20 #원기옥 생성 one = pygame.image.load(os.path.join(image_path, 'one2.png')) one_size = weapon.get_rect().size one_width = one_size[0] one_height = one_size[1] #볼 이미지 ball_images = [ pygame.image.load(os.path.join(image_path, 'ball1.png')), pygame.image.load(os.path.join(image_path, 'ball2.png')), pygame.image.load(os.path.join(image_path, 'ball3.png')), pygame.image.load(os.path.join(image_path, 'ball4.png')) ] #볼 크기에 따른 속도 ball_speed_y = [-18, -15, -12, -9] #여러개의 볼이 들어올 것 balls = [] #초기 공 1개 삽입 balls.append({ "pos_x" : 50, "pos_y" : 50, "img_idx" : 0, "to_x" : 3, "to_y" : -6, "init_spd_y" : ball_speed_y[0] }) # 공과 무기의 충돌시 인덱스 초기값 -1 weapon_to_remove = -1 ball_to_remove = -1 # 게임 폰트 game_font = pygame.font.Font(None, 40) #게임시간 설정과 현재 틱(시간) total_time = 100 start_ticks = pygame.time.get_ticks() # 게임 결과 (실패, 완료, 타임오버) game_result = 'Game Over' running = True while running: dt = clock.tick(60) # 2. 이벤트 처리 (키보드, 마우스 등) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: character = pygame.image.load(os.path.join(image_path, 'character.png')) x_to -= foot if event.key == pygame.K_RIGHT: character = pygame.image.load(os.path.join(image_path, 'character2.png')) x_to += foot if event.key == pygame.K_SPACE: weapon_x_pos = character_x_pos + character_width//2 - weapon_width//2 weapon_y_pos = character_y_pos #쏠 때마다 무기의 위치 값 삽입 weapons.append([weapon_x_pos,weapon_y_pos]) if event.key == pygame.K_UP: #바닥에서 50내의 위치에선 점프 가능하게 설정 if character_y_pos > screen_height - character_height - 50 : y_to = 10 #필살기의 횟수 존재 시 사용가능하게 설정 if event.key == pygame.K_DOWN: if one_cnt > 0: one_exis = True character = pygame.image.load(os.path.join(image_path, 'character3.png')) one_cnt -= 1 one_x_pos = character_x_pos + character_width//2 - one_width//2 one_y_pos = 0 if event.type == pygame.KEYUP: if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: x_to = 0 # 3. 캐리터 위치 정의 character_x_pos += x_to character_y_pos -= y_to if character_y_pos < screen_height - character_height * 4: y_to = -3 if character_x_pos < 0: character_x_pos = 0 elif character_x_pos > screen_width - character_width: character_x_pos = screen_width - character_width if character_y_pos > screen_height - character_height: character_y_pos = screen_height - character_height weapons = [[w[0], w[1] - weapon_speed ] for w in weapons] weapons = [[w[0], w[1]] for w in weapons if w[1] > 0 ] #공이 볼 리스트에 있으면 반복문을 돌것(초기에 큰 공 하나 삽입함) for ball_idx, ball_val in enumerate(balls): #현재 공의 위치 ball_pos_x = ball_val["pos_x"] ball_pos_y = ball_val["pos_y"] #이미지에 따라 크기가 달라지므로 구해줘야함 ball_img_idx = ball_val["img_idx"] ball_size = ball_images[ball_img_idx].get_rect().size ball_width = ball_size[0] ball_height = ball_size[1] #이미지가 벽에 닿으면 방향을 바꿔줌 if ball_pos_x < 0 or ball_pos_x > screen_width - ball_width: ball_val['to_x'] *= -1 #공이 바닥에 닿으면 해당공의 속도로 변경 if ball_pos_y > screen_height-ball_height: ball_val["to_y"] = ball_val["init_spd_y"] else: ball_val['to_y'] += 0.5 ball_val["pos_x"] += ball_val["to_x"] ball_val["pos_y"] += ball_val["to_y"] # 4. 충돌 처리 character_rect = character.get_rect() character_rect.left = character_x_pos character_rect.top = character_y_pos for ball_idx, ball_val in enumerate(balls): ball_pos_x = ball_val["pos_x"] ball_pos_y = ball_val["pos_y"] ball_img_idx = ball_val["img_idx"] ball_rect = ball_images[ball_img_idx].get_rect() ball_rect.left = ball_pos_x ball_rect.top = ball_pos_y if character_rect.colliderect(ball_rect): running = False break if one_exis: one_rect = one.get_rect() one_rect.left = one_x_pos one_rect.top = one_y_pos if one_rect.colliderect(ball_rect): ball_to_remove = ball_idx if ball_img_idx < 3: ball_width = ball_rect.size[0] ball_height = ball_rect.size[1] small_ball_rect = ball_images[ball_img_idx + 1].get_rect() small_ball_width = small_ball_rect.size[0] small_ball_height = small_ball_rect.size[1] balls.append({ "pos_x" : ball_pos_x + (ball_width/2) - (small_ball_width/2), "pos_y" : ball_pos_y + (ball_height/2) - (small_ball_height/2), "img_idx" : ball_img_idx + 1, "to_x" : -3, "to_y" : -6, "init_spd_y" : ball_speed_y[ball_img_idx + 1] }) balls.append({ "pos_x" : ball_pos_x + (ball_width/2) - (small_ball_width/2), "pos_y" : ball_pos_y + (ball_height/2) - (small_ball_height/2), "img_idx" : ball_img_idx + 1, "to_x" : 3 , "to_y" : -6, "init_spd_y" : ball_speed_y[ball_img_idx + 1] }) break for weapon_idx, weapon_val in enumerate(weapons): weapon_pos_x = weapon_val[0] weapon_pos_y = weapon_val[1] weapon_rect = weapon.get_rect() weapon_rect.left = weapon_pos_x weapon_rect.top = weapon_pos_y if weapon_rect.colliderect(ball_rect): weapon_to_remove = weapon_idx ball_to_remove = ball_idx if ball_img_idx < 3: ball_width = ball_rect.size[0] ball_height = ball_rect.size[1] small_ball_rect = ball_images[ball_img_idx + 1].get_rect() small_ball_width = small_ball_rect.size[0] small_ball_height = small_ball_rect.size[1] balls.append({ "pos_x" : ball_pos_x + (ball_width/2) - (small_ball_width/2), "pos_y" : ball_pos_y + (ball_height/2) - (small_ball_height/2), "img_idx" : ball_img_idx + 1, "to_x" : -3, "to_y" : -6, "init_spd_y" : ball_speed_y[ball_img_idx + 1] }) balls.append({ "pos_x" : ball_pos_x + (ball_width/2) - (small_ball_width/2), "pos_y" : ball_pos_y + (ball_height/2) - (small_ball_height/2), "img_idx" : ball_img_idx + 1, "to_x" : 3 , "to_y" : -6, "init_spd_y" : ball_speed_y[ball_img_idx + 1] }) break else: continue break if ball_to_remove > -1: del balls[ball_to_remove] ball_to_remove = -1 if weapon_to_remove > -1: del weapons[weapon_to_remove] weapon_to_remove = -1 if len(balls) == 0: game_result = 'Mission Complete' running = False # 5. 화면에 그리기 screen.blit(background, (0,0)) for weapon_x_pos, weapon_y_pos in weapons: screen.blit(weapon, (weapon_x_pos, weapon_y_pos)) if one_exis: screen.blit(one, (one_x_pos, one_y_pos)) one_x_pos -= 5 one_y_pos += 5 for idx, val in enumerate(balls): ball_pos_x = val['pos_x'] ball_pos_y = val['pos_y'] ball_img_idx = val['img_idx'] screen.blit(ball_images[ball_img_idx], (ball_pos_x, ball_pos_y)) screen.blit(character, (character_x_pos, character_y_pos)) elapsed_time = (pygame.time.get_ticks() - start_ticks)/1000 timer = game_font.render("Time : {}".format(int(total_time - elapsed_time)), True, (255,255,255 )) chance = game_font.render("Chance : {}".format(one_cnt), True, (255,255,255 )) screen.blit(timer, (10,10)) screen.blit(chance, (10,60)) if total_time - elapsed_time< 0: game_result = 'Time Over' running = False pygame.display.update() msg = game_font.render(game_result, True, (255,255,0)) msg_rect = msg.get_rect(center = (int(screen_height / 2) , int(screen_height / 2))) screen.blit(msg, msg_rect) pygame.display.update() # redraw screen pygame.time.delay(2000) pygame.quit()
출처.
https://www.youtube.com/watch?v=Dkx8Pl6QKW0
'내일배움캠프 > 과제' 카테고리의 다른 글
[내배캠] 사전과제 왕초보 3주차 개발일지 (0) 2022.08.15 [내배캠] 사전과제 왕초보 2주차 개발일지 (0) 2022.08.12 [내배캠] 사전과제 왕초보 1주차 개발일지 (0) 2022.08.11 [내배캠] Python으로 기억력 테스트 게임 만들기 ft.나도코딩, pygame (0) 2022.08.10 [내배캠] tkinter 모듈을 통한 계산기 만들기(Python) (0) 2022.08.08