Constantly changing the background color in swift - colors

Hi there im finishing my game but i want to add some detail and one of them is looping trough a color cycle i have tried SKActions, that worked fine but it overlapped everything else.
then i made this in the update function but it doesn't do anything
if BGRed == 1 {RedBoolIs1 = true}
else {RedBoolIs1 = false}
if BGGreen == 1 {GreenBoolIs1 = true}
else {GreenBoolIs1 = false}
if BGBlue == 1 {BlueBoolIs1 = true}
else {BlueBoolIs1 = false}
//red only
if RedBoolIs1 == true && GreenBoolIs1 == false && BlueBoolIs1 == false {
BGGreen = BGGreen + 0.01 }
//red and green
if RedBoolIs1 == true && GreenBoolIs1 == true && BlueBoolIs1 == false {
BGRed = BGRed - 0.01 }
//green only
if RedBoolIs1 == false && GreenBoolIs1 == true && BlueBoolIs1 == false {
BGBlue = BGBlue + 0.01 }
//green and blue
if RedBoolIs1 == false && GreenBoolIs1 == true && BlueBoolIs1 == true {
BGGreen = BGGreen - 0.01 }
//blue only
if RedBoolIs1 == false && GreenBoolIs1 == false && BlueBoolIs1 == true {
BGRed = BGRed + 0.01 }
//blue and red
if RedBoolIs1 == true && GreenBoolIs1 == false && BlueBoolIs1 == true {
BGBlue = BGBlue - 0.01 }
self.backgroundColor = SKColor(red: CGFloat(BGRed), green: CGFloat(BGGreen), blue: CGFloat(BGBlue), alpha: 1)
also is it possible to make labels readable on all colors ? my solution now is placing 2 labels on each other the first one is white and 45 big and the one above that is black and 40 big but it doesn't look always good
thanks

First we initialise the color variables like this:
var BGRed: Float = 1
var BGGreen: Float = 0
var BGBlue: Float = 0
The reason nothing happens is that adding 0.1 10 times does not equal 1.0. This is because of floating point number accuracy. I myself asked the same type of SO question.
To fix this, remove comparisons like this:
if BGGreen == 1
And replace with:
if round(BGGreen * 100) / 100.0 == 1.0
It will solve this particular problem, but the better approach is to start using decimal floating point
For the second issue, there is no easy answer but there are multiple answers on SO like this one.

Related

The function 'connect()' returns a value, but this value is never used. What does this mean?

I am new to Godot, and I am creating my first project. There's something that annoys the heck out of me. It's this: "The function 'connect()' returns a value, but this value is never used." I don't know what to add to the line of code, but I will first show the code:
extends KinematicBody2D
var gravity = 1000
var velocity = Vector2.ZERO
var maxHorizontalSpeed = 120
var horizontalAcceleration = 100
var jumpSpeed = 320
var jumpTerminationMultiplier = 4
var hasDoubleJump = false
func _ready():
warning-ignore:return_value_discarded
$HazardArea.connect("area_entered", self, "on_hazard_area_entered")
func _process(delta):
var moveVector = Vector2.ZERO
moveVector.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
moveVector.y = -1 if Input.is_action_just_pressed("jump") else 0
velocity.x += moveVector.x * horizontalAcceleration * delta
if (moveVector.x == 0):
velocity.x = lerp(0, velocity.x, pow(2, -50))
velocity.x = clamp(velocity.x, -maxHorizontalSpeed, maxHorizontalSpeed)
if (moveVector.y < 0 && (is_on_floor() || $CoyoteTimer.is_stopped() || hasDoubleJump)):
velocity.y = moveVector.y * jumpSpeed
if(!is_on_floor() && $CoyoteTimer.is_stopped()):
hasDoubleJump = false
$CoyoteTimer.stop()
if(moveVector.y < 0 && !Input.is_action_just_pressed("jump")):
velocity.x = gravity * jumpTerminationMultiplier * delta
else:
velocity.y += gravity * delta
var wasOnFloor = is_on_floor()
velocity = move_and_slide(velocity, Vector2.UP)
if(wasOnFloor && !is_on_floor()):
$CoyoteTimer.start()
if(is_on_floor()):
hasDoubleJump = true
update_animation()
func get_movement_vector():
var moveVector = Vector2.ZERO
moveVector.x = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
moveVector.y = -1 if Input.is_action_just_pressed("jump") else 0
return moveVector
func update_animation():
var moveVec = get_movement_vector()
if(!is_on_floor()):
$AnimatedSprite.play("Jump")
elif(moveVec.x != 0):
$AnimatedSprite.play("Run")
else:
$AnimatedSprite.play("Idle")
$AnimatedSprite.flip_h = true if moveVec.x > 0 else false
func on_hazard_area_entered(_area2d):
print("die")
The problem is on line 13, and I would really appreciate some help!
there is not a solution for this problem. The only thinks you can do are these:
Or use the returning value (if you want)
Or press ignore in warning tab
This link can help you more https://godotengine.org/qa/78337/the-function-connect-returns-value-but-this-value-never-used

