网络编程
位置:首页>> 网络编程>> Python编程>> 基于Python实现经典植物大战僵尸游戏

基于Python实现经典植物大战僵尸游戏

作者:梦执.py  发布时间:2021-01-28 11:17:20 

标签:Python,植物大战僵尸,游戏

游戏截图

基于Python实现经典植物大战僵尸游戏

基于Python实现经典植物大战僵尸游戏

基于Python实现经典植物大战僵尸游戏

动态演示

基于Python实现经典植物大战僵尸游戏

源码分享

state/tool.py

import os
import json
from abc import abstractmethod
import pygame as pg
from . import constants as c

class State():
   def __init__(self):
       self.start_time = 0.0
       self.current_time = 0.0
       self.done = False
       self.next = None
       self.persist = {}

@abstractmethod
   def startup(self, current_time, persist):
       '''abstract method'''

def cleanup(self):
       self.done = False
       return self.persist

@abstractmethod
   def update(self, surface, keys, current_time):
       '''abstract method'''

class Control():
   def __init__(self):
       self.screen = pg.display.get_surface()
       self.done = False
       self.clock = pg.time.Clock()
       self.fps = 60
       self.keys = pg.key.get_pressed()
       self.mouse_pos = None
       self.mouse_click = [False, False]  # value:[left mouse click, right mouse click]
       self.current_time = 0.0
       self.state_dict = {}
       self.state_name = None
       self.state = None
       self.game_info = {c.CURRENT_TIME:0.0,
                         c.LEVEL_NUM:c.START_LEVEL_NUM}

def setup_states(self, state_dict, start_state):
       self.state_dict = state_dict
       self.state_name = start_state
       self.state = self.state_dict[self.state_name]
       self.state.startup(self.current_time, self.game_info)

def update(self):
       self.current_time = pg.time.get_ticks()
       if self.state.done:
           self.flip_state()
       self.state.update(self.screen, self.current_time, self.mouse_pos, self.mouse_click)
       self.mouse_pos = None
       self.mouse_click[0] = False
       self.mouse_click[1] = False

def flip_state(self):
       previous, self.state_name = self.state_name, self.state.next
       persist = self.state.cleanup()
       self.state = self.state_dict[self.state_name]
       self.state.startup(self.current_time, persist)

def event_loop(self):
       for event in pg.event.get():
           if event.type == pg.QUIT:
               self.done = True
           elif event.type == pg.KEYDOWN:
               self.keys = pg.key.get_pressed()
           elif event.type == pg.KEYUP:
               self.keys = pg.key.get_pressed()
           elif event.type == pg.MOUSEBUTTONDOWN:
               self.mouse_pos = pg.mouse.get_pos()
               self.mouse_click[0], _, self.mouse_click[1] = pg.mouse.get_pressed()
               print('pos:', self.mouse_pos, ' mouse:', self.mouse_click)

def main(self):
       while not self.done:
           self.event_loop()
           self.update()
           pg.display.update()
           self.clock.tick(self.fps)
       print('game over')

def get_image(sheet, x, y, width, height, colorkey=c.BLACK, scale=1):
       image = pg.Surface([width, height])
       rect = image.get_rect()

image.blit(sheet, (0, 0), (x, y, width, height))
       image.set_colorkey(colorkey)
       image = pg.transform.scale(image,
                                  (int(rect.width*scale),
                                   int(rect.height*scale)))
       return image

def load_image_frames(directory, image_name, colorkey, accept):
   frame_list = []
   tmp = {}
   # image_name is "Peashooter", pic name is 'Peashooter_1', get the index 1
   index_start = len(image_name) + 1
   frame_num = 0;
   for pic in os.listdir(directory):
       name, ext = os.path.splitext(pic)
       if ext.lower() in accept:
           index = int(name[index_start:])
           img = pg.image.load(os.path.join(directory, pic))
           if img.get_alpha():
               img = img.convert_alpha()
           else:
               img = img.convert()
               img.set_colorkey(colorkey)
           tmp[index]= img
           frame_num += 1

for i in range(frame_num):
       frame_list.append(tmp[i])
   return frame_list

