diff --git a/res/enemies/rockman_hurt.mp3 b/res/enemies/rockman_hurt.mp3 new file mode 100644 index 0000000..4a9ac6e Binary files /dev/null and b/res/enemies/rockman_hurt.mp3 differ diff --git a/res/level1/back.png b/res/level1/back.png new file mode 100644 index 0000000..03b901a Binary files /dev/null and b/res/level1/back.png differ diff --git a/res/level1/map.png b/res/level1/map.png index 2ed1b27..9df1f14 100644 Binary files a/res/level1/map.png and b/res/level1/map.png differ diff --git a/res/level1/map.yaml b/res/level1/map.yaml index 2d57ff3..de30753 100644 --- a/res/level1/map.yaml +++ b/res/level1/map.yaml @@ -2,6 +2,7 @@ seed: 1234 images: - res/level1/map.png +- res/level1/map_ent.png tiles: - class: ground @@ -19,6 +20,16 @@ tiles: noise: 3.0 color: [200, 200, 200] +- class: B@back + texture: res/level1/back.png + noise: 1.0 + color: [240, 240, 240] + +- class: B@backwood + texture: res/level1/wood_back.png + noise: 0.0 + color: [160, 160, 160] + areas: - name: water color: [0, 0, 255] diff --git a/res/level1/map_ent.png b/res/level1/map_ent.png new file mode 100644 index 0000000..7ee9bf5 Binary files /dev/null and b/res/level1/map_ent.png differ diff --git a/res/level1/wood_back.png b/res/level1/wood_back.png new file mode 100644 index 0000000..2595e78 Binary files /dev/null and b/res/level1/wood_back.png differ diff --git a/res/player/attack.mp3 b/res/player/attack.mp3 new file mode 100644 index 0000000..fde3a90 Binary files /dev/null and b/res/player/attack.mp3 differ diff --git a/res/player/hit.mp3 b/res/player/hit.mp3 new file mode 100644 index 0000000..c7a26da Binary files /dev/null and b/res/player/hit.mp3 differ diff --git a/res/player/hit_connect.mp3 b/res/player/hit_connect.mp3 new file mode 100644 index 0000000..9f1186f Binary files /dev/null and b/res/player/hit_connect.mp3 differ diff --git a/res/player/player.png b/res/player/player.png index ad5506d..81c32d0 100644 Binary files a/res/player/player.png and b/res/player/player.png differ diff --git a/res/player/player.yaml b/res/player/player.yaml index 0e612d3..1574626 100644 --- a/res/player/player.yaml +++ b/res/player/player.yaml @@ -39,4 +39,40 @@ animations: loop: true frames: - clip: [210, 76, 70, 76] - duration: 0.2 \ No newline at end of file + duration: 0.2 +- name: "attack" + loop: false + frames: + - clip: [140, 152, 70, 76] + duration: 0.1 + - clip: [210, 152, 70, 76] + duration: 0.1 + - clip: [280, 152, 70, 76] + duration: 0.1 + - clip: [280, 76, 70, 76] + duration: 0.2 + - clip: [280, 0, 70, 76] + duration: 0.3 +- name: "toss" + loop: false + frames: + - clip: [350, 0, 70, 76] + duration: 0.6 + - clip: [350, 76, 70, 76] + duration: 0.4 + - clip: [350, 152, 70, 76] + duration: 0.1 + - clip: [350, 76, 70, 76] + duration: 0.1 + - clip: [350, 152, 70, 76] + duration: 0.1 + - clip: [350, 76, 70, 76] + duration: 0.1 + - clip: [350, 152, 70, 76] + duration: 0.1 + - clip: [350, 76, 70, 76] + duration: 0.1 + - clip: [350, 152, 70, 76] + duration: 0.1 + - clip: [350, 76, 70, 76] + duration: 0.1 \ No newline at end of file diff --git a/res/player/player_emit.png b/res/player/player_emit.png index 9617de5..6c9a606 100644 Binary files a/res/player/player_emit.png and b/res/player/player_emit.png differ diff --git a/src/engine/graphics/sprite.nim b/src/engine/graphics/sprite.nim index 1a9e833..c88f27b 100644 --- a/src/engine/graphics/sprite.nim +++ b/src/engine/graphics/sprite.nim @@ -206,6 +206,10 @@ proc rotation*(sprite: AnimatedSprite): float = return sprite.sprite.rotation proc animate*(sprite: var AnimatedSprite, dt: float) = + if sprite.animations.has_key(sprite.cur_anim): + var anim = sprite.animations[sprite.cur_anim] + if anim.frame < anim.frames.len: + sprite.sprite.clip = anim.frames[anim.frame].frame if sprite.paused: return diff --git a/src/engine/map/map_loader.nim b/src/engine/map/map_loader.nim index 63d2bc5..66f9f62 100644 --- a/src/engine/map/map_loader.nim +++ b/src/engine/map/map_loader.nim @@ -250,12 +250,12 @@ proc bilinear_interp(tl: Vec3i, tr: Vec3i, bl: Vec3i, br: Vec3i, h: float, v: fl return vec3i(sum.x.int32, sum.y.int32, sum.z.int32) proc marching_squares(tile: Image, scale: int, tile_info: Table[Vec3i, TileData], space: Space, - segments: var seq[SegmentShape]): Tile = + segments: var seq[SegmentShape], collide: bool): Tile = let bounds = get_bounds(tile) echo "Processing tile of size: " & $(bounds.z - bounds.x + 1) & "x" & $(bounds.w - bounds.y + 1) let pos = vec2i(bounds.x * scale.int32, bounds.y * scale.int32) echo bounds - var image = create_image((bounds.z - bounds.x + 2) * scale, (bounds.w - bounds.y + 2) * scale) + var image = create_image((bounds.z - bounds.x + 2) * scale, (bounds.w - bounds.y + 2) * scale, true) var body = newBody(1.0, 1.0) # We travel the corners of the pixels in the map texture @@ -279,57 +279,58 @@ proc marching_squares(tile: Image, scale: int, tile_info: Table[Vec3i, TileData] continue # Generate the segment(s) - if ms_case != 15: - var v0: Vect - var v1: Vect - var has_two: bool - var v2: Vect - var v3: Vect - case ms_case: - of 1, 14: - v0 = v(tx - 0.5, ty + 0.5) - v1 = v(tx, ty + 1.0) - of 2, 13: - v0 = v(tx + 0.5, ty + 0.5) - v1 = v(tx, ty + 1.0) - of 3, 12: - v0 = v(tx - 0.5, ty) - v1 = v(tx + 0.5, ty) - of 4, 11: - v0 = v(tx + 0.5, ty) - v1 = v(tx, ty - 0.5) - of 5: - v0 = v(tx - 0.5, ty) - v1 = v(tx, ty - 0.5) - has_two = true - v2 = v(tx + 0.5, ty + 0.5) - v1 = v(tx, ty + 1.0) - of 6, 9: - v0 = v(tx, ty - 0.5) - v1 = v(tx, ty + 0.5) - of 7, 8: - v0 = v(tx - 0.5, ty) - v1 = v(tx, ty - 0.5) - of 10: - v0 = v(tx - 0.5, ty + 0.5) - v1 = v(tx, ty + 1.0) - has_two = true - v2 = v(tx + 0.5, ty) - v3 = v(tx, ty - 0.5) - else: - discard - - v0 = v(v0.x * scale.toFloat, v0.y * scale.toFloat) - v1 = v(v1.x * scale.toFloat, v1.y * scale.toFloat) - v2 = v(v2.x * scale.toFloat, v2.y * scale.toFloat) - v3 = v(v3.x * scale.toFloat, v3.y * scale.toFloat) - var segment = newSegmentShape(space.staticBody, v0, v1, 1) - segments.add(segment) - discard space.addShape(segments[^1]) - if has_two: - let segment2 = newSegmentShape(space.staticBody, v2, v3, 1) + if collide: + if ms_case != 15: + var v0: Vect + var v1: Vect + var has_two: bool = false + var v2: Vect + var v3: Vect + case ms_case: + of 1, 14: + v0 = v(tx - 0.5, ty + 0.5) + v1 = v(tx, ty + 1.0) + of 2, 13: + v0 = v(tx + 0.5, ty + 0.5) + v1 = v(tx, ty + 1.0) + of 3, 12: + v0 = v(tx - 0.5, ty) + v1 = v(tx + 0.5, ty) + of 4, 11: + v0 = v(tx + 0.5, ty) + v1 = v(tx, ty - 0.5) + of 5: + v0 = v(tx - 0.5, ty) + v1 = v(tx, ty - 0.5) + has_two = true + v2 = v(tx + 0.5, ty + 0.5) + v3 = v(tx, ty + 1.0) + of 6, 9: + v0 = v(tx, ty - 0.5) + v1 = v(tx, ty + 0.5) + of 7, 8: + v0 = v(tx - 0.5, ty) + v1 = v(tx, ty - 0.5) + of 10: + v0 = v(tx - 0.5, ty + 0.5) + v1 = v(tx, ty + 1.0) + has_two = true + v2 = v(tx + 0.5, ty) + v3 = v(tx, ty - 0.5) + else: + discard + + v0 = v(v0.x * scale.toFloat, v0.y * scale.toFloat) + v1 = v(v1.x * scale.toFloat, v1.y * scale.toFloat) + v2 = v(v2.x * scale.toFloat, v2.y * scale.toFloat) + v3 = v(v3.x * scale.toFloat, v3.y * scale.toFloat) + var segment = newSegmentShape(space.staticBody, v0, v1, 1) segments.add(segment) discard space.addShape(segments[^1]) + if has_two: + var segment2 = newSegmentShape(space.staticBody, v2, v3, 1) + segments.add(segment2) + discard space.addShape(segments[^1]) var tldata, trdata, bldata, brdata: Option[TileData] @@ -488,6 +489,7 @@ proc extract_separated_tiles(imageo: Image): seq[Image] = return tiles +# classes of name B@wathever will not have collision (they are useful as backgrounds) proc load_map*(map: string, scale: int, space: Space): Map = let map_info = load_map_info(map) # Load images @@ -524,7 +526,8 @@ proc load_map*(map: string, scale: int, space: Space): Map = for class, images in ground_tiles_img: var tiles: seq[Tile] for image in images: - tiles.add(marching_squares(image, scale, tile_textures, space, segments)) + tiles.add(marching_squares(image, scale, tile_textures, space, segments, + not(class[0] == 'B' and class[1] == '@'))) ground_tiles[class] = tiles diff --git a/src/game/entities/enemies/rockman.nim b/src/game/entities/enemies/rockman.nim deleted file mode 100644 index e69de29..0000000 diff --git a/src/game/entities/enemy.nim b/src/game/entities/enemy.nim index 1d14c0d..c780ee2 100644 --- a/src/game/entities/enemy.nim +++ b/src/game/entities/enemy.nim @@ -1,7 +1,7 @@ include ../../engine/base -import enemies/rockman import player +import physical_object import random import ../userdata @@ -17,12 +17,15 @@ type retreat_goal: float retreat: bool + dead*: bool + health: float + hurt_wav: WavHandle sprite*: AnimatedSprite phys_body: Body phys_shape: Shape - user_data: UserData + user_data*: UserData -proc create_rockman*(pos: Vec2f, space: Space): Enemy = +proc create_rockman*(pos: Vec2f, space: Space, id: int): Enemy = result = new(Enemy) result.sprite = create_animated_sprite("res/enemies/rockman.yaml") let mass = 50.0 @@ -30,18 +33,30 @@ proc create_rockman*(pos: Vec2f, space: Space): Enemy = result.phys_body = space.addBody(newBody(mass, moment)) result.phys_shape = space.addShape(newBoxShape(result.phys_body, 31.0, 31.0, 0.0)) - result.user_data = make_enemy_userdata(addr result) - result.phys_shape.userData = addr result.user_data result.phys_shape.friction = 0.8 result.phys_body.position = v(pos.x, pos.y) + result.hurt_wav = load_sound("res/enemies/rockman_hurt.mp3") + result.user_data = make_enemy_userdata(id) + result.phys_shape.userData = addr result.user_data result.kind = ekRockman + result.health = 2.0 + + +proc die(this: var Enemy, objects: var seq[PhysicalObject], space: Space) = + space.removeShape(this.phys_shape) + space.removeBody(this.phys_body) + this.dead = true + discard -proc update*(this: var Enemy, player: Player) = +proc update*(this: var Enemy, player: Player, objects: var seq[PhysicalObject], space: Space) = this.sprite.center_position = vec2f(this.phys_body.position.x, this.phys_body.position.y) this.sprite.animate(dt) + if this.health <= 0.0: + this.die(objects, space) + if this.kind == ekRockman: # Simple moving towards player behaviour, with random retreats if this.retreat: @@ -59,10 +74,17 @@ proc update*(this: var Enemy, player: Player) = player_dir /= player_dist if player_dist < 300.0: if this.retreat: - this.phys_body.velocity = v(player_dir.x * 80.0, this.phys_body.velocity.y) + 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) +proc hurt*(this: var Enemy, point: Vect) = + this.health -= 1.0 + let p = this.phys_body.position + this.phys_body.applyImpulseAtWorldPoint(v(0, -5000.0), p) + discard this.hurt_wav.play_sound() + proc draw*(this: var Enemy) = renderer.draw(this.sprite) + diff --git a/src/game/entities/objects/rocks.nim b/src/game/entities/objects/rocks.nim deleted file mode 100644 index 52bc48e..0000000 --- a/src/game/entities/objects/rocks.nim +++ /dev/null @@ -1,29 +0,0 @@ -proc create_rock*(pos: Vec2f, space: Space): PhysicalObject = - result = new(PhysicalObject) - result.sprite = create_animated_sprite("res/objects/rock.yaml") - let mass = 50.0 - let moment = momentForCircle(mass, 0.0, 58.0, vzero) - - result.phys_body = space.addBody(newBody(mass, moment)) - result.phys_shape = space.addShape(newCircleShape(result.phys_body, 58.0, vzero)) - result.user_data = make_enemy_userdata(addr result) - result.phys_shape.userData = addr result.user_data - result.phys_body.position = v(pos.x, pos.y) - result.phys_shape.friction = 0.1 - - result.kind = okRock - -proc create_magmarock*(pos: Vec2f, space: Space): PhysicalObject = - result = new(PhysicalObject) - result.sprite = create_animated_sprite("res/objects/magmarock.yaml") - let mass = 60.0 - let moment = momentForCircle(mass, 0.0, 58.0, vzero) - - result.phys_body = space.addBody(newBody(mass, moment)) - result.phys_shape = space.addShape(newCircleShape(result.phys_body, 58.0, vzero)) - result.user_data = make_enemy_userdata(addr result) - result.phys_shape.userData = addr result.user_data - result.phys_body.position = v(pos.x, pos.y) - result.phys_shape.friction = 0.1 - - result.kind = okMagmaRock diff --git a/src/game/entities/physical_object.nim b/src/game/entities/physical_object.nim index 074e520..8147e26 100644 --- a/src/game/entities/physical_object.nim +++ b/src/game/entities/physical_object.nim @@ -17,14 +17,40 @@ type phys_shape: Shape user_data: UserData -include objects/rocks - proc update*(this: var PhysicalObject) = this.sprite.center_position = vec2f(this.phys_body.position.x, this.phys_body.position.y) this.sprite.rotation = this.phys_body.angle - echo this.phys_body.angle this.sprite.animate(dt) proc draw*(this: var PhysicalObject) = renderer.draw(this.sprite) +proc create_rock*(pos: Vec2f, space: Space, id: int): PhysicalObject = + result = new(PhysicalObject) + result.sprite = create_animated_sprite("res/objects/rock.yaml") + let mass = 50.0 + let moment = momentForCircle(mass, 0.0, 58.0, vzero) + + result.phys_body = space.addBody(newBody(mass, moment)) + result.phys_shape = space.addShape(newCircleShape(result.phys_body, 58.0, vzero)) + result.user_data = make_enemy_userdata(id) + result.phys_shape.userData = addr result.user_data + result.phys_body.position = v(pos.x, pos.y) + result.phys_shape.friction = 0.1 + + result.kind = okRock + +proc create_magmarock*(pos: Vec2f, space: Space, id: int): PhysicalObject = + result = new(PhysicalObject) + result.sprite = create_animated_sprite("res/objects/magmarock.yaml") + let mass = 60.0 + let moment = momentForCircle(mass, 0.0, 58.0, vzero) + + result.phys_body = space.addBody(newBody(mass, moment)) + result.phys_shape = space.addShape(newCircleShape(result.phys_body, 58.0, vzero)) + result.user_data = make_enemy_userdata(id) + result.phys_shape.userData = addr result.user_data + result.phys_body.position = v(pos.x, pos.y) + result.phys_shape.friction = 0.1 + + result.kind = okMagmaRock \ No newline at end of file diff --git a/src/game/entities/player.nim b/src/game/entities/player.nim index 8071a8d..bbfe53e 100644 --- a/src/game/entities/player.nim +++ b/src/game/entities/player.nim @@ -2,6 +2,7 @@ include ../../engine/base import nimgl/glfw import ../userdata + type Player* = ref object sprite*: AnimatedSprite lantern*: Sprite @@ -15,15 +16,27 @@ type Player* = ref object sliding: bool time_in_air: float our_data: UserData + attack_timer: float + played_attack: bool + in_attack: bool + in_toss: bool + release_toss: bool step_wav: WavHandle fall_wav: WavHandle jump_wav: WavHandle land_wav: WavHandle + miss_wav: WavHandle + hit_wav: WavHandle + attack_wav: WavHandle step_sound: AudioHandle fall_sound: AudioHandle +# This must be here to avoid circular dependency hell +import enemy +import physical_object + proc create_player*(pos: Vec2f, space: Space): Player = result = new(Player) @@ -35,7 +48,7 @@ proc create_player*(pos: Vec2f, space: Space): Player = result.phys_body = space.addBody(newBody(mass, moment)) result.phys_shape = space.addShape(newCircleShape(result.phys_body, 25.0, vzero)) - result.our_data = make_player_userdata(unsafeAddr result) + result.our_data = make_player_userdata() result.phys_shape.userData = unsafeAddr result.our_data result.phys_shape.friction = 0.0 result.phys_body.position = v(pos.x, pos.y) @@ -45,6 +58,9 @@ proc create_player*(pos: Vec2f, space: Space): Player = result.jump_wav = load_sound("res/player/jump.mp3") result.fall_wav = load_sound("res/player/fall.mp3") result.land_wav = load_sound("res/player/land.mp3") + result.hit_wav = load_sound("res/player/hit_connect.mp3") + result.attack_wav = load_sound("res/player/attack.mp3") + result.miss_wav = load_sound("res/player/hit.mp3") result.step_sound = create_sound(result.step_wav, true) result.fall_sound = create_sound(result.fall_wav, true) @@ -61,7 +77,43 @@ proc ground_query_foot(sh: Shape, p: Vect, n: Vect, a: Float, data: pointer) {.c # We can stand on anything cast[ptr bool](data)[] = true -proc update*(this: var Player) = +type ToHitData = object + hit: bool + enemies: seq[Enemy] + +# Sends hit to enemies +proc query_hit(sh: Shape, p: Vect, n: Vect, a: Float, data: pointer) {.cdecl.} = + # There's this weird 38 user data that we must ignore + if cast[int](sh.userData) > 100000: + let udata = cast[ptr UserData](sh.userData)[] + if udata.kind == bkEnemy: + let enemy_idx = udata.point + var datac = cast[ptr ToHitData](data) + datac[].hit = true + hurt(datac[].enemies[enemy_idx], p) + + +proc hit(this: Player, enemies: seq[Enemy]): bool = + 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: ToHitData + query_data.enemies = enemies + segmentQuery(this.phys_space, rays, raye, Float(4.0), filter, query_hit, addr query_data) + + return query_data.hit + +proc toss(this: Player, enemies: seq[Enemy], objects: seq[PhysicalObject]) = + discard + +proc update*(this: var Player, enemies: seq[Enemy], objects: seq[PhysicalObject]) = # Ground check let rfootp = this.phys_body.position + v(34.0, 25.0) let lfootp = this.phys_body.position + v(-34.0, 25.0) @@ -98,37 +150,73 @@ proc update*(this: var Player) = this.time_in_air += dt # Movement - var lateral = false - if glfw_window.getKey(GLFWKey.A) == GLFW_PRESS: - this.phys_body.position = this.phys_body.position + v(-dt * 100.0, 0.0) - this.sprite.scale = vec2f(-1.0, 1.0) - lateral = true - if glfw_window.getKey(GLFWKey.D) == GLFW_PRESS: - this.phys_body.position = this.phys_body.position + v(dt * 100.0, 0.0) - this.sprite.scale = vec2f(1.0, 1.0) - lateral = true - if glfw_window.getKey(GLFWKey.Space) == GLFW_PRESS: - if not this.last_jump and this.grounded: - this.phys_body.applyImpulseAtWorldPoint(v(0, -15000.0), v(0, 0)) - discard this.jump_wav.play_sound() - this.last_jump = true - else: - this.last_jump = false - - if this.time_in_air > 0.5: - this.sprite.start_anim("fall") + if this.in_attack: + this.attack_timer += dt + this.sprite.start_anim("attack") this.step_sound.pause() - this.fall_sound.resume() - this.fall_sound.set_volume(this.time_in_air - 0.5) + if this.attack_timer > 0.3 and not this.played_attack: + let connect = this.hit(enemies) + if connect: + discard this.hit_wav.play_sound() + else: + discard this.miss_wav.play_sound() + this.played_attack = true + if this.attack_timer > 0.8: + this.in_attack = false + elif this.in_toss: + if glfw_window.getKey(GLFWKey.C) != GLFW_PRESS or this.attack_timer > 1.8: + this.in_toss = false + this.toss(enemies, objects) + this.attack_timer += dt + this.sprite.start_anim("toss") + this.step_sound.pause() + else: - this.fall_sound.pause() - if lateral: - this.sprite.start_anim("walk") - this.step_sound.resume() - - if not lateral: - this.sprite.start_anim("idle") + var lateral = false + if glfw_window.getKey(GLFWKey.A) == GLFW_PRESS: + this.phys_body.position = this.phys_body.position + v(-dt * 100.0, 0.0) + this.sprite.scale = vec2f(-1.0, 1.0) + lateral = true + if glfw_window.getKey(GLFWKey.D) == GLFW_PRESS: + this.phys_body.position = this.phys_body.position + v(dt * 100.0, 0.0) + this.sprite.scale = vec2f(1.0, 1.0) + lateral = true + if glfw_window.getKey(GLFWKey.V) == GLFW_PRESS: + this.attack_timer = 0.0 + this.in_attack = true + this.played_attack = false + discard this.attack_wav.play_sound() + if glfw_window.getKey(GLFWKey.C) == GLFW_PRESS: + if this.release_toss: + this.attack_timer = 0.0 + this.in_toss = true + this.played_attack = false + this.release_toss = false + discard this.attack_wav.play_sound() + else: + this.release_toss = true + if glfw_window.getKey(GLFWKey.Space) == GLFW_PRESS: + if not this.last_jump and this.grounded: + this.phys_body.applyImpulseAtWorldPoint(v(0, -15000.0), v(0, 0)) + discard this.jump_wav.play_sound() + this.last_jump = true + else: + this.last_jump = false + + if this.time_in_air > 0.5: + this.sprite.start_anim("fall") this.step_sound.pause() + this.fall_sound.resume() + this.fall_sound.set_volume(this.time_in_air - 0.5) + else: + this.fall_sound.pause() + if lateral: + this.sprite.start_anim("walk") + this.step_sound.resume() + + if not lateral: + this.sprite.start_anim("idle") + this.step_sound.pause() if not this.sliding: this.phys_body.velocity = v(0, this.phys_body.velocity.y) @@ -140,6 +228,8 @@ proc update*(this: var Player) = this.sprite.animate(dt) + + proc draw*(this: var Player) = renderer.draw(this.sprite) renderer.draw(this.lantern) diff --git a/src/game/scenes/level.nim b/src/game/scenes/level.nim index 5bd4c75..0f37db4 100644 --- a/src/game/scenes/level.nim +++ b/src/game/scenes/level.nim @@ -43,23 +43,24 @@ proc init*(this: var Level, map: string, scale: int) = # Create all types of stuff if this.map.points.hasKey("rockman"): for point in this.map.points["rockman"]: - this.enemies.add(create_rockman(point, this.physics_space)) + this.enemies.add(create_rockman(point, this.physics_space, this.enemies.len)) if this.map.points.hasKey("rock"): for point in this.map.points["rock"]: - this.physical_objects.add(create_rock(point, this.physics_space)) + this.physical_objects.add(create_rock(point, this.physics_space, this.physical_objects.len)) if this.map.points.hasKey("magmarock"): for point in this.map.points["magmarock"]: - this.physical_objects.add(create_magmarock(point, this.physics_space)) + this.physical_objects.add(create_magmarock(point, this.physics_space, this.physical_objects.len)) proc update*(this: var Level) = this.physics_space.step(dt) for enemy in mitems(this.enemies): - enemy.update(this.player) + if not enemy.dead: + enemy.update(this.player, this.physical_objects, this.physics_space) for phys_obj in mitems(this.physical_objects): phys_obj.update() - this.player.update() + this.player.update(this.enemies, this.physical_objects) renderer.camera.center = this.player.sprite.position renderer.camera.scale = 1.0 @@ -67,7 +68,8 @@ proc update*(this: var Level) = proc draw*(this: var Level) = this.map.drawer.draw_tiles() for enemy in mitems(this.enemies): - enemy.draw() + if not enemy.dead: + enemy.draw() for phys_obj in mitems(this.physical_objects): phys_obj.draw() this.player.draw() diff --git a/src/game/userdata.nim b/src/game/userdata.nim index f6b1e5d..27aac93 100644 --- a/src/game/userdata.nim +++ b/src/game/userdata.nim @@ -7,24 +7,24 @@ type UserData* = ref object kind*: BodyKind - point*: pointer + point*: int proc make_terrain_userdata*(): UserData = result = new(UserData) result.kind = bkPlayer - result.point = nil + result.point = 0 -proc make_player_userdata*(player: pointer): UserData = +proc make_player_userdata*(): UserData = result = new(UserData) result.kind = bkPlayer - result.point = player + result.point = 0 -proc make_enemy_userdata*(enemy: pointer): UserData = +proc make_enemy_userdata*(enemy: int): UserData = result = new(UserData) result.kind = bkEnemy result.point = enemy -proc make_object_userdata*(obj: pointer): UserData = +proc make_object_userdata*(obj: int): UserData = result = new(UserData) result.kind = bkObject result.point = obj \ No newline at end of file