Skip to main content
Total re-write of my original reply based on clarified information from the OP.
Source Link
Ian Moote
  • 214
  • 1
  • 8

You'reSorry for the delay in getting back to this question is a little unclear. Things move on maps, and/or maps move under things. Objects on maps are typically stored in lists or some other data structure Based upon your clarification I have completely re-written this answer.

ForWhat you're basically doing here is "tiling". You have a zero-indexed matrix with5x5 map (0,0real pixel dimensions are 500x500) in the top left-hand corner the objectsand each coordinate on the map can have a rock or not have a rock. You will have a tile for no rock on the map, and another tile which will have the rock. This tile will be find bya static or animated graphics image like a y * mapWidth + x.png, .jpg, or .gif and you would copy -- or "blit" -- it onto the display in the proper place.

I don't have those graphical files so I have to make do. I will create a "surface" for the tile, and instead of importing an image into it I'll just fill it with a background colour:

maptileEmpty = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]

for y in range(3):
    for x in range(5):
        printpygame.Surface("({}100,{}100) = {}")
tileEmpty.formatfill(x(0, y255, map[y*5+x]0))

You'd probably have thisI will base the tile for the rock on the empty tile, then just add the "rock" over top of whatever's there. The "rock" isn't elaborate in any way, just a functiongrey circle, but I first will copy the empty tile:

deftileRock whatsatthecoordinates(x,= ytileEmpty.copy():
  tempRect global= maptileRock.get_rect()
pygame.draw.circle(tileRock, (128,1,28,128), tempRect.center, returntempRect.center[0], map[y*5+x]tempRect.center[0])

or you may actually passWhat's going on here is that I'm creating a new surface for the rock by copying the surface which contains the "empty" map tile. To do the figuring-outs I'll need to get the function, whichrect of that surface. On that surface I will simply draw a grey circle. The .draw.circle() method is well-documented, but I'll need the colour, the centre of the rect, and the width of the line used to draw the circle. The .center property of the rect conveniently gives us the width of the line as well as the centre of the circle.

You wouldn't do it this way, of course; you'd have a little more versatile:tilesheet already drawn up with 100x100 (or whatever) images and you'd just pick off of that.

def whatsatthecoordinates(map, x, y):
   return map[y*5+x]

As per my previous reply, you'd still use y * mapwidth + x to pluck the map contents from the bitmapped map contents. What's different in this reply is that you'd multiply the x and y by the width of the tile to find where to put it.

orThere are many ways that you could objectifyget tiles onto the display, but for simplicity I've chosen to use a simple 'for x / for y' iteration. In practice you'd have a limited view onto your map and you'd have to calculate a rectangle out of a much larger bitmap to display it.

Here is a working program which demonstrates the basics:

classimport Mappygame

pygame.init(): 

#this is the entire def5x5 __init__(self,map xSize,as ySize,a listofmapcontents):bitmap
bitMap = [1,1,1,1,0,
      if not type(listofmapcontents) == type(list()):0,0,0,0,0,
            raise RuntimeError0,0,0,0,0,
        self.xSize = xSize0,0,0,0,0,
        self.ySize = ySize0,0,0,0,0]

#some predefined colour constants
FIELD = pygame.Color(0,255,0)   self.array =#colour listofmapcontents

of the empty field
ROCK def= whatsatthesecoordinatespygame.Color(self128, x128, y128):
 #colour of the rock

#set up the main if500x500 xdisplay
display <= selfpygame.xSize and y <display.set_mode((500, self500))
pygame.ySize:display.set_caption("Tile Time")

#make an empty tile
tileEmpty = pygame.Surface((100,100))
tileEmpty.fill(FIELD)

#make a tile with a rock
tileRock = returntileEmpty.copy()
tempRect self= tileRock.array[yget_rect()
pygame.draw.circle(tileRock, *ROCK, selftempRect.xSizecenter, +tempRect.center[0], x]tempRect.center[0])

#draw the map -- very straight-forward!
for x in elserange(5):
       #because bitMap is 5x5
  print("Coordinates ({}, {})for outy ofin range.".format(x, y)5)
 :  #because bitMap is 5x5
      print("Should be xdest = 0 to(x {}* and100, y = 0 to {}".format(self.xSize-1,* self.ySize-1)100)
        #calculate where to put returnthe None
tile
    def placearock(self, x, y):
     if bitMap[y*5+x] == map[y1: * xSize + x] = 1

#gets contents of bitmap defat destroyarock(self, x, y):
        map[y * xSize + x] = 0

map = Mapdisplay.blit(5tileRock, 3,dest) [1, 0, 0, 0,#display 0,a 0,rock
 0, 0, 0, 0, 0, 1, 0, 0, 0])
else:
for y in range(3):
    for x in range(5):
  display.blit(tileEmpty, dest)   #display not print("a rock

