1

I'm having a bug in a small pygame excercise where I'm trying to build a hex-field boardgame...

I tried to minimize the code, but since I have absolutely no clue, where something goes wrong, it's still a bit in order to work:

import pygame, random, math, time, sys


# Important Game Vars - SCREEN and PLAYFIELD
width = 1024
length = 680

hexW = 50
hexH = 60
playFieldSize = 1

midpoint = [int(width / 2), int(length / 2)]
print('midpoint:', midpoint)

playFields = [midpoint]
holderList = []

for i in range(playFieldSize):
    for currentpoint in playFields:
        field = [currentpoint[0] + hexW, currentpoint[1]]
        if field not in playFields and field not in holderList:
            holderList.append(field)
        field = [currentpoint[0] - hexW, currentpoint[1]]
        if field not in playFields and field not in holderList:
            holderList.append(field)
        field = [currentpoint[0] - hexW / 2, currentpoint[1] + hexH * 0.75]
        if field not in playFields and field not in holderList:
            holderList.append(field)
        field = [currentpoint[0] + hexW / 2, currentpoint[1] + hexH * 0.75]
        if field not in playFields and field not in holderList:
            holderList.append(field)
        field = [currentpoint[0] - hexW / 2, currentpoint[1] - hexH * 0.75]
        if field not in playFields and field not in holderList:
            holderList.append(field)
        field = [currentpoint[0] + hexW / 2, currentpoint[1] - hexH * 0.75]
        if field not in playFields and field not in holderList:
            holderList.append(field)
        print('holder: ', holderList)
    for i in holderList:
        playFields.append(i)
    holderList = []

print('playfields:', playFields)
print('len playfields:', len(playFields))

# Important Game Vars - POSITIONS AND COUNTS

heroPos = []
activeHeroNo = 0
print('heroPos: ', heroPos)

heroCount = 3
for i in (random.choices(playFields, k=heroCount)):
    heroPos.append(i)

print('heroPos: ', heroPos)
inputCooldown = 10
inputCooldownCounter = inputCooldown

playSurface = pygame.display.set_mode((width, length))
pygame.display.set_caption('Herobrawl')

# Colors
red = pygame.Color(255, 0, 0)
blue = pygame.Color(0, 0, 255)
green = pygame.Color(0, 255, 0)
white = pygame.Color(255, 255, 255)
black = pygame.Color(0, 0, 0)
grey = pygame.Color(128, 128, 128)

# FPS controller
fpsController = pygame.time.Clock()


# Important Game Functions
def HexDrawer(pos):
    return [[pos[0] - hexW / 2, pos[1] - hexH / 4], [pos[0], pos[1] - hexH / 2], [pos[0] + hexW / 2, pos[1] - hexH / 4],
            [pos[0] + hexW / 2, pos[1] + hexH / 4], [pos[0], pos[1] + hexH / 2], [pos[0] - hexW / 2, pos[1] + hexH / 4]]


def Move(direction):
    if direction == 'RIGHT':
        heroPos[activeHeroNo][0] += hexW
    if direction == 'LEFT':
        heroPos[activeHeroNo][0] -= hexW
    if direction == 'UPRIGHT':
        heroPos[activeHeroNo][0] += hexW * 0.5
        heroPos[activeHeroNo][1] -= hexH * 0.75
    if direction == 'DOWNRIGHT':
        heroPos[activeHeroNo][0] += hexW * 0.5
        heroPos[activeHeroNo][1] += hexH * 0.75
    if direction == 'UPLEFT':
        heroPos[activeHeroNo][0] -= hexW * 0.5
        heroPos[activeHeroNo][1] -= hexH * 0.75
    if direction == 'DOWNLEFT':
        heroPos[activeHeroNo][0] -= hexW * 0.5
        heroPos[activeHeroNo][1] += hexH * 0.75
    else:
        return


# Main Logic and Loop *************************************************************************************************

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT] and not keys[pygame.K_DOWN] and not keys[pygame.K_UP]:
        if inputCooldownCounter == 0:
            Move('LEFT')
            inputCooldownCounter = inputCooldown
    if keys[pygame.K_RIGHT] and not keys[pygame.K_DOWN] and not keys[pygame.K_UP]:
        if inputCooldownCounter == 0:
            Move('RIGHT')
            inputCooldownCounter = inputCooldown
    if keys[pygame.K_DOWN] and keys[pygame.K_RIGHT]:
        if inputCooldownCounter == 0:
            Move('DOWNRIGHT')
            inputCooldownCounter = inputCooldown
    if keys[pygame.K_DOWN] and keys[pygame.K_LEFT]:
        if inputCooldownCounter == 0:
            Move('DOWNLEFT')
            inputCooldownCounter = inputCooldown
    if keys[pygame.K_UP] and keys[pygame.K_RIGHT]:
        if inputCooldownCounter == 0:
            Move('UPRIGHT')
            inputCooldownCounter = inputCooldown
    if keys[pygame.K_UP] and keys[pygame.K_LEFT]:
        if inputCooldownCounter == 0:
            Move('UPLEFT')
            inputCooldownCounter = inputCooldown
    if keys[pygame.K_SPACE]:  # change hero
        if inputCooldownCounter == 0:
            if activeHeroNo <= heroCount - 2:
                activeHeroNo += 1
            else:
                activeHeroNo = 0
            print('activeHeroNo: ', activeHeroNo)
            inputCooldownCounter = inputCooldown

    # Rendering
    playSurface.fill(grey)

    for pos in heroPos:  # rendering heroes
        if pos == heroPos[activeHeroNo]:
            pygame.draw.polygon(playSurface, white, HexDrawer(pos))
        else:
            pygame.draw.polygon(playSurface, green, HexDrawer(pos))

    for field in playFields :  # rendering hex fields
        pygame.draw.polygon(playSurface, black, HexDrawer(field), 3)
        #pygame.draw.polygon(playSurface, black, HexDrawer(pos))

    # common main logic parts

    if inputCooldownCounter >= 1:
        inputCooldownCounter -= 1

    pygame.display.flip()

    fpsController.tick(30)

Now to the bug... scroll down to the bottom of the code where the rendering happens, you'll see I render all items in "heroPos" as solid colors, and after that, on top, all items in "playFields" as black outlines.

So no matter how long I think about it, I don't get why the movement moves the black outline as well!?!

In theory it should work: I build a list of coords for the playfield I choose the amount n(heroCount) of random coords for heroPos The "Move" function modifies a entry in heroPos NOT in playfield

I'm really thankful for any advice whatsoever that could point me into the right direction! Cheers guys!

Thilo G
  • 95
  • 5
  • 1
    The positions in `heroPos` and the matching positions in `playField` refer to the *same object*. If you modify one, the other will see the change too. – MB-F May 08 '18 at 13:46
  • Excellent answer, thanks! I'm baffled, I made it this long without realising this - I always thought assignments where creating new objects. – Thilo G May 08 '18 at 14:50
  • While I'm at it though, how should I .append choices elegantely as a copy? or append to heroPos list and copy it after? - nevermind, I guess its: heroPos.append(copy.copy(i)) ...wrote faster then I was thinking... – Thilo G May 08 '18 at 14:55
  • 2
    if you follow the duplicate chain in the link I posted you will find [this answer](https://stackoverflow.com/a/2612815/3005167) that lists some options. – MB-F May 08 '18 at 14:58

0 Answers0