def load_all_gfx(directory, colorkey=c.WHITE, accept=('.png', '.jpg', '.bmp', '.gif')):
   graphics = {}
   for name1 in os.listdir(directory):
       # subfolders under the folder resources\graphics
       dir1 = os.path.join(directory, name1)
       if os.path.isdir(dir1):
           for name2 in os.listdir(dir1):
               dir2 = os.path.join(dir1, name2)
               if os.path.isdir(dir2):
               # e.g. subfolders under the folder resources\graphics\Zombies
                   for name3 in os.listdir(dir2):
                       dir3 = os.path.join(dir2, name3)
                       # e.g. subfolders or pics under the folder resources\graphics\Zombies\ConeheadZombie
                       if os.path.isdir(dir3):
                           # e.g. it's the folder resources\graphics\Zombies\ConeheadZombie\ConeheadZombieAttack
                           image_name, _ = os.path.splitext(name3)
                           graphics[image_name] = load_image_frames(dir3, image_name, colorkey, accept)
                       else:
                           # e.g. pics under the folder resources\graphics\Plants\Peashooter
                           image_name, _ = os.path.splitext(name2)
                           graphics[image_name] = load_image_frames(dir2, image_name, colorkey, accept)
                           break
               else:
               # e.g. pics under the folder resources\graphics\Screen
                   name, ext = os.path.splitext(name2)
                   if ext.lower() in accept:
                       img = pg.image.load(dir2)
                       if img.get_alpha():
                           img = img.convert_alpha()
                       else:
                           img = img.convert()
                           img.set_colorkey(colorkey)
                       graphics[name] = img
   return graphics

def loadZombieImageRect():
   file_path = os.path.join('source', 'data', 'entity', 'zombie.json')
   f = open(file_path)
   data = json.load(f)
   f.close()
   return data[c.ZOMBIE_IMAGE_RECT]

def loadPlantImageRect():
   file_path = os.path.join('source', 'data', 'entity', 'plant.json')
   f = open(file_path)
   data = json.load(f)
   f.close()
   return data[c.PLANT_IMAGE_RECT]

pg.init()
pg.display.set_caption(c.ORIGINAL_CAPTION)
SCREEN = pg.display.set_mode(c.SCREEN_SIZE)

GFX = load_all_gfx(os.path.join("resources","graphics"))
ZOMBIE_RECT = loadZombieImageRect()
PLANT_RECT = loadPlantImageRect()

state/constants.py



START_LEVEL_NUM = 1

ORIGINAL_CAPTION = 'Plant VS Zombies Game'

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
SCREEN_SIZE = (SCREEN_WIDTH, SCREEN_HEIGHT)

GRID_X_LEN = 9
GRID_Y_LEN = 5
GRID_X_SIZE = 80
GRID_Y_SIZE = 100

WHITE        = (255, 255, 255)
NAVYBLUE     = ( 60,  60, 100)
SKY_BLUE     = ( 39, 145, 251)
BLACK        = (  0,   0,   0)
LIGHTYELLOW  = (234, 233, 171)
RED          = (255,   0,   0)
PURPLE       = (255,   0, 255)
GOLD         = (255, 215,   0)
GREEN        = (  0, 255,   0)

SIZE_MULTIPLIER = 1.3

#GAME INFO DICTIONARY KEYS
CURRENT_TIME = 'current time'
LEVEL_NUM = 'level num'

#STATES FOR ENTIRE GAME
MAIN_MENU = 'main menu'
LOAD_SCREEN = 'load screen'
GAME_LOSE = 'game los'
GAME_VICTORY = 'game victory'
LEVEL = 'level'

MAIN_MENU_IMAGE = 'MainMenu'
OPTION_ADVENTURE = 'Adventure'
GAME_LOOSE_IMAGE = 'GameLoose'
GAME_VICTORY_IMAGE = 'GameVictory'

#MAP COMPONENTS
BACKGROUND_NAME = 'Background'
BACKGROUND_TYPE = 'background_type'
INIT_SUN_NAME = 'init_sun_value'
ZOMBIE_LIST = 'zombie_list'

MAP_EMPTY = 0
MAP_EXIST = 1

BACKGROUND_OFFSET_X = 220
MAP_OFFSET_X = 35
MAP_OFFSET_Y = 100

#MENUBAR
CHOOSEBAR_TYPE = 'choosebar_type'
CHOOSEBAR_STATIC = 0
CHOOSEBAR_MOVE = 1
CHOSSEBAR_BOWLING = 2
MENUBAR_BACKGROUND = 'ChooserBackground'
MOVEBAR_BACKGROUND = 'MoveBackground'
PANEL_BACKGROUND = 'PanelBackground'
START_BUTTON = 'StartButton'
CARD_POOL = 'card_pool'

