8000 Fix CCJ-229: implement new health bar styles for Junior by nwinter · Pull Request #7761 · codecombat/codecombat · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Fix CCJ-229: implement new health bar styles for Junior #7761

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions app/lib/surface/Lank.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ healthColors =
humans: [255, 0, 0]
neutral: [64, 212, 128]

juniorHealthColors =
ogres: [0, 240, 255]
humans: [253, 20, 48]
neutral: [64, 212, 128]

# Sprite: EaselJS-based view/controller for Thang model
module.exports = Lank = class Lank extends CocoClass
thangType: null # ThangType instance
Expand Down Expand Up @@ -559,9 +564,14 @@ module.exports = Lank = class Lank extends CocoClass
updateStats: ->
return unless @thang and @thang.health isnt @lastHealth
@lastHealth = @thang.health
if bar = @healthBar
healthPct = Math.max(@thang.health / @thang.maxHealth, 0)
bar.scaleX = healthPct / @options.floatingLayer.resolutionFactor
if @healthBar
if @thang.healthBarStyle is 'pill-with-ticks'
# We have to redraw the health bar
@addHealthBar()
else
# We can just scale the health bar
healthPct = Math.max(@thang.health / @thang.maxHealth, 0)
@healthBar.scaleX = healthPct / @options.floatingLayer.resolutionFactor
if @thang.id is 'Hero Placeholder'
Backbone.Mediator.publish 'sprite:hero-health-updated', health: @thang.health, maxHealth: @thang.maxHealth
if @thang.showsName
Expand Down Expand Up @@ -589,16 +599,22 @@ module.exports = Lank = class Lank extends CocoClass
@gameUIState.trigger(ourEventName, newEvent)

addHealthBar: ->
return unless @thang?.health? and 'health' in (@thang?.hudProperties ? []) and @options.floatingLayer
team = @thang?.team or 'neutral'
return unless @thang?.health? and 'health' in (@thang.hudProperties || []) and @options.floatingLayer
team = @thang.team or 'neutral'
key = "#{team}-health-bar"
if (@thang.healthBarStyle is 'pill-with-ticks') and @thang.maxHealth <= 10
health = Math.max(0, Math.ceil(@thang.health))
maxHealth = Math.ceil(@thang.maxHealth || @thang.health)
key = "#{key}-#{health}-#{maxHealth}"

unless key in @options.floatingLayer.spriteSheet.animations
healthColor = healthColors[team]
bar = createProgressBar(healthColor)
healthColor = (if @thang.healthBarStyle is 'pill-with-ticks' then juniorHealthColors else healthColors)[team]
bar = createProgressBar(healthColor, health, maxHealth)
@options.floatingLayer.addCustomGraphic(key, bar, bar.bounds)

hadHealthBar = @healthBar
if hadHealthBar
@options.floatingLayer.removeChild @healthBar
@healthBar = new createjs.Sprite(@options.floatingLayer.spriteSheet)
@healthBar.gotoAndStop(key)
offset = @getOffset 'aboveHead'
Expand Down
86 changes: 76 additions & 10 deletions app/lib/surface/sprite_utils.coffee
Original file line number Diff line number Diff line change
@@ -1,16 +1,82 @@
createjs = require 'lib/createjs-parts'

WIDTH = 20
HEIGHT = 2
EDGE = 0.3

module.exports.createProgressBar = createProgressBar = (color) ->
module.exports.createProgressBar = createProgressBar = (color, ticks, maxTicks) ->
g = new createjs.Graphics()
g.setStrokeStyle(1)
g.beginFill(createjs.Graphics.getRGB(0, 0, 0))
g.drawRect(0, -HEIGHT/2, WIDTH, HEIGHT, HEIGHT)
g.beginFill(createjs.Graphics.getRGB(color...))
g.drawRoundRect(EDGE, EDGE - HEIGHT/2, WIDTH-EDGE*2, HEIGHT-EDGE*2, HEIGHT-EDGE*2)

