I am creating a program that allows a user to make a custom dice, but when I open a GUI window with a button that calls the backend dice roll logic, it breaks. In other words, the window doesn't open, and the code just runs in the terminal. It doesn't happen when the button is clicked like I want it to, instead when I run the code, it doesn't open any GUI window and the code executes in the terminal. The code works without the GUI, and if i take out the dice button callback, the GUI works but together it doesn't.
Any help is appreciated!
import random
import tkinter as tk
def dice_roll():
dice = []
x = 0
# used to check if the input is a whole number, if it isn't, you get a message
while True:
while x == 0:
try:
SIDE_AMT = int(input("How many sides would you like? (min is 2, max is infinite): ")) # amt is amount
x = 1
except ValueError:
print("Sorry it has to be a whole number.")
if SIDE_AMT > 1:
for side in range(SIDE_AMT):
print(f"What would you like side {side + 1} to be?:")
dice.append(str(input()))
break
else:
print("You can't have a dice with one side!")
x = 0
# roll function
def roll():
dice_side = random.choice(dice)
print(f"I choose {dice_side}!")
roll_num = 0
while True:
if roll_num == 0:
spin_it = str(input("Type 'roll' if you would like to roll the dice: "))
if spin_it == "roll":
roll()
else:
print("Sorry, you have to type roll correctly.")
roll_num += 1
elif roll_num == 1:
while True:
spin_it = str(input("Type 'roll' if you would like to roll the dice again!: "))
if spin_it == "roll":
roll()
else:
print("Sorry, you have to type roll correctly.")
if __name__ == '__main__':
gui = tk.Tk()
gui.title("Dice Roll")
gui.geometry("1912x1090")
gui.configure(bg='#a2a2a1', borderwidth=5,
relief="raised")
# title
title = tk.Label(gui, text='Unique Dice', font=("Times
New Roman", 52))
title.configure(bg='#a2a2a1', fg='#195190',
borderwidth=3, relief='raised')
# make a dice?
dice = tk.Button(gui,
text="Yes!",
fg="red",
command=dice_roll())
no_dice = tk.Button(gui,
text="No",
fg="red",
command=quit)
# frame = tk.Frame(gui, height=200, width=200)
# frame['borderwidth'] = 10
# frame['relief'] = 'sunken'
# frame.pack()
dice.pack()
no_dice.pack()
title.pack()
gui.mainloop()
you may want to do something like this:
import tkinter as tk
from random import choice
root = tk.Tk()
root.geometry('400x600')
root.resizable(False, False)
root.config(bg='light blue')
dice_numbers = [1, 2, 3, 4, 5, 6]
rolled_nums = []
def roll():
if len(rolled_nums):
rolled_nums[0].pack_forget()
rolled_nums.pop(0)
chosen_number = choice(dice_numbers)
text = tk.Label(root, text=f'{chosen_number}',
font='arial 500 bold', bg='light blue')
text.pack()
rolled_nums.append(text)
button = tk.Button(root, text='Roll Dice!', font='arial 20 bold', relief='raised', width='300',
bg='dark red', fg='black', command=lambda: roll())
button.pack()
root.mainloop()
fell free to adjust this code and if you have questions -> ask
Related
I would like to set up a trading bot via Google Cloud to run around the clock.
In Google Cloud Functions I use the Inline editor with runtime Python 3.7.
I have two questions:
1) Main.py section: Here I copied the full code of my Python script (Trading Bot) - see code below for reference (which works well when run as a script in my IDE Spyder).
However, below Google asks to provide a function to execute. However, my code is just a script with no main function. Can I just put at the top of the code e.g.: "def trading_bot(self):" and indent the remaining part below?
While the code as a script copied below works well, if I add the "def trading_bot(self):" at the top in my IDE (Spyder), the code doesnt seem to work properly...How can I make sure the code within the function runs properly, when I call the function from Google Cloud (or from my IDE).
2) Requirements.txt section: Can you provide guidance what exactly I need to put there, i.e. can I look up the dependencies used in my code somewhere? I use Anaconda for distribution, the classes imported for the script are at the top of the script provided below.
Thanks for any help. Glad also for your advice if you think Google Cloud Functions is not the best approach to run a trading bot but it seemed to me to be the simplest solution.
import bitmex
import json
from time import sleep
from bitmex_websocket import BitMEXWebsocket
import logging, time, requests
import numpy as np
import pandas as pd
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore")
from datetime import datetime
import math
from statistics import mean
#-------------------------
#variable
symbol = "XBTUSD"
#standard API connection
api_key = "XXX"
api_secret = "XXX"
#True for testnet
client = bitmex.bitmex(test=False, api_key=api_key, api_secret=api_secret)
#------------------
# Trading algorithm
symbol = "XBTUSD"
ordType = 'Stop'
#starting order quantity
orderQty = 1
leftBars = 6
rightBars = 2
#round to 0.5
def round_to_BTC(n):
result = round(n*2)/2
return result
t=1
while t < 1000000:
time_now = (time.strftime('%H:%M:%S', time.localtime(int(time.time()))))
t_now = time_now[6:8]
t1 = "00"
t2 = "59"
FMT = '%S'
def days_hours_minutes_seconds(td):
return td.days, td.seconds//3600, (td.seconds//60)%60, td.seconds
if t_now == str('00'):
#give 1 second to candlestick to properly close
sleep(1)
elif t_now > str('00') and t_now <= str('59'):
s1 = datetime.strptime(t2, FMT) - datetime.strptime(t_now, FMT)
s1_seconds = days_hours_minutes_seconds(s1)[3]+2
sleep(s1_seconds)
else:
pass
time_now = (time.strftime('%H:%M:%S', time.localtime(int(time.time()))))
print("The time is now: " + time_now)
#most recent swing candles, get highs and lows / #binsizes = {"1m": 1, "5m": 5, "1h": 60, "1d": 1440}
#+1 is the middle bar
totalBars = leftBars + rightBars + 1
swing_candles = client.Trade.Trade_getBucketed(symbol=symbol, binSize="1m", count=totalBars, reverse=True).result()[0]
last_highs = []
last_lows = []
i=0
while i <= (len(swing_candles)-1):
last_highs.append(swing_candles[i]["high"])
last_lows.append(swing_candles[i]["low"])
i += 1
#get the highest high and the lowest low
highest_high = max(last_highs)
lowest_low = min(last_lows)
#check if there are existing positions & orders
if client.Position.Position_get().result()[0] != []:
positions_quantity = client.Position.Position_get().result()[0][0]["currentQty"]
else:
positions_quantity = 0
#check existing orders
buy_orders_quantity = []
sell_orders_quantity = []
orders_quantity = client.Order.Order_getOrders(filter=json.dumps({"open": True})).result()[0]
h=0
while h <= len(orders_quantity)-1:
if orders_quantity[h]["side"] == "Sell":
sell_orders_quantity.append(orders_quantity[h])
elif orders_quantity[h]["side"] == "Buy":
buy_orders_quantity.append(orders_quantity[h])
h += 1
if highest_high == last_highs[rightBars] and positions_quantity == 0:
if buy_orders_quantity == []:
client.Order.Order_new(symbol = symbol, orderQty = orderQty*1, side = "Buy", ordType = 'Stop', stopPx = (highest_high+0.5), execInst ='LastPrice' ).result()
elif buy_orders_quantity != []:
orderID = buy_orders_quantity[0]["orderID"]
client.Order.Order_amend(orderID=orderID, orderQty=orderQty*1, stopPx = (highest_high+0.5)).result()
else:
pass
elif highest_high == last_highs[rightBars] and positions_quantity > 0:
#dont place any additional long
pass
elif highest_high == last_highs[rightBars] and positions_quantity < 0:
if buy_orders_quantity != []:
orderID = buy_orders_quantity[0]["orderID"]
client.Order.Order_amend(orderID=orderID, orderQty=orderQty*2, stopPx = (highest_high+0.5)).result()
else:
client.Order.Order_new(symbol = symbol, orderQty = (orderQty)*2, side = "Buy", ordType = 'Stop', stopPx = (highest_high+0.5), execInst ='LastPrice' ).result()
elif lowest_low == last_lows[rightBars] and positions_quantity == 0:
if sell_orders_quantity == []:
client.Order.Order_new(symbol = symbol, orderQty = (orderQty)*-1, side = "Sell", ordType = 'Stop', stopPx = (lowest_low-0.5), execInst ='LastPrice' ).result()
elif sell_orders_quantity != []:
orderID = sell_orders_quantity[0]["orderID"]
client.Order.Order_amend(orderID=orderID, orderQty=orderQty*-1, stopPx = (lowest_low-0.5)).result()
else:
pass
elif lowest_low == last_lows[rightBars] and positions_quantity < 0:
#dont place any additional shorts
pass
elif lowest_low == last_lows[rightBars] and positions_quantity > 0:
if sell_orders_quantity != []:
orderID = sell_orders_quantity[0]["orderID"]
client.Order.Order_amend(orderID=orderID, orderQty=orderQty*-2, stopPx = (lowest_low-0.5)).result()
else:
client.Order.Order_new(symbol = symbol, orderQty = (orderQty)*-2, side = "Sell", ordType = 'Stop', stopPx = (lowest_low-0.5), execInst ='LastPrice' ).result()
positions_quantity = client.Position.Position_get().result()[0][0]["currentQty"]
buy_orders_quantity = []
sell_orders_quantity = []
orders_quantity = client.Order.Order_getOrders(filter=json.dumps({"open": True})).result()[0]
h=0
while h <= len(orders_quantity)-1:
if orders_quantity[h]["side"] == "Sell":
sell_orders_quantity.append(orders_quantity[h])
elif orders_quantity[h]["side"] == "Buy":
buy_orders_quantity.append(orders_quantity[h])
h += 1
if positions_quantity > 0:
if sell_orders_quantity != []:
orderID = sell_orders_quantity[0]["orderID"]
client.Order.Order_amend(orderID=orderID, orderQty=orderQty*-2).result()
elif positions_quantity < 0:
if buy_orders_quantity != []:
orderID = buy_orders_quantity[0]["orderID"]
client.Order.Order_amend(orderID=orderID, orderQty=orderQty*2).result()
print("Your current position is " + str(positions_quantity))
print("This is iteration: " + str(t))
t += 1
As concerns my second question, I solved it in the following way:
In the command terminal, type: pip freeze > requirements.txt
The file contains all dependencies.
As concerns question 1 I still dont understand what code exactly needs to be put in the section main.py.
Thanks!
Cloud Functions is not an adequate product for your use case. They are mostly used for lightweight calculations or not high resource consuming methods.
The magic of CF consists in that they execute your code whenever you hit the URL that belongs to it. This is important to understand for your question number 1. If you want your function to work, you need to always create a method that accepts the "request" parameter. As it is the information from the HTTP request made when the URL is hit.
You can take a look at this document for reference.
You function should always start like this
from flask #import your dependencies
def my_awesome_function(request):
#Your logic
In this case you should write "my_awesome_function" on the Function to Execute textbox.
You also have to be careful with your resources, as CF have 5 presentations. They differ in CPU and Memory you can read more about this here.
This, among many reasons, you should not use Cloud Functions for your bot. I could recommend you to use a virtual machine, but activities related to use of the Services for cryptocurrency mining without Google's prior written approval are frowned upon and may result in the deactivation of your product as stated in the terms of service.
Modifying the Squirrel Eat Squirrel Pygame for a class project. Trying to add in a menu, with basic Start, Quit and Settings buttons. I have the buttons there, and they will light up as the mouse scrolls over them. However, I can't figure out how to call their respective functions when I click on them. I am trying to call them by this:
def runMenu(self):
mainloop = True
while mainloop:
self.__clock.tick(50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
mainloop == False
if event.type == MOUSEBUTTONDOWN:
for item in self.__items:
#print(item)
if item.isMouseSelecting(pygame.mouse.get_pos()):
print(self.__functions)
self.__functions[item]() #HERE <----
I believe it is because I am using a dictionary in my if name == "main" (See below) therefore it's not actually the dictionary, but its referencing its location? If that makes sense. (i'm not very good at explaining it, so sorry)
if __name__ == "__main__":
screen = pygame.display.set_mode((640, 480), 0 , 32)
menuItems = ('Start', 'Quit', 'Settings')
functions = {'Start': main, 'Quit': terminate, 'Settings': None}
pygame.display.set_caption('Main Menu')
game = MainMenu(screen, functions, menuItems)
game.runMenu()
The error it gives me in shell:
>>> ================================ RESTART ================================
>>>
({'Start': <function main at 0x2969ab0>, 'Settings': None, 'Quit': <function terminate at 0x2969cf0>}, '#')
{'Start': <function main at 0x2969ab0>, 'Settings': None, 'Quit': <function terminate at 0x2969cf0>}
Traceback (most recent call last):
File "/Users/tjleggz/Documents/CS 110/squirrel/squirrel.py", line 501, in <module>
game.runMenu()
File "/Users/tjleggz/Documents/CS 110/squirrel/squirrel.py", line 138, in runMenu
self.__functions[item]() #cant call bc its not same object, just a ref to object or something???#
KeyError: <__main__.MenuItem object at 0x29758c8>
>>>
THANKS!
EDIT:
class MenuItem(pygame.font.Font):
def __init__(self, text, font=None, fontSize=30,
fontColor=(255, 255, 255), (posX, posY)=(0, 0)):
pygame.font.Font.__init__(self, font, fontSize) #initializes font module
self.__text = text
self.__fontSize = fontSize
self.__fontColor = fontColor
self.label = self.render(self.__text, 1, self.__fontColor) #not private??
self.width = self.label.get_rect().width
self.height = self.label.get_rect().height
self.__posX = posX
self.__posY = posY
self.position = posX, posY
def set_position(self, x, y):
self.position = (x, y)
self.__posX = x
self.__posY = y
def isMouseSelecting(self, (posX, posY)): #change to conditional?!
if (posX >= self.__posX and posX <= self.__posX + self.width) and \
(posY >= self.__posY and posY <= self.__posY + self.height):
return True
else:
return False
def setFontColor(self, rgbTuple):
self.fontColor = rgbTuple
self.label = self.render(self.__text, 1, self.fontColor)
Your self.items contains MenuItem objects, not strings which are the keys to your dictionary. You can work around this in a couple ways, for example you could use the __text attribute of MenuItem which is I think what you are looking for.
A better way to do this (instead of using a dictionary of functions like you are now) might be to pass an on_click function to each MenuItem instance you make, and then you just have to write
if item.isMouseSelecting(pygame.mouse.get_pos()):
item.on_click()
however you seem to be relatively new to programming, so you may just want to use the first suggestion.
i am totally new to python. thus please explain thoroughly wen u respond to my query.
in my code i want to measure the time the player lasts before his cursor touches the bouncing ball on the screen but the time i am obtaining is the sum of all the seconds since the first time the command was initialised. i need to stop the counting of seconds as soon as the user ends the game and to begin afresh wen the play again option is chosen...
also i wud lyk a way to make the player qualify for the next level without usin d detection of position of mouse....since dat is making the program code logic incorrect...
here is my code:
import pygame,sys
from pygame.locals import*
from pygame import *
import random
def main():
# set up sounds
# import pygame
#gameOverSound = pygame.mixer.Sound('gameover.wav')
#pygame.mixer.music.load('background.mid')
#from pygame import *
#import random
#pygame.mixer.pre_init(44100, 16, 2, 4096)
#background =image.load('C:\Users\Administrator\Desktop\oearth.png')
ballpic = image.load('ball1.png')
ballpic.set_colorkey((0,0,0))
#find a way to include verification of more than one colour key
# to add more than one shape....pending
numballs = 10
delay = 5
done = False
balls = []
stars = []
#generate an if loop for execution of both the parts
k = 2
init()
screen = display.set_mode((640, 480))
display.set_caption('mouse game by shivangi and ananya')
event.set_grab(1)
#pygame.time.Clock() Creates a Clock object (assign this to a name), which you can then call the tick() method on
#to find out how much time has passed since the last time you called tick()
#pygame.time.delay(milliseconds) Pauses game for time specified
#pygame.time.get_ticks() Returns the number of milliseconds passed since pygame.init() was #called
for count in range(numballs):
balls.append(dict)
balls[count] = {'x': 0, 'y': 0, 'xmove': random.randint(1, 2), 'ymove': random.randint(1, 2)}
screen = display.set_mode((640, 480)) #####screen = display.set_mode((640,480),FULLSCREEN,32).....check functioning...
#pygame.display.list_modes()
#[(800, 600), (1280, 1024), (1280, 960), (1280, 800), (1280, 768), (1280, 720),
#(1152, 864), (1088, 612), (1024, 768), (960, 600), (848, 480), (800, 600),
#(720, 576), (720, 480), (640, 480), (640, 400), (512, 384), (480, 360), (400, 300),
#(320, 240), (320, 200), (640, 480)]
while done == False:
pygame.time.Clock()
init()
screen.fill((0,100,0))
for count in range(numballs):
screen.blit(ballpic, (balls[count]['x'], balls[count]['y']))
display.update()
time.delay(delay)
for count in range(numballs):
balls[count]['x'] = balls[count]['x'] + balls[count]['xmove']
balls[count]['y'] = balls[count]['y'] + balls[count]['ymove']
for count in range(numballs):
if balls[count]['x'] > 620:
balls[count]['xmove'] = random.randint(-2, 0)
if balls[count]['x'] < -10:
balls[count]['xmove'] = random.randint(0, 6)
if balls[count]['y'] > 470:
balls[count]['ymove'] = random.randint(-9, 0)
if balls[count]['y'] < -10:
balls[count]['ymove'] = random.randint(0, 5)
for e in event.get():
if e.type == KEYUP:
if e.key == K_ESCAPE:
done = True
if screen.get_at((mouse.get_pos())) == (227,209,43):
done = True
if done == True:
#pygame.mixer.init()
break
sec = time.get_ticks()/1000
quit()
while sec < k:
print "you lasted for only",sec,"seconds...try again to qualify for the next level..."
quit()
break
time_lasted = 0
while sec >= k:
starpic = image.load('star.png')
starpic.set_colorkey((0,0,0))
#find a way to include verification of more than one colour key...PENDING
numstars = 30
delay = 8
done = False
stars = []
for count in range(numstars):
stars.append(dict)
stars[count] = {'x': 0, 'y': 0, 'xmove': random.randint(1, 2), 'ymove': random.randint(1, 2)}
screen = display.set_mode((640, 480))
display.set_caption('mouse game')
event.set_grab(1)
while done == False:
init()
screen.fill((160,32,240))
for count in range(numstars):
screen.blit(starpic, (stars[count]['x'], stars[count]['y']))
display.update()
time.delay(delay)
for count in range(numstars):
stars[count]['x'] = stars[count]['x'] + stars[count]['xmove']
stars[count]['y'] = stars[count]['y'] + stars[count]['ymove']
for count in range(numstars):
if stars[count]['x'] > 620:
stars[count]['xmove'] = random.randint(-2, 0)
if stars[count]['x'] < -10:
stars[count]['xmove'] = random.randint(0, 2)
if stars[count]['y'] > 470:
stars[count]['ymove'] = random.randint(-2, 0)
if stars[count]['y'] < -10:
stars[count]['ymove'] = random.randint(0, 2)
for e in event.get():
if e.type == KEYUP:
if e.key == K_ESCAPE:
done = True
if screen.get_at((mouse.get_pos())) == (255,255,255,255):
done = True
if done == True:
time_lasted = time.get_ticks()/1000
quit()
break
#sec = time.update()
#time_lasted = time.update()
#correction of time error to be done....pending....
quit()
print "You lasted for", sec, "seconds in the first level!"
print "\n"
print "you lasted for",time_lasted,"in the second level!"
print "\n"
print "your total score is :", int(sec) + int(time_lasted)
print "\n"
print "game over...! Thank you for playing!! :D :P :)"
quit()
break
main()
x = 1
x = raw_input("Do you want to play again?")
while x.upper() in ['YES','Y']:
main()
x = raw_input("Do you want to play again?")
while x.upper() in ['NO','N']:
break
# when player starts game
start = time.get_ticks()
# during game
current = time.get_ticks()
time_you_played = (current - start)/1000
EDIT:
Timer to count seconds.
class Timer():
def __init__(self):
self._start = 0
def start(self):
self._start = pygame.time.get_ticks()
def current(self):
return (pygame.time.get_ticks() - self._start)/1000
Example - how to use:
import pygame
# add class Timer here
pygame.init()
t = Timer()
t.start() # start or restart timer
pygame.time.wait(3000) # for test only
print t.current() # print seconds
pygame.time.wait(2000) # for test only
print t.current() # print seconds
You don't have to stop timer because you can use start() to restart timer.
OK so I am making a math question game in pygame. I have 8 separate selections so I am spliting them up into functions. Now I have all of my questions and answers in txt files that I am reading into arrays. What I am trying to do is for the first question to pop up, I select my answer, the computer tells if I'm right or wrong, then a button pops up to go to the next question. For some reason, it does not want to loop throught right and the random function alls generates numbers. What am I doing wrong?
import pygame,time,sys,pygbutton,random,time
from pygame.locals import *
pygame.init()
mainclock = pygame.time.Clock()
width = 1024
height = 768
screen = pygame.display.set_mode([width,height])
pygame.display.set_caption('Dividing Fractions')
background = pygame.image.load("tv2.png").convert()
background_poistion = [0,0]
screen.blit(background,background_poistion)
pygame.display.flip()
######tester
def tester_Function():
i = 0
questionUNanswered = 1
Section1Q = [0]*5
Section1Ques = open('questions1.txt','r')
with open('questions1.txt','r') as file:
Section1Q = file.readlines()
Section1A = [0]*5
Section1Ans = open('answer1.txt','r')
with open('answer1.txt','r') as file:
Section1A = file.readlines()
num1 = str(random.randint(0,5))
num2 = str(random.randint(0,5))
question = pygbutton.PygButton((100,40,200,30),Section1Q[i])
tester2 = pygbutton.PygButton((100,70,200,30),'Clicl Here')
Ranswer = pygbutton.PygButton((100,110,200,30),Section1A[i])
Wanswer1 = pygbutton.PygButton((100,150,200,30),num1)
Wanswer2 = pygbutton.PygButton((100,190,200,30),num2)
winner = pygbutton.PygButton((500,190,200,30),'')
question.draw(screen)
tester2.draw(screen)
Ranswer.draw(screen)
Wanswer1.draw(screen)
Wanswer2.draw(screen)
winner.draw(screen)
buttonEvent = Ranswer.handleEvent(event)
buttonEvent2= Wanswer1.handleEvent(event)
buttonEvent3= Wanswer2.handleEvent(event)
if 'click' in buttonEvent:
winner = pygbutton.PygButton((500,190,200,30),'Winner')
winner.draw(screen)
i = i+1
if 'click' in buttonEvent2 :
winner = pygbutton.PygButton((500,190,200,30),'Lose')
winner.draw(screen)
i = i+1
if 'click' in buttonEvent3 :
winner = pygbutton.PygButton((500,190,200,30),'Lose')
winner.draw(screen)
i= i +1
question.draw(screen)
tester2.draw(screen)
Ranswer.draw(screen)
Wanswer1.draw(screen)
Wanswer2.draw(screen)
winner.draw(screen)
while True: # main game loop
for event in pygame.event.get(): # event handling loop
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
tester_Function()
pygame.display.update()
In main loop you call tester_Function() so every loop you starts at the beginning. Every loop you read file, set i to zero, create buttons, etc. Some functions should be done before main loop.
I am currently working on a game called Table Wars, a turn based strategy game for two players. Progress has been going smoothly, until I ran into a problem with spawning units.
The program won't spawn multiple of the same unit, or respawn new ones after the old ones die.
Here is some information that may help:
Each class is stored in a variable: (redI = Red_Infantry())
All functions are stored in the main loop.
The sprite classes have hard-coded X and Y values, used when spawning units and moving units.
What should I do?
As requested, here is the class for the Red Infantry:
class Red_Infantry(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image, self.rect = load_image('Soldier_red.png', -1)
self.selected = 0
self.area = screen.get_rect()
self.rect.topleft = (100, 300)
self.health = 100 #Soldiers are have mediocre toughness.
self.attack_damage = 25
self.range_maximum = 20 #in pixels, this is melee range
self.range_minimum = 0
self.update()
def update(self):
if self.health <= 0:
self.kill()
and the code to spawn this unit:
if spawned_units < 3 and PHASE == 1 and TURN == 'Red':
if REDGOLD < 10:
print "Out of money! Moving to Phase 2!"
PHASE = 2
spawned_units = 0
elif event.type == KEYDOWN and event.key == K_1:
if REDGOLD >= 10 and REDCOMMAND >= 5:
Sprites.append(redI)
REDGOLD -= 10
REDCOMMAND -= 5
spawned_units = spawned_units + 1
else:
print "Not enough gold!"
This is similar style with all units. It performs correctly the first time, but not in the second, third, and so on, meaning I can only have one Soldier. Also, when that soldier dies via self.kill, it won't come back if I try to spawn it.
The part of the spawn procedure you posted doesn't create any new instances. Unless redI is declared as a new Red_Infantry somewhere else, you need to modify the code to create a new instance of Red_Infantry every time you want to spawn a soldier.
sprites.append(Red_Infantry())
To update the sprites:
for sprite in sprites:
sprite.update()
Put movement and other state changes in the update method. This is what pygame expects, but you can use a different style if you want. The main point is you must have multiple instances of Red_Infantry in order to see multiple sprites.
You could also use pygame's Group class instead of a simple list to hold the sprites.
Here's a full example that uses Group instead of list. In the example, an Enemy is spawned each time a key is pressed. Each Enemy prints its unique ID to stdout.
import sys
import random
import pygame
from pygame.locals import *
def main():
pygame.init()
screen = pygame.display.set_mode((480, 320))
enemies = pygame.sprite.Group()
while True:
for event in pygame.event.get():
if event.type == KEYDOWN:
enemies.add(Enemy(screen))
elif event.type == QUIT:
sys.exit()
enemies.update()
screen.fill(pygame.Color("black"))
enemies.draw(screen)
pygame.display.update()
class Enemy(pygame.sprite.Sprite):
def __init__(self, screen):
pygame.sprite.Sprite.__init__(self)
print "created a new sprite:", id(self)
self.image = pygame.image.load("sprite.png")
self.rect = self.image.get_rect()
self.rect.move_ip(random.randint(0, screen.get_width()),
random.randint(0, screen.get_height()))
def update(self):
self.rect.move_ip(random.randint(-3, 3), 0)
if __name__ == "__main__":
main()