From 5326e7670c33853f4109174884110647d01bec6e Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 30 Mar 2026 21:01:59 -0400 Subject: [PATCH] multi level, autoload, coins, raycasts, enemies, dictionary damage health --- assets/graphics/enimes/slime_green.png | Bin 0 -> 908 bytes assets/graphics/enimes/slime_green.png.import | 40 ++ assets/graphics/pickup/coin.png | Bin 0 -> 500 bytes assets/graphics/pickup/coin.png.import | 40 ++ project.godot | 4 + scenes/bullet.tscn | 1 + scenes/coin.tscn | 114 +++++ scenes/game.tscn | 97 +++- scenes/level2.tscn | 475 ++++++++++++++++++ scenes/level3.tscn | 475 ++++++++++++++++++ scenes/slime.tscn | 73 +++ scripts/SceneManager.gd | 48 +- scripts/bullet.gd | 4 + scripts/coin.gd | 7 + scripts/coin.gd.uid | 1 + scripts/gameController.gd | 53 +- scripts/slime.gd | 32 ++ scripts/slime.gd.uid | 1 + 18 files changed, 1426 insertions(+), 39 deletions(-) create mode 100644 assets/graphics/enimes/slime_green.png create mode 100644 assets/graphics/enimes/slime_green.png.import create mode 100644 assets/graphics/pickup/coin.png create mode 100644 assets/graphics/pickup/coin.png.import create mode 100644 scenes/coin.tscn create mode 100644 scenes/level2.tscn create mode 100644 scenes/level3.tscn create mode 100644 scenes/slime.tscn create mode 100644 scripts/coin.gd create mode 100644 scripts/coin.gd.uid create mode 100644 scripts/slime.gd create mode 100644 scripts/slime.gd.uid diff --git a/assets/graphics/enimes/slime_green.png b/assets/graphics/enimes/slime_green.png new file mode 100644 index 0000000000000000000000000000000000000000..a21cb6fa253a2142be9bdad248238299dce6e695 GIT binary patch literal 908 zcmeAS@N?(olHy`uVBq!ia0vp^2|(<@!3HEb(?2AGr~;43Vg?3oVGw3ym^DX&fq~i1 z)5S5QV$Rz+)_J!b1lrmiqe6M+oJ(NX&NN4Phv|b`z4{NYP5+>JWrs--17qeTsRD5g z!(g=zZP^CRNrf+-+NH@KR$Td0s&mngVw3+xu0?EXcCBM}?K8i`C}Wk?V1NhZ=gNnL znwH6IezGFZ!~9a6?RHUyhPV4>Uu{?_FnfW>zS{qPKK*<4uVTZ$ce_63>1Q2~5psEW zx_|#J@#X97|9=sRdr@7gG^K>%S{q!=tk;zc{umA757CW^gF~?Y* zzL@Q4_FeSScBuyG05^_0b=8H-_E|RV`0{(oCG+JLF?=tr`x)+BFt>laYl`#E_4#US z^)8yV;ydQc)Lt=IzWv`O|NWa{=kBflzObA3)w^Aa^ZVqko^^cn|Ic5O3*}M*OaJxH zkT2-?mBRcbPJn+~%B^6jY(87p9(Mo#>Q7(h~rm&XFcnS2%Pu(#j4I<=R1EbeZ((y;O5o?wIy5Q|G$2J-k$H; z`tsE}e}z7FZ&xe&&T>;Ie$t&EuHB#RoL~6BudegQ(e6(xj^8Zaa&Il$W#4ySE~~5m zTfmt7%O>)U?6I5hEH)mc^Zy7i2AYE5_cS8+Pd zEL*XBwVBru|99M6hFkZ|y>aAN9DmO}@fM%8>yNRi-8VbG`yY1_&*gmzOfw=rUyaF+ zc6a>UWOJqT@=>+Yz0nhwE57CCn(*tmRI)?YzOxPXujg|0Ui|Qj8JN8oJYD@<);T3K F0RY5^vzq__ literal 0 HcmV?d00001 diff --git a/assets/graphics/enimes/slime_green.png.import b/assets/graphics/enimes/slime_green.png.import new file mode 100644 index 0000000..27a1090 --- /dev/null +++ b/assets/graphics/enimes/slime_green.png.import @@ -0,0 +1,40 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://3nqjbe8l8lb" +path="res://.godot/imported/slime_green.png-3dde82d6daac4b061a10b675e2b5c05f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/graphics/enimes/slime_green.png" +dest_files=["res://.godot/imported/slime_green.png-3dde82d6daac4b061a10b675e2b5c05f.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/uastc_level=0 +compress/rdo_quality_loss=0.0 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/channel_remap/red=0 +process/channel_remap/green=1 +process/channel_remap/blue=2 +process/channel_remap/alpha=3 +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/assets/graphics/pickup/coin.png b/assets/graphics/pickup/coin.png new file mode 100644 index 0000000000000000000000000000000000000000..01ae33d70b398db7f1f7bcafe883a0a469805201 GIT binary patch literal 500 zcmV^r!6hi!Wct>kSmw76A*+mkqIDVjdDL!Rb}5E?Td;C@2y9S zHih2xK(yTWh+gXdrTqK8Uwx^_$MoI4V|67Hn26^Qp-rJ*c_3P5d_*tx|6%^yEznE& zeE6^KHvJ|vI7934d=L#ytZIR)9hxaN1Jm8sZ6_j{Yx1#nTWt!D2<;1?{VNX?M*l~R zzukKP+i+D+FAlB;7qkOXfaGA?&h>EX&+$Oxqgs>{d4C#zhd05hUS`kO@{&+Bb`?-H zKXwYn7Ms9B!`F}PQh%-o65r;4=uy!A4;g>*6iCRL!wF!o{9{X0YM%Mf@U=DvM2}Kx zY#A;!e+4Y{Qh#m^NPMe5dkcj0f5`ZIy8@JYG2kpkh}LrU76{dHI?&Z}2LKX(>v1MX z4k6>OaQ_N1p97frj@jdSpELonJ&y=&3jN9h(K6#Bda3^x^WUBW>`ee7IfzLSUk<|l qVg27u071wNc?u+CjZ6R`YyJS*Ofbr5QwY-l0000 void: + Gamecontroller.reset() buildLevel() @@ -22,18 +24,42 @@ func buildLevel()->void: print("building level") updateCrates() updateTriggers() + updateCoins() + updateEnemies() #wire up signals from GameController - game.destroySignal.connect(destroy) - game.teleportSignal.connect(teleport) - game.levelChangeSignal.connect(loadLevel) - + Gamecontroller.destroySignal.connect(destroy) + Gamecontroller.teleportSignal.connect(teleport) + Gamecontroller.levelChangeSignal.connect(loadLevel) +func updateEnemies()->void: + if slimes: + var totalSlimes = 0 + for obj in slimes.get_children(): + if obj is Slime: + totalSlimes +=1 + Gamecontroller.addEnemyToLevel(obj) + #hook up to game controller + if not obj.slimeDamageSignal.is_connected(Gamecontroller._on_slime_damage): + obj.slimeDamageSignal.connect(Gamecontroller._on_slime_damage) +func updateCoins()->void: + if coins: + var totalCoins = 0 + for obj in coins.get_children(): + if obj is Coin: + totalCoins+=1 + #hook up coin to gamecontroller + if not obj.coinCollectedSignal.is_connected(Gamecontroller._on_coin_collected): + obj.coinCollectedSignal.connect(Gamecontroller._on_coin_collected) + if not obj.tree_exited.is_connected(updateCoins): + obj.tree_exited.connect(updateCoins) + + Gamecontroller.totalCoins(totalCoins) func updateTriggers()->void: if triggers: for obj in triggers.get_children(): if obj is Trigger: - if not obj.AreaTrigger.is_connected(game._on_trigger): - obj.AreaTrigger.connect(game._on_trigger) + if not obj.AreaTrigger.is_connected(Gamecontroller._on_trigger): + obj.AreaTrigger.connect(Gamecontroller._on_trigger) func updateCrates()->void: #check that there is a crates node if crates: @@ -43,7 +69,7 @@ func updateCrates()->void: if not obj.tree_exited.is_connected(updateCrates): obj.tree_exited.connect(updateCrates) totalCrates +=1 - game.crateUpdate(totalCrates) + Gamecontroller.crateUpdate(totalCrates) func destroy(body)->void: if body is Bullet: stashBullet(body) @@ -70,9 +96,9 @@ func bullectFactory()->Bullet : #how many bullets have we made if bulletArray.size() <= totalAllowedBullets: myBullet = bullet.instantiate() - if not myBullet.bulletDamageSignal.is_connected(game.bulletDamage): - myBullet.bulletDamageSignal.connect(game.bulletDamage) - game.add_child(myBullet) + if not myBullet.bulletDamageSignal.is_connected(Gamecontroller.bulletDamage): + myBullet.bulletDamageSignal.connect(Gamecontroller.bulletDamage) + add_sibling(myBullet) else: myBullet = bulletArray.pop_back() bulletArray.push_front(myBullet) diff --git a/scripts/bullet.gd b/scripts/bullet.gd index 649c623..27e96bd 100644 --- a/scripts/bullet.gd +++ b/scripts/bullet.gd @@ -21,3 +21,7 @@ func _process(delta: float) -> void: func _on_body_entered(body: Node2D) -> void: bulletDamageSignal.emit(body, self) + + +func _on_area_entered(area: Area2D) -> void: + bulletDamageSignal.emit(area, self) diff --git a/scripts/coin.gd b/scripts/coin.gd new file mode 100644 index 0000000..c1af065 --- /dev/null +++ b/scripts/coin.gd @@ -0,0 +1,7 @@ +class_name Coin extends Area2D + +signal coinCollectedSignal(body,coin) + +func _on_body_entered(body: Node2D) -> void: + if body is Player: + coinCollectedSignal.emit(body, self) diff --git a/scripts/coin.gd.uid b/scripts/coin.gd.uid new file mode 100644 index 0000000..5cd4456 --- /dev/null +++ b/scripts/coin.gd.uid @@ -0,0 +1 @@ +uid://ci5pqwcmdavsg diff --git a/scripts/gameController.gd b/scripts/gameController.gd index 3d649b8..4b12228 100644 --- a/scripts/gameController.gd +++ b/scripts/gameController.gd @@ -8,6 +8,17 @@ var currentScene:String = "res://scenes/game.tscn" var timer := Timer.new() var timeAvailable := 10 + +var levels=["res://scenes/game.tscn","res://scenes/level2.tscn","res://scenes/level3.tscn"] +var timers=[15,10,5] +var currentLevel = 0 + +var coinsCollected = 0 + +var playerHealth = 100 +var playerStartingHealth = 100 + +var enemiesDict={} # Called when the node enters the scene tree for the first time. func _ready() -> void: get_window().grab_focus() @@ -17,11 +28,15 @@ func _ready() -> void: timer.connect("timeout", secondCounter) timer.start() +func reset()->void: + timeAvailable = timers[currentLevel] + playerHealth = playerStartingHealth + func secondCounter()->void: timeAvailable -=1 if timeAvailable <=0: print("YOU LOST YOU ARE A LOSER YOU SUCK") - levelChangeSignal.emit(currentScene) + levelChangeSignal.emit(levels[currentLevel]) # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta: float) -> void: @@ -47,9 +62,43 @@ func crateUpdate(cratesAmount)->void: print("GC updated crates: "+str(crateTotal)) if crateTotal <=0: print("You WON!!!") - levelChangeSignal.emit(currentScene) + currentLevel += 1 + if currentLevel >= levels.size(): + currentLevel = 0 + levelChangeSignal.emit(levels[currentLevel]) func bulletDamage(body:Node2D, bullet:Bullet)->void: if body is Crate: destroySignal.emit(body) destroySignal.emit(bullet) + if body is Slime: + enemiesDict[body]["health"] -= 10 + if enemiesDict[body]["health"] <= 0: + destroySignal.emit(body) + destroySignal.emit(bullet) + +func _on_coin_collected(body:Node2D, coin:Coin): + print("GC know coin") + coinsCollected += 1 + destroySignal.emit(coin) + +func totalCoins(value)->void: + print("GC know coins remaning "+str(value)) + if value <= 0: + currentLevel += 1 + if currentLevel >= levels.size(): + currentLevel = 0 + levelChangeSignal.emit(levels[currentLevel]) +func _on_slime_damage(boyd:Node2D, slime:Slime)->void: + playerHealth -= enemiesDict[slime]["damage"] + print("GC DAMAGE THE PLAYER AND KILL THEM "+str(playerHealth)) + if playerHealth <=0: + print(" YOU DED ") + levelChangeSignal.emit(levels[currentLevel]) +func addEnemyToLevel(slime:Slime)->void: + var randDamage:int = randi()%10 + var enemyStat = { + "health":50, + "damage":randDamage + } + enemiesDict[slime]=enemyStat diff --git a/scripts/slime.gd b/scripts/slime.gd new file mode 100644 index 0000000..5adf2dd --- /dev/null +++ b/scripts/slime.gd @@ -0,0 +1,32 @@ +class_name Slime extends Area2D +@onready var right_cast: RayCast2D = $RightCast +@onready var left_cast: RayCast2D = $LeftCast +@onready var left_down_cast: RayCast2D = $LeftDownCast +@onready var right_down_cast: RayCast2D = $RightDownCast +@onready var slime_graphic: AnimatedSprite2D = $SlimeGraphic + +var speed:int = 100 +var direction = 1 + +signal slimeDamageSignal(body, slime) + +#Animation code +func _process(delta: float) -> void: + if not right_down_cast.is_colliding(): + direction = -1 + slime_graphic.flip_h = true + if not left_down_cast.is_colliding(): + direction = 1 + slime_graphic.flip_h = false + if right_cast.is_colliding() && not right_cast.get_collider() is Player: + direction = -1 + slime_graphic.flip_h = true + if left_cast.is_colliding() && not left_cast.get_collider() is Player: + direction = 1 + slime_graphic.flip_h = false + position.x += direction * speed * delta + + +func _on_body_entered(body: Node2D) -> void: + if body is Player: + slimeDamageSignal.emit(body, self) diff --git a/scripts/slime.gd.uid b/scripts/slime.gd.uid new file mode 100644 index 0000000..87ddceb --- /dev/null +++ b/scripts/slime.gd.uid @@ -0,0 +1 @@ +uid://cyn4llpk3qcub