Aerial Attack on Godot

I'm new to Godot, and I'm making a personal project, a 2D platformer, a clone of Ninja Gaiden (1988), but I'm having trouble getting the aerial attack to work. The Player script is the following:
extends KinematicBody2D
onready var Animated_player = $AnimatedSprite
onready var Sword = $Sword/CollisionShape2D
export var Acceleration = 512
export var Max_speed = 64
export var Friction = 0.25
export var Air_resistance = 0.02
export var Gravity = 200
export var Jump_force = 100
var Is_attacking = false
var motion = Vector2.ZERO
func _physics_process(delta):
var x_input = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
if Input.is_action_just_pressed("Attack"):
Animated_player.play("Attack")
Sword.disabled = false
Is_attacking = true
motion.x = 0
if x_input != 0 and Is_attacking == false:
Sword.disabled = true
Animated_player.play("Walk")
motion.x += x_input * Acceleration * delta
motion.x = clamp(motion.x, -Max_speed, Max_speed )
Animated_player.flip_h = motion.x < 0
else:
if Is_attacking == false:
Sword.disabled = true
Animated_player.play("Idle")
motion.x = lerp(motion.x, 0, Friction * delta)
motion.y += Gravity * delta
if test_move(transform, Vector2.DOWN):
if x_input == 0:
motion.x = lerp(motion.x, 0, Friction)
if Input.is_action_just_pressed("Jump"):
motion.y = -Jump_force
else:
if Input.is_action_just_pressed("Attack"):
Sword.disabled = false
motion.x = lerp(motion.x, 0, Air_resistance)
Animated_player.play("Jump_Attack")
motion.x = lerp(motion.x, 0, Air_resistance)
if Is_attacking == false:
Sword.disabled = true
if motion.y < 0:
Animated_player.play("Jump")
if motion.y > 0:
Animated_player.play("Fall")
if Input.is_action_just_released("Jump") and motion.y < -Jump_force/2:
motion.y = -Jump_force/2
if x_input == 0:
motion.x = lerp(motion.x, 0, Air_resistance)
move_and_slide(motion)
motion = move_and_slide(motion, Vector2.UP)
func _on_AnimatedSprite_animation_finished():
if Animated_player.animation == "Attack" or Animated_player.animation == "Jump_Attack":
Is_attacking = false
Sword.disabled = true
The Jump_Attack animation plays right, but I want the "Air resistance" to be true while you attack on the air, but if you attack on the ground I want motion.x to be zero.
but whenever I make motion.x = 0 inside the if Input.is_action_just_pressed: it stops your movement on the air as well.
How can I solve this?
When making any kind of platformer, a good thing to add to the movement script is a "grounded" variable, which determine if the player is on the ground or not. you can do so with something like this (when using is on floor, make sure you always have a gravity applied to your player, and set it after the move_and_slide()):
var grounded = false
func process(_delta):
#move_and_slide(...)
grounded = is_on_floor()
then in your if that check if the attack key is pressed, if the player is grounded, you cant set your motion.x to 0 and if not, don't.
As you mentioned in your comment, now when you land during an attack, the idle or walk animation doesn't play right away because you don't check if the player is grounded when you set your animation to walk or idle and that your condition for your walk and idle animation check if the player is attacking and the only time your variable Is_Attacking is set to false is when the animation ends. here is what I would try,
in your physics_process function:
physics_process(delta):
var x_input = Input.get_action_strength("ui_right") -Input.get_action_strength("ui_left")
if Input.is_action_just_pressed("Attack"):
Animated_player.play("Attack")
Sword.disabled = false
Is_attacking = true
if Is_Attacking and grounded:
motion.x = 0
#the rest of your code
move_and_slide(...)
grounded = is_on_floor()
So you check if the player is grounded and attacking then you set the motion to 0. the player should be able to move and attack in the air, but if he touch the ground while attacking, motion is set to 0, and when the animation end, the player can walk or idle. this solve the animation issue and the "gliding".
Now if you want to just cancel the attack animation when landing so the player can walk or idle as he touch the ground, you can add a variable "Is_air_attacking" and do:
physics_process(delta):
var x_input = Input.get_action_strength("ui_right") -Input.get_action_strength("ui_left")
if Input.is_action_just_pressed("Attack"):
Animated_player.play("Attack")
Sword.disabled = false
Is_attacking = true
if !grounded:
Is_air_attacking = true
if Is_Attacking and grounded:
if Is_air_attacking:
Is_air_attacking = false
Is_Attacking = false
Sword.disabled = false
else:
motion.x = 0
#the rest of your code
move_and_slide(...)
grounded = is_on_floor()

