Skip to content

Commit

Permalink
Tossing stuff (initial)
Browse files Browse the repository at this point in the history
  • Loading branch information
tatjam committed Jul 10, 2022
1 parent d0e42fe commit ca59b3c
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 21 deletions.
Binary file modified res/level1/map.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 27 additions & 19 deletions src/game/entities/enemy.nim
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ type
health: float
hurt_wav: WavHandle
sprite*: AnimatedSprite
phys_body: Body
phys_body*: Body
phys_shape: Shape
user_data*: UserData
toss_timer: float

proc create_rockman*(pos: Vec2f, space: Space, id: int): Enemy =
result = new(Enemy)
Expand Down Expand Up @@ -57,26 +58,29 @@ proc update*(this: var Enemy, player: Player, objects: var seq[PhysicalObject],
if this.health <= 0.0:
this.die(objects, space)

if this.kind == ekRockman:
# Simple moving towards player behaviour, with random retreats
if this.retreat:
this.retreat_timer -= dt * 4.0
if this.retreat_timer < 0.0:
this.retreat = false
this.retreat_goal = rand(10.0)
else:
this.retreat_timer += dt
if this.retreat_timer > this.retreat_goal:
this.retreat = true

var player_dir = this.sprite.position - player.sprite.position
let player_dist = length(player_dir)
player_dir /= player_dist
if player_dist < 300.0:
if this.toss_timer < 0.0:
if this.kind == ekRockman:
# Simple moving towards player behaviour, with random retreats
if this.retreat:
this.phys_body.velocity = v(player_dir.x * 70.0, this.phys_body.velocity.y)
this.retreat_timer -= dt * 4.0
if this.retreat_timer < 0.0:
this.retreat = false
this.retreat_goal = rand(10.0)
else:
this.phys_body.velocity = v(-player_dir.x * 60.0, this.phys_body.velocity.y)
this.retreat_timer += dt
if this.retreat_timer > this.retreat_goal:
this.retreat = true

var player_dir = this.sprite.position - player.sprite.position
let player_dist = length(player_dir)
player_dir /= player_dist
if player_dist < 300.0:
if this.retreat:
this.phys_body.velocity = v(player_dir.x * 70.0, this.phys_body.velocity.y)
else:
this.phys_body.velocity = v(-player_dir.x * 60.0, this.phys_body.velocity.y)
else:
this.toss_timer -= dt


proc hurt*(this: var Enemy, point: Vect) =
Expand All @@ -85,6 +89,10 @@ proc hurt*(this: var Enemy, point: Vect) =
this.phys_body.applyImpulseAtWorldPoint(v(0, -5000.0), p)
discard this.hurt_wav.play_sound()

# Enemies are knocked by default
proc toss*(this: var Enemy) =
this.toss_timer = 2.0

proc draw*(this: var Enemy) =
renderer.draw(this.sprite)

2 changes: 1 addition & 1 deletion src/game/entities/physical_object.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type
PhysicalObject* = ref object
kind: ObjectKind
sprite*: AnimatedSprite
phys_body: Body
phys_body*: Body
phys_shape: Shape
user_data: UserData

Expand Down
61 changes: 60 additions & 1 deletion src/game/entities/player.nim
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,67 @@ proc hit(this: Player, enemies: seq[Enemy]): bool =

return query_data.hit

type ToTossData = object
enemies: seq[Enemy]
objects: seq[PhysicalObject]
force: Vect

proc query_toss(sh: Shape, p: Vect, n: Vect, a: Float, data: pointer) {.cdecl.} =
# There's this weird 38 user data that we must ignore
var body: Body = nil
var datac = cast[ptr ToTossData](data)
if cast[int](sh.userData) > 100000:
let udata = cast[ptr UserData](sh.userData)[]
if udata.kind == bkEnemy:
let enemy_idx = udata.point
body = datac[].enemies[enemy_idx].phys_body
datac[].enemies[enemy_idx].toss()
elif udata.kind == bkObject:
let object_idx = udata.point
body = datac[].objects[object_idx].phys_body

if body != nil:
let fp = body.position
body.applyImpulseAtWorldPoint(fp, datac[].force)

proc toss(this: Player, enemies: seq[Enemy], objects: seq[PhysicalObject]) =
discard
let rays = this.phys_body.position + v(0.0, 0.0)
var raye = this.phys_body.position + v(34.0, 23.0)
if this.sprite.scale.x < 0.0:
raye = this.phys_body.position + v(-34.0, 23.0)

let filter = chipmunk.ShapeFilter(
group:nil,
categories: 0b1111,
mask: 0b1111
)
var query_data: ToTossData
query_data.enemies = enemies
query_data.objects = objects

# Toss timer goes from 0.0 to 1.8
# from 0.0 to 0.4 we do nothing
# from 0.4 to 1.2 linear rampup (0.8 size)
# from 1.2 to 1.8 capped
var toss_prog = 0.0
if this.attack_timer > 0.4:
toss_prog = (this.attack_timer - 0.4) / 0.8
toss_prog = min(toss_prog, 1.0)

if toss_prog == 0.0:
return

# Direction
var ver = 0.5 * sin(PI * toss_prog)
if this.sprite.scale.x < 0.0:
query_data.force = v(-1.0, -ver)
else:
query_data.force = v(1.0, -ver)

var force = 300.0 * (cos(PI * 0.5 * toss_prog - PI * 0.5) + 0.3)
query_data.force = v(query_data.force.x * force, query_data.force.y * force)

segmentQuery(this.phys_space, rays, raye, Float(4.0), filter, query_toss, addr query_data)

proc update*(this: var Player, enemies: seq[Enemy], objects: seq[PhysicalObject]) =
# Ground check
Expand Down

0 comments on commit ca59b3c

Please sign in to comment.