Add coins, enemy slime, and level reset.

This commit is contained in:
CatherineHoang committed 2026-07-27 21:13:39 -04:00
1 parent 8f29753f2e
commit 0c52a8d411
36 files changed
+970 -41

No files matched your search

+1 -1
View File
@@ -9,5 +9,5 @@ func _process(delta: float) -> void:
position += transform.x * speed * delta
func _on_body_entered(body: Node2D) -> void:
if body is Crate:
if body.is_in_group("shootable"):
bulletHitSignal.emit(body,self)
+60 -5
View File
@@ -1,13 +1,27 @@
class_name GameController extends Node2D
signal destroySignal(body)
signal playerHurtSignal(playerHealth,maxHealth)
signal playerDeadSignal
var numberOfCrates = 2
var totalCoinsCollected = 0
var timer = Timer.new()
var timeAvailable = 50
var currentPlayerHealth = 100
var startingHealth = 100
var enemiesDict = {}
var enemy:CharacterStats
var player:CharacterStats
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
get_window().grab_focus()
player = load("res://Scripts/rscs/playerStats.tres")
enemy = load("res://Scripts/rscs/slimeStats.tres")
add_child(timer)
# time based on seconds
timer.wait_time = 1
@@ -16,12 +30,15 @@ func _ready() -> void:
timer.connect("timeout", countdown)
timer.start()
func reset()->void:
currentPlayerHealth = player.startingHealth
func countdown() -> void:
# Reduce time left
timeAvailable -= 1
if timeAvailable <= 0 and numberOfCrates > 0:
print("LOSER")
get_tree().reload_current_scene()
playerDeadSignal.emit()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
@@ -32,7 +49,8 @@ func _on_trigger(body: Variant, trigger: Variant, intent:String) -> void:
print("Game controller knows trigger fired")
match intent:
"destroy":
destroySignal.emit(body)
if body is RigidBody2D:
destroySignal.emit(body)
func crateTotal(howMany):
numberOfCrates = howMany
@@ -41,8 +59,45 @@ func crateTotal(howMany):
print("YOU WON!!!")
get_tree().reload_current_scene()
func coinCollected(body,coin)->void:
print("GC knows coin collected")
totalCoinsCollected +=1
destroySignal.emit(coin)
func coinTotal(totalAmount)->void:
print("GC knows total coins "+str(totalAmount))
func totalEnemies(numberOfEnemies)->void:
print("GC knows total bad guys "+str(numberOfEnemies))
func slimeAttack(body,slime)->void:
print("GC knows slime attack "+str(enemiesDict[slime]["damage"]))
currentPlayerHealth -= enemiesDict[slime]["damage"]
if currentPlayerHealth > 0:
print("ouch")
playerHurtSignal.emit(currentPlayerHealth,startingHealth)
else:
print("ded")
playerDeadSignal.emit()
func bulletDamage(body, _bullet)->void:
if body.is_in_group("shootable"):
destroySignal.emit(body)
destroySignal.emit(_bullet)
if body is Crate:
destroySignal.emit(body)
destroySignal.emit(_bullet)
if body is Slime:
enemiesDict[body]["health"]-=player.rangeDamage
if enemiesDict[body]["health"] <=0:
enemiesDict.erase(body)
destroySignal.emit(body)
destroySignal.emit(_bullet)
func levelChange()->void:
get_tree().reload_current_scene()
func addEnemyToLevel(slime)->void:
var stats = {
"health": enemy.startingHealth+randi_range(0,20),
"damage": enemy.meleeDamage+randi_range(0,10)
}
enemiesDict[slime]=stats
+18 -7
View File
@@ -1,6 +1,7 @@
class_name Player extends CharacterBody2D
signal pushSignal(body, direction)
signal shootSignal(markerPosition, speed)
signal deathAnimationCompleteSignal
const SPEED = 300.0
const JUMP_VELOCITY = -400.0
@@ -18,18 +19,25 @@ var pushTimer = 0
enum FaceDirection {RIGHT,LEFT}
var facing:FaceDirection = FaceDirection.RIGHT
enum playerStates {IDLE, RUNNING, JUMPING, FALLING, CHARGING, SHOVING}
enum playerStates {IDLE, RUNNING, JUMPING, FALLING, CHARGING, SHOVING, HURT, DEAD}
var current_player_state:playerStates = playerStates.IDLE
var upJump = false
func _physics_process(delta: float) -> void:
if current_player_state != playerStates.DEAD:
handle_input()
handle_movement(delta)
handle_input()
handle_states()
handle_animation()
move_and_slide()
handle_collisions()
func hurt(playerHealth, maxHealth)->void:
current_player_state = playerStates.HURT
func kill()->void:
current_player_state = playerStates.DEAD
func handle_input()->void:
# Handle jump.
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
@@ -38,7 +46,6 @@ func handle_input()->void:
upJump = true
#Handle shove target
if Input.is_action_just_pressed("shove"):
print("I want to shove")
if pushRightEnabled && facing==FaceDirection.RIGHT:
current_player_state = playerStates.CHARGING
pushTimer = Time.get_ticks_msec()
@@ -59,7 +66,6 @@ func handle_input()->void:
#Handle Shoot Bullet
if Input.is_action_just_pressed("shoot"):
print("Ima shoot a bullet")
#marker postion, speed
match facing:
FaceDirection.RIGHT:
@@ -88,7 +94,6 @@ func handle_movement(delta)->void:
func handle_collisions()->void:
if right_cast.is_colliding():
print("Right raycast collision")
var collider = right_cast.get_collider()
if collider is Node:
pushRightEnabled = true
@@ -97,7 +102,6 @@ func handle_collisions()->void:
pushRightEnabled = false
if left_cast.is_colliding():
print("Left raycast collision")
var collider = left_cast.get_collider()
if collider is Node:
pushLeftEnabled = true
@@ -115,7 +119,6 @@ func handle_collisions()->void:
func handle_states()->void:
match current_player_state:
playerStates.IDLE when velocity.x != 0:
print("I run")
current_player_state = playerStates.RUNNING
playerStates.RUNNING when velocity.x == 0:
current_player_state = playerStates.IDLE
@@ -142,6 +145,10 @@ func handle_animation()->void:
player_graphic.play("charging")
playerStates.SHOVING:
player_graphic.play("shoving")
playerStates.HURT:
player_graphic.play("hurt")
playerStates.DEAD:
player_graphic.play("dead")
func _on_animation_finished() -> void:
@@ -150,3 +157,7 @@ func _on_animation_finished() -> void:
upJump = false
playerStates.SHOVING:
current_player_state = playerStates.IDLE
playerStates.HURT:
current_player_state = playerStates.IDLE
playerStates.DEAD:
deathAnimationCompleteSignal.emit()
+10
View File
@@ -0,0 +1,10 @@
class_name CharacterStats extends Resource
#health
@export var currentHealth:int = 100
@export var maxHealth := 150
@export var startingHealth := 100
#damage
@export var meleeDamage := 20
@export var rangeDamage := 15
+1
View File
@@ -0,0 +1 @@
uid://b184uwt12pcwt
+10
View File
@@ -0,0 +1,10 @@
[gd_resource type="Resource" script_class="CharacterStats" format=3 uid="uid://be2pt870o5sfl"]
[ext_resource type="Script" uid="uid://b184uwt12pcwt" path="res://Scripts/rscs/characterstats.gd" id="1_eiyfu"]
[resource]
script = ExtResource("1_eiyfu")
maxHealth = 200
meleeDamage = 30
rangeDamage = 20
metadata/_custom_type_script = "uid://b184uwt12pcwt"
+11
View File
@@ -0,0 +1,11 @@
[gd_resource type="Resource" script_class="CharacterStats" format=3 uid="uid://bv3403ln5bjch"]
[ext_resource type="Script" uid="uid://b184uwt12pcwt" path="res://Scripts/rscs/characterstats.gd" id="1_g41dv"]
[resource]
script = ExtResource("1_g41dv")
currentHealth = 60
maxHealth = 80
startingHealth = 60
rangeDamage = 0
metadata/_custom_type_script = "uid://b184uwt12pcwt"
+43 -6
View File
@@ -1,29 +1,42 @@
extends Node2D
# hold control and drag + drop
@onready var game:GameController = $".."
@onready var crates: Node2D = $"../Crates"
@onready var player: Player = $"../Player"
@onready var coins: Node2D = $"../Coins"
@onready var enemies: Node2D = $"../Enemies"
var bullet = preload("res://Scenes/bullet.tscn")
var bulletArray:Array[Bullet] = []
var totalAllowedBullets:int = 7
var coin
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
Gamecontroller.reset()
player.pushSignal.connect(pushTarget)
player.shootSignal.connect(makeBullet)
player.deathAnimationCompleteSignal.connect(Gamecontroller.levelChange)
#signals from the GameController
game.destroySignal.connect(destroy)
Gamecontroller.destroySignal.connect(destroy)
Gamecontroller.playerHurtSignal.connect(player.hurt)
Gamecontroller.playerDeadSignal.connect(player.kill)
#signals from pickups
#coin.coinCollectedSignal.connect(Gamecontroller.coinCollected)
buildLevel()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
func buildLevel() -> void:
#tell GC how many crates...
updateCrates()
updateCoins()
updateEnemies()
func updateCrates()->void:
var totalCrates = 0
if crates:
@@ -33,7 +46,31 @@ func updateCrates()->void:
obj.tree_exited.connect(updateCrates)
totalCrates +=1
game.crateTotal(totalCrates)
Gamecontroller.crateTotal(totalCrates)
func updateCoins()->void:
var totalCoins = 0
if coins:
print("updateCoins called")
for obj in coins.get_children():
if obj is Coin:
if not obj.tree_exited.is_connected(updateCoins):
obj.tree_exited.connect(updateCoins)
if not obj.coinCollectedSignal.is_connected(Gamecontroller.coinCollected):
obj.coinCollectedSignal.connect(Gamecontroller.coinCollected)
totalCoins +=1
Gamecontroller.coinTotal(totalCoins)
func updateEnemies()->void:
var totalEnemies = 0
if enemies:
for obj in enemies.get_children():
if obj is Slime:
Gamecontroller.addEnemyToLevel(obj)
obj.slimeDamageSignal.connect(Gamecontroller.slimeAttack)
totalEnemies += 1
Gamecontroller.totalEnemies(totalEnemies)
func pushTarget(body,pushDirection)->void:
if body is RigidBody2D:
body.apply_central_impulse(pushDirection)
@@ -61,8 +98,8 @@ func bulletFactory()->Bullet:
#make a new bullet
myBullet = bullet.instantiate()
add_sibling(myBullet)
if not myBullet.bulletHitSignal.is_connected(game.bulletDamage):
myBullet.bulletHitSignal.connect(game.bulletDamage)
if not myBullet.bulletHitSignal.is_connected(Gamecontroller.bulletDamage):
myBullet.bulletHitSignal.connect(Gamecontroller.bulletDamage)
else:
# gets oldest one - pop_back
myBullet = bulletArray.pop_back()
+30
View File
@@ -0,0 +1,30 @@
class_name Slime extends Area2D
@onready var right_cast: RayCast2D = $rightCast
@onready var right_down_cast: RayCast2D = $rightDownCast
@onready var left_down_cast: RayCast2D = $leftDownCast
@onready var left_cast: RayCast2D = $leftCast
@onready var slime_graphic: AnimatedSprite2D = $slimeGraphic
signal slimeDamageSignal(body,slime)
@export var speed:int = 100
var direction = 1
# Called every frame. 'delta' is the elapsed time since the previous frame.
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:
slimeDamageSignal.emit(body,self)
+1
View File
@@ -0,0 +1 @@
uid://0upi64wxvgdi