Whack-a-mole python programming instructions, the simplest code for whack-a-mole in python

This article mainly introduces the python programming instructions for whack-a-mole, which has certain reference value. Friends in need can refer to it. I hope you will gain a lot after reading this article. Let the editor take you to understand it together.

Pygame library is an open source module of the Python programming language specifically designed to help make games and other multimedia applications PHP vs. PYTHON: Detailed comparison based on syntax, functionality, applications, etc. This article will use the Pygame module to create a small game of whack-a-mole. Come and learn with the editor. Click to get programming learning materials for free

Preface

Today I will write a mini game of whack-a-mole for everyone. Let’s get started without further ado~

development tools

Python version: 3.6.4

Related modules:

pygame module;

And some modules that come with Python.

Environment build

Install Python and add it to the environment variables, and pip to install the required relevant modules.

Principle introduction

I believe everyone knows the rules of the game of whack-a-mole, so I won’t go into details here. Anyway, it’s just a mole that keeps digging holes with a hammer~

First, let's identify what elements are in the game. To play whack-a-mole, of course there must be a mole, so let’s write a game elf class for the mole:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

'''地鼠'''

class Mole(pygame.sprite.Sprite):

    def __init__(self, image_paths, position, **kwargs):

        pygame.sprite.Sprite.__init__(self)

        self.images = [pygame.transform.scale(pygame.image.load(image_paths[0]), (101, 103)),

                       pygame.transform.scale(pygame.image.load(image_paths[-1]), (101, 103))]

        self.image = self.images[0]

        self.rect = self.image.get_rect()

        self.mask = pygame.mask.from_surface(self.image)

        self.setPosition(position)

        self.is_hammer = False

    '''设置位置'''

    def setPosition(self, pos):

        self.rect.left, self.rect.top = pos

    '''设置被击中'''

    def setBeHammered(self):

        self.is_hammer = True

    '''显示在屏幕上'''

    def draw(self, screen):

        if self.is_hammer: self.image = self.images[1]

        screen.blit(self.image, self.rect)

    '''重置'''

    def reset(self):

        self.image = self.images[0]

        self.is_hammer = False

Obviously, the mole has two states: being hit by the hammer and not being hit by the hammer, so two pictures need to be loaded. When the mole is hit, the state diagram of the mole that has not been hit is switched to the state diagram of the mole after being hit. Gopher status chart (ps: the picture may not look like a gopher).

Then let's define the game elf class of hammer. Similar to the gopher, the hammer also has two states: unhammered and hammered. However, after hammering, it needs to quickly return to the unhammered state. Specifically, the code implementation as follows:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

class Hammer(pygame.sprite.Sprite):

    def __init__(self, image_paths, position, **kwargs):

        pygame.sprite.Sprite.__init__(self)

        self.images = [pygame.image.load(image_paths[0]), pygame.image.load(image_paths[1])]

        self.image = self.images[0]

        self.rect = self.image.get_rect()

        self.mask = pygame.mask.from_surface(self.images[1])

        self.rect.left, self.rect.top = position

        # 用于显示锤击时的特效

        self.hammer_count = 0

        self.hammer_last_time = 4

        self.is_hammering = False

    '''设置位置'''

    def setPosition(self, pos):

        self.rect.centerx, self.rect.centery = pos

    '''设置hammering'''

    def setHammering(self):

        self.is_hammering = True

    '''显示在屏幕上'''

    def draw(self, screen):

        if self.is_hammering:

            self.image = self.images[1]

            self.hammer_count += 1

            if self.hammer_count > self.hammer_last_time:

                self.is_hammering = False

                self.hammer_count = 0

        else:

            self.image = self.images[0]

        screen.blit(self.image, self.rect)

OK, after defining the game wizard, we can start writing the main program. The first thing is to initialize the game:

1

2

3

4

5

6

7

'''游戏初始化'''

def initGame():

  pygame.init()

  pygame.mixer.init()

  screen = pygame.display.set_mode(cfg.SCREENSIZE)

  pygame.display.set_caption('Whac A Mole-微信公众号:Charles的皮卡丘')

  return screen

Then load the necessary game materials and define the necessary game variables

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

# 加载背景音乐和其他音效

pygame.mixer.music.load(cfg.BGM_PATH)

pygame.mixer.music.play(-1)

audios = {

      'count_down': pygame.mixer.Sound(cfg.COUNT_DOWN_SOUND_PATH),

      'hammering': pygame.mixer.Sound(cfg.HAMMERING_SOUND_PATH)

    }

# 加载字体

font = pygame.font.Font(cfg.FONT_PATH, 40)

# 加载背景图片

bg_img = pygame.image.load(cfg.GAME_BG_IMAGEPATH)

# 开始界面

startInterface(screen, cfg.GAME_BEGIN_IMAGEPATHS)

# 地鼠改变位置的计时

hole_pos = random.choice(cfg.HOLE_POSITIONS)

change_hole_event = pygame.USEREVENT

pygame.time.set_timer(change_hole_event, 800)

# 地鼠

mole = Mole(cfg.MOLE_IMAGEPATHS, hole_pos)

# 锤子

hammer = Hammer(cfg.HAMMER_IMAGEPATHS, (500, 250))

# 时钟

clock = pygame.time.Clock()

# 分数

your_score = 0