How can I make the player and enemies fall to the ground when they die?

I'm making my first game in Godot.
No matter what I try, if the player/enemies die while in the air, they stay there. I want them to fall to the ground when they die. Help?
While at it if you have any pointers based on what you can see from my code, I'll really appreciate it. Especially when it comes to player movement and such. Currently, very few actions feel smooth; a lot of stuff feels rather rigid and wonky (jumping, falling from edges, and the enemy's collision shape somehow displaces itself as the enemy moves).
PLAYER CODE:
var motion = Vector2 ()
var is_in_attack = false
var fireball_power = 1
var is_dead = false
var is_jumping = false
func _physics_process(delta):
if is_dead == false:
motion.y += GRAVITY
var friction = false
if Input.is_action_pressed("ui_right"):
if is_in_attack == false || is_on_floor() == false:
motion.x = min(motion.x+ACCELERATION, MAX_SPEED)
if is_in_attack == false:
$Sprite.flip_h = false
$Sprite.play("run")
if sign($FireballPosition2D.position.x) == -1:
$FireballPosition2D.position.x *= -1
if sign($FireballPosition2D2.position.x) == -1:
$FireballPosition2D2.position.x *= -1
if sign($ArrowPosition2D.position.x) == -1:
$ArrowPosition2D.position.x *= -1
elif Input.is_action_pressed("ui_left"):
if is_in_attack == false || is_on_floor() == false:
motion.x = max(motion.x-ACCELERATION, -MAX_SPEED)
if is_in_attack == false:
$Sprite.flip_h = true
$Sprite.play("run")
if sign($FireballPosition2D.position.x) == 1:
$FireballPosition2D.position.x *= -1
if sign($FireballPosition2D2.position.x) == 1:
$FireballPosition2D2.position.x *= -1
if sign($ArrowPosition2D.position.x) == 1:
$ArrowPosition2D.position.x *= -1
else:
if is_in_attack == false:
$Sprite.play("idle")
friction = true
var snap = Vector2.DOWN *32 if !is_jumping else Vector2.ZERO
motion = move_and_slide_with_snap(motion,snap, UP)
pass
if get_slide_count() > 0:
for i in range(get_slide_count()):
if "Enemy" in get_slide_collision(i).collider.name:
dead()
for i in get_slide_count():
var collision = get_slide_collision(i)
if collision.collider.has_method("collide_with"):
collision.collider.collide_with(collision, self)
func dead():
is_dead = true
motion = Vector2(0,0)
$CollisionShape2D.set_deferred("disabled", true)
$Sprite.play("dead")
$Timer.start()
PlayerData.deaths += 1
func _on_attackarea_body_entered(body):
if "Enemy" in body.name:
body.dead(1)
ENEMY CODE:
const UP = Vector2 (0, -1)
const GRAVITY = 20
const ACCELERATION = 50
const JUMP_HEIGHT = -500
var motion = Vector2 ()
var direction = 1
var is_dead = false
export(int) var speed = 50
export(int) var hp = 1
export(Vector2) var size = Vector2(1, 1)
export var score: = 100
func _ready():
scale = size
pass
func dead(damage):
hp = hp -damage
if hp <=0:
is_dead = true
motion = Vector2(0,0)
$AnimatedSprite.play("dead")
$CollisionShape2D.set_deferred("disabled", true)
$Timer.start()
PlayerData.score += score
#calling the screenshake for large enemies
if scale > Vector2(1.6, 1.6):
get_parent().get_node("ScreenShake").screen_shake(1, 10, 100)
func _physics_process(delta):
if is_dead == false:
motion.x = speed * direction
if direction == 1:
$AnimatedSprite.flip_h = false
$CollisionShape2D.position.x = 1
else:
$AnimatedSprite.flip_h = true
$CollisionShape2D.position.x = -1
$AnimatedSprite.play("walk")
motion.y += GRAVITY
motion = move_and_slide(motion, UP)
if is_on_wall():
direction = direction * -1
if get_slide_count() > 0:
for i in range (get_slide_count()):
if "Player" in get_slide_collision(i).collider.name:
get_slide_collision(i).collider.dead()
Since it worked, I will add it as an official answer:
you only move the character in your physics_process as long as he is still alive:
func _physics_process(delta):
if is_dead == false:
# all the gravity code is in here.
Add an else statement for 'if is_dead == false' which moves the node on y direction as long as its not on the ground. Something like that should work:
func _physics_process(delta):
if is_dead == false:
# your code
else:
if not is_on_floor():
motion.y += GRAVITY
motion = move_and_slide(motion, UP)

