amazeballs2
Attribution
Retro Gaming with Raspberry Pi, pages 106 - 111.
Licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported.
Original Python code
import pgzrun
import json
import os
def loadmap(mp):
with open(mp) as json_data:
d = json.load(json_data)
mapdata = {"width":d["width"], "height":d["height"]}
rawdata = d["layers"][0]["data"]
mapdata["data"] = []
for x in range(0, mapdata["width"]):
st = x*mapdata["width"]
mapdata["data"].append(rawdata[st:st+mapdata["height"]])
tileset = "maps/" + d["tilesets"][0]["source"].replace(".tsx",".json")
with open(tileset) as json_data:
t = json.load(json_data)
mapdata["tiles"] = t["tiles"]
for tile in range(0,len(mapdata["tiles"])):
path = mapdata["tiles"][tile]["image"]
mapdata["tiles"][tile]["image"] = os.path.basename(path)
mapdata["tiles"][tile]["id"] = mapdata["tiles"][tile]["id"]+1
return mapdata
player = {"x":3, "y":3, "frame":0, "sx":0, "sy":96,
"moveX":0, "moveY":0, "queueX":0, "queueY":0,
"moveDone":True, "movingNow":False, "animCounter":0}
OFFSETX = 368
OFFSETY = 300
timer = 0
mazeSolved = False
mapData = loadmap("maps/map1.json")
def draw(): # Pygame Zero draw function
screen.fill((0, 0, 0))
drawMap()
screen.blit('title', (0, 0))
screen.draw.text("TIME: "+str(timer) , topleft=(20, 80), owidth=0.5, ocolor=(255,255,0), color=(255,0,0) , fontsize=60)
if mazeSolved:
screen.draw.text("MAZE SOLVED in " + str(timer) + " seconds!" , center=(400, 450), owidth=0.5, ocolor=(0,0,0), color=(0,255,0) , fontsize=60)
def update(): # Pygame Zero update function
global player, timer
if player["moveDone"] == True:
if keyboard.left: doMove(player, -1, 0)
if keyboard.right: doMove(player, 1, 0)
if keyboard.up: doMove(player, 0, -1)
if keyboard.down: doMove(player, 0, 1)
updateBall(player)
def timerTick():
global timer
if not mazeSolved:
timer += 1
def drawMap():
psx = OFFSETX
psy = OFFSETY-32
mx = psx - player["sx"]
my = psy - player["sy"]+32
for x in range(player["x"]-12, player["x"]+16):
for y in range(player["y"]-12, player["y"]+16):
if onMap(x,y):
b = mapData["data"][y][x]
td = findData(mapData["tiles"], "id", b)
block = td["image"]
bheight = td["imageheight"]-34
bx = (x*32)-(y*32) + mx
by = (y*16)+(x*16) + my
if -32 <= bx < 800 and 100 <= by < 620:
screen.blit(block, (bx, by - bheight))
if x == player["x"] and y == player["y"]:
screen.blit("ball"+str(player["frame"]), (psx, psy))
def findData(lst, key, value):
for i, dic in enumerate(lst):
if dic[key] == value:
return dic
return -1
def onMap(x,y):
if 0 <= x < mapData["width"] and 0 <= y < mapData["height"]:
return True
return False
def doMove(p, x, y):
global mazeSolved
if onMap(p["x"]+x, p["y"]+y):
mt = mapData["data"][p["y"]+y][p["x"]+x]
if mt == 1 or mt == 3:
p.update({"queueX":x, "queueY":y, "moveDone":False})
if mt == 3:
mazeSolved = True
def updateBall(p):
if p["movingNow"]:
if p["moveX"] == -1: moveP(p,-1,-0.5)
if p["moveX"] == 1: moveP(p,1,0.5)
if p["moveY"] == -1: moveP(p,1,-0.5)
if p["moveY"] == 1: moveP(p,-1,0.5)
p["animCounter"] += 1
if p["animCounter"] == 4:
p["animCounter"] = 0
p["frame"] += 1
if p["frame"] > 7:
p["frame"] = 0
if p["frame"] == 4:
if p["moveDone"] == False:
if p["queueX"] != 0 or p["queueY"] !=0:
p.update({"moveX":p["queueX"], "moveY":p["queueY"], "queueX":0, "queueY":0, "movingNow": True})
else:
p.update({"moveDone":True, "moveX":0, "moveY":0, "movingNow":False})
if p["frame"] == 7 and p["moveDone"] == False and p["movingNow"] == True:
p["x"] += p["moveX"]
p["y"] += p["moveY"]
p["moveDone"] = True
def moveP(p,x,y):
p["sx"] += x
p["sy"] += y
clock.schedule_interval(timerTick, 1.0)
pgzrun.go()