From 1720aff1fca37717991376a129f1ef4c62342f05 Mon Sep 17 00:00:00 2001 From: AliJaffar Date: Mon, 24 Mar 2025 21:03:05 -0400 Subject: [PATCH] level changing, autoloads, coins, player damage, player death --- .../assets/graphics/enemies/slime_green.png | Bin 0 -> 908 bytes .../graphics/enemies/slime_green.png.import | 34 ++ .../assets/graphics/pickups/coin.png | Bin 0 -> 500 bytes .../assets/graphics/pickups/coin.png.import | 34 ++ .../player/hurt/Player Hurt 48x48.png | Bin 0 -> 1448 bytes .../player/hurt/Player Hurt 48x48.png.import | 34 ++ februarygodotgame/project.godot | 8 + februarygodotgame/scenes/coin.tscn | 113 ++++ februarygodotgame/scenes/game.tscn | 35 +- februarygodotgame/scenes/level2.tscn | 2 +- februarygodotgame/scenes/level3.tscn | 491 ++++++++++++++++++ februarygodotgame/scenes/player.tscn | 43 +- februarygodotgame/scenes/slime.tscn | 61 +++ februarygodotgame/scripts/coin.gd | 7 + februarygodotgame/scripts/gamecontroller.gd | 71 ++- februarygodotgame/scripts/player.gd | 148 +++--- .../scripts/res/characterStats.gd | 8 + .../scripts/res/playerStats.tres | 11 + februarygodotgame/scripts/res/slimeStats.tres | 11 + februarygodotgame/scripts/scene_manager.gd | 42 +- februarygodotgame/scripts/slime.gd | 10 + 21 files changed, 1076 insertions(+), 87 deletions(-) create mode 100644 februarygodotgame/assets/graphics/enemies/slime_green.png create mode 100644 februarygodotgame/assets/graphics/enemies/slime_green.png.import create mode 100644 februarygodotgame/assets/graphics/pickups/coin.png create mode 100644 februarygodotgame/assets/graphics/pickups/coin.png.import create mode 100644 februarygodotgame/assets/graphics/player/hurt/Player Hurt 48x48.png create mode 100644 februarygodotgame/assets/graphics/player/hurt/Player Hurt 48x48.png.import create mode 100644 februarygodotgame/scenes/coin.tscn create mode 100644 februarygodotgame/scenes/level3.tscn create mode 100644 februarygodotgame/scenes/slime.tscn create mode 100644 februarygodotgame/scripts/coin.gd create mode 100644 februarygodotgame/scripts/res/characterStats.gd create mode 100644 februarygodotgame/scripts/res/playerStats.tres create mode 100644 februarygodotgame/scripts/res/slimeStats.tres create mode 100644 februarygodotgame/scripts/slime.gd diff --git a/februarygodotgame/assets/graphics/enemies/slime_green.png b/februarygodotgame/assets/graphics/enemies/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/februarygodotgame/assets/graphics/enemies/slime_green.png.import b/februarygodotgame/assets/graphics/enemies/slime_green.png.import new file mode 100644 index 0000000..3a4a4c5 --- /dev/null +++ b/februarygodotgame/assets/graphics/enemies/slime_green.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dh1ujlbcmhclf" +path="res://.godot/imported/slime_green.png-5261ffd1254c816fe62b35227a9aa11d.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/graphics/enemies/slime_green.png" +dest_files=["res://.godot/imported/slime_green.png-5261ffd1254c816fe62b35227a9aa11d.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +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/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/februarygodotgame/assets/graphics/pickups/coin.png b/februarygodotgame/assets/graphics/pickups/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-l0000Px)Vo5|nRCt{2n@>y}RUF4ZkJerOE#kjMStQgHNr?OjDhY`uTxqn~MsGFI8%cX2 z#+wHZ-nkf)9-7#Lo=hNMy_gUWrUz6Ku)&lxmefL8tXe6HK*8r>dAl>i%(BbQ?!JNF zC)s3n-t6r6_vZI~zxQT#K@bE%5ClOG1VIo4K@bE%5ClOG1VIo4;mDxEKB3kcfQ3g} z+PS|g5mx|8h5nVH@&3Aq|r=_kK&wGEuT zmfemKQw=rs)TufE&aa%SkiuY`+5tYA+TfG-rd`JjoV~_c_tUEBm%q4lf25-N3dI?R zUkp~>2EDsErvcVCHeLJM9_;Qr_Ro850JOfDbbVj7&EV|#;VTb$bTgKVnw}Fa`j(3H%HIITHZHRh;MEc($q) z;h^LizHn7g?I6s=!@9VRFw`3-wCCUn zV_s{X2{^C8L2>M%6RMH%mPy82CPUG1@~|IF#(UKA)_k@zm$&A1JmA>6jzQJhk=b@8 z{@!-g=0Uxk?TjQR)aSs|g?8;7MNf|{Dp&-rnq5{cU`CP?%1^fg)m*>By^L;W;#alb zA!lTB4TdkY2O85gm8(gZr5l*ZT~pTRL4wxs)cg|^>Sl% zyOL6hCP;fe-GkqKW;U%dZ!vUqUso|=WvOI`t^i6YwATA70YG|N(-6z_cU{Mz@_we; zCNPX7C-&*E-2?`&cCYTYzg+TLs9VwRP9vKt2ALTAs_^YmNH4qtWvFB&RRA-pC*wUT zeruiht@UhMdRu3!fpej&lybdnU@D;e2JNpFeuh12+*sXqy#P*+Etbv1hpqqyGpa|K zw$UK~?u>m8Kr-FuXkDtboV<8V;MH!JO{H}IM6?a#tYT1}N>;J~47D#d1F-pfZZ#j@ zZ3Hq8&1@O%^NpfyqeJX|TF~7H>u?&uZD4yb*P?B7XrF;AMJPXoaAJ&LlK;{Cd}PW) z)RKShrw{h^Z4{D!Bsrn{Dw#1cWa5}j1>dj;i%^~etgkJ&gqq}!0w#%~mi&H1F$S-R z+eU|6CN8%LWZ>4FSbiKUbdha!@ z?QwYZo8uN4{ZRfGN}2+h void: + print("Coin collision") + coinCollectedSignal.emit(body, self) diff --git a/februarygodotgame/scripts/gamecontroller.gd b/februarygodotgame/scripts/gamecontroller.gd index 3c35e8c..569723f 100644 --- a/februarygodotgame/scripts/gamecontroller.gd +++ b/februarygodotgame/scripts/gamecontroller.gd @@ -3,12 +3,44 @@ class_name GameController extends Node2D #Game Data var totalCrates = 2 var cratesDestroyed = 0 +var coinsCollected = 0 +var totalCoinsAvailable = 0 + +var enemies = 0 +signal destroytSignal(body) +signal levelCompleteSignal(level) +signal playerHurtSignal(healthRemaining) +#level info +var timer:= Timer.new() +var levels = ["res://scenes/game.tscn","res://scenes/level2.tscn","res://scenes/level3.tscn"] +var timers = [20,15,25] +var currentLevel = 0 +var countdown = 0 + + +var player:Resource +var slime:Resource # Called when the node enters the scene tree for the first time. func _ready() -> void: - pass # Replace with function body. - - + player = load("res://scripts/res/playerStats.tres") + slime = load("res://scripts/res/slimeStats.tres") + + countdown = timers[currentLevel] + add_child(timer) + timer.wait_time = 1 + timer.one_shot = false + timer.connect("timeout", secondCounter) + timer.start() +func reset(): + countdown = timers[currentLevel] + +func secondCounter(): + + countdown -=1 + if countdown <=0: + print("YOU LOSE") + levelCompleteSignal.emit(levels[currentLevel]) # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta: float) -> void: pass @@ -20,7 +52,7 @@ func _on_trigger_area_trigger(effect, body) -> void: "destroy": #write code to destroy if body is Crate: - %SceneManager.destroy(body) + destroytSignal.emit(body) cratesDestroyed +=1 "powerup": if body is Player: @@ -31,10 +63,37 @@ func bulletHit(body): print("Game controller knows bullet hit") if body is Crate: print("You hit a Crate") - cratesDestroyed +=1 - %SceneManager.destroy(body) + totalCrates -=1 + destroytSignal.emit(body) print("Crates Remaining :: "+str(totalCrates - cratesDestroyed)) + if totalCrates <= 0: + print("You won!!!") + currentLevel +=1 + if currentLevel >= levels.size(): + currentLevel = 0 + levelCompleteSignal.emit(levels[currentLevel]) func numberOfCrates(value): totalCrates = value print("Game Controller knows crates "+str(totalCrates)) +func numberOfCoins(value): + totalCoinsAvailable = value +func coinCollected(body, coin): + print("GC knows coin collected") + if body is Player: + #increase coins collected count + coinsCollected +=1 + destroytSignal.emit(coin) +func playerDamage(body, badguy): + if body is Player: + print("GC knows player taking damage") + print("Player health"+str(player.health)+"takes damage"+str(slime.meleeDamage)) + player.health -= slime.meleeDamage + if player.health > 0: + playerHurtSignal.emit(player.health) + else: + print("kill em") + +func numberOfBadguys(value): + enemies = value + diff --git a/februarygodotgame/scripts/player.gd b/februarygodotgame/scripts/player.gd index ed3446a..13b5d71 100644 --- a/februarygodotgame/scripts/player.gd +++ b/februarygodotgame/scripts/player.gd @@ -17,74 +17,88 @@ var isJumping = false @onready var right_target: Node2D = $rightTarget @onready var left_target: Node2D = $leftTarget -func _physics_process(delta: float) -> void: - # Add the gravity. - if not is_on_floor(): - velocity += get_gravity() * delta - else: - isJumping = false +var animPlaying = "idle" +var living = true - # Handle jump. - if Input.is_action_just_pressed("ui_accept") and is_on_floor(): - velocity.y = JUMP_VELOCITY - isJumping = true - playerGraphic.play("jump") +func _physics_process(delta: float) -> void: + if living and not animPlaying =="hurt": + # Add the gravity. + if not is_on_floor(): + velocity += get_gravity() * delta + else: + isJumping = false + + # Handle jump. + if Input.is_action_just_pressed("ui_accept") and is_on_floor(): + velocity.y = JUMP_VELOCITY + isJumping = true + playerGraphic.play("jump") + + # Get the input direction and handle the movement/deceleration. + # As good practice, you should replace UI actions with custom gameplay actions. + var direction := Input.get_axis("left", "right") + if Input.is_action_just_pressed("shove") && pushRightEnabled && faceLeft == false: + pushTarget.apply_central_impulse(Vector2(1,0) * PUSH_FORCE) + pushRightEnabled = false + if Input.is_action_just_pressed("shove") && pushLeftEnabled && faceLeft == true: + pushTarget.apply_central_impulse(Vector2(-1,0) * PUSH_FORCE) + pushLeftEnabled = false + # Shoot attack + if Input.is_action_just_pressed("shoot"): + if faceLeft == false: + %SceneManager.makeBullet(right_target.global_transform, 700) + if faceLeft == true: + %SceneManager.makeBullet(left_target.global_transform, -700) - # Get the input direction and handle the movement/deceleration. - # As good practice, you should replace UI actions with custom gameplay actions. - var direction := Input.get_axis("left", "right") - if Input.is_action_just_pressed("shove") && pushRightEnabled && faceLeft == false: - pushTarget.apply_central_impulse(Vector2(1,0) * PUSH_FORCE) - pushRightEnabled = false - if Input.is_action_just_pressed("shove") && pushLeftEnabled && faceLeft == true: - pushTarget.apply_central_impulse(Vector2(-1,0) * PUSH_FORCE) - pushLeftEnabled = false - # Shoot attack - if Input.is_action_just_pressed("shoot"): - if faceLeft == false: - %SceneManager.makeBullet(right_target.global_transform, 700) - if faceLeft == true: - %SceneManager.makeBullet(left_target.global_transform, -700) - - - if direction: - velocity.x = direction * SPEED - else: - velocity.x = move_toward(velocity.x, 0, SPEED) - if direction: - if not isJumping: - playerGraphic.play("run") - if direction == 0: - if not isJumping: - playerGraphic.play("idle") - if direction <0: - faceLeft = true - playerGraphic.flip_h = true - if direction >0: - faceLeft = false - playerGraphic.flip_h = false - - move_and_slide() - if rightcast.is_colliding(): - print("something on my right") - var collider = rightcast.get_collider() - if collider is Node: - if collider is RigidBody2D: - print ("shove this crave") - #record that we can shove right - pushRightEnabled = true - #record what objet to shove - pushTarget = collider + if direction: + velocity.x = direction * SPEED + else: + velocity.x = move_toward(velocity.x, 0, SPEED) + if direction: + if not isJumping: + playerGraphic.play("run") + if direction == 0: + if not isJumping: + playerGraphic.play("idle") + + if direction <0: + faceLeft = true + playerGraphic.flip_h = true + if direction >0: + faceLeft = false + playerGraphic.flip_h = false + + move_and_slide() + if rightcast.is_colliding(): + print("something on my right") + var collider = rightcast.get_collider() + if collider is Node: + if collider is RigidBody2D: + print ("shove this crave") + #record that we can shove right + pushRightEnabled = true + #record what objet to shove + pushTarget = collider + + if leftcast.is_colliding(): + var collider = leftcast.get_collider() + if collider is Node: + if collider is RigidBody2D: + pushLeftEnabled = true + pushTarget = collider + + for i in get_slide_collision_count(): + var c = get_slide_collision(i) + if c.get_collider() is RigidBody2D: + c.get_collider().apply_central_impulse(-c.get_normal() *50) - if leftcast.is_colliding(): - var collider = leftcast.get_collider() - if collider is Node: - if collider is RigidBody2D: - pushLeftEnabled = true - pushTarget = collider - - for i in get_slide_collision_count(): - var c = get_slide_collision(i) - if c.get_collider() is RigidBody2D: - c.get_collider().apply_central_impulse(-c.get_normal() *50) +func hurtPlayer(health): + print("Player takes damage, health remaining:: "+str(health)) + animPlaying = "hurt" + playerGraphic.play(animPlaying) + + +func _on_animation_finished() -> void: + if animPlaying=="hurt": + animPlaying=="idle" diff --git a/februarygodotgame/scripts/res/characterStats.gd b/februarygodotgame/scripts/res/characterStats.gd new file mode 100644 index 0000000..acfaff9 --- /dev/null +++ b/februarygodotgame/scripts/res/characterStats.gd @@ -0,0 +1,8 @@ +class_name CharacterStats extends Resource + +@export var max_health:int = 100 +@export var starting_health:int = 100 +@export var health:int = 100 + +@export var meleeDamage:int = 10 +@export var rangeDamage:int = 8 diff --git a/februarygodotgame/scripts/res/playerStats.tres b/februarygodotgame/scripts/res/playerStats.tres new file mode 100644 index 0000000..02d2464 --- /dev/null +++ b/februarygodotgame/scripts/res/playerStats.tres @@ -0,0 +1,11 @@ +[gd_resource type="Resource" script_class="CharacterStats" load_steps=2 format=3 uid="uid://uiy3jm3rn86r"] + +[ext_resource type="Script" path="res://scripts/res/characterStats.gd" id="1_xg86d"] + +[resource] +script = ExtResource("1_xg86d") +max_health = 110 +starting_health = 110 +health = 110 +meleeDamage = 15 +rangeDamage = 20 diff --git a/februarygodotgame/scripts/res/slimeStats.tres b/februarygodotgame/scripts/res/slimeStats.tres new file mode 100644 index 0000000..eee2aba --- /dev/null +++ b/februarygodotgame/scripts/res/slimeStats.tres @@ -0,0 +1,11 @@ +[gd_resource type="Resource" script_class="CharacterStats" load_steps=2 format=3 uid="uid://pj5dr8ee8h7i"] + +[ext_resource type="Script" path="res://scripts/res/characterStats.gd" id="1_k2ehn"] + +[resource] +script = ExtResource("1_k2ehn") +max_health = 50 +starting_health = 50 +health = 110 +meleeDamage = 30 +rangeDamage = 0 diff --git a/februarygodotgame/scripts/scene_manager.gd b/februarygodotgame/scripts/scene_manager.gd index a1f31e0..d1736e0 100644 --- a/februarygodotgame/scripts/scene_manager.gd +++ b/februarygodotgame/scripts/scene_manager.gd @@ -1,7 +1,11 @@ extends Node -@onready var gameController: Node2D = $".." + @onready var crates: Node2D = $"../crates" @onready var triggers: Node2D = $"../triggers" +@onready var coins: Node2D = $"../coins" +@onready var badguys: Node2D = $"../badguys" +@onready var player: Player = $"../CharacterBody2D" + var bulletsFiredTotal = 0 @@ -33,7 +37,7 @@ func makeBullet(position,speed): func bulletHit(bullet, body): print("Tell the game controller a bullet hit something") - gameController.bulletHit(body) + Gamecontroller.bulletHit(body) bullet.setSpeed(0) bullet.position = Vector2(-100,-100) @@ -46,13 +50,41 @@ func buildLevel(): for obj in crates.get_children(): if obj is Crate: totalCrates +=1 - gameController.numberOfCrates(totalCrates) + Gamecontroller.numberOfCrates(totalCrates) + #how many coins? + var totalCoins = 0 + if coins: + for obj in coins.get_children(): + if obj is Coin: + totalCoins +=1 + obj.coinCollectedSignal.connect(Gamecontroller.coinCollected) + Gamecontroller.numberOfCoins(totalCoins) + #how many badguys? + var totalBadguys = 0 + if badguys: + for obj in badguys.get_children(): + if obj is Slime: + totalBadguys += 1 + obj.playerDamageSignal.connect(Gamecontroller.playerDamage) + Gamecontroller.numberOfBadguys(totalBadguys) + #wire up the triggers for obj in triggers.get_children(): if obj is Trigger: #wire up to GC - obj.areaTrigger.connect(gameController._on_trigger_area_trigger) - + obj.areaTrigger.connect(Gamecontroller._on_trigger_area_trigger) + + #Listen to Gamecontroller + Gamecontroller.destroytSignal.connect(destroy) + Gamecontroller.levelCompleteSignal.connect(loadLevel) + Gamecontroller.playerHurtSignal.connect(playerHurt) + +func loadLevel(level): + get_tree().change_scene_to_file(level) + func _ready() -> void: buildLevel() + Gamecontroller.reset() +func playerHurt(health): + player.hurtPlayer(health) diff --git a/februarygodotgame/scripts/slime.gd b/februarygodotgame/scripts/slime.gd new file mode 100644 index 0000000..a2ef821 --- /dev/null +++ b/februarygodotgame/scripts/slime.gd @@ -0,0 +1,10 @@ +class_name Slime extends Area2D + +signal playerDamageSignal + + + + +func _on_body_entered(body: Node2D) -> void: + print("Bad guy contact") + playerDamageSignal.emit(body, self)