Trying to get ball to return to middle after ball has left screen

I'm trying to recreate a game of pong just for fun.
Here is my full code as of right now.
import pygame, random, math
pygame.init()
#colours:-------------------------------------------------------------
R = random.randrange(1,255)
B = random.randrange(1,255)
G = random.randrange(1,255)
WHITE = (255, 255, 255)
GREEN = (39, 133, 20)
YELLOW = (252, 252, 25)
BLACK = (0, 0, 0)
BLUE = (30, 100, 225)
RED = (255,0,0)
RANDOM_COLOR = (R, B, G)
#Surface:-------------------------------------------------------------
width = 700
height = 600
size = (width, height)
screen = pygame.display.set_mode(size)
screen_rect = screen.get_rect()
pygame.display.set_caption("Pong Remake")
background = pygame.image.load("background.png").convert()
background = pygame.transform.scale(background, (width, height))
logo = pygame.image.load("logo.png").convert()
logo.set_colorkey((BLACK))
credits = pygame.image.load("credits.png")
credits.set_colorkey((BLACK))
#variables:-----------------------------------------------------------
clock = pygame.time.Clock()
done = False
text = pygame.font.Font(None,25)
display_instructions = True
instruction_page = 1
start_font = pygame.font.Font("C:\Windows\Fonts\BAUHS93.TTF", 35)
instruction_font = pygame.font.Font(None, 17)
win_lose_font = pygame.font.Font("C:\Windows\Fonts\BAUHS93.TTF",50)
score = pygame.font.Font(None, 100)
bounce = pygame.mixer.Sound("bounce.wav")
playerOne_score = 0
playerTwo_score = 0
playerOne = ""
playerTwo = ""
x = 350
y = 300
ball_rect = pygame.Rect(x,y,10,10)
paddleOne_rect = pygame.Rect(10, 250, 20, 60)
paddleTwo_rect = pygame.Rect(670, 250, 20, 60)
x_speed = random.randrange(5, 10)
y_speed = random.randrange(5,10)
def draw_background(screen, pic, x,y):
screen.blit(pic, (x,y))
#main loop
#INPUT v ---------------------------------------------------------
#Start Page
while not done and display_instructions:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
instruction_page += 1
if instruction_page == 2:
display_instructions = False
#Shows the start of the page
if instruction_page == 1:
draw_background(screen, logo, 100,-150)
draw_background(screen, credits, 100,50)
instruction_text = instruction_font.render("How to Play. The objective to this game is to score the ball on the other side before the opponent can.", False, WHITE)
instruction_text_three = instruction_font.render("First Player to get 10 points wins, Have Fun and Good Luck!", False, WHITE)
instruction_text_two = instruction_font.render("For Player One, use the a and the z keys to move up and down, For Player Two, use the k and m keys.", False, WHITE)
continue_text= start_font.render("Click to Play...",True, WHITE)
screen.blit(continue_text, [200, 400])
screen.blit(instruction_text, [0,500])
screen.blit(instruction_text_three, [0,532])
screen.blit(instruction_text_two,[0,516])
if instruction_page == 2:
display_instructions = False
clock.tick(60)
pygame.display.flip()
while not done:
click = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.MOUSEBUTTONDOWN:
click = True
#INPUT ^ =========================================================
#PROCESS v -------------------------------------------------------
str(playerOne_score)
str(playerTwo_score)
scoreOne = text.render("Player One:" + str(playerOne_score), False, WHITE)
scoreTwo = text.render("Player Two:" + str(playerTwo_score), False, WHITE)
#moves paddles with keys on keyboar
key = pygame.key.get_pressed()
if key[pygame.K_a]: paddleOne_rect.move_ip(0, -10)
if key[pygame.K_z]: paddleOne_rect.move_ip(0, 10)
if key[pygame.K_k]: paddleTwo_rect.move_ip(0, -10)
if key[pygame.K_m]: paddleTwo_rect.move_ip(0, 10)
#makes sure paddles stay on screen
paddleOne_rect.clamp_ip(screen_rect)
paddleTwo_rect.clamp_ip(screen_rect)
ball_rect.move_ip(x_speed, y_speed)
if ball_rect.y + ball_rect.height> screen_rect.height or ball_rect.y < 0:
y_speed = y_speed * -1
bounce.play()
if ball_rect.collidelist([paddleOne_rect, paddleTwo_rect]) > -1:
x_speed = -x_speed
R = random.randrange(1,255)
B = random.randrange(1,255)
G = random.randrange(1,255)
bounce.play()
if ball_rect.x >= 700:
x_speed * -1
playerOne_score += 1
pygame.display.flip
if ball_rect.x <= 0:
x_speed * -1
playerTwo_score += 1
#PROCESS ^ =======================================================
#DRAWING GOES BELOW HERE v ------------------------------------
draw_background(screen, background, 0,0)
screen.blit(scoreOne, (0,0))
screen.blit(scoreTwo, (500,0))
pygame.draw.ellipse(screen, WHITE,ball_rect )
pygame.draw.rect(screen,RANDOM_COLOR, paddleOne_rect)
pygame.draw.rect(screen,RANDOM_COLOR, paddleTwo_rect)
pygame.draw.line(screen, WHITE, (350,0),(350,700), 1)
#DRAWING GOES ABOVE HERE ^ ------------------------------------
pygame.display.flip()
clock.tick(60)
pygame.quit()
What I am currently having problems with at the moment is when the ball goes off the screen, I want it to go back to the middle again as someone has scored a point. But I'm a bit stuck on what to do.
If you guys can help me out, that would be amazing!!
There is a lot of code here, so this does not follow specific variables you used, but I hope this helps.
1) Find the width of you screen
2) Take the x and y coordinates that you use to know where to draw the ball
3) Make an if statement that essentially says
(pseudocode)
if x > 1000
score1 += 1
x = 500
if x < 0
score2 += 1
x = 500
``
I hope this can set you on the right track, and I suggest checking out the pygame docs.
Cheers!

