1

I'm making a civilization builder game in pygame. Right now all you can do is click on cities to claim them as yours and every 2 seconds you get money equal to how many cities you have. So the problem I'm at right now is because of for event in pygame.event.get(): the screen only updates when I move my mouse. I'm not sure how to rearrange the code so it updates by itself.

import pygame, time, random, threading
import numpy as np
from PIL import Image
from threading import Timer

pygame.init()
width=525
height=700
screen = pygame.display.set_mode( (width, height ) )
pygame.display.set_caption('Territory Game')

font = pygame.font.Font('freesansbold.ttf', 20)

base = pygame.image.load("base.png").convert()
character = pygame.image.load("character.png").convert()
captured_base = pygame.image.load("captured-base.png").convert()

xIm = 10 # x coordnate of image
yIm = 10 # y coordinate of image

Startlist = []
for lop in range(441):
    Startlist.append(random.randint(0,20))
Map = np.reshape((Startlist),(21, 21))
Startlist = []
Map[10,10] = 1
xcounter = -1
captured = ([[10,10]])
money = 0

def printit():
    global money
    money += len(captured)
    t = Timer(2, printit)
    t.start()
t = Timer(2, printit)
t.start()
running = True
while (running):
    for event in pygame.event.get():
        screen.fill((79,250,91))
        pygame.draw.rect(screen, (0,0,0), (0,525,525,10))
        pygame.draw.rect(screen, (164,164,164), (0,535,525,165))
        for iterate in np.nditer(Map):
            xcounter +=1
            Icony = int(xcounter/21)
            Iconx = xcounter-(Icony*21)
            if iterate == 1:
                if [Iconx,Icony] not in captured:
                    screen.blit(base,(Iconx*25,Icony*25))
                if [Iconx,Icony] in captured:
                    screen.blit(captured_base,(Iconx*25,Icony*25))
                if event.type == pygame.MOUSEBUTTONDOWN:
                    #Set the x, y postions of the mouse click
                    x, y = event.pos
                    if base.get_rect().collidepoint(x-(Iconx*25), y-(Icony*25)):
                        if [Iconx,Icony] not in captured:
                            captured.append([Iconx,Icony])
        for thing in captured:
            screen.blit(captured_base,(thing[0]*25,thing[1]*25))

        screen.blit(font.render("Money: "+str(money), True, (0,0,0)),(5, 541))
        xcounter = -1
        pygame.display.flip()
        if event.type == pygame.QUIT:
            running = False
pygame.quit()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
TNTOutburst
  • 124
  • 1
  • 7
  • 2
    You shouldnt do anything in the ‘ for event in pygame.event.get():’ loop other than process user input. After this for loop but still in the while loop is where you should be doing your rendering – Iain Shelvington Dec 29 '19 at 06:21
  • @Iain Shelvington thank you, that helped me get it to work – TNTOutburst Dec 29 '19 at 08:50

1 Answers1

1

[...] So the problem I'm at right now is because of for event in pygame.event.get(): the screen only updates when I move my mouse [...]

The answer is encoded in the question. You have to do the update of the window in the main application loop, rather than the event loop. The event loop has to process the user input (mentioned in the comment to your question) and change game status to reflect the inputs. But the responsibility of the event loop is not to draw the scene.

For an optimal control flow the main application loop has to do the following:

  • handle the events
  • clear the display
  • draw the scene
  • update the display

This causes that the scene is redraw in every frame with the current states of the game:

running = True
while running:

    # handle the events
    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            running = False

        if event.type == pygame.MOUSEBUTTONDOWN:
            xcounter = -1
            for iterate in np.nditer(Map):
                xcounter +=1
                Icony = int(xcounter/21)
                Iconx = xcounter-(Icony*21)
                if iterate == 1:
                    #Set the x, y postions of the mouse click
                    x, y = event.pos
                    if base.get_rect().collidepoint(x-(Iconx*25), y-(Icony*25)):
                        if [Iconx,Icony] not in captured:
                            captured.append([Iconx,Icony])

    # clear the display
    screen.fill((79,250,91))

    # draw the scene
    pygame.draw.rect(screen, (0,0,0), (0,525,525,10))
    pygame.draw.rect(screen, (164,164,164), (0,535,525,165))

    xcounter = -1
    for iterate in np.nditer(Map):
        xcounter += 1
        Icony = int(xcounter/21)
        Iconx = xcounter-(Icony*21)
        if iterate == 1:
            if [Iconx,Icony] not in captured:
                screen.blit(base,(Iconx*25,Icony*25))
            if [Iconx,Icony] in captured:
                screen.blit(captured_base,(Iconx*25,Icony*25))

    for thing in captured:
        screen.blit(captured_base,(thing[0]*25,thing[1]*25))

    screen.blit(font.render("Money: "+str(money), True, (0,0,0)),(5, 541))

    # update the display
    pygame.display.flip()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174