From a5f092f12590ee3158e6350ec956b348dfc25866 Mon Sep 17 00:00:00 2001 From: OddlyTimbot Date: Mon, 16 Dec 2024 21:14:32 -0500 Subject: [PATCH] enemies, gamecontroller, playerdeath, coins --- .../assets/graphics/enemies/slime_green.png | Bin 0 -> 908 bytes .../graphics/enemies/slime_green.png.import | 34 ++++ novembergame/assets/graphics/pickups/coin.png | Bin 0 -> 500 bytes .../assets/graphics/pickups/coin.png.import | 34 ++++ .../player/death/Player Death 64x64.png | Bin 0 -> 1584 bytes .../death/Player Death 64x64.png.import | 34 ++++ .../player/hurt/Player Hurt 48x48.png | Bin 0 -> 1448 bytes .../player/hurt/Player Hurt 48x48.png.import | 34 ++++ novembergame/project.godot | 4 + novembergame/scenes/badguy.tscn | 74 +++++++ novembergame/scenes/character.tscn | 118 ++++++++++- novembergame/scenes/coin.tscn | 112 +++++++++++ novembergame/scenes/game.tscn | 29 ++- novembergame/scripts/badguy.gd | 39 ++++ novembergame/scripts/coin.gd | 12 ++ novembergame/scripts/dudecontroller.gd | 184 ++++++++++-------- novembergame/scripts/game_controller.gd | 34 ++++ novembergame/scripts/res/characterstats.gd | 6 + novembergame/scripts/res/enemystats.tres | 9 + novembergame/scripts/res/playerstats.tres | 9 + novembergame/scripts/scene_manager.gd | 31 +++ 21 files changed, 705 insertions(+), 92 deletions(-) create mode 100644 novembergame/assets/graphics/enemies/slime_green.png create mode 100644 novembergame/assets/graphics/enemies/slime_green.png.import create mode 100644 novembergame/assets/graphics/pickups/coin.png create mode 100644 novembergame/assets/graphics/pickups/coin.png.import create mode 100644 novembergame/assets/graphics/player/death/Player Death 64x64.png create mode 100644 novembergame/assets/graphics/player/death/Player Death 64x64.png.import create mode 100644 novembergame/assets/graphics/player/hurt/Player Hurt 48x48.png create mode 100644 novembergame/assets/graphics/player/hurt/Player Hurt 48x48.png.import create mode 100644 novembergame/scenes/badguy.tscn create mode 100644 novembergame/scenes/coin.tscn create mode 100644 novembergame/scripts/badguy.gd create mode 100644 novembergame/scripts/coin.gd create mode 100644 novembergame/scripts/game_controller.gd create mode 100644 novembergame/scripts/res/characterstats.gd create mode 100644 novembergame/scripts/res/enemystats.tres create mode 100644 novembergame/scripts/res/playerstats.tres diff --git a/novembergame/assets/graphics/enemies/slime_green.png b/novembergame/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/novembergame/assets/graphics/enemies/slime_green.png.import b/novembergame/assets/graphics/enemies/slime_green.png.import new file mode 100644 index 0000000..2c776eb --- /dev/null +++ b/novembergame/assets/graphics/enemies/slime_green.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://da7ap0kxh23js" +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/novembergame/assets/graphics/pickups/coin.png b/novembergame/assets/graphics/pickups/coin.png new file mode 100644 index 0000000000000000000000000000000000000000..01ae33d70b398db7f1f7bcafe883a0a469805201 GIT binary patch literal 500 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 void: + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + if cast_right.is_colliding(): + if not cast_right.get_collider().is_in_group("player"): + direction = -1 + sprite.flip_h = true + if cast_left.is_colliding(): + if not cast_left.get_collider().is_in_group("player"): + direction = 1 + sprite.flip_h = false + if not cast_floor_right.is_colliding(): + direction =-1 + sprite.flip_h = true + if not cast_floor_left.is_colliding(): + direction = 1 + sprite.flip_h = false + + position.x += direction * speed * delta + + +func _on_body_entered(body: Node2D) -> void: + if body.is_in_group("player"): + playerDamage.emit() diff --git a/novembergame/scripts/coin.gd b/novembergame/scripts/coin.gd new file mode 100644 index 0000000..182bc62 --- /dev/null +++ b/novembergame/scripts/coin.gd @@ -0,0 +1,12 @@ +class_name Coin extends Area2D + +signal coinCollected + + + + +func _on_body_entered(body: Node2D) -> void: + if body.is_in_group("player"): + coinCollected.emit() + queue_free() + diff --git a/novembergame/scripts/dudecontroller.gd b/novembergame/scripts/dudecontroller.gd index 32f5225..12b43df 100644 --- a/novembergame/scripts/dudecontroller.gd +++ b/novembergame/scripts/dudecontroller.gd @@ -17,93 +17,117 @@ var pushLeftEnabled = false var pushRightEnabled = false var isJumping = false +var animPlaying = "idle" +var living = true + +signal playerDead + @onready var right_target: Node2D = $RightTarget @onready var left_target: Node2D = $LeftTarget +func hurtPlayer(amt): + print("Character knows it should be hurt") + animPlaying = "hurt" + playerSprite.play("hurt") +func killPlayer(): + if living: + living = false + animPlaying = "death" + playerSprite.play(animPlaying) + func _physics_process(delta: float) -> void: - # Add the gravity. - if not is_on_floor(): - velocity += get_gravity() * delta + if living and not animPlaying =="hurt": + # Add the gravity. + if not is_on_floor(): + velocity += get_gravity() * delta - # Handle jump. - if Input.is_action_just_pressed("ui_accept") and is_on_floor(): - velocity.y = JUMP_VELOCITY + # Handle jump. + if Input.is_action_just_pressed("ui_accept") and is_on_floor(): + velocity.y = JUMP_VELOCITY - # 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("ui_left", "ui_right") - if Input.is_action_just_pressed("shove") && pushRightEnabled && faceLeft == false: - print("Shove a box") - pushTarget.apply_central_impulse(Vector2(1,0) * PUSHFORCE * 2 ) - pushRightEnabled = false - - if Input.is_action_just_pressed("shove") && faceLeft == true && pushLeftEnabled == true: - pushTarget.apply_central_impulse(Vector2(-1,0) * PUSHFORCE *2 ) - pushLeftEnabled = false - - if Input.is_action_just_pressed("shoot"): - print("Shoot a bullet") - var myBullet = %SceneManager.bulletFactory() - if not faceLeft: - myBullet.transform = right_target.global_transform - myBullet.setSpeed(700) - if faceLeft ==true: - myBullet.transform = left_target.global_transform - myBullet.setSpeed(-700) - - if direction: - velocity.x = direction * SPEED - if direction >0: - faceLeft = false - if direction < 0: - faceLeft = true - else:#TODO: implement jump - pass - velocity.x = move_toward(velocity.x, 0, SPEED) - - if faceLeft: - playerSprite.flip_h = true - else: - playerSprite.flip_h = false - - if is_on_floor(): - isJumping = false - if direction == 0: - playerSprite.play("idle") - else: - playerSprite.play("run") - else: - if not isJumping: - playerSprite.play("jump") - isJumping = true - - move_and_slide() - if right_ray.is_colliding(): - print("Something is on my right") - if not faceLeft: - var collider = right_ray.get_collider() - if collider is Node: - if collider.is_in_group("box"): - print("This is a pushable box") - pushTarget = collider - pushRightEnabled = true - else: - pushRightEnabled = false - - if left_ray.is_colliding(): - if faceLeft: - var collider = left_ray.get_collider() - if collider is Node: - if collider.is_in_group("box"): - pushTarget = collider - pushLeftEnabled = true - else: - pushLeftEnabled = false + # 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("ui_left", "ui_right") + if Input.is_action_just_pressed("shove") && pushRightEnabled && faceLeft == false: + print("Shove a box") + pushTarget.apply_central_impulse(Vector2(1,0) * PUSHFORCE * 2 ) + pushRightEnabled = false + if Input.is_action_just_pressed("shove") && faceLeft == true && pushLeftEnabled == true: + pushTarget.apply_central_impulse(Vector2(-1,0) * PUSHFORCE *2 ) + pushLeftEnabled = false + if Input.is_action_just_pressed("shoot"): + print("Shoot a bullet") + var myBullet = %SceneManager.bulletFactory() + if not faceLeft: + myBullet.transform = right_target.global_transform + myBullet.setSpeed(700) + if faceLeft ==true: + myBullet.transform = left_target.global_transform + myBullet.setSpeed(-700) + + if direction: + velocity.x = direction * SPEED + if direction >0: + faceLeft = false + if direction < 0: + faceLeft = true + else:#TODO: implement jump + pass + velocity.x = move_toward(velocity.x, 0, SPEED) - 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() * BUMPFORCE) + if faceLeft: + playerSprite.flip_h = true + else: + playerSprite.flip_h = false + + if is_on_floor(): + isJumping = false + if direction == 0: + playerSprite.play("idle") + else: + playerSprite.play("run") + else: + if not isJumping: + playerSprite.play("jump") + isJumping = true + + move_and_slide() + if right_ray.is_colliding(): + print("Something is on my right") + if not faceLeft: + var collider = right_ray.get_collider() + if collider is Node: + if collider.is_in_group("box"): + print("This is a pushable box") + pushTarget = collider + pushRightEnabled = true + else: + pushRightEnabled = false + + if left_ray.is_colliding(): + if faceLeft: + var collider = left_ray.get_collider() + if collider is Node: + if collider.is_in_group("box"): + pushTarget = collider + pushLeftEnabled = true + else: + pushLeftEnabled = false + + + + 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() * BUMPFORCE) + + +func _on_animation_finished() -> void: + if animPlaying == "hurt": + animPlaying ="idle" + if animPlaying=="death": + ## emit a custom signal + playerDead.emit() diff --git a/novembergame/scripts/game_controller.gd b/novembergame/scripts/game_controller.gd new file mode 100644 index 0000000..6c3e6b3 --- /dev/null +++ b/novembergame/scripts/game_controller.gd @@ -0,0 +1,34 @@ +extends Node + +var coinsCollected:int = 0 +var player:Resource + +signal playerHurt(amt) +signal playerDeath() + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + player = load("res://scripts/res/playerstats.tres") + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + pass + +func coinCollected(): + coinsCollected +=1 + print("Total coins collected "+str(coinsCollected) ) + +func playerDamage(): + if player.health > 0: + player.health -= 20 + if player.health <=0: + ## kill him + playerDeath.emit() + else: + ## damage him + playerHurt.emit(20) +func reset(): + player.health = player.max_health + coinsCollected = 0 + diff --git a/novembergame/scripts/res/characterstats.gd b/novembergame/scripts/res/characterstats.gd new file mode 100644 index 0000000..4fa7691 --- /dev/null +++ b/novembergame/scripts/res/characterstats.gd @@ -0,0 +1,6 @@ +class_name CharacterStats extends Resource + + +@export var max_health:int = 100 +@export var starting_health: int = 100 +@export var health: int = 100 diff --git a/novembergame/scripts/res/enemystats.tres b/novembergame/scripts/res/enemystats.tres new file mode 100644 index 0000000..da597df --- /dev/null +++ b/novembergame/scripts/res/enemystats.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="CharacterStats" load_steps=2 format=3 uid="uid://dlllgnb2qyb2p"] + +[ext_resource type="Script" path="res://scripts/res/characterstats.gd" id="1_yv8hh"] + +[resource] +script = ExtResource("1_yv8hh") +max_health = 50 +starting_health = 50 +health = 50 diff --git a/novembergame/scripts/res/playerstats.tres b/novembergame/scripts/res/playerstats.tres new file mode 100644 index 0000000..1dba6b6 --- /dev/null +++ b/novembergame/scripts/res/playerstats.tres @@ -0,0 +1,9 @@ +[gd_resource type="Resource" script_class="CharacterStats" load_steps=2 format=3 uid="uid://bqbgmfbankxvw"] + +[ext_resource type="Script" path="res://scripts/res/characterstats.gd" id="1_8phuw"] + +[resource] +script = ExtResource("1_8phuw") +max_health = 100 +starting_health = 100 +health = 100 diff --git a/novembergame/scripts/scene_manager.gd b/novembergame/scripts/scene_manager.gd index 5837143..5cb2ba2 100644 --- a/novembergame/scripts/scene_manager.gd +++ b/novembergame/scripts/scene_manager.gd @@ -3,9 +3,29 @@ extends Node var bulletsFiredTotal :=0 var bulletsMadeTotal :=0 var bulletArray:Array = [] +@onready var coins: Node = $"../coins" +@onready var enemies: Node = $"../enemies" + +@onready var player: CharacterBody2D = $"../CharacterBody2D" var bullet = preload("res://scenes/bullet.tscn") +func _ready() -> void: + ### coins loop + for n in coins.get_children(): + print("coin found") + n.coinCollected.connect(GameController.coinCollected) + ### enemies loop + for n in enemies.get_children(): + print("enemy found") + n.playerDamage.connect(GameController.playerDamage) + + ## wire up GameController signals to Player + GameController.playerHurt.connect(hurtPlayer) + GameController.playerDeath.connect(killPlayer) + + player.playerDead.connect(deadPlayer) + func bulletFactory(): print("Make a bullet at the factory") var mybullet @@ -28,3 +48,14 @@ func onBulletHit(bullet, body): if body.is_in_group("shootable"): print("explode this thing") body.queue_free() + +func hurtPlayer(amt): + player.hurtPlayer(amt) + +func killPlayer(): + player.killPlayer() + +func deadPlayer(): + GameController.reset() + get_tree().reload_current_scene() +