I have a game where if the enemy dies they queue free and disappear. But when I play the scene, the enemy does not disappear, and still interacts as a kinematic body 2d.
Script:
if health == 0:
battle_area.enemy_list.erase(self)
self.queue_free()
Related
This simple piece of code crashes (the window is not responding) after a few seconds (around 5).
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 24)
#clock = pygame.time.Clock()
#font = pygame.font.Font(None, 32)
cycles = 0
while True:
screen.fill(0)
# text = font.render('Cycles : %d' % cycles, True, (255, 255, 255))
# screen.blit(text, (100, 100))
cycles += 1
pygame.display.update()
If I uncomment the commented lines, I can clearly see the program going out of control when displaying values between 47 and 50.
I use python 2.7 and pygame 1.9.2, Windows 8 (64 bits) and Eclipse + PyDev.
Call pygame.event.get() at the beginning of the while loop.
You need to regularly make a call to one of four functions in the pygame.event module in order for pygame to internally interact with your OS. Otherwise the OS will think your game has crashed. So make sure you call one of these:
pygame.event.get() returns a list of all events currently in the event queue.
pygame.event.poll() returns a single event from the event queue or pygame.NOEVENT if the queue is empty.
pygame.event.wait() returns a single event from the event queue or waits until an event can be returned.
pygame.event.pump() allows pygame to handle internal actions. Useful when you don't want to handle events from the event queue.
The window does not respond (freeze), because you do not handle the events. You have to handle the events by either pygame.event.pump() or pygame.event.get(), to keep the window responding.
See the documentation of pygame.event.pump():
For each frame of your game, you will need to make some sort of call to the event queue. This ensures your program can internally interact with the rest of the operating system.
Add an event loop, for instance:
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# [...]
Alternatively just pump the events:
while True:
pygame.event.pump()
# [...]
Minimal example: repl.it/#Rabbid76/PyGame-MinimalApplicationLoop
I have the following Scenes:
Player
Enemy
Attack
When an Attack collides with the Enemy, the Enemy emits a "onHit" signal.
The Player listens for that signal and bounces back.
This is all working good, but now if I duplicate the enemy so there are multiple Enemy scenes, how do I listen to the signal on all of them? Is there a way to grab all instances of a Scene and connect to all of their signals? Is there a better way of sending this message back to the Player?
I'm very new to Godot so any advice is very helpful! Thanks.
Use a Signal Bus.
Yes, you could iterate over the nodes and find all the enemies (e.g. by comparing their script). However, it is easier if all the enemies register themselves to a list (or a group) on _ready. However, you don't need any of that.
The insight is this: An object can emit signals of other objects.
We take advantage of that by creating a Signal Bus. Which is a a common pattern in Godot. It goes as follows:
Create an autoload (singleton) script. Let us call it SignalBus.
In the script, define signals. And nothing else. *In our case, we define on_hit:
signal on_hit
Every place that needs to emit a signal does it from the signal bus. In this case the enemies do this:
SignalBus.emit_signal("on_hit")
And where you need to handle the signal, connect to it. For example on _ready. Something like this:
func _ready() -> void:
SignalBus.connect("on_hit", self, "_on_hit")
func _on_hit() -> void:
# whatever
pass
This way the emitters and receivers of a signal don't need to know each other. They only need to know the Signal Bus. Which is available everywhere (by virtue of being an autoload).
I am trying to implement an alarm trigger functionality for an IoT device using Python thread, but have a problem understanding the logic for it.
My scenario:
I have a sensor that can send me triggers for motion and tamper. So if there is any motion or tamper detected by the sensor, it should trigger the siren.
The Siren is on a GPIO port that I have configured in a separate class. There is only one siren.
Now my code:
def siren(self):
print("Turning on the siren")
setGPIOvalue(<port>, <value>)
def triggeralarms(self,):
siren_trigger = threading.Thread(target=self.siren)
if (alarmed == True):
# Check for all the sensors if there is any alarms to be triggered
for i in range(len(a.senList)):
# Motion alarm
if (motion == True):
print("-----------------> Setting the motion alarm")
if not siren_trigger.is_alive():
siren_trigger.start()
motion == False
# Tamper alarm
if (tamper == True):
print("-----------------> Setting the tamper alarm")
if not siren_trigger.is_alive():
siren_trigger.start()
tamper == False
In the siren, there is a delay of 10 sec.
The triggeralarms() function keeps on checking the status in loop.
Issue:
Now the problem is that the code triggers the GPIO for both motion and tamper sometimes. So both motion and tamper create a thread to trigger the siren.
What I am looking is for to somehow to check if the siren thread is already running, then it should now be started again.
For example, if the motion sensor triggers the siren, and I also receive the trigger for tamper, then if the siren thread is already running, tamper should not start the siren thread again.
I tried to by checking siren_trigger.is_alive() but it seems to be not working.
I am missing the logic here.
I just finished implementing the game Pong using node.js and socket.io for backend, with jQuery for client-side. I put the game on my free-tier AWS instance and the mechanics work fine but the latency is unplayable. In the game, the paddle of the player who controls it moves locally. The client-side also sends a server request which broadcasts paddle movement to the opponent every requestFrameAnimation. To launch the ball the player whose serve it is presses spacebar which sends a server request, which then emits to both players to start the ball movement.
Both the paddle movement and the ball launching are suffering from latency. For the paddles I think the problem is that I'm sending a server request every requestFrameAnimation which is probably to fast of a rate. Maybe I should make a setInterval that sends the player's paddle position to his opponent every fraction of a second. As for the ball, since the signal for it to start moving is sent by the server I think I need to send an actual time for the ball to launch ahead of the time the spacebar was pressed so each local machine can count down to that time.
Here is a snipped of my client-side code for some context:
function updateFrame(){
paddleSpeed = 0;
if (keysPressed.up){ // Move paddle up
if (!(myPaddle.offset().top <= arena.offset().top)){ // Make sure paddle isn't at top
paddleSpeed -= 8;
}
}
if (keysPressed.down) { // Move paddle down
if (!(myPaddle.offset().top+paddleL.height() >= arena.offset().top + arena.height())){ // Make sure paddle isn't at bottom
paddleSpeed += 8;
}
}
if (paddleSpeed != 0) socket.emit("moveReq", paddleSpeed); // Send server request to be sent to opponent
myPaddle.css({top: '+='+paddleSpeed+'px'}); // Move paddle locally
if (gameInProgress){ // If round has started, move the ball
ball.css({left: '+='+ballSpeed.hor+'px', top: '+='+ballSpeed.ver+'px'});
window.requestAnimationFrame(updateFrame); // Request next frame
and my server-side:
socket.on('moveReq', function(data){
socket.broadcast.emit("movePaddle", data); // Send opponent's paddle movement to user
});
socket.on('launchGame', function(){ // Launch the game
io.sockets.emit('startGame');
});
Does anybody have any tips to reduce the latency on my game, or is my free-tier just too low bandwidth for this sort of web app?
There should be enough bandwidth to run this game easy, so I do not think that is your problem.
Instead I recommend you to take a look at this blog about online game developing. I used the ideas described in there myself when I started developing multiplayer games. It explains several key problems and solutions when developing online games.
I am currently writing a text based game where you decide your path through the story. I am having trouble with allocating the letter A so that when ever it is pressed the next paragraph/text comes up. At the moment this is what I have got but if there is a better way to do i would love to know.
A =input("Click A to move on")
if A == "a":
print(" When you wake up, the sun is up and the birds are singing. Your musles scream out in pain as you slowly stand up and survey your surroundings.")
import time
time.sleep(3)
B =input("Click B to move on")
if B == "B":
print (" The clearing is small, surrounding by towering trees and bathed in warm light. The ground is littled with orange-golden leafs. Something catches your eye and you bend to pick it up.")
import time
time.sleep(2)
print ("\n Its a small shiny silver locket which feels cold and damp in your hands.")