pygame.display.flip({},{}) = {}".format(x, y,#update map.whatsatthesecoordinates(x,the y))display

input()

Not fully tested. IfThe input() is just to keep the code simple; no need for a game loop for this doesn't answer your question. Depending how you run the code you may need to Ctl-C out of it, please clarifythough.

You're question is a little unclear. Things move on maps, and/or maps move under things. Objects on maps are typically stored in lists or some other data structure.

For a zero-indexed matrix with (0,0) in the top left-hand corner the objects on the map can be find by y * mapWidth + x:

map = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]

for y in range(3):
    for x in range(5):
        print("({},{}) = {}".format(x, y, map[y*5+x]))

You'd probably have this in a function:

def whatsatthecoordinates(x, y):
   global map
   return map[y*5+x]

or you may actually pass the map to the function, which is a little more versatile:

def whatsatthecoordinates(map, x, y):
   return map[y*5+x]

or you could objectify map:

class Map():
    def __init__(self, xSize, ySize, listofmapcontents):
        if not type(listofmapcontents) == type(list()):
            raise RuntimeError
        self.xSize = xSize
        self.ySize = ySize
        self.array = listofmapcontents

    def whatsatthesecoordinates(self, x, y):
        if x < self.xSize and y < self.ySize:
            return self.array[y * self.xSize + x]
        else:
            print("Coordinates ({}, {}) out of range.".format(x, y))
            print("Should be x = 0 to {} and y = 0 to {}".format(self.xSize-1, self.ySize-1))
            return None

    def placearock(self, x, y):
        map[y * xSize + x] = 1

    def destroyarock(self, x, y):
        map[y * xSize + x] = 0

map = Map(5, 3, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0])

for y in range(3):
    for x in range(5):
        print("({},{}) = {}".format(x, y, map.whatsatthesecoordinates(x, y)))

Not fully tested. If this doesn't answer your question, please clarify.

Sorry for the delay in getting back to this question. Based upon your clarification I have completely re-written this answer.

What you're basically doing here is "tiling". You have a 5x5 map (real pixel dimensions are 500x500) and each coordinate on the map can have a rock or not have a rock. You will have a tile for no rock on the map, and another tile which will have the rock. This tile will be a static or animated graphics image like a .png, .jpg, or .gif and you would copy -- or "blit" -- it onto the display in the proper place.

I don't have those graphical files so I have to make do. I will create a "surface" for the tile, and instead of importing an image into it I'll just fill it with a background colour:

tileEmpty = pygame.Surface((100,100))
tileEmpty.fill((0,255,0))

I will base the tile for the rock on the empty tile, then just add the "rock" over top of whatever's there. The "rock" isn't elaborate in any way, just a grey circle, but I first will copy the empty tile:

tileRock = tileEmpty.copy()
tempRect = tileRock.get_rect()
pygame.draw.circle(tileRock, (128,1,28,128), tempRect.center, tempRect.center[0], tempRect.center[0])

What's going on here is that I'm creating a new surface for the rock by copying the surface which contains the "empty" map tile. To do the figuring-outs I'll need to get the rect of that surface. On that surface I will simply draw a grey circle. The .draw.circle() method is well-documented, but I'll need the colour, the centre of the rect, and the width of the line used to draw the circle. The .center property of the rect conveniently gives us the width of the line as well as the centre of the circle.

You wouldn't do it this way, of course; you'd have a tilesheet already drawn up with 100x100 (or whatever) images and you'd just pick off of that.

As per my previous reply, you'd still use y * mapwidth + x to pluck the map contents from the bitmapped map contents. What's different in this reply is that you'd multiply the x and y by the width of the tile to find where to put it.

There are many ways that you could get tiles onto the display, but for simplicity I've chosen to use a simple 'for x / for y' iteration. In practice you'd have a limited view onto your map and you'd have to calculate a rectangle out of a much larger bitmap to display it.

Here is a working program which demonstrates the basics:

import pygame

pygame.init() 

#this is the entire 5x5 map as a bitmap
bitMap = [1,1,1,1,0,
          0,0,0,0,0,
          0,0,0,0,0,
          0,0,0,0,0,
          0,0,0,0,0]

#some predefined colour constants
FIELD = pygame.Color(0,255,0)    #colour of the empty field
ROCK = pygame.Color(128,128,128) #colour of the rock

#set up the main 500x500 display
display = pygame.display.set_mode((500, 500))
pygame.display.set_caption("Tile Time")

#make an empty tile
tileEmpty = pygame.Surface((100,100))
tileEmpty.fill(FIELD)

#make a tile with a rock
tileRock = tileEmpty.copy()
tempRect = tileRock.get_rect()
pygame.draw.circle(tileRock, ROCK, tempRect.center, tempRect.center[0], tempRect.center[0])

