Skip to content

Commit

Permalink
Bugfix/inactive handling (#84)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyjor authored Oct 28, 2024
1 parent 8105d6b commit e8490da
Show file tree
Hide file tree
Showing 18 changed files with 105 additions and 55 deletions.
17 changes: 10 additions & 7 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,22 @@ repo = "https://github.com/Kyjor/JulGame.jl.git"
version = "0.1.0"

[deps]
CImGui = "5d785b6c-b76f-510e-a07c-3070796c7e87"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
NativeFileDialog = "e1fe445b-aa65-4df4-81c1-2041507f0fd4"
SimpleDirectMediaLayer = "98e33af6-2ee5-5afd-9e75-cbc738b767c4"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
CImGui = "5d785b6c-b76f-510e-a07c-3070796c7e87"
NativeFileDialog = "e1fe445b-aa65-4df4-81c1-2041507f0fd4"
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[compat]
JSON3 = "1"
SimpleDirectMediaLayer = "0.5"
CImGui = "~2.0"
julia = "1.9"
julia = "^1.9"
CImGui = "^2.0"
JSON3 = "^1"
NativeFileDialog = "^0.2"
SimpleDirectMediaLayer = "^0.5"
Test = "^1"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

Expand Down
15 changes: 12 additions & 3 deletions src/Main.jl
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ function initialize_scripts_and_components()
this.spriteLayers = build_sprite_layers()

if !JulGame.IS_EDITOR || this.isGameModeRunningInEditor

for script in scripts
try
Base.invokelatest(JulGame.initialize, script)
Expand All @@ -274,6 +275,14 @@ function initialize_scripts_and_components()
end
end
build_sprite_layers()

for entity in MAIN.scene.entities
@debug "Checking for a soundSource that needs to be activated"
if entity.soundSource != C_NULL && entity.soundSource !== nothing && entity.soundSource.playOnStart
Component.toggle_sound(entity.soundSource)
@debug("Playing $(entity.name)'s ($(entity.id)) sound source on start")
end
end
end

MAIN.scene.rigidbodies = []
Expand Down Expand Up @@ -639,9 +648,9 @@ function game_loop(this::Main, startTime::Ref{UInt64} = Ref(UInt64(0)), lastPhys
else
for i = eachindex(this.debugTextBoxes)
db_textbox = this.debugTextBoxes[i]
JulGame.update_text(db_textbox, statTexts[i])
db_textbox.text = statTexts[i]
JulGame.render(db_textbox, false)
end
end
end
end

Expand Down Expand Up @@ -726,7 +735,7 @@ function game_loop(this::Main, startTime::Ref{UInt64} = Ref(UInt64(0)), lastPhys
this.isGameModeRunningInEditor = false
SDL2.Mix_HaltMusic()
if this.scene.camera !== nothing && this.scene.camera != C_NULL
#this.scene.camera.target = C_NULL
this.scene.camera.target = C_NULL
end
end

Expand Down
3 changes: 2 additions & 1 deletion src/editor/JulGameEditor/Components/ComponentInputs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ function show_animator_properties(animator, animation_window_dict, animator_prev
show_image_with_hover_preview(sprite.texture, sprite.size.x, sprite.size.y, animations[i].frames[k])
end
if CImGui.TreeNode("frame $(k)")
CImGui.Button("Delete") && (deleteat!(animations[i].frames, k); break;)
if animator.parent.sprite != C_NULL && animator.parent.sprite !== nothing

points = Ref(Vector{ImVec2}([ImVec2(anim_x, anim_y), ImVec2(anim_x + anim_w, anim_y + anim_h)]))
Expand Down Expand Up @@ -636,4 +637,4 @@ end

function scriptObj(name::String, fields::Array)
() -> (name; fields)
end
end
11 changes: 5 additions & 6 deletions src/editor/JulGameEditor/Components/TextBoxFields.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,15 @@ function show_textbox_fields(selectedTextBox, textBoxField)
setfield!(selectedTextBox, textBoxField, currentTextInTextBox)

if currentTextInTextBox != Value
JulGame.update_text(selectedTextBox, selectedTextBox.text)
selectedTextBox.text = selectedTextBox.text
end

elseif fieldName == "alpha"
x = Cint(Value)
@c CImGui.SliderInt("$(textBoxField)", &x, 0, 255)
setfield!(selectedTextBox, textBoxField, convert(Int32, round(x)))

if x != Value
JulGame.update_text(selectedTextBox, selectedTextBox.text)
selectedTextBox.text = selectedTextBox.text
end

elseif fieldName == "color"
Expand All @@ -38,7 +37,7 @@ function show_textbox_fields(selectedTextBox, textBoxField)
setfield!(selectedTextBox, textBoxField, Color(convert(Int32, round(x)), convert(Int32, round(y)), convert(Int32, round(z)), convert(Int32, round(w))))

if x != Value.r || y != Value.g || z != Value.b || w != Value.a
JulGame.update_text(selectedTextBox, selectedTextBox.text)
selectedTextBox.text = selectedTextBox.text
end
elseif fieldName == "position"
x = Cint(Value.x)
Expand All @@ -49,14 +48,14 @@ function show_textbox_fields(selectedTextBox, textBoxField)
if x != Value.x || y != Value.y
#selectedTextBox.setVector2Value(textBoxField, convert(Float64, x), convert(Float64, y))
setfield!(selectedTextBox, textBoxField, Vector2(x, y))
JulGame.update_text(selectedTextBox, selectedTextBox.text)
selectedTextBox.text = selectedTextBox.text
end
elseif fieldName == "autoSizeText" || fieldName == "isCenteredX" || fieldName == "isCenteredY" || fieldName == "isWorldEntity" || fieldName == "isActive"
@c CImGui.Checkbox("$(textBoxField)", &Value)

if Value != getfield(selectedTextBox, textBoxField)
setfield!(selectedTextBox, textBoxField, Value)
JulGame.update_text(selectedTextBox, selectedTextBox.text)
selectedTextBox.text = selectedTextBox.text
end
elseif fieldName == "fontSize"
newSize = Cint(Value)
Expand Down
8 changes: 7 additions & 1 deletion src/editor/JulGameEditor/Editor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ module Editor
playMode = !playMode
if playMode
startTime[] = SDL2.SDL_GetTicks()

# Animate the text in the window title
SDL2.SDL_SetWindowTitle(window, "PLAYING $(windowTitle) - $(currentSelectedProjectPath[])")
end
Expand All @@ -253,6 +253,7 @@ module Editor
if playMode != wasPlaying && currentSceneMain !== nothing
if playMode
JulGame.MainLoop.start_game_in_editor(currentSceneMain, currentSelectedProjectPath[])
currentSceneMain.scene.camera = gameCamera
elseif !playMode
JulGame.MainLoop.stop_game_in_editor(currentSceneMain)
JulGame.change_scene(String(currentSceneName))
Expand Down Expand Up @@ -509,6 +510,11 @@ module Editor
#region Input
try
if currentSceneMain !== nothing
if currentSceneMain.scene.camera != gameCamera
gameCamera = currentSceneMain.scene.camera
cameraWindow.camera = gameCamera
end

if JulGame.InputModule.get_button_held_down(currentSceneMain.input, "LCTRL") && JulGame.InputModule.get_button_pressed(currentSceneMain.input, "S")
@info string("Saving scene")
events["Save"]()
Expand Down
2 changes: 1 addition & 1 deletion src/editor/JulGameEditor/Windows/GameControls.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
function show_game_controls()
@cstatic begin
CImGui.Begin("Controls")
CImGui.Text("Pan scene: Arrow keys/Hold middle mouse button and move mouse")
CImGui.Text("Pan scene: Hold right mouse button and move mouse")
CImGui.NewLine()
CImGui.Text("Select entity: Click on entity in scene window or in hierarchy window")
CImGui.NewLine()
Expand Down
12 changes: 11 additions & 1 deletion src/engine/Camera/Camera.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ module CameraModule
SDL2.SDL_SetRenderDrawColor(Renderer, this.backgroundColor[1], this.backgroundColor[2], this.backgroundColor[3], this.backgroundColor[4]);
SDL2.SDL_RenderFillRectF(Renderer, Ref(SDL2.SDL_FRect(this.windowPos.x, this.windowPos.y, this.size.x, this.size.y)))
SDL2.SDL_SetRenderDrawColor(JulGame.Renderer::Ptr{SDL2.SDL_Renderer}, rgba.r[], rgba.g[], rgba.b[], rgba.a[]);

center = Vector2f(this.size.x/SCALE_UNITS/2, this.size.y/SCALE_UNITS/2)
if this.target !== nothing && newPosition === nothing && this.target !== C_NULL && newPosition !== C_NULL
targetPos = this.target.position
Expand All @@ -51,4 +51,14 @@ module CameraModule
end
this.position = newPosition
end

# making set property observable
function Base.setproperty!(this::Camera, s::Symbol, x)
@debug("setting camera property $(s) to: $(x)")
try
setfield!(this, s, x)
catch e
println(e)
end
end
end
12 changes: 8 additions & 4 deletions src/engine/Component/Collider.jl
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ module ColliderModule
colliderCheckedCount = 0
i = 0
onGround = false
if !this.parent.isActive || !this.enabled
return
end

for collider in colliders
i += 1

Expand All @@ -101,7 +105,7 @@ module ColliderModule
Base.invokelatest(eventToCall,(collider=collider, direction=collision[1]))
end
#Begin to overlap, correct position
if !collider.isTrigger
if !collider.isTrigger && !this.isTrigger
this.parent.transform.position = Math.Vector2f(transform.position.x, transform.position.y + collision[2])
end
end
Expand All @@ -111,7 +115,7 @@ module ColliderModule
Base.invokelatest(eventToCall,(collider=collider, direction=collision[1]))
end

if !collider.isTrigger
if !collider.isTrigger && !this.isTrigger
#Begin to overlap, correct position
this.parent.transform.position = Math.Vector2f(transform.position.x + collision[2], transform.position.y)
end
Expand All @@ -122,7 +126,7 @@ module ColliderModule
Base.invokelatest(eventToCall,(collider=collider, direction=collision[1]))
end
#Begin to overlap, correct position
if !collider.isTrigger
if !collider.isTrigger && !this.isTrigger
this.parent.transform.position = Math.Vector2f(transform.position.x - collision[2], transform.position.y)
end
end
Expand All @@ -133,7 +137,7 @@ module ColliderModule
end
#Begin to overlap, correct position

if !collider.isTrigger
if !collider.isTrigger && !this.isTrigger
this.parent.transform.position = Math.Vector2f(transform.position.x, transform.position.y - collision[2])
if this.parent.rigidbody.velocity.y >= 0
this.parent.rigidbody.grounded = true
Expand Down
3 changes: 2 additions & 1 deletion src/engine/Component/SoundSource.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module SoundSourceModule
channel::Int32
isMusic::Bool
path::String
playOnStart::Bool
volume::Int32
end

Expand All @@ -22,7 +23,7 @@ module SoundSourceModule
volume::Int32

# Music
function InternalSoundSource(parent::Any, path::String, channel::Int32, volume::Int32, isMusic::Bool, playOnStart::Bool = false)
function InternalSoundSource(parent::Any, path::String, channel::Int32 = Int32(-1), volume::Int32 = Int32(-1), isMusic::Bool = false, playOnStart::Bool = false)
this = new()

SDL2.SDL_ClearError()
Expand Down
12 changes: 8 additions & 4 deletions src/engine/Entity.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ module EntityModule
end

function JulGame.update(this::Entity, deltaTime)
if !this.isActive
return
end

for script in this.scripts
try
Base.invokelatest(JulGame.update, script, deltaTime)
Expand Down Expand Up @@ -127,19 +131,19 @@ module EntityModule
return this.rigidbody
end

function JulGame.add_sound_source(this::Entity, soundSource::SoundSource = SoundSource(Int32(-1), false, "", Int32(50)))
function JulGame.add_sound_source(this::Entity, soundSource::SoundSource = SoundSource(Int32(-1), false, "", false, Int32(50)))
if this.soundSource != C_NULL
println("SoundSource already exists on entity named ", this.name)
return
end

this.soundSource = InternalSoundSource(this::Entity, soundSource.path, soundSource.channel, soundSource.volume, soundSource.isMusic)
this.soundSource = InternalSoundSource(this::Entity, soundSource.path, soundSource.channel, soundSource.volume, soundSource.isMusic, soundSource.playOnStart)

return this.soundSource
end

function JulGame.create_sound_source(this::Entity, soundSource::SoundSource = SoundSource(Int32(-1), false, "", Int32(50)))
newSoundSource::InternalSoundSource = InternalSoundSource(this::Entity, soundSource.path, soundSource.channel, soundSource.volume, soundSource.isMusic)
function JulGame.create_sound_source(this::Entity, soundSource::SoundSource = SoundSource(Int32(-1), false, "", false, Int32(50)))
newSoundSource::InternalSoundSource = InternalSoundSource(this::Entity, soundSource.path, soundSource.channel, soundSource.volume, soundSource.isMusic, soundSource.playOnStart)
return newSoundSource
end

Expand Down
4 changes: 2 additions & 2 deletions src/engine/SceneManagement/SceneReader.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ module SceneReaderModule
try
newUIElement = nothing
if uiElement.type == "TextBox"
newUIElement = TextBox(uiElement.name, uiElement.fontPath, uiElement.fontSize, Vector2(uiElement.position.x, uiElement.position.y), uiElement.text, uiElement.isCenteredX, uiElement.isCenteredY)
newUIElement = TextBox(uiElement.name, uiElement.fontPath, uiElement.fontSize, Vector2(uiElement.position.x, uiElement.position.y), get(uiElement, "text", " "), uiElement.isCenteredX, uiElement.isCenteredY)
newUIElement.isWorldEntity = uiElement.isWorldEntity
isActive::Bool = !haskey(uiElement, "isActive") ? true : uiElement.isActive
newUIElement.isActive = isActive
Expand Down Expand Up @@ -156,7 +156,7 @@ module SceneReaderModule
elseif component.type == "Rigidbody"
newComponent = Rigidbody(; mass = convert(Float64, component.mass), useGravity = !haskey(component, "useGravity") ? true : component.useGravity)
elseif component.type == "SoundSource"
newComponent = SoundSource(Int32(component.channel), component.isMusic, component.path, Int32(component.volume))
newComponent = SoundSource(Int32(component.channel), component.isMusic, component.path, get(component, "playOnStart", false), Int32(component.volume))
elseif component.type == "Sprite"
color = !haskey(component, "color") || isempty(component.color) ? Vector3(255,255,255) : Vector3(component.color.x, component.color.y, component.color.z)
crop = !haskey(component, "crop") || isempty(component.crop) ? Vector4(0,0,0,0) : Vector4(component.crop.x, component.crop.y, component.crop.z, component.crop.t)
Expand Down
3 changes: 2 additions & 1 deletion src/engine/SceneManagement/SceneWriter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ module SceneWriterModule
"channel" => component.channel,
"isMusic" => component.isMusic,
"path" => normalize_path(component.path),
"playOnStart" => component.playOnStart,
"sound" => component.sound,
"volume" => component.volume,
)
Expand Down Expand Up @@ -257,4 +258,4 @@ module SceneWriterModule
return false
end
end
end # module
end # module
36 changes: 24 additions & 12 deletions src/engine/UI/TextBox.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ module TextBoxModule

this.alpha = 255
this.fontPath = fontPath
this.fontSize = fontSize
this.id = 0
this.fontSize = Int32(fontSize)
this.id = Int32(0)
this.isCenteredX = isCenteredX
this.isCenteredY = isCenteredY
this.name = name
this.position = position
this.text = text
setfield!(this, :text, text)
this.isWorldEntity = isWorldEntity
this.textTexture = C_NULL
this.persistentBetweenScenes = false
Expand Down Expand Up @@ -95,22 +95,16 @@ module TextBoxModule
end

"""
update_text(this::TextBox, newText)
rerender_text(this::TextBox)
Update the text of the TextBox with the given `newText`. This function updates the `text` field of the TextBox, renders the new text using the specified font, and creates a texture from the rendered text. If the TextBox is not a world entity, it centers the text.
Recreates the font surface and texture. If the TextBox is not a world entity, it centers the text.
# Arguments
- `this::TextBox`: The TextBox object to update.
- `newText`: The new text to set for the TextBox.
# Examples
"""
function UI.update_text(this::TextBox, newText::String)
if length(newText) == 0
newText = " " # prevents segfault when text is empty
end

this.text = newText
function UI.rerender_text(this::TextBox)
SDL2.SDL_FreeSurface(this.renderText)
SDL2.SDL_DestroyTexture(this.textTexture)
this.renderText = SDL2.TTF_RenderUTF8_Blended(this.font, this.text, SDL2.SDL_Color(255,255,255,(this.alpha+1)%256))
Expand Down Expand Up @@ -162,4 +156,22 @@ module TextBoxModule
SDL2.SDL_DestroyTexture(this.textTexture)
this.textTexture = C_NULL
end

function Base.setproperty!(this::TextBox, s::Symbol, x)
@debug("setting textbox property $(s) to: $(x)")
try
setfield!(this, s, x)
if s == :text
if length(x) == 0
setfield!(this, s, " ")# prevents segfault when text is empty
end

UI.rerender_text(this)
end
catch e
error(e)
Base.show_backtrace(stderr, catch_backtrace())
end
end

end
Loading

0 comments on commit e8490da

Please sign in to comment.