I took a sprite sheet of 7 frames (character running animation) and put it in a Tile array. For some strange reason, I can toggle the visibility of each frame (on or off) unless it is placed inside a conditional (if/then), in which case it stays on the scree even though the trace reveals that visibility is false. Any ideas why?
char[0].visible = false; //works!
s = 10;
if (s > 2) {
char[0].visible = false; //trace's as false, but remains on screen
}
Related
Unsquashed Sprite Squashed Sprite
My brother has issues with his sprite squashing whilst moving horizontally. The squashing is permanent after moving. I have found the line that causes the problem but cannot figure out what is causing this issue. When I remove this line the squashing stops however the sprite does not turn. He is following Shaun Spalding's Complete Platformer Tutorial and though I've watched it over I cannot find any issues with the actual code.
/// #description Insert description here
// You can write your code in this editor
// get player input
key_left=keyboard_check(vk_left);
key_right=keyboard_check(vk_right);
key_jump=keyboard_check_pressed(vk_up);
// calculate movement
var move=key_right-key_left;
hsp=move*walksp;
vsp=vsp+grv;
if(place_meeting(x,y+1,o_wall)) and (key_jump)
{
vsp=-7;
}
// horizontal collision
if (place_meeting(x+hsp,y,o_wall))
{
while(!place_meeting(x+sign(hsp),y,o_wall))
{
x=x+sign(hsp);
}
hsp=0;
}
x=x+hsp;
// vertical collision
if (place_meeting(x,y+vsp,o_wall))
{
while(!place_meeting(x,y+sign(vsp),o_wall))
{
y=y+sign(vsp);
}
vsp=0;
}
y=y+vsp;
// animation
if(!place_meeting(x,y+1,o_wall))
{
sprite_index=splayerA;
image_speed=0;
if (sign(vsp) > 0) image_index = 1; else image_index = 0;
}
else
{
image_speed=1;
if (hsp==0)
{
sprite_index=s_player;
}
else
{
sprite_index=splayerR;
}
}
if (hsp != 0) image_xscale = sign(hsp); //this line is wrong and causes the squishing
A possible cause of this is that you've set the image_xscale to a different value before using the line:
if (hsp != 0) image_xscale = sign(hsp);
For example, you may have set this in the Create Event to enlarge the sprite:
image_xscale = 2;
But that value is reset after setting image_xscale again, as that line will only return -1 or 1 because of the Sign().
One quick solution is to apply the scale change to that line of code, like this:
if (hsp != 0) image_xscale = 2 * sign(hsp);
(Once again, presuming you've changed it's scale value somewhere else)
Though another solution is to enlarge the sprite itself in the sprite editor, so the scale doesn't have to be kept in mind everytime.
I have a task on Unity 3d that if the player doesn't move for 5 seconds, a pop-up shows on the center of the screen and if the player moves, the pop-up disappears. How can I write the logic for this task please ?
Thanks
Here is code that will check the mouse position of the user and see if it has moved in the last 5 seconds. If it has not, then the popup window will show up. If it's hard to read here with the comments (I kind of think it is) copy and paste this code into Visual Studio so the colors will help distinguish code from comments.
[SerializeField] GameObject popupWindow = null;
float totTime;
float timeBeforePause = 5f;
Vector3 updatedMousePosition;
private void Update()
{
// Add the time delta between frames to the totTime var
totTime += Time.deltaTime;
// Check to see if the current mouse position input is equivalent to updateMousePosition from the previous update
// If they are equivalent, this means that the user hasn't moved the mouse
if (Input.mousePosition == updatedMousePosition)
{
// Since the user hasn't moved the mouse, check to see if the total Time is greater than the timeBeforePause
if (totTime >= timeBeforePause)
{
// Set the popup window to true in order to show the window (instantiate instead it if if doesn't exist already)
popupWindow.SetActive(true);
}
}
// If the user has moved the mouse, set the totTime back to 0 in order to restart the totTime tracking variable
else
{
totTime = 0;
}
// Check to see if the popup window is visible (active)
if (popupWindow.activeSelf == true)
{
// Check to see if the user has pressed the Esc button
if (Input.GetKeyDown(KeyCode.Escape))
{
// Hide the window
popupWindow.SetActive(false);
}
}
// Update the updatedMousePosition before the next frame/update loop executes
updatedMousePosition = Input.mousePosition;
}
If you want to track different user input (key presses) you can use a similar method. Also you will have to implement some sort of button on the popup window that will allow the user to exit out from the popup window once they return. Hope this helps!
Is there a reliable way to get the inner and outer rectangle of a top
level window with XCB/Xlib? (IOW frame and client rectangle).
Here's what I tried:
xcb_get_geometry always returns the initial dimensions even after
the window gets resized (what gives?)
I figured I would call xcb_query_tree repeatedly until I find the
window's frame window - is this the way to do it? I figure ICCCM/EWMH
should provide this but couldn't find anything. Is there any other
standard/non-standard for this? Anyway that doesn't work with
compiz/ubuntu10 because xcb_query_tree reports the client window as
having root = parent (under normal ubuntu wm the window gets properly
reparented).
xcb_translate_coordinates() seemed to be the only reliable way to
get root-based coords[1] in 2007 -- is this still the case? I.e. is
XCB_CONFIGURE_NOTIFY non-standard with WMs?
[1] http://fixunix.com/xwindows/91652-finding-position-top-level-windows.html
This is a partial answer as it only explains how to find the inner dimensions of a window. Also I am not sure if this is the canonical way to go but it works for me.
You can subscribe to the XCB_EVENT_MASK_RESIZE_REDIRECT event when creating a window:
xcb_window_t window = xcb_generate_id (connection);
const xcb_setup_t *setup = xcb_get_setup (connection);
xcb_screen_t *screen = xcb_setup_roots_iterator (setup).data;
uint32_t mask = XCB_CW_EVENT_MASK;
uint32_t valwin[1] = { XCB_EVENT_MASK_EXPOSURE
| XCB_EVENT_MASK_RESIZE_REDIRECT };
xcb_create_window(
connection,
XCB_COPY_FROM_PARENT,
window,
screen->root,
0, 0,
800, 600,
0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->root_visual,
mask, valwin);
xcb_map_window(connection, window);
xcb_flush(connection);
In the event loop you can then keep track of resizes:
xcb_generic_event_t *event;
uint16_t width = 0, height = 0;
while ((event = xcb_wait_for_event(connection)) != NULL) {
switch (event->response_type & ~0x80) {
case XCB_EXPOSE: {
/* ... */
break;
}
case XCB_RESIZE_REQUEST: {
auto resize = (xcb_resize_request_event_t*) event;
if (resize->width > 0) width = resize->width;
if (resize->height > 0) height = resize->height;
break;
}
default:
break;
}
free(event);
xcb_flush(connection);
}
Note that I am not sure whether this event is emitted when you initiate the resize from your application code using xcb_configure_window for example. I never tested it and just update the width and height in a wrapper function for xcb_configure_window.
I do a growth animation of a fixed number of items, and after growth, i moved it to left.
Make growth by apply matrix
var trans_vector = new THREE.Matrix4().makeTranslation(0, height / 2, 0);
var graphics = new Graphics();
var rectangle = graphics.box(width, height, material);
rectangle.geometry.applyMatrix(trans_vector);
When a new item is added, i remove one from the container that will be added to scene
var children = this.container.children;
if (this.current_number === this.max_number) {
this.container.remove(children[0]);
this.current_number = this.max_number - 1;
}
object.position.copy(this.position); // this is a fixed position
this.container.add(object);
this.current_number++;
I write a function to translate to left, using tweenjs (sole)
animateTranslation : function(object, padding, duration) {
var new_x = object.position.x - padding; // Move to left
console.log(new_x); // Duplicated item here :(
new TWEEN.Tween(object.position).to({
x : new_x
}, duration).start();
},
And I remove all the "previous" items, using for loop
for (var i = 0; i < this.current_number-1; i++) {
this.animateTranslation(this.container.children[i],
this.padding,
this.duration/4)
}
The above code run correctly if we open and keep this current tab.
The problem is when we move to another tab, do something and then move back, some objects have the same position, that cause the translation to the same position. It looks weird.
It appears on both Chrome, Firefox and IE11.
I dont know why, please point me out what happened.
Most modern browsers choose to limit the delay in setInterval and pause requestAnimationFrame in inactive tabs. This is done in order to preserve CPU cycles and to reduce power consumption, especially important for mobile devices. You can find more details about each browser in this answer
That means, while the tab is inactive, your tween animation is not working the way it is normally expected to.
A simple solution would be to halt the main animation loop if the tab is inactive using a variable.
window.onfocus = function () {
isActive = true;
};
window.onblur = function () {
isActive = false;
};
I have ~10000 objects in my game and exactly 60 (maximum) FPS when mouse isn't moved. But just when you start moving mouse in circles FPS tries to reach 30 averaging at 45. When you stop mouse it's INSTANTLY 60 (as so program lost it's heartbeat). SWF is run standalone - without any browsers.
I removed any MouseEvent.MOUSE_MOVE listeners and made mouseEnabled=false and mouseChildren=false for the main class.
I increased my FPS one-by-one from 12 to 60 - I gave name to each frame I born and it's really painful watching how 15 of them die just because of nothing...
Sample code:
public class Main extends Sprite
{
private var _periods : int = 0;
/** Idling FPS is 23. Move mouse to drop FPS to 21.*/
public function Main() : void
{
//true if need to drop FPS to 18 instead of 21 moving mouse:
const readyToKill2MoreFrames : Boolean = true;
if ( readyToKill2MoreFrames )
{
var ellipse : Sprite = new Sprite;
ellipse.graphics.beginFill( 0x00FF00 );
ellipse.graphics.drawEllipse( 300, 300, 400, 200 );
ellipse.graphics.endFill();
addChild( ellipse );
//uncomment to fall only to 21 instead of 18:
/*ellipse.mouseChildren = false;
ellipse.mouseEnabled = false;*/
}
var fps : TextField = new TextField;
//uncommenting doesn't change FPS:
//fps.mouseEnabled = false;
addChild( fps );
fps.text = "???";
fps.scaleX = fps.scaleY = 3;
var timer : Timer = new Timer( 1000 );
timer.addEventListener( TimerEvent.TIMER, function( ... args ) : void
{
fps.text = _periods.toString();
_periods = 0;
} );
timer.start();
addEventListener( Event.ENTER_FRAME, function( ... args ) : void
{
//seems like PC is too fast to demonstrate mouse movement
// drawbacks when he has nothing else to do, so let's make
// his attention flow:
for ( var i : int = 0; i < 500000; ++i )
{
var j : int = 2 + 2;
}
++_periods;
} );
}
}
You've probably moved on to more modern problems, but I've recently struggled with this issue myself, so here's an answer for future unfortunates stuck with the problems created by Adobe's decade-old sins.
It turns out legacy support for old-style buttons is the culprit. Quote from Adobe's tutorial on the excellent Scout profiling tool:
"Flash Player has some special code to handle old-style button objects (the kind that you create in Flash Professional).
Independently of looking for ActionScript event handlers for mouse
events, it searches the display list for any of these buttons whenever
the mouse moves. This can be expensive if you have a large number of
objects on the display list. Unfortunately, this operation happens
even if you don't use old-style button objects, but Adobe is working
on a fix for this."
Turns out Adobe never really got around to fixing this, so any large number of DisplayObjects will wreak havoc on your FPS while the mouse is moved. Only fix is to merge them somehow, e.g. by batch drawing them using Graphics. In my early tests, it seems setting mouseEnabled = false has no real effect, either.