MOVEBAR_CARD_FRESH_TIME = 6000
CARD_MOVE_TIME = 60

#PLANT INFO
PLANT_IMAGE_RECT = 'plant_image_rect'
CAR = 'car'
SUN = 'Sun'
SUNFLOWER = 'SunFlower'
PEASHOOTER = 'Peashooter'
SNOWPEASHOOTER = 'SnowPea'
WALLNUT = 'WallNut'
CHERRYBOMB = 'CherryBomb'
THREEPEASHOOTER = 'Threepeater'
REPEATERPEA = 'RepeaterPea'
CHOMPER = 'Chomper'
CHERRY_BOOM_IMAGE = 'Boom'
PUFFSHROOM = 'PuffShroom'
POT * INE = 'PotatoMine'
SQUASH = 'Squash'
SPIKEWEED = 'Spikeweed'
JALAPENO = 'Jalapeno'
SCAREDYSHROOM = 'ScaredyShroom'
SUNSHROOM = 'SunShroom'
ICESHROOM = 'IceShroom'
HYPNOSHROOM = 'HypnoShroom'
WALLNUTBOWLING = 'WallNutBowling'
REDWALLNUTBOWLING = 'RedWallNutBowling'

PLANT_HEALTH = 5
WALLNUT_HEALTH = 30
WALLNUT_CRACKED1_HEALTH = 20
WALLNUT_CRACKED2_HEALTH = 10
WALLNUT_BOWLING_DAMAGE = 10

PRODUCE_SUN_INTERVAL = 7000
FLOWER_SUN_INTERVAL = 22000
SUN_LIVE_TIME = 7000
SUN_VALUE = 25

ICE_SLOW_TIME = 2000

FREEZE_TIME = 7500
ICETRAP = 'IceTrap'

#PLANT CARD INFO
CARD_SUNFLOWER = 'card_sunflower'
CARD_PEASHOOTER = 'card_peashooter'
CARD_SNOWPEASHOOTER = 'card_snowpea'
CARD_WALLNUT = 'card_wallnut'
CARD_CHERRYBOMB = 'card_cherrybomb'
CARD_THREEPEASHOOTER = 'card_threepeashooter'
CARD_REPEATERPEA = 'card_repeaterpea'
CARD_CHOMPER = 'card_chomper'
CARD_PUFFSHROOM = 'card_puffshroom'
CARD_POT * INE = 'card_potatomine'
CARD_SQUASH = 'card_squash'
CARD_SPIKEWEED = 'card_spikeweed'
CARD_JALAPENO = 'card_jalapeno'
CARD_SCAREDYSHROOM = 'card_scaredyshroom'
CARD_SUNSHROOM = 'card_sunshroom'
CARD_ICESHROOM = 'card_iceshroom'
CARD_HYPNOSHROOM = 'card_hypnoshroom'
CARD_REDWALLNUT = 'card_redwallnut'

#BULLET INFO
BULLET_PEA = 'PeaNormal'
BULLET_PEA_ICE = 'PeaIce'
BULLET_MUSHROOM = 'BulletMushRoom'
BULLET_DAMAGE_NORMAL = 1

#ZOMBIE INFO
ZOMBIE_IMAGE_RECT = 'zombie_image_rect'
ZOMBIE_HEAD = 'ZombieHead'
NORMAL_ZOMBIE = 'Zombie'
CONEHEAD_ZOMBIE = 'ConeheadZombie'
BUCKETHEAD_ZOMBIE = 'BucketheadZombie'
FLAG_ZOMBIE = 'FlagZombie'
NEWSPAPER_ZOMBIE = 'NewspaperZombie'
BOOMDIE = 'BoomDie'

LOSTHEAD_HEALTH = 5
NORMAL_HEALTH = 10
FLAG_HEALTH = 15
CONEHEAD_HEALTH = 20
BUCKETHEAD_HEALTH = 30
NEWSPAPER_HEALTH = 15

ATTACK_INTERVAL = 1000
ZOMBIE_WALK_INTERVAL = 70

ZOMBIE_START_X = SCREEN_WIDTH + 50

