4 Commits

2 changed files with 220 additions and 91 deletions
+220
View File
@@ -0,0 +1,220 @@
import arcade
from random import randint
import numpy as np
SCREEN_SIZE = (800,600)
TICK_TIME = 0.5
class Wolf(arcade.SpriteCircle):
ls = arcade.SpriteList()
def __init__(self,parent=None):
super().__init__(radius=5, color=arcade.color.RED)
if parent:
self.center_x = parent.center_x
self.center_y = parent.center_y
else:
self.center_x = randint(1,SCREEN_SIZE[0])
self.center_y = randint(1,SCREEN_SIZE[1])
self.age = 0
self.age_to_bride = 3
self.health = 30
self.speed = 8
self.move_target = 0
self.target_timer = 0
Wolf.ls.append(self)
@classmethod
def update(cls):
if len(cls.ls) == 0:
Wolf()
for e in cls.ls:
e.age += 1
if e.age >= 30:
cls.ls.remove(e)
continue
if e.health >= 50 and e.age_to_bride < e.age:
Wolf(e)
e.health -= 30
hit_cow = arcade.check_for_collision_with_list(e,Cow.ls)
for c in hit_cow:
e.health += c.health
Cow.ls.remove(c)
else:
if e.target_timer <= 0:
e.move_target = Cow.get_near(e.center_x,e.center_y)
e.target_timer = 3
if e.move_target:
vec = cls.get_vector(e.center_x,e.move_target.center_x,
e.center_y,e.move_target.center_y)
new_x = e.center_x + vec[0]*e.speed
new_y = e.center_y + vec[1]*e.speed
if 0 < new_x < SCREEN_SIZE[0] and 0 < new_y < SCREEN_SIZE[1]:
e.center_x = new_x
e.center_y = new_y
e.health -= 1
if e.health <= 0:
cls.ls.remove(e)
@classmethod
def draw(cls):
cls.ls.draw()
@staticmethod
def get_vector(src_x,target_x,src_y,target_y):
source = np.array([src_x, src_y])
target = np.array([target_x, target_y])
direction = target - source
length = np.linalg.norm(direction)
return direction / length
class Cow(arcade.SpriteCircle):
ls = arcade.SpriteList()
def __init__(self,parent=None):
super().__init__(radius=5, color=arcade.color.BROWN)
if parent:
self.center_x = parent.center_x
self.center_y = parent.center_y
else:
self.center_x = randint(1,SCREEN_SIZE[0])
self.center_y = randint(1,SCREEN_SIZE[1])
self.age = 0
self.age_to_bride = 3
self.health = 30
self.speed = 5
self.move_target = 0
self.target_timer = 0
Cow.ls.append(self)
@classmethod
def get_near(cls,x,y):
dist_list = list()
for e in cls.ls:
dist_list.append((e,((e.center_x - x)**2 + (e.center_y - y)**2)**0.5))
dist_list.sort(key=lambda x: x[1])
if len(dist_list) == 0:
return None
return dist_list[0][0]
@classmethod
def update(cls):
if len(cls.ls) == 0:
Cow()
for c in cls.ls:
c.age += 1
if c.age >= 30:
cls.ls.remove(c)
continue
if c.health >= 50 and c.age_to_bride < c.age:
Cow(c)
c.health -= 30
hit_plant = arcade.check_for_collision_with_list(c,Plant.ls)
for p in hit_plant:
c.health += p.width
Plant.ls.remove(p)
else:
if c.target_timer <= 0:
c.move_target = Plant.get_near(c.center_x,c.center_y)
c.target_timer = 5
if c.move_target:
vec = cls.get_vector(c.center_x,c.move_target.center_x,
c.center_y,c.move_target.center_y)
new_x = c.center_x + vec[0]*randint(0,c.speed)
new_y = c.center_y + vec[1]*randint(0,c.speed)
if 0 < new_x < SCREEN_SIZE[0] and 0 < new_y < SCREEN_SIZE[1]:
c.center_x = new_x
c.center_y = new_y
c.health -= 1
if c.health <= 0:
cls.ls.remove(c)
@classmethod
def draw(cls):
cls.ls.draw()
@staticmethod
def get_vector(src_x,target_x,src_y,target_y):
source = np.array([src_x, src_y])
target = np.array([target_x, target_y])
direction = target - source
length = np.linalg.norm(direction)
return direction / length
class Plant(arcade.SpriteCircle):
ls = arcade.SpriteList()
def __init__(self,parent=None):
super().__init__(radius=1, color=arcade.color.GREEN)
if parent:
self.center_x = parent.center_x + randint(-parent.fly_distance,parent.fly_distance)
self.center_y = parent.center_y + randint(-parent.fly_distance,parent.fly_distance)
else:
self.center_x = randint(1,SCREEN_SIZE[0])
self.center_y = randint(1,SCREEN_SIZE[1])
self.age = 0
self.fly_distance = 100
self.age_to_plant = 10
if not arcade.check_for_collision_with_list(self,Plant.ls) and 0 < self.center_x < SCREEN_SIZE[0] and 0 < self.center_y < SCREEN_SIZE[1]:
Plant.ls.append(self)
@classmethod
def get_near(cls,x,y):
dist_list = list()
for p in cls.ls:
dist_list.append((p,((p.center_x - x)**2 + (p.center_y - y)**2)**0.5 - p.width ))
dist_list.sort(key=lambda x: x[1])
if len(dist_list) == 0:
return None
if len(dist_list) < 3:
return dist_list[0][0]
return dist_list[randint(0,3)][0]
@classmethod
def update(cls):
for p in cls.ls:
p.age += 1
hit_list = arcade.check_for_collision_with_list(p,cls.ls)
if p.center_x - p.width//2 > 0 and p.center_x + p.width//2 < SCREEN_SIZE[0] and p.center_y - p.height//2 > 0 and p.center_y + p.width//2 < SCREEN_SIZE[1] and not hit_list:
p.width += 2
p.height += 2
else:
for h in hit_list:
if p.width < h.width:
cls.ls.remove(p)
break
if p.age >= p.age_to_plant:
Plant(p)
@classmethod
def draw(cls):
cls.ls.draw()
for p in cls.ls:
p.draw_hit_box()
class MainView(arcade.View):
def __init__(self):
super().__init__()
self.background_color = (100,100,200)
Plant()
self.time = 0
self.cur_time = 0
self.text = None
def on_update(self, delta_time):
self.cur_time += delta_time
if self.cur_time >= TICK_TIME:
print(f'Total plants: {len(Plant.ls)}, total cows: {len(Cow.ls)}')
Plant.update()
Cow.update()
Wolf.update()
self.time += 1
self.cur_time = 0
def on_draw(self):
self.clear()
Plant.draw()
Cow.draw()
Wolf.draw()
if __name__ == '__main__':
window = arcade.Window(*SCREEN_SIZE,"Игра про жизнь")
view = MainView()
window.show_view(view)
arcade.run()
-91
View File
@@ -1,91 +0,0 @@
import arcade
from random import randint
class MainView(arcade.View):
def __init__(self):
super().__init__()
self.background_color = (100,100,200)
self.engine = arcade.PymunkPhysicsEngine(gravity=(0, 0))
self.key_up = False
self.key_down = False
self.key_left = False
self.key_right = False
self.objects = arcade.SpriteList()
for _ in range(10):
self.objects.append(
arcade.Sprite(
':resources:/images/tiles/bomb.png',
scale=0.5,
center_x = randint(0,800),
center_y = randint(0,800)
)
)
self.engine.add_sprite_list(
self.objects,
mass=1,
friction=0.0,
elasticity=0.0,
moment_of_inertia=float('inf'),
damping=0.1
)
self.walls = arcade.SpriteList()
for i in range(15):
for j in range(15):
if i==0 or j==0 or i==12 or j==12:
self.walls.append(
arcade.Sprite(
':resources:/images/tiles/brickBrown.png',
scale=0.5,
center_x = 32 + i*64,
center_y = 32 + j*64
)
)
self.engine.add_sprite_list(
self.walls,
body_type=arcade.PymunkPhysicsEngine.STATIC)
def on_update(self, delta_time):
self.objects.update()
for obj in self.objects:
if self.key_up:
self.engine.apply_force(obj,(0,100))
if self.key_down:
self.engine.apply_force(obj,(0,-100))
if self.key_left:
self.engine.apply_force(obj,(-100,0))
if self.key_right:
self.engine.apply_force(obj,(100,0))
self.engine.step(delta_time)
def on_draw(self):
self.clear()
self.objects.draw()
self.walls.draw()
def on_key_press(self,key,mod):
if key == arcade.key.W:
self.key_up = True
if key == arcade.key.S:
self.key_down = True
if key == arcade.key.A:
self.key_left = True
if key == arcade.key.D:
self.key_right = True
def on_key_release(self,key,mod):
if key == arcade.key.W:
self.key_up = False
if key == arcade.key.S:
self.key_down = False
if key == arcade.key.A:
self.key_left = False
if key == arcade.key.D:
self.key_right = False
if __name__ == '__main__':
window = arcade.Window(800,800,'')
view = MainView()
window.show_view(view)
arcade.run()