Then comes the main game loop:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

# 游戏主循环

while True:

  # --游戏时间为60s

  time_remain = round((61000 - pygame.time.get_ticks()) / 1000.)

  # --游戏时间减少, 地鼠变位置速度变快

  if time_remain == 40:

    pygame.time.set_timer(change_hole_event, 650)

  elif time_remain == 20:

    pygame.time.set_timer(change_hole_event, 500)

  # --倒计时音效

  if time_remain == 10:

    audios['count_down'].play()

  # --游戏结束

  if time_remain < 0: break

  count_down_text = font.render('Time: '+str(time_remain), True, cfg.WHITE)

  # --按键检测

  for event in pygame.event.get():

    if event.type == pygame.QUIT:

      pygame.quit()

      sys.exit()

    elif event.type == pygame.MOUSEMOTION:

      hammer.setPosition(pygame.mouse.get_pos())

    elif event.type == pygame.MOUSEBUTTONDOWN:

      if event.button == 1:

        hammer.setHammering()

    elif event.type == change_hole_event:

      hole_pos = random.choice(cfg.HOLE_POSITIONS)

      mole.reset()

      mole.setPosition(hole_pos)

  # --碰撞检测

  if hammer.is_hammering and not mole.is_hammer:

    is_hammer = pygame.sprite.collide_mask(hammer, mole)

    if is_hammer:

      audios['hammering'].play()

      mole.setBeHammered()

      your_score += 10

  # --分数

  your_score_text = font.render('Score: '+str(your_score), True, cfg.BROWN)

  # --绑定必要的游戏元素到屏幕(注意顺序)

  screen.blit(bg_img, (0, 0))

  screen.blit(count_down_text, (875, 8))

  screen.blit(your_score_text, (800, 430))

  mole.draw(screen)

  hammer.draw(screen)

  # --更新

  pygame.display.flip()

  clock.tick(60)

I have also commented on each part. The logic is very simple, so I won’t go into too much nonsense. After 60 seconds, the game is over, and we can count the scores and compare them with the highest score in history:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

# 读取最佳分数(try块避免第一次游戏无.rec文件)

try:

  best_score = int(open(cfg.RECORD_PATH).read())

except:

  best_score = 0

# 若当前分数大于最佳分数则更新最佳分数

if your_score > best_score:

  f = open(cfg.RECORD_PATH, 'w')

  f.write(str(your_score))

  f.close()

为了使游戏看起来更“正式”,再随手添个开始界面和结束界面呗:

'''游戏开始界面'''

def startInterface(screen, begin_image_paths):

    begin_images = [pygame.image.load(begin_image_paths[0]), pygame.image.load(begin_image_paths[1])]

    begin_image = begin_images[0]

    while True:

        for event in pygame.event.get():

            if event.type == pygame.QUIT:

                pygame.quit()

                sys.exit()

            elif event.type == pygame.MOUSEMOTION:

                mouse_pos = pygame.mouse.get_pos()

                if mouse_pos[0] in list(range(419, 574)) and mouse_pos[1] in list(range(374, 416)):

                    begin_image = begin_images[1]

                else:

                    begin_image = begin_images[0]

            elif event.type == pygame.MOUSEBUTTONDOWN:

                if event.button == 1 and mouse_pos[0] in list(range(419, 574)) and mouse_pos[1] in list(range(374, 416)):

                    return True

        screen.blit(begin_image, (0, 0))

        pygame.display.update()

'''结束界面'''

def endInterface(screen, end_image_path, again_image_paths, score_info, font_path, font_colors, screensize):

    end_image = pygame.image.load(end_image_path)

    again_images = [pygame.image.load(again_image_paths[0]), pygame.image.load(again_image_paths[1])]

    again_image = again_images[0]

    font = pygame.font.Font(font_path, 50)

    your_score_text = font.render('Your Score: %s' % score_info['your_score'], True, font_colors[0])

    your_score_rect = your_score_text.get_rect()

    your_score_rect.left, your_score_rect.top = (screensize[0] - your_score_rect.width) / 2, 215

    best_score_text = font.render('Best Score: %s' % score_info['best_score'], True, font_colors[1])

    best_score_rect = best_score_text.get_rect()

    best_score_rect.left, best_score_rect.top = (screensize[0] - best_score_rect.width) / 2, 275

    while True:

        for event in pygame.event.get():

            if event.type == pygame.QUIT:

                pygame.quit()

                sys.exit()

            elif event.type == pygame.MOUSEMOTION:

                mouse_pos = pygame.mouse.get_pos()

                if mouse_pos[0] in list(range(419, 574)) and mouse_pos[1] in list(range(374, 416)):

                    again_image = again_images[1]

                else:

                    again_image = again_images[0]

            elif event.type == pygame.MOUSEBUTTONDOWN:

                if event.button == 1 and mouse_pos[0] in list(range(419, 574)) and mouse_pos[1] in list(range(374, 416)):

                    return True

        screen.blit(end_image, (0, 0))

        screen.blit(again_image, (416, 370))

        screen.blit(your_score_text, your_score_rect)

        screen.blit(best_score_text, best_score_rect)

        pygame.display.update()

This concludes this article about the actual Whac-A-Mole game in Python Pygame.

Guess you like

Origin blog.csdn.net/i_like_cpp/article/details/132163851