What's wrong with this Groovy expression?

Running the following Groovy expression through the GroovyShell (interpreter):
if(fizz.subtype == null) {
if(fizz.color == 'RED') fizz.subtype = "DOG";
else if(fizz.color == 'BLUE') fizz.subtype = "CAT";
else if(fizz.color == 'GREEN') fizz.subtype = "SHEEP";
else if(fizz.color == 'ORANGE') fizz.subtype = "LION";
else if(fizz.color == 'YELLOW') fizz.subtype = "SNAIL";
else if(fizz.color == 'GRAY') fizz.subtype = "SHARK";
else if(fizz.color == 'PURPLE') fizz.subtype = "BAT";
else if(fizz.color == 'BLACK') fizz.subtype = "FOX";
}; fizz;
Gives me the following stack trace:
groovy.lang.MissingPropertyException: No such property: subtype for class: com.me.myapp.Fizz
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:50)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.getProperty(ScriptBytecodeAdapter.java:479)
at Script1.run(Script1.groovy:1)
at groovy.lang.GroovyShell.evaluate(GroovyShell.java:543)
at groovy.lang.GroovyShell.evaluate(GroovyShell.java:518)
at com.tms.evaluator.GroovyEvaluator._evaluate(GroovyEvaluator.java:51)
...rest of stacktrace omitted for brevity
Any ideas? Thanks in advance!
You are missing a semicolon after the closing bracket of the if expression:
fizz = [:]
if(fizz.subtype == null) {
if(fizz.color == 'RED') fizz.subtype = "DOG";
else if(fizz.color == 'BLUE') fizz.subtype = "CAT";
else if(fizz.color == 'GREEN') fizz.subtype = "SHEEP";
else if(fizz.color == 'ORANGE') fizz.subtype = "LION";
else if(fizz.color == 'YELLOW') fizz.subtype = "SNAIL";
else if(fizz.color == 'GRAY') fizz.subtype = "SHARK";
else if(fizz.color == 'PURPLE') fizz.subtype = "BAT";
else if(fizz.color == 'BLACK') fizz.subtype = "FOX";
}; fizz;
Also, may i suggest using a map for this kind of data matching?
fizz.color = 'ORANGE'
fizz.subtype = [
'RED' : 'DOG',
'BLUE' : "CAT",
'GREEN' : "SHEEP",
'ORANGE' : "LION",
'YELLOW' : "SNAIL",
'GRAY' : "SHARK",
'PURPLE' : "BAT",
'BLACK' : "FOX"
][fizz.color]
assert fizz.subtype == 'LION'
A case-match could also work, but it would be best suited if you had a more complex task:
fizz.color = 'BLUE'
fizz.subtype = fizz.color.case {
when 'RED' then 'DOG'
when 'BLUE' then "CAT"
when 'GREEN' then "SHEEP"
when 'ORANGE' then "LION"
when 'YELLOW' then "SNAIL"
when 'GRAY' then "SHARK"
when 'PURPLE' then "BAT"
when 'BLACK' then "FOX"
}
assert fizz.subtype == 'CAT'

Resources