Reputation: 71
Below is the code I am trying to get working, i currently have it creating the sprites although once the second sprite is created the movement for the first is stopped.
Say there are 2 sprites both of them should be moving individually, completely random from each other.
The code creates a new sprite every 3 seconds(for testing purposes once the code is working it will be set to 10 seconds)
class enemymove(object):
def create():
global enemy, radiusenemy, xenemy, yenemy
amount = 0
enemy = list()
xenemy = list()
yenemy = list()
enemypositionx = list()
enemypositiony = list()
lastop = len(enemy)
enemy.append(amount)
xenemy.append(amount)
yenemy.append(amount)
enemypositionx.append(amount)
enemypositiony.append(amount)
amount = amount + 1
radiusenemy = 12.5
enemypositionx[lastop] = random.uniform(12.5, resX-12.5)
enemypositiony[lastop] = random.uniform(12.5, resY-12.5)
print(lastop)
enemy[lastop] = canvas.create_oval((enemypositionx[lastop]) + radiusenemy ,(enemypositiony[lastop]) - radiusenemy ,(enemypositionx[lastop]) - radiusenemy ,(enemypositiony[lastop]) + radiusenemy, fill="black", outline="black")
xenemy[lastop] = (canvas.coords(enemy[lastop])[2]) - 12.5
yenemy[lastop] = (canvas.coords(enemy[lastop])[3]) - 12.5
Thread(target = spawntime.timer).start()
enemymove.movement(lastop);
def movement(lastop):
global timer
timer = random.randint(150,3000)
count = random.randint(1, 4)
print(count)
if count == 1:
enemymove.up(lastop);
if count == 2:
enemymove.downward(lastop);
if count == 3:
enemymove.rightran(lastop);
if count == 4:
enemymove.leftran(lastop);
def up(lastop):
global xenemy, yenemy
print ("forward")
yenemy[lastop] = (canvas.coords(enemy[lastop])[1])
canvas.coords(enemy[lastop], xenemy[lastop] + radiusenemy, yenemy[lastop] + radiusenemy, xenemy[lastop] - radiusenemy, yenemy[lastop] - radiusenemy)
print(yenemy)
print(xenemy)
canvas.after(timer, enemymove.movement, lastop)
def downward(lastop):
global xenemy, yenemy
print("back")
yenemy[lastop] = (canvas.coords(enemy[lastop])[3])
canvas.coords(enemy[lastop], xenemy[lastop] - radiusenemy, yenemy[lastop] + radiusenemy, xenemy[lastop] + radiusenemy, yenemy[lastop] - radiusenemy)
print(yenemy)
print(xenemy)
canvas.after(timer, enemymove.movement, lastop)
def rightran(lastop):
global xenemy, yenemy
print("right")
xenemy[lastop] = (canvas.coords(enemy[lastop])[2])
canvas.coords(enemy[lastop], xenemy[lastop] - radiusenemy, yenemy[lastop] - radiusenemy, xenemy[lastop] + radiusenemy, yenemy[lastop] + radiusenemy)
print(yenemy)
print(xenemy)
canvas.after(timer, enemymove.movement, lastop)
def leftran(lastop):
global xenemy, yenemy
print("left")
xenemy[lastop] = (canvas.coords(enemy[lastop])[0])
canvas.coords(enemy[lastop], xenemy[lastop] - radiusenemy, yenemy[lastop] - radiusenemy, xenemy[lastop] + radiusenemy, yenemy[lastop] + radiusenemy)
print(yenemy)
print(xenemy)
canvas.after(timer, enemymove.movement, lastop)
class spawntime():
def timer():
global timeset
timeset = 3
spawntime.calculation()
def calculation():
global timeset
print ('The count is: ', timeset)
if timeset <= 0:
enemymove.create()
else:
timeset -= 1
canvas.after(1000, spawntime.calculation)
#runs the main code
def main():
global root, canvas
root.title("")
canvas = Canvas(root, width= resX, height=resY, bg = "white")
canvas.pack()
Thread(target = spawntime.timer).start()
root.mainloop()
main()
I'm reasonably new to appending, so making multiple different appended sprites move all together is out of my range, and so I am unsure of how to get this to work.
Upvotes: 0
Views: 791
Reputation: 142641
I don't understand your code so I create own version. Now every enemy moves after random time. After random time I add new enemy
I keep enemies on list but I don't need this list.
import random
import tkinter as tk
# --- constants --- # UPPERCASE name
RES_X = 800
RES_Y = 600
# --- classes --- # CamelCase name
class Enemies(object):
def __init__(self, canvas):
# access to canvas
self.canvas = canvas
# started amount of enemies
self.amount = 5
# list for all enemies
self.enemies = list()
# create enemies
for _ in range(self.amount):
self.create_one_enemy()
def create_one_enemy(self):
radius = 12.5 # random
x = random.uniform(radius, RES_X-radius)
y = random.uniform(radius, RES_Y-radius)
oval = self.canvas.create_oval(x-radius, y-radius, x+radius, y+radius, fill="black", outline="black")
# one enemy
enemy = [x, y, radius, oval]
# apped to list - but I don't need this list
self.enemies.append(enemy)
# move this enemy after random time
random_time = random.randint(150, 3000)
root.after(random_time, self.move_one_enemy, enemy)
def move_one_enemy(self, enemy):
#print('moving:', enemy)
# get old values
x, y, radius, oval = enemy
direction = random.randint(1,4)
if direction == 1: # up
y -= radius
elif direction == 2: # down
y += radius
elif direction == 3: # left
x -= radius
elif direction == 4: # right
x += radius
self.canvas.coords(oval, x-radius, y-radius, x+radius, y+radius)
# remember new values
enemy[0] = x
enemy[1] = y
# move this enemy after random time
random_time = random.randint(150, 3000)
root.after(random_time, self.move_one_enemy, enemy)
# --- functions --- # lower_case name
def add_new_enemy():
enemies.create_one_enemy()
# add next enemy after random time
timer = random.randint(150, 3000)
root.after(random_time, add_new_enemy)
# --- main ---
root = tk.Tk()
root.title("")
canvas = tk.Canvas(root, width=RES_X, height=RES_Y, bg="white")
canvas.pack()
# create enemies and move it using `root.after`
enemies = Enemies(canvas)
# add new enemy after random time
random_time = random.randint(150, 3000)
root.after(random_time, add_new_enemy)
root.mainloop()
EDIT: but rather I would create class Enemy
for single enemy and then list enemies
to keep all Enemy
instances.
import random
import tkinter as tk
# --- constants --- # UPPERCASE name
RES_X = 800
RES_Y = 600
# --- classes --- # CamelCase name
class Enemy(object):
'''single enemy'''
def __init__(self, canvas):
# access to canvas
self.canvas = canvas
self.radius = 12.5 # random
self.color = random.choice( ('black', 'red', 'green', 'blue', 'yellow') )
self.x = random.uniform(self.radius, RES_X-self.radius)
self.y = random.uniform(self.radius, RES_Y-self.radius)
self.x1 = self.x-self.radius
self.y1 = self.y-self.radius
self.x2 = self.x+self.radius
self.y2 = self.y+self.radius
self.oval = self.canvas.create_oval(self.x1, self.y1, self.x2, self.y2, fill=self.color, outline=self.color)
self.moving = True
self.start()
def start(self):
'''start moving'''
self.moving = True
# move this enemy after random time
random_time = random.randint(150, 3000)
root.after(random_time, self.move)
def stop(self):
'''stop moving'''
self.moving = False
def move(self):
if self.moving: # to stop root.after
direction = random.randint(1,4)
if direction == 1: # up
self.y -= self.radius
self.y1 -= self.radius
self.y2 -= self.radius
elif direction == 2: # down
self.y += self.radius
self.y1 += self.radius
self.y2 += self.radius
elif direction == 3: # left
self.x -= self.radius
self.x1 -= self.radius
self.x2 -= self.radius
elif direction == 4: # right
self.x += self.radius
self.x1 += self.radius
self.x2 += self.radius
self.canvas.coords(self.oval, self.x1, self.y1, self.x2, self.y2)
# move this enemy after random time
random_time = random.randint(150, 3000)
root.after(random_time, self.move)
# --- functions --- # lower_case name
def add_new_enemy():
enemies.append(Enemy(canvas))
# add next enemy after random time
timer = random.randint(150, 3000)
root.after(random_time, add_new_enemy)
# --- main ---
root = tk.Tk()
root.title("")
canvas = tk.Canvas(root, width=RES_X, height=RES_Y, bg="white")
canvas.pack()
# 5 enemies at the beginning
enemies = list()
for _ in range(5):
enemies.append(Enemy(canvas))
# add new enemy after random time
random_time = random.randint(150, 3000)
root.after(random_time, add_new_enemy)
root.mainloop()
And now you can use list to stop/start enemies
for one_enemy in enemies:
one_enemy.stop()
or check some information
for one_enemy in enemies:
print("x:", one_enemy.x)
print("y:", one_enemy.y)
btw: and then you can create EnemiesGroup
class
EDIT: EnemiesGroup
and buttons to control group
import random
import tkinter as tk
# --- constants --- # UPPERCASE name
RES_X = 800
RES_Y = 600
# --- classes --- # CamelCase name
class Enemy(object):
'''single enemy'''
def __init__(self, canvas):
# access to canvas
self.canvas = canvas
self.radius = 12.5 # random
self.color = random.choice( ('black', 'red', 'green', 'blue', 'yellow') )
self.x = random.uniform(self.radius, RES_X-self.radius)
self.y = random.uniform(self.radius, RES_Y-self.radius)
self.x1 = self.x-self.radius
self.y1 = self.y-self.radius
self.x2 = self.x+self.radius
self.y2 = self.y+self.radius
self.oval = self.canvas.create_oval(self.x1, self.y1, self.x2, self.y2, fill=self.color, outline=self.color)
self.moving = True
self.start()
def start(self):
'''start moving'''
self.moving = True
# move this enemy after random time
random_time = random.randint(150, 3000)
root.after(random_time, self.move)
def stop(self):
'''stop moving'''
self.moving = False
def move(self):
if self.moving: # to stop root.after
direction = random.randint(1,4)
if direction == 1: # up
self.y -= self.radius
self.y1 -= self.radius
self.y2 -= self.radius
elif direction == 2: # down
self.y += self.radius
self.y1 += self.radius
self.y2 += self.radius
elif direction == 3: # left
self.x -= self.radius
self.x1 -= self.radius
self.x2 -= self.radius
elif direction == 4: # right
self.x += self.radius
self.x1 += self.radius
self.x2 += self.radius
self.canvas.coords(self.oval, self.x1, self.y1, self.x2, self.y2)
# move this enemy after random time
random_time = random.randint(150, 3000)
root.after(random_time, self.move)
class EnemiesGroup(object):
def __init__(self, canvas):
self.canvas = canvas
self.enemies = list()
self.moving = True
def add_new_enemy(self):
# can be only 5 enemies
if len(self.enemies) < 5:
e = Enemy(self.canvas)
# stop new enemy if all enemies are stoped
e.moving = self.moving
self.enemies.append(e)
else:
print("You have 5 enemies - I can't add more.")
def stop_all_enemies(self):
for e in self.enemies:
e.stop()
# all enemies are stoped
self.moving = False
def start_all_enemies(self):
for e in self.enemies:
e.start()
# all enemies are moving
self.moving = True
# --- functions --- # lower_case name
def add_new_enemy():
enemies_group.add_new_enemy()
# add next enemy after random time
timer = random.randint(150, 3000)
root.after(random_time, add_new_enemy)
# --- main ---
root = tk.Tk()
root.title("")
canvas = tk.Canvas(root, width=RES_X, height=RES_Y, bg="white")
canvas.pack()
# enemies
enemies_group = EnemiesGroup(canvas)
for _ in range(5):
enemies_group.add_new_enemy()
# add new enemy after random time
random_time = random.randint(150, 3000)
root.after(random_time, add_new_enemy)
# buttons to control all enemies
button_stop = tk.Button(root, text='STOP', command=enemies_group.stop_all_enemies)
button_stop.pack()
button_start = tk.Button(root, text='START', command=enemies_group.start_all_enemies)
button_start.pack()
button_add = tk.Button(root, text='ADD NEW ENEMY', command=enemies_group.add_new_enemy)
button_add.pack()
root.mainloop()
EDIT: removing enemy by clicking oval.
In add_new_enemy
I bind to oval
event <Button-1>
and function clicked
(with enemy object).
Function clicked
removes oval
from canvas
and removes enemy
from enemies group
.
class EnemiesGroup(object):
# ... other functions ...
def clicked(self, event, enemy):
print('clicked:', enemy),
# remove oval from canvas
self.canvas.delete(enemy.oval)
# remove enemy from list
self.enemies.remove(enemy)
# create new enemy after 10s
root.after(10000, self.add_new_enemy)
def add_new_enemy(self):
# can be only 5 enemies
if len(self.enemies) < 5:
print('create new enemy')
e = Enemy(self.canvas)
# stop new enemy if all enemies are stoped
e.moving = self.moving
# bind mouse button to enemy
self.canvas.tag_bind(e.oval, '<Button-1>', lambda event:self.clicked(event, e))
self.enemies.append(e)
else:
print("You have 5 enemies - I can't add more.")
# ... other functions ...
Upvotes: 1