unless maxTicks
# Simple rectangular bar style
WIDTH = 20
HEIGHT = 2
EDGE = 0.3
TICK_WIDTH = 2
g.setStrokeStyle(1)
g.beginFill(createjs.Graphics.getRGB(0, 0, 0))
g.drawRect(0, -HEIGHT/2, WIDTH, HEIGHT, HEIGHT)
g.beginFill(createjs.Graphics.getRGB(color...))
g.drawRoundRect(EDGE, EDGE - HEIGHT/2, WIDTH-EDGE*2, HEIGHT-EDGE*2, HEIGHT-EDGE*2)
else if not ticks
# Draw no bar if health is 0
else
# Dimensions and settings
# Scale width from 12 (1 health) to 34 (10+ health)
WIDTH = 8 + 4 * Math.min(maxTicks, 3) + 2 * Math.max(0, Math.min(maxTicks - 3, 7))
HEIGHT = 6
STROKE_WIDTH = 1
TICK_WIDTH = 1
EDGE = STROKE_WIDTH / 2 # Adjust EDGE to be half the stroke width

# Calculate dimensions
pieceWidth = (WIDTH - (maxTicks - 1) * TICK_WIDTH) / maxTicks
radius = HEIGHT / 2

# Draw background
g.setStrokeStyle(STROKE_WIDTH)
g.beginStroke(createjs.Graphics.getRGB(59, 39, 34, 1))
g.beginFill(createjs.Graphics.getRGB(28, 14, 83, 0.4))

# Draw background shape with precise curvature
g.moveTo(radius, -HEIGHT/2)
g.lineTo(WIDTH - radius, -HEIGHT/2)
g.arc(WIDTH - radius, 0, radius, -Math.PI/2, Math.PI/2, false)
g.lineTo(radius, HEIGHT/2)
g.arc(radius, 0, radius, Math.PI/2, -Math.PI/2, false)
g.closePath()
g.endStroke()

# Draw filled pieces
if ticks > 0
g.setStrokeStyle(0) # No stroke for filled pieces
g.beginFill(createjs.Graphics.getRGB(color...))

filledWidth = Math.min(ticks * (pieceWidth + TICK_WIDTH) - TICK_WIDTH, WIDTH - STROKE_WIDTH)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Review filledWidth calculation for potential off-by-one error

The computation of filledWidth:

filledWidth = Math.min(ticks * (pieceWidth + TICK_WIDTH) - TICK_WIDTH, WIDTH - STROKE_WIDTH)

may lead to an off-by-one error due to the subtraction of TICK_WIDTH. This could result in improper rendering of the filled portion of the progress bar. Please confirm that the formula accurately reflects the intended visual representation for all values of ticks.


# Calculate the inset for the progress bar
inset = EDGE

# Left cap (outset)
g.moveTo(radius, -HEIGHT/2 + inset)
g.arcTo(inset, -HEIGHT/2 + inset, inset, 0, radius - inset)
g.arcTo(inset, HEIGHT/2 - inset, radius, HEIGHT/2 - inset, radius - inset)
g.lineTo(filledWidth, HEIGHT/2 - inset)

# Right cap (full outset if full, straight line if not)
if ticks == maxTicks
g.lineTo(WIDTH - radius, HEIGHT/2 - inset)
g.arc(WIDTH - radius, 0, radius - inset, Math.PI/2, -Math.PI/2, true)
g.lineTo(inset, -HEIGHT/2 + inset)
else
g.lineTo(filledWidth, -HEIGHT/2 + inset)

g.closePath()

# Add vertical tick marks
g.setStrokeStyle(TICK_WIDTH)
g.beginStroke(createjs.Graphics.getRGB(147, 129, 107, 1))
for i in [1...maxTicks]
tickX = i * (pieceWidth + TICK_WIDTH) - TICK_WIDTH/2
g.moveTo(tickX, -HEIGHT/2 - 5)
g.lineTo(tickX, HEIGHT/2 + 5)

s = new createjs.Shape(g)
s.z = 100
s.bounds = [0, -HEIGHT/2, WIDTH, HEIGHT]
Expand Down
Loading
0