Делаю физический движок

This commit is contained in:
2026-05-25 18:00:55 +03:00
parent e02e2ad194
commit 2b50846297
4 changed files with 30 additions and 17 deletions
+4 -2
View File
@@ -3,14 +3,16 @@ import math
class Bullet(arcade.Sprite): class Bullet(arcade.Sprite):
ls = arcade.SpriteList() ls = arcade.SpriteList()
def __init__(self,x,y,a,shift=0): def __init__(self,x,y,a,shift=0,power=0,owner=None):
super().__init__( super().__init__(
'./assets/laserBlue01.png', './assets/laserBlue01.png',
scale=0.7) scale=power/30)
self.angle = a self.angle = a
self.center_x = x + math.sin(self.angle * math.pi / 180) * shift self.center_x = x + math.sin(self.angle * math.pi / 180) * shift
self.center_y = y + math.cos(self.angle * math.pi / 180) * shift self.center_y = y + math.cos(self.angle * math.pi / 180) * shift
self.speed = 10 self.speed = 10
self.power = power
self.owner = owner
Bullet.ls.append(self) Bullet.ls.append(self)
def destroy(self): def destroy(self):
Bullet.ls.remove(self) Bullet.ls.remove(self)
+4
View File
@@ -12,8 +12,11 @@ class MainView(arcade.View):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.background_color = (100,100,200) self.background_color = (100,100,200)
self.block_list = arcade.SpriteList()
self.map = Map(SCREEN_WIDTH,SCREEN_HEIGHT,64,64) self.map = Map(SCREEN_WIDTH,SCREEN_HEIGHT,64,64)
self.player = list(filter(lambda tank: tank.type=='player', Tank.ls))[0] self.player = list(filter(lambda tank: tank.type=='player', Tank.ls))[0]
self.physics_engine = arcade.PhysicsEngineSimple(self.player.get_sprite(),Map.block_list)
def on_draw(self): def on_draw(self):
self.clear() self.clear()
@@ -23,6 +26,7 @@ class MainView(arcade.View):
Bullet.draw() Bullet.draw()
def on_update(self,time_delta): def on_update(self,time_delta):
self.physics_engine.update()
Tank.update() Tank.update()
Bonus.update_list(time_delta) Bonus.update_list(time_delta)
Bullet.update_list() Bullet.update_list()
+5 -3
View File
@@ -6,6 +6,7 @@ from random import randint
class Map(): class Map():
ground_tiles = arcade.SpriteList() ground_tiles = arcade.SpriteList()
object_tiles = arcade.SpriteList() object_tiles = arcade.SpriteList()
block_list = arcade.SpriteList()
def __init__(self,width,height,tw,th): def __init__(self,width,height,tw,th):
self.height = height self.height = height
self.width = width self.width = width
@@ -27,9 +28,9 @@ class Map():
' e e ', ' e e ',
' s ', ' s ',
' ', ' ',
' p ', ' s p ',
' ', ' ',
' e ', ' e s ',
' ', ' ',
' s e ', ' s e ',
] ]
@@ -59,10 +60,11 @@ class Map():
self.height - (self.tileh//2 + i * self.tileh), self.height - (self.tileh//2 + i * self.tileh),
'player') 'player')
elif self.objects[i][j] == 'e': elif self.objects[i][j] == 'e':
Tank( tank = Tank(
self.tilew//2 + j * self.tilew, self.tilew//2 + j * self.tilew,
self.height - (self.tileh//2 + i * self.tileh) self.height - (self.tileh//2 + i * self.tileh)
) )
Map.block_list.append(tank.get_sprite())
elif self.objects[i][j] == 's': elif self.objects[i][j] == 's':
Bonus( Bonus(
self.tilew//2 + j * self.tilew, self.tilew//2 + j * self.tilew,
+17 -12
View File
@@ -5,16 +5,17 @@ from bonus import Bonus
class Tank(): class Tank():
ls = list() ls = list()
def __init__(self,x,y,type='enemy'): def __init__(self,x,y,type='enemy',max_health=100,speed = 5):
self.sp_body = arcade.SpriteList() self.sp_body = arcade.SpriteList()
self.sp_gun = arcade.SpriteList() self.sp_gun = arcade.SpriteList()
self.type = type self.type = type
self.x = x self.x = x
self.y = y self.y = y
self.gun_angle = 0 self.gun_angle = 0
self.speed = 5 self.speed = speed
self.health = 100 self.max_health = max_health
self.max_health = 100 self.health = self.max_health
self.power = 10
if type == 'player': if type == 'player':
body = arcade.Sprite( body = arcade.Sprite(
'./assets/tankBody_blue.png', './assets/tankBody_blue.png',
@@ -43,6 +44,8 @@ class Tank():
self.sp_gun.append(gun) self.sp_gun.append(gun)
Tank.ls.append(self) Tank.ls.append(self)
def get_sprite(self):
return self.sp_body[0]
def gun_to_xy(self,x,y): def gun_to_xy(self,x,y):
for gun in self.sp_gun: for gun in self.sp_gun:
gun.angle = math.atan2(x-gun.center_x,y-gun.center_y) * 180 / math.pi gun.angle = math.atan2(x-gun.center_x,y-gun.center_y) * 180 / math.pi
@@ -53,15 +56,17 @@ class Tank():
if dx != 0 or dy != 0: if dx != 0 or dy != 0:
body.angle = math.atan2(dx,dy) * 180 / math.pi body.angle = math.atan2(dx,dy) * 180 / math.pi
for gun in self.sp_gun: for gun in self.sp_gun:
gun.change_x = dx*self.speed gun.change_x = self.sp_body[0].change_x
gun.change_y = dy*self.speed gun.change_y = self.sp_body[0].change_y
def shoot(self): def shoot(self):
for gun in self.sp_gun: for gun in self.sp_gun:
Bullet( Bullet(
gun.center_x, gun.center_x,
gun.center_y, gun.center_y,
gun.angle, gun.angle,
shift = 50 shift = 20+self.power*0.6,
power = self.power,
owner=self
) )
def destroy(self): def destroy(self):
Tank.ls.remove(self) Tank.ls.remove(self)
@@ -77,17 +82,17 @@ class Tank():
for bonus in colls: for bonus in colls:
if bonus.type == 'star': if bonus.type == 'star':
for gun in tank.sp_gun: for gun in tank.sp_gun:
if gun.cur > len(gun.textures): if gun.cur < len(gun.textures)-1:
gun.cur = 0
gun.set_texture(gun.cur)
else:
gun.cur += 1 gun.cur += 1
gun.set_texture(gun.cur) gun.set_texture(gun.cur)
tank.power *= 2
bonus.destroy() bonus.destroy()
#Столкновения с пулями #Столкновения с пулями
colls = Bullet.get_colls(tank.sp_body[0]) colls = Bullet.get_colls(tank.sp_body[0])
for bullet in colls: for bullet in colls:
tank.health -= 10 if tank == bullet.owner:
continue
tank.health -= bullet.power
bullet.destroy() bullet.destroy()
if tank.health <= 0: if tank.health <= 0:
tank.destroy() tank.destroy()