To start with I'm using Python and pygame to program a Dr. Mario clone. A lot of what I read reccommended on starting with a Tetris like game as a beginner project, but I thought I'd try out Dr. Mario instead. My current problem is figuring out the best way to transition from one active piece to another while drawing the previous active piece to the game board.
The issue in particular is how I can load a specific graphic for linked pieces and non-linked pieces and how to distinguish them within an array. Currently, the array keeps track of the element, if any, that resides in each square on the grid. While I'm fairly confident I could get the program to load the desired element in each square, I have no clue how to load a single graphic that takes up two spots on the grid while simultaneously keeping them linked after they are no longer active.
Any pointers, tips, or resources (ideally aimed at beginners) would be appreciated. I've done preliminary research but sadly the only sources I could find were not well documented so I couldn't understand them (and I don't want to just copy/paste because then I won't learn any thing.) Below is the pseudo code for those that have never played Dr. Mario so that you can understand what I am trying to do and below that is the full code I have so far. Apologies in advance for not shortening it because I'm afraid I might leave out something vital. Thank you for taking the time to help me out!
Pseudo Code:
Spoiler
Source Code:
import pygame, random
pygame.init()
NUM_COLUMNS = 8
NUM_ROWS = 16
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
class Element(pygame.sprite.Sprite):
def __init__(self, element):
self.element = element
pygame.sprite.Sprite.__init__(self)
self.imageMaster = pygame.image.load("WMana.xcf")
self.generateElements()
self.image = self.imageMaster
self.rect = self.image.get_rect()
self.image.set_colorkey((255, 255, 255))
self.x = 0
self.y = 0
def generateElements(self):
#1 = W, 2 = G, 3 = Y
if self.element == 0:
self.element = random.randrange(1, 4)
if self.element == 1:
self.imageMaster = pygame.image.load("WMana.xcf")
elif self.element == 2:
self.imageMaster = pygame.image.load("GMana.xcf")
elif self.element == 3:
self.imageMaster = pygame.image.load("YMana.xcf")
self.imageMaster = self.imageMaster.convert()
def settle(self, occupiedGrid):
occupiedGrid[ xToGrid(self.x) ][ yToGrid(self.y) ] = self.element
def unSettle(self, occupiedGrid):
occupiedGrid[ xToGrid(self.x) ][ yToGrid(self.y) ] = None
def xToGrid(pixel_coordinate):
return ((pixel_coordinate - 10) - 240) / 20
def yToGrid(pixel_coordinate):
return ((pixel_coordinate - 10) - 100) / 20
class Mana(pygame.sprite.Sprite):
def __init__(self, pelement, selement):
self.pelement = pelement
self.selement = selement
pygame.sprite.Sprite.__init__(self)
self.imageMaster = pygame.image.load("testWW.xcf")
self.elements()
self.image = self.imageMaster
self.rect = self.image.get_rect()
self.image.set_colorkey((255, 255, 255))
self.x = 300
self.y = 100
self.dir = 0
self.wait = 0
self.drop = 6
def update(self):
self.checkKeys()
self.rotate()
self.rect.bottomleft = (self.x, self.y)
self.wait += 1
if self.wait >= self.drop:
self.wait = 0
self.y += 20
if self.rect.bottom >= 400:
self.y = 400
self.checkPos()
def elements(self):
#1 = W, 2 = G, 3 = Y
if self.pelement.element == 1:
if self.selement.element == 1:
self.imageMaster = pygame.image.load("testWW.xcf")
elif self.selement.element == 2:
self.imageMaster = pygame.image.load("testWG.xcf")
elif self.selement.element == 3:
self.imageMaster = pygame.image.load("testWY.xcf")
elif self.pelement.element == 2:
if self.selement.element == 1:
self.imageMaster = pygame.image.load("testGW.xcf")
elif self.selement.element == 2:
self.imageMaster = pygame.image.load("testGG.xcf")
elif self.selement.element == 3:
self.imageMaster = pygame.image.load("testGY.xcf")
elif self.pelement.element == 3:
if self.selement.element == 1:
self.imageMaster = pygame.image.load("testYW.xcf")
elif self.selement.element == 2:
self.imageMaster = pygame.image.load("testYG.xcf")
elif self.selement.element == 3:
self.imageMaster = pygame.image.load("testYY.xcf")
self.imageMaster = self.imageMaster.convert()
def checkKeys(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.x -= 20
if self.rect.left <= 240:
self.x = 240
if keys[pygame.K_RIGHT]:
if self.rect.right <= 380:
self.x += 20
if keys[pygame.K_DOWN]:
self.y += 20
self.wait = 0
if self.rect.bottom >= 400:
self.y = 400
def rotate(self):
oldBL = self.rect.bottomleft
self.image = pygame.transform.rotate(self.imageMaster, self.dir)
self.rect = self.image.get_rect()
self.rect.bottomleft = oldBL
def checkPos(self):
if self.dir == 0 or self.dir == 360:
self.pelement.x = (self.x + 10)
self.pelement.y = (self.y + 10)
self.selement.x = (self.x + 30)
self.selement.y = (self.y + 10)
elif self.dir == 90:
self.pelement.x = (self.x + 10)
self.pelement.y = (self.y + 10)
self.selement.x = (self.x + 10)
self.selement.y = (self.y - 10)
elif self.dir == 180:
self.pelement.x = (self.x + 30)
self.pelement.y = (self.y + 10)
self.selement.x = (self.x + 10)
self.selement.y = (self.y + 10)
elif self.dir == 270:
self.pelement.x = (self.x + 10)
self.pelement.y = (self.y - 10)
self.selement.x = (self.x + 10)
self.selement.y = (self.y + 10)
def settle(self, occupiedGrid):
self.pelement.settle(occupiedGrid)
self.selement.settle(occupiedGrid)
class Backdrop(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("Border.xcf")
self.image = self.image.convert()
self.rect = self.image.get_rect()
def update(self):
self.rect.center = (320, 240)
class Game():
def __init__(self):
pygame.display.set_caption("Mana Clash!")
self.background = pygame.Surface(screen.get_size())
self.background.fill((100, 100, 100))
screen.blit(self.background, (0, 0))
self.pelement = Element(0)
self.selement = Element(0)
self.mana = Mana(self.pelement, self.selement)
self.backdrop = Backdrop()
self.allSprites = pygame.sprite.OrderedUpdates(self.backdrop, self.mana)
self.occupiedGrid = []
for x in range(0, NUM_COLUMNS):
self.occupiedGrid.append([])
for y in range(0, NUM_ROWS):
self.occupiedGrid[x].append(0)
def debug(self):
for x in range(0, NUM_COLUMNS):
for y in range(0, NUM_ROWS):
print self.occupiedGrid
break
def mainLoop(self):
keepGoing = True
while keepGoing:
clock.tick(5)
pygame.mouse.set_visible(False)
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RCTRL:
self.mana.dir += 90
if self.mana.dir > 360:
self.mana.dir = 90
elif event.key == pygame.K_RALT:
self.mana.dir -= 90
if self.mana.dir < 0:
self.mana.dir = 270
if event.key == pygame.K_d:
self.debug()
if event.key == pygame.K_s:
self.mana.settle(self.occupiedGrid)
self.allSprites.clear (screen, self.background)
self.allSprites.update()
self.allSprites.draw(screen)
pygame.display.flip()
pygame.mouse.set_visible(True)
def main():
game = Game()
game.mainLoop()
if __name__ == "__main__":
main()






