python实现minecraft二维文字版小游戏

该博客介绍了如何使用Python编程实现一个Minecraft风格的二维文字版小游戏。代码基于面向对象设计,包括Engine、Map、Player、Goods和Direction类。作者提到了在Windows和Linux上运行的注意事项,并指出游戏难点涉及地图对象的表示、视野更新和友好的文字显示。文章末尾展示了一张游戏效果截图。
摘要由CSDN通过智能技术生成

Python阶段学习之文字版MineCraft


最近在学习Python,读了《Learn Python3 the Hard Way》一大半,正好要求自己写一个游戏,就想起写一个文字版的MineCraft了。一开始写的很简单,就是一个很小的用input输入操作,得到随机物品,每种物品分数不同,最后全部挖光或者有某种结束机制,看得分论输赢。作为简单演练基本语法还可以,不过要说像minecraft还差很多了,所以做了一次大改动。

代码介绍:
主要是Engine、地图Map、玩家Player、物品goods(工厂类)、定位方向direction类,最右侧记录logs类。
按照面向对象的思想写的,后面可以轻松扩展,有兴趣可以下下代码自己加点东西玩一玩。

代码在Windows上编写,按照powershell全屏时的大小显示,在linux上简单添加文件解释器一行,调整一下显示大小和getch部分修改即可。

难点:

  1. 表达未知和物品:地图每个点都是一个对象,未知不显示,有各种物品和“空”,“空”也不显示,工厂类实现。
  2. 人的视野:随挖动、移动而显示物品,物品基类中增加exposed属性,操作后修改;
  3. 友好显示:分成三栏,分别是player、map、logs,每次获取一行,文字隔行显示。

缺点:
主要还是在于显示。

效果图如下:
文字版还是比较简陋

主程序.

# minecraft.py
# -*- coding = utf-8
# little minecraft game

import time
from minecraft_map import Map 
from minecraft_player import Player 
from minecraft_goods import scores
from minecraft_common import printmid
from minecraft_common import front_size
from minecraft_common import back_size
from minecraft_log import Logs
#from minecraft_common import fill_line

#windows
from msvcrt import getch
#linux
#import os
#import sys
#import tty, termios


def elect_act():
	#return input("选择操作:前进(w), 后退(s), 左转(a),右转(d),挖(空格),退出(quit)>")
	print("选择操作:前进(w), 后退(s), 左转(a),右转(d),挖(空格),退出(quit)>")
	
	#windows
	chr = str(getch(), encoding = "utf-8")
	#getch()  得到的是byte 而不是str, 需要转化
	#print(chr)
	return chr
	
	'''
	#使用终端的设置,在c中也使用tty.setraw
	fd = sys.stdin.fileno()
	tty.setraw(fd)
	ch = sys.stdin.read(1)
	'''


class Engine(object):

	def __init__(self):
	
		print("""
					   ===================================
					   ||                               ||
					   ||   欢迎来到文字版MineCraft!      ||
					   ||        尽情的挖矿吧 !           ||
					   ||                               ||
					   ||-------------------------------||
					   ||       最后得分结果为胜负         ||
					   ||-------------------------------||
					   ||       作者:  HHAHAA           ||
					   ||       尝鲜版:20190221         ||
					   ||       初改版:20190301         ||
					   ||       二改版:20190302         ||
					   ===================================
		""")
		time.sleep(1)
		
		self.create_map(50)
		print("\n生成地图中...")
		time.sleep(1)
		
		self.create_player()
		print("\n创建玩家中...")
		time.sleep(1)
		
		self.create_logs()
		print("\n小伙子,小菇凉,开始闯荡吧!")
		time.sleep(1)
		
	def create_map(self, size):
		self.map = Map(size)
		
	def create_player(self):
		self.player = Player()
		self.player.born(self.map)
		self.map.expose_around(self.player.pos_x, self.player.pos_y)
		self.map.set_empty(self.player.pos_x, self.player.pos_y)
	def create_logs(self):
		self.logs = Logs()
	
	def play(self):

		res = 0
		while res != -1:
			self.printscreen()
			#print(f"当前分数: {scores(self.player.pocket)}")
			#self.map.print_map_now(self.player.pos_x, 
			#	self.player.pos_y, self.player.head)
			act = elect_act()
			words = ""
			
			if act == "w":              #前进
				words = self.player.forward(self.map)
				#由于空的地方比较多,前进也需要扩大视野
				self.map.expose_view_by_move(self.player.pos_x, 
						self.player.pos_y, self.player.head)
			elif act == "s":            #后退
				words = self.player.backward(self.map)
			elif act == "a":            #左转
				words = self.player.turn_left()
				self.map.expose_view_by_move(self.player.pos_x, 
						self.player.pos_y, self.player.head)
						
			elif act == "d":            #右转
				words = self.player.turn_right()
				self.map.expose_view_by_move(self.player.pos_x, 
						self.player.pos_y, self.player.head)
			elif act == " ":             #挖
				words = self.player.dig(self.map)
				self.logs.push(words)
				#print("dig")
				pos = self.player.get_dig_pos()
				self.map.set_empty(pos.x, pos.y)
				
				sentence = self.map.expose_view_by_dig(self.player.pos_x, 
						self.player.pos_y, self.player.head)
				#print("after dig")
				if sentence != "":
					#print(f"sentence is not empty{sentence}")
					res = -1
					self.logs.push(sentence)
					self.logs.push("游戏结束...")
					self.printscreen()
					exit(1)
				else:
					continue
			elif act == "q":
				self.logs.push("游戏结束...")
				self.printscreen()
				exit(1)
			else:
				continue
			self.logs.push(words)
			
	def printscreen(self):
		out_buf = ""
		#print(f"\n\n{'-'*(front_size + 2*self.map.x + 3 + back_size )}")
		out_buf = f"\n\n{'-'*(front_size + 2*self.map.x + 3 + back_size )}"
		for i in range(self.map.x):
			player_line = self.player.getline(i)
			map_line = self.map.get_line( i, self.player.pos_x, 
				self.player.pos_y, self.player.head)
			#log_line = " "*(back_size - 1) + "|"
			log_line = self.logs.get_line(i)
			#print(player_line + map_line + log_line)
			line = player_line + map_line + log_line
			out_buf += "\n" + line
		
		out_buf += "\n" + f"{'-'*(front_size + 2*self.map.x + 3 + back_size )}"
		print(out_buf)
		#print(f"{'-'*(front_size + 2*self.map.x + 3 + back_size )}")
			
		
engine = Engine()
engine.play()
#printmid(f"此次得分:{scores(engine.player.pocket)}")

common部分

# minecraft_common.py
# -*- coding: utf-8
# minecraft common class etc.

#common part
front_size = 8*6    #front
back_size = 59

tab = " "*front_size  #目前tab为8个空格


def printmid(words):
   print(f"{tab}" + words)

def fill_line(sentence, size):
   sentence_occu = 0
   for word in sentence:
   	if len( bytes(word, 'utf-8')) != 1:
   		sentence_occu += 2
   	else:
   		sentence_occu += 1
   #print(sentence_occu)
   return sentence + " "*(size - sentence_occu)

def fill_line_back(words, size):
   return words + " "*size	
   
class pair(object):
   def __init__(self, x, y):
   	self.x = x
   	self.y = y

class pos(object):
   def __init__(self, x
  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值