#STATE
IDLE = 'idle'
FLY = 'fly'
EXPLODE = 'explode'
ATTACK = 'attack'
ATTACKED = 'attacked'
DIGEST = 'digest'
WALK = 'walk'
DIE = 'die'
CRY = 'cry'
FREEZE = 'freeze'
SLEEP = 'sleep'

#LEVEL STATE
CHOOSE = 'choose'
PLAY = 'play'

#BACKGROUND
BACKGROUND_DAY = 0
BACKGROUND_NIGHT = 1

state/main.py

from . import tool
from . import constants as c
from .state import mainmenu, screen, level

def main():
   game = tool.Control()
   state_dict = {c.MAIN_MENU: mainmenu.Menu(),
                 c.GAME_VICTORY: screen.GameVictoryScreen(),
                 c.GAME_LOSE: screen.GameLoseScreen(),
                 c.LEVEL: level.Level()}
   game.setup_states(state_dict, c.MAIN_MENU)
   game.main()

主执行文件main.py

import pygame as pg
from source.main import main

if __name__=='__main__':
   main()
   pg.quit()

来源:https://blog.csdn.net/m0_70127749/article/details/124697185

0
投稿

猜你喜欢

  • Microsoft SQL Server 2000 能提供超大型系统所需的数据库服务。大型服务器可能有成千上万的用户同时连接到 SQL Se
  • 本文研究的主要是Python生成器及其应用,具体如下。一、定义可以理解为一种数据类型,这种数据类型自动实现了迭代器协议(其他的数据类型需要调
  • 本文介绍了在js和asp中使用FileSystemObject(fso)来: 创建、添加或删除数据,以及读取文件; 移动、复制和删除文件;创
  • 什么是浮动?浮动是 css 的定位属性。我们可以看一下印刷设计来了解它的起源和作用。印刷布局中,文本可以按照需要围绕图片。一般把这种方式称为
  • Dean Edwards 最近有篇文章很精彩,忍不住在这里翻译下。-- Split --很多 Javascript 框架都提供了自定义事件(
  • 本文深入剖析了python中dict,set,list,tuple应用及对应示例,有助于读者对其概念及原理的掌握。具体如下:1.字典(dic
  • 写了网址规范化后,尚奇公司的柳先生建议再深入讨论一下301转向/重定向。下面就谈谈我所了解的301转向在搜索引擎优化方面的应用。什么是301
  • 在本文中,以'哈'来解释作示例解释所有的问题,“哈”的各种编码如下: 1. UNICODE (UTF8-16),C854;
  • python有时候需要清除字符串前后空格,而字符本身的空格不需要清除掉,那就不能用正则re.sub来实现。这时用到strip()函数用法:s
  • 微软建议用Request.BinaryRead()读取表单数据,但由于这种方法读出的是二进制数据,需要对读出的数据逐字节进行分析,生成有意义
  • 在Web开发中,后端代码写起来其实是相当容易的。例如,我们编写一个REST API,用于创建一个Blog:@api@post('/a
  • 一般情况下,访问或设置剪贴板,IE 只需使用 window.clipboardData 的 getData 或 setData 方法即可。M
  • 对于outerHTML这个DOM属性,在IE/Opera/google Chorme等浏览器中都是可以使用的,但唯独Firefox是不支持的
  • 本文实例为大家分享了Python3实现飞机大战游戏的具体代码,供大家参考,具体内容如下1、主程序:plane_main.pyimport p
  • 如何做一个计数器并让人家申请使用?    第一步:创建一个计数器(最简单的数字计数器,不是图片式的):&nbs
  • ASP给图片加水印是需要组件的...常用的有aspjpeg软件和中国人自己开发的wsImage软件,可以上网搜索下载这两个软件,推荐使用咱们
  •     网页过渡是指当浏览者进入或离开网页时,页面呈现的不同的刷新效果,比如卷动、百叶窗等。这样你的网页看起来
  • 在oracle中有很多关于日期的函数,如:1、add_months()用于从一个日期值增加或减少一些月份 date_value:=add_m
  • blankzheng的blog:http://www.planabc.net/margin在中文中我们翻译成外边距或者外补白(本文中引用外边
  • 本文实例为大家分享了python实现邮箱发送信息的具体代码,供大家参考,具体内容如下一、SSLSSL 是指安全套接字层,简而言之,它是一项标
手机版 网络编程 asp之家 www.aspxhome.com