我在做游戏。
游戏世界由图块地图表示。这些图块对应于2D数组中的值。
如果任何三个墙砖都呈L形,我想使用特殊的“角”墙精灵。也就是说,
V
## # >##
# ## #
^
用箭头指示的图块应为边角图块。
我有用于搜索墙的代码,但是我不知道如何识别哪些砖是角砖。
我的代码是:
import pygame, sys
import Sprites
import random
from pygame.locals import *
pygame.init()
fpsClock = pygame.time.Clock()
cloudx = -200
cloudy = 0
infoObject = pygame.display.Info()
DIRT = 0
GRASS = 1
WATER = 2
COAL = 3
CLOUD = 4
WALL = 5
CWALL = 6
controls = {
DIRT : 49,
GRASS: 50,
WATER: 51,
COAL : 52,
WALL : 53
}
infoObject = pygame.display.Info()
w = infoObject.current_w
h = infoObject.current_h
TILESIZE = 40
MAPWIDTH = 15
MAPHEIGHT = 15
WHITE = (255,255,255)
BLACK = (0,0,0)
resources = [DIRT, GRASS, WATER, COAL]
textures = {
DIRT : pygame.image.load('Sprites/Dirt.png'),
GRASS : pygame.image.load('Sprites/tile130.png'),
WATER : pygame.image.load('Sprites/Water.png'),
COAL : pygame.image.load('Sprites/Coal.png'),
CLOUD : pygame.image.load('Sprites/Cloud.png'),
WALL : pygame.image.load('Sprites/Swall.png'),
CWALL : pygame.image.load('Sprites/Swall.png')
}
playerPos = [0,0]
inventory = {
DIRT : 0,
GRASS : 0,
WATER : 0,
COAL : 0,
WALL : 10,
}
tilemap = [[DIRT for w in range(MAPWIDTH)] for h in range(MAPHEIGHT)]
DISPLAYSURF = pygame.display.set_mode((MAPWIDTH*TILESIZE,MAPHEIGHT*TILESIZE + 50))
pygame.display.set_caption('M I N E C R A F T -- 2D')
pygame.display.set_icon(pygame.image.load('Sprites/player.png'))
PLAYER = pygame.image.load('Sprites/Player.png').convert_alpha()
for rw in range(MAPHEIGHT):
for cl in range(MAPWIDTH):
randomNumber = random.randint(0,15)
if randomNumber == 0:
tile = COAL
elif randomNumber == 1 or randomNumber == 2:
tile = WATER
elif randomNumber >= 3 and randomNumber <=7:
tile = GRASS
else:
tile = DIRT
tilemap[rw][cl] = tile
INVFONT = pygame.font.Font('freesansbold.ttf', 18)
print(tilemap)
while True:
currentTile = tilemap[playerPos[1]][playerPos[0]]
DISPLAYSURF.fill(BLACK)
for event in pygame.event.get():
# print(event)
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
for key in controls:
if (event.key == controls[key]):
if inventory[key] > 0:
inventory[key] -=1
inventory[currentTile] += 1
tilemap[playerPos[1]][playerPos[0]] = key
if(event.key == K_RIGHT) and playerPos[0] < MAPWIDTH - 1:
playerPos[0]+=1
elif(event.key == K_LEFT) and playerPos[0] > 0:
playerPos[0]-=1
elif(event.key == K_DOWN) and playerPos[1] < MAPHEIGHT - 1:
playerPos[1]+=1
elif(event.key == K_UP) and playerPos[1] > 0:
playerPos[1]-=1
if event.key == K_SPACE:
currentTile = tilemap[playerPos[1]][playerPos[0]]
inventory[currentTile] += 1
tilemap[playerPos[1]][playerPos[0]] = DIRT
for row in range(MAPHEIGHT):
for column in range(MAPWIDTH):
DISPLAYSURF.blit(textures[tilemap[row][column]],(column*TILESIZE, row*TILESIZE, TILESIZE, TILESIZE))
DISPLAYSURF.blit(PLAYER,(playerPos[0]*TILESIZE,playerPos[1]*TILESIZE))
DISPLAYSURF.blit(textures[CLOUD].convert_alpha(),(cloudx,cloudy))
cloudx +=1
if cloudx > MAPWIDTH*TILESIZE:
cloudy = random.randint(0, MAPHEIGHT*TILESIZE)
cloudx = -200
placePosition = 10
for item in resources:
DISPLAYSURF.blit(textures[item],(placePosition, MAPHEIGHT*TILESIZE+10))
placePosition+=50
textObj = INVFONT.render(str(inventory[item]), True, WHITE, BLACK)
DISPLAYSURF.blit(textObj,(placePosition, MAPHEIGHT*TILESIZE+20))
placePosition += 50
pygame.display.update()
fpsClock.tick(24)
for x in range(MAPWIDTH):
for y in range(MAPHEIGHT):
if tilemap[x][y] == WALL:
go_left = x > 1
go_right = x < MAPWIDTH - 1
go_up = y > 1
go_down = y < MAPHEIGHT - 1
if go_left:
tilemap[x - 1][y] = CWALL
if go_up:
pass
if go_right:
tilemap[x + 1][y] = WALL
if go_up:
pass
if go_down:
pass
print('WALL')
pygame.display.update()
这是精灵的链接: https://framadrop.org/r/fmReup_rTK#bMSywSUa7nxb1qL/a4FIbns+VaspgE0c/FU+9f1drHI=
https://framadrop.org/r/pBOfrnKcdT#eNEZQ9QjX5Cl6X4gH4UwdIg3eBPnY/L4WcSGYtUR5PE=
https://framadrop.org/r/ZFfTz_Lq9V#2Nd5ba1iE7miyFg8JpPFvwabAkdnHds/GfVkSAQeJaQ=
https://framadrop.org/r/gN9Y748L9G#Z552pPpgjTcSubt9tn74mZ0tT1COv7UCFdkUq2DorAU=
https://framadrop.org/r/d9k4hyCUni#OTza8UbsR8Am/R1PA9MAWkLDPRDBsT1rAHMgr61jusc=
https://framadrop.org/r/1mv777OR6d#pkqwaQrmVRElUPcdEV5K4UhmALsJSYX7z3WtrZXl4TE=
https://framadrop.org/r/CyF-tk7yUb#IFexcePe418JizElZzCJzDENTJPDfz7i1nr+lGns0rU=
https://framadrop.org/r/VzVfAz6bnL#oLHivyHPtTD8+IxliDD4yc+6LS9kpGyEp1HNFGUsBHo=
https://framadrop.org/r/0V0ShMH0uq#PZHdPSQNbgL7QqH2niwdS4HO34ZRMfIlhpvpRqbWwng=
答案 0 :(得分:0)
根据评论,我不确定是什么问题...让我向您展示我将要做什么,以便我们可以在需要时进行进一步讨论:
for x in range(MAPWIDTH):
for y in range(MAPHEIGHT):
if tilemap[x][y] == WALL:
# there is a wall at indices x and y
# get neighbouring tiles (check for limits)
go_left = x > 1
go_right = x < MAPWIDTH - 1
go_up = y > 1
go_down = y < MAPHEIGHT - 1
if go_left:
# you can use x-1
tilemap[x-1][y] = WALL # set left tile to WALL
if go_up:
# do something in the diagonal with x-1 y-1?
pass
if go_right:
# you can use x+1
tilemap[x+1][y] = WALL # set right tile to WALL
if go_up:
pass # same story
if go_down:
pass # and again
编辑,这是一种简单的方法(因此希望很容易理解)
为了使纹理清洁,我首先必须旋转墙壁和角落以获得所有可能的配置(墙壁的垂直/水平以及角落的所有四种可能性)
VWALL = 5
HWALL = 6
CORNERLD = 7
CORNERRD = 8
CORNERLU = 9
CORNERRU = 10
controls = {
DIRT : 49,
GRASS : 50,
WATER : 51,
COAL : 52,
VWALL : 53,
HWALL : 54,
CORNERLD: 55,
CORNERRD: 56,
CORNERLU: 57,
CORNERRU: 58,
}
tex_wall = pygame.image.load('Sprites/Swall.png')
tex_corner = pygame.image.load('Sprites/Corner.png')
textures = {
DIRT : pygame.image.load('Sprites/Dirt.png'),
GRASS : pygame.image.load('Sprites/tile130.png'),
WATER : pygame.image.load('Sprites/Water.png'),
COAL : pygame.image.load('Sprites/Coal.png'),
CLOUD : pygame.image.load('Sprites/Cloud.png'),
HWALL : pygame.transform.rotate(tex_wall, 90),
VWALL : tex_wall,
CORNERRD: tex_corner,
CORNERLD: pygame.transform.flip(tex_corner, True, False),
CORNERLU: pygame.transform.flip(tex_corner, True, True),
CORNERRU: pygame.transform.flip(tex_corner, False, True),
}
我创建了墙字典,以in walls
walls = {
VWALL : None,
HWALL : None,
CORNERLD: None,
CORNERRD: None,
CORNERLU: None,
CORNERRU: None,
}
然后我检查地图
for x in range(MAPWIDTH):
for y in range(MAPHEIGHT):
if tilemap[x][y] in walls:
# there is a wall at indices x and y
# get neighbouring tiles (check for limits)
go_left = x > 1
go_right = x < MAPWIDTH - 1
go_up = y > 1
go_down = y < MAPHEIGHT - 1
l_wall = False
r_wall = False
u_wall = False
d_wall = False
if go_left and tilemap[x-1][y] in walls:
# left tile is WALL
l_wall = True
if go_right and tilemap[x+1][y] in walls:
# right tile is WALL
r_wall = True
if go_up and tilemap[x][y-1] in walls:
u_wall = True
if go_down and tilemap[x][y+1] in walls:
d_wall = True
if l_wall and u_wall:
# upper left corner
tilemap[x][y] = CORNERLU
elif l_wall and d_wall:
# down left corner
tilemap[x][y] = CORNERRU
elif r_wall and u_wall:
# upper left corner
tilemap[x][y] = CORNERLD
elif r_wall and d_wall:
# down left corner
tilemap[x][y] = CORNERRD
elif (l_wall or r_wall) and not (u_wall or d_wall):
# tiles in a vertical wall, use VWALL
tilemap[x][y] = VWALL
elif (u_wall or d_wall) and not (l_wall or r_wall):
# tiles in a horizontal wall, use HWALL
tilemap[x][y] = HWALL
我们得到
请注意,虽然墙的一些随机配置看起来不太好,但是(T形...),但这些墙需要额外的精灵。
我使用的完整代码可以找到here
EDIT2 请注意,您将不得不更新一些其他内容,以使一切顺利进行(例如,库存中的墙壁吸收量)
另外,每个循环都要运行此检查,因此代价很高,因此,您应该声明一个env_changed
布尔值以仅在对环境进行更改时进行测试。
对于库存,您将需要
if currentTile in walls:
inventory[VWALL] += 1
这使VWALL成为库存中的默认墙,并且循环会注意将其切换为适合显示的墙。 剩下的,好吧...这是你的游戏,所以我让你弄清楚;)
答案 1 :(得分:0)
我将从生成一个偏移量开始
// 1
//0 2 Neighbour directions
// 3
// 0 1 2 3 Corresponding offsets
dx = [-1, 0, 1, 0]
dy = [0, -1, 0, 1]
Nmax = 4
现在,我可以得到相邻墙的n值,就像这样:
nwalls = []
for n in range(Nmax): #n is the direction of the neighbour
#Ensure that the neighbour tile, identified as (x+dx[n], y+dy[n])
#is in the map and check to see if it is a wall
if 1<x+dx[n]<WIDTH and 1<y+dy[n]<HEIGHT and tilemap[x+dx[n]][y+dy[n]]==WALL:
nwalls.append(n) #Neighbour was a wall, add its direction to this list
现在,我可以将列表转换为图块名称:
#nwalls is a list of all the directions pointing to a wall
nwalls.sort() #Sort list, e.g. 3,1,2 -> 1,2,3
nwalls = map(str,nwalls) #Convert from numbers to strings
nwalls = ''.join(nwalls) #Append strings together: ['1','2','3'] -> '123'
if nwalls: #If the string is not empty
nwalls = 'corner_tile_{0}.jpg'.format(nwalls) #Convert string to tile name
现在我只需要一堆名为,例如:
corner_tile_01.jpg
corner_tile_013.jpg
那我可以说:
if nwalls: #Only true if this was a corner
Code to display the tile whose name is stored in `nwalls`