#draw the map -- very straight-forward!
for x in range(5):      #because bitMap is 5x5
    for y in range(5):  #because bitMap is 5x5
        dest = (x * 100, y * 100)   #calculate where to put the tile
        if bitMap[y*5+x] == 1:      #gets contents of bitmap at (x,y)
            display.blit(tileRock, dest)    #display a rock
        else:
            display.blit(tileEmpty, dest)   #display not a rock

pygame.display.flip()   #update the display

input()

The input() is just to keep the code simple; no need for a game loop for this. Depending how you run the code you may need to Ctl-C out of it, though.

Added missing formatting to a print string.
Source Link
Ian Moote
  • 214
  • 1
  • 8
class Map():
    def __init__(self, xSize, ySize, listofmapcontents):
        if not type(listofmapcontents) == type(list()):
            raise RuntimeError
        self.xSize = xSize
        self.ySize = ySize
        self.array = listofmapcontents

    def whatsatthesecoordinates(self, x, y):
        if x < self.xSize and y < self.ySize:
            return self.array[y * self.xSize + x]
        else:
            print("Coordinates ({}, {}) out of range.".format(x, y))
            print("Should be x = 0 to {} and y = 0 to {}".format(self.xSize-1, self.ySize-1))
            return None

    def placearock(self, x, y):
        map[y * xSize + x] = 1

    def destroyarock(self, x, y):
        map[y * xSize + x] = 0

map = Map(5, 3, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0])

for y in range(3):
    for x in range(5):
        print("({},{}) = {}".format(x, y, map.whatsatthesecoordinates(x, y)))
class Map():
    def __init__(self, xSize, ySize, listofmapcontents):
        if not type(listofmapcontents) == type(list()):
            raise RuntimeError
        self.xSize = xSize
        self.ySize = ySize
        self.array = listofmapcontents

    def whatsatthesecoordinates(self, x, y):
        if x < self.xSize and y < self.ySize:
            return self.array[y * self.xSize + x]
        else:
            print("Coordinates ({}, {}) out of range.")
            print("Should be x = 0 to {} and y = 0 to {}".format(self.xSize-1, self.ySize-1))
            return None

    def placearock(self, x, y):
        map[y * xSize + x] = 1

    def destroyarock(self, x, y):
        map[y * xSize + x] = 0

map = Map(5, 3, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0])

for y in range(3):
    for x in range(5):
        print("({},{}) = {}".format(x, y, map.whatsatthesecoordinates(x, y)))
class Map():
    def __init__(self, xSize, ySize, listofmapcontents):
        if not type(listofmapcontents) == type(list()):
            raise RuntimeError
        self.xSize = xSize
        self.ySize = ySize
        self.array = listofmapcontents

    def whatsatthesecoordinates(self, x, y):
        if x < self.xSize and y < self.ySize:
            return self.array[y * self.xSize + x]
        else:
            print("Coordinates ({}, {}) out of range.".format(x, y))
            print("Should be x = 0 to {} and y = 0 to {}".format(self.xSize-1, self.ySize-1))
            return None

    def placearock(self, x, y):
        map[y * xSize + x] = 1

    def destroyarock(self, x, y):
        map[y * xSize + x] = 0

map = Map(5, 3, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0])

for y in range(3):
    for x in range(5):
        print("({},{}) = {}".format(x, y, map.whatsatthesecoordinates(x, y)))
Source Link
Ian Moote
  • 214
  • 1
  • 8

You're question is a little unclear. Things move on maps, and/or maps move under things. Objects on maps are typically stored in lists or some other data structure.

For a zero-indexed matrix with (0,0) in the top left-hand corner the objects on the map can be find by y * mapWidth + x:

map = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]

for y in range(3):
    for x in range(5):
        print("({},{}) = {}".format(x, y, map[y*5+x]))

You'd probably have this in a function:

def whatsatthecoordinates(x, y):
   global map
   return map[y*5+x]

or you may actually pass the map to the function, which is a little more versatile:

def whatsatthecoordinates(map, x, y):
   return map[y*5+x]

or you could objectify map:

class Map():
    def __init__(self, xSize, ySize, listofmapcontents):
        if not type(listofmapcontents) == type(list()):
            raise RuntimeError
        self.xSize = xSize
        self.ySize = ySize
        self.array = listofmapcontents

    def whatsatthesecoordinates(self, x, y):
        if x < self.xSize and y < self.ySize:
            return self.array[y * self.xSize + x]
        else:
            print("Coordinates ({}, {}) out of range.")
            print("Should be x = 0 to {} and y = 0 to {}".format(self.xSize-1, self.ySize-1))
            return None

    def placearock(self, x, y):
        map[y * xSize + x] = 1

    def destroyarock(self, x, y):
        map[y * xSize + x] = 0

map = Map(5, 3, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0])

for y in range(3):
    for x in range(5):
        print("({},{}) = {}".format(x, y, map.whatsatthesecoordinates(x, y)))

Not fully tested. If this doesn't answer your question, please clarify.