[[archiv:ef:ef2020_2022:minecraft:projekt:maximandrin:start| Zurück zum Projekt]] #Globale Variabeln initiieren #Nach Präferenz ändern: w = 0 h = 0 playerY = 3 playerZ = 20 buildGlass = True #Nicht ändern: board = [[0]] piece = [[0]] pieceX = 0 pieceY = 0 color = DIAMOND_BLOCK isRunning = False origin = player.position() score = 0 unusedPieces = range(7) #Generelle Funktionen def startTetris(): global w global h global playerZ global board global piece global pieceX global pieceY global isRunning global origin global score global unusedPieces #erstellen einer zweidimensionalen Liste zum Speichern der Spielfläche # (0/1) (1/1) # (0/0) (1/0) board = [] for i in range(w): temparr = range(h) board[i] = temparr for j in range(h): board[i][j] = 0 #erstellen des ersten Tetrominos unusedPieces = range(7) pieceX = Math.round(w/2) - 2 pieceY = h - 1 getPiece() #Spieler zentrieren und Agenten wegteleportieren agent.teleport_to_player() player.teleport(agent.get_position()) origin = player.position() player.execute("tp ~ ~ ~ facing ~ ~ ~1") agent.teleport(pos(0, -10, 0), SOUTH) #"Spielkonsole" bauen makeBoard(w - 1, h - 1) #Spiel starten isRunning = True score = 0 gameloop() player.on_chat("start", startTetris) def makeBoard(w, h): global playerY global playerZ global buildGlass #Plattform bauen blocks.fill(GLASS, pos(-1, -2, -1), pos(1, -2, 1)) blocks.fill(blocks.block_by_name("scaffolding"), pos(-1, -1, -1), pos(1, -1, 1)) blocks.fill(GLASS_PANE, pos(-1, 0, -1), pos(1, 0, -1)) blocks.fill(GLASS_PANE, pos(-1, 0, 1), pos(1, 0, 1)) blocks.place(GLASS_PANE, pos(-1, 0, 0)) blocks.place(GLASS_PANE, pos(1, 0, 0)) #Bildschirm bauen n = Math.round(w / 2) o = Math.round(w/2%1) blocks.fill(BLACK_CONCRETE, pos(-n, -playerY, playerZ+1), pos(n+o, h-playerY, playerZ+1)) blocks.fill(POLISHED_ANDESITE, pos(-n-1, -1-playerY, playerZ+1), pos(-n-1, h+1-playerY, playerZ-1)) blocks.fill(POLISHED_ANDESITE, pos(n+o+1, -1-playerY, playerZ+1), pos(n+o+1, h+1-playerY, playerZ-1)) blocks.fill(POLISHED_ANDESITE, pos(-n-1, -1-playerY, playerZ+1), pos(n+o+1, -1-playerY, playerZ-1)) blocks.fill(POLISHED_ANDESITE, pos(-n-1, h+1-playerY, playerZ+1), pos(n+o+1, h+1-playerY, playerZ-1)) blocks.fill(AIR, pos(-n, -playerY, playerZ-1), pos(n+o, h-playerY, playerZ)) if buildGlass: blocks.fill(GLASS, pos(-n, -playerY, playerZ-1), pos(n+o, h-playerY, playerZ-1)) def stopTetris(): global isRunning #Aus gameloop() ausbrechen isRunning = False player.on_chat("stop", stopTetris) def getPiece(): global piece global color global pieceX global unusedPieces #Eines der Tetrominos wählen random = Math.round(Math.random()*unusedPieces.length) n = unusedPieces[random] if unusedPieces.length < 1: unusedPieces = range(7) else: unusedPieces.remove(n) if n < 1: #I piece = [[0,1,0,0],[0,1,0,0],[0,1,0,0],[0,1,0,0]] color = LIGHT_BLUE_WOOL elif n < 2: #O piece = [[1,1],[1,1]] color = YELLOW_WOOL pieceX = pieceX + 1 elif n < 3: #T piece = [[0,1,0],[1,1,0],[0,1,0]] color = PURPLE_WOOL elif n < 4: #S piece = [[1,0,0],[1,1,0],[0,1,0]] color = RED_WOOL elif n < 5: #2 piece = [[0,1,0],[1,1,0],[1,0,0]] color = LIME_WOOL elif n < 6: #L piece = [[1,1,0],[0,1,0],[0,1,0]] color = ORANGE_WOOL elif n < 7: #J piece = [[0,1,0],[0,1,0],[1,1,0]] color = BLUE_WOOL #Durchgehend wiederholende Funktion die Spiel "steuert" def gameloop(): global isRunning frame = 0 #Wiederholen bis Spieler "stop" schreibt while isRunning: #Bei Bewegung den Tetromino bewegen movedDirection = playerMoved() if movedDirection[0] != "": movePiece(movedDirection[0], movedDirection[1]) player.teleport(origin) #Alle 20 Durchläufe den Tetromino nach unten bewegen if frame % 20 == 0: moveDown() frame += 1 #Bewegen der Tetrominos def playerMoved(): #neue und alte Position vergleichen cPos = player.position() if origin.to_string() == cPos.to_string(): return ["", ""] else: #Richtung bestimmen x = origin.get_value(Axis.X) - cPos.get_value(Axis.X) y = origin.get_value(Axis.Y) - cPos.get_value(Axis.Y) z = origin.get_value(Axis.Z) - cPos.get_value(Axis.Z) if x < 0: return ["x", "+"] elif x > 0: return ["x", "-"] elif y != 0: return ["y", "+"] elif z < 0: return ["z", "+"] else: return ["z", "-"] def movePiece(direction, sign): global piece #Je nach Richtung richtige Bewegung ausführen if direction == "x" and sign == "-": move(-1) elif direction == "x" and sign == "+": move(1) elif direction == "y": moveToBottom() elif direction == "z" and sign == "-": rotateLeft() else: rotateRight() def move(n): global piece global pieceX global pieceY #X Wert des Tetrominos ändern newX = pieceX + n if not checkCollisions(piece, newX, pieceY, False): checkCollisions(piece, newX, pieceY, True) def moveDown(): global piece global pieceX global pieceY #Y Wert des Tetrominos ändern newY = pieceY - 1 checkCollisions(piece, pieceX, newY, True) def moveToBottom(): global piece global pieceX global pieceY global board global playerY global playerZ #Y Wert des Tetrominos senken bis Kollision stattfindet newY = pieceY while not checkCollisions(piece, pieceX, newY, False): newY = newY - 1 player.execute("fill ~" + str(-w/2-1) + " ~" + str(-playerY) + " ~" + str(playerZ) + " ~" + str(w/2+1) + " ~" + str(h-playerY) + " ~" + str(playerZ) + " air 0 replace wool " + id(color)) pieceY = newY + 1 placePiece() def rotateLeft(): global piece global pieceX global pieceY tempPiece = [] newPiece = [] for i in range(piece.length): tr = range(piece.length) tempPiece[i] = tr newPiece[i] = tr for j in range(piece.length): tempPiece[i][j] = 0 newPiece[i][j] = 0 newPiece = piece tPiece = piece #gedrehtes Tetromino in neue Liste speichern for i in range(piece.length): for j in range(piece.length): tempPiece[i][j] = tPiece[i][piece.length-1-j] for i in range(piece.length): for j in range(piece.length): newPiece[j][i] = tempPiece[i][j] player.execute("fill ~" + str(-w/2) + " ~" + str(-playerY) + " ~" + str(playerZ) + " ~" + str(w/2) + " ~" + str(h-playerY) + " ~" + str(playerZ+1) + " air 0 replace wool " + id(color)) checkCollisions(newPiece, pieceX, pieceY, True) def rotateRight(): global piece global pieceX global pieceY tempPiece = [] newPiece = [] for i in range(piece.length): tr = range(piece.length) tempPiece[i] = tr newPiece[i] = tr for j in range(piece.length): tempPiece[i][j] = 0 newPiece[i][j] = 0 newPiece = piece #gedrehtes Tetromino in neue Liste speichern for i in range(piece.length): for j in range(piece.length): tempPiece[j][i] = piece[i][j] for i in range(tempPiece.length): for j in range(tempPiece.length): newPiece[i][tempPiece.length-1-j] = tempPiece[i][j] player.execute("fill ~" + str(-w/2) + " ~" + str(-playerY) + " ~" + str(playerZ) + " ~" + str(w/2) + " ~" + str(h-playerY) + " ~" + str(playerZ-1) + " air 0 replace wool " + id(color)) checkCollisions(newPiece, pieceX, pieceY, True) def checkCollisions(newPiece, newX, newY, proceed): global board #Kollisionen finden und testen ob Tetromino zuunterst ist #Ohne tempPiece entsteht Error, weil type von newPiece nicht bekannt ist tempPiece = [[0]] tempPiece = newPiece collided = False bottom = False walls = False for i in range(newPiece.length): for j in range(newPiece.length): if newPiece[i][j] == 1: if i + newX >= board.length or i + newX < 0: walls = True elif board[i + newX][j + newY] == 1: collided = True elif j + newY < 0: bottom = True if proceed and not walls : if bottom: placePiece() elif not collided: updatePiece(newPiece, newX, newY) else: placePiece() elif bottom or collided or walls: return(True) return(False) #Funktionen zum Ändern des Bildschirms der "Konsole" def updatePiece(newPiece, newX, newY): global board global piece global pieceX global pieceY global h global playerY global playerZ global color player.execute("fill ~" + str(-w/2-1) + " ~" + str(-playerY) + " ~" + str(playerZ) + " ~" + str(w/2+1) + " ~" + str(h-playerY) + " ~" + str(playerZ) + " air 0 replace wool " + id(color)) for i in range(newPiece.length): for j in range(newPiece.length): if newPiece[i][j] == 1: if newY + j < h: blocks.place(color, positions.add(origin, pos(-w/2+newX+i, newY+j-playerY, playerZ))) piece = newPiece pieceX = newX pieceY = newY def placePiece(): global board global piece global pieceX global pieceY global score global isRunning #Tetromino zur "board" Liste hinzufügen for i in range(piece.length): for j in range(piece.length): if piece[i][j] == 1: board[i + pieceX][j + pieceY] = 1 if pieceY + j < h: blocks.place(placeColor(color), positions.add(origin, pos(-w/2+pieceX+i, pieceY+j-playerY, playerZ))) if pieceY + j >= h: isRunning = False if isRunning: #Komplette Reihen entfernen removeRow(i) #Neues Tetromino generieren score = score + 1 pieceX = Math.round(w/2) - 2 pieceY = h - 1 getPiece() else: player.say("Zu langsam ☹") player.say("score: " + str(score)) def removeRow(j): global board global w global h y = 0 for _ in range(h): complete = 1 for i in range(w): complete = complete * board[i][y] if complete == 1: #alles über der Reihe nach unten schieben for k in range(w): for l in range(y, h): board[k][l] = board[k][l+1] for l in range(y, h-1): blocks.clone(positions.add(origin, pos(-w/2, l+1-playerY, playerZ)), positions.add(origin, pos(w/2, l+1-playerY, playerZ)), positions.add(origin, pos(-w/2, l-playerY, playerZ)), CloneMask.REPLACE, CloneMode.NORMAL) for k in range(w-2): board[k][h-1]=0 blocks.fill(AIR, positions.add(origin, pos(-w/2,h-1-playerY, playerZ)), positions.add(origin, pos(w/2-1, h-1-playerY, playerZ))) else: y = y + 1 def placeColor(color): if color == LIGHT_BLUE_WOOL: return(LIGHT_BLUE_CONCRETE) elif color == YELLOW_WOOL: return(YELLOW_CONCRETE) elif color == PURPLE_WOOL: return(PURPLE_CONCRETE) elif color == LIME_WOOL: return(LIME_CONCRETE) elif color == RED_WOOL: return(RED_CONCRETE) elif color == ORANGE_WOOL: return(ORANGE_CONCRETE) else: return(BLUE_CONCRETE) def id(color): if color == LIGHT_BLUE_WOOL: return 3 elif color == YELLOW_WOOL: return 4 elif color == PURPLE_WOOL: return 10 elif color == LIME_WOOL: return 5 elif color == RED_WOOL: return 14 elif color == ORANGE_WOOL: return 1 else: return 11