I'm trying to make a game and still in the opening stages, I have the character and the code I thought would work, except when I run it nothing happens. I cant seem to find an error in it.
document.body.onkeydown = function(event){
var k = event.keyCode;
var chr = {
updown: function (){
var y = 0;
if (k==38) {
--y;
} else if (k == 40) {
++y;
}
return y;
},
leftright: function (){
var x = 0;
if (k == 37) {
--x;
} else if (k == 39) {
++x;
}
return x;
}
};
rogue.style.top = (chr.updown()) + "px";
rogue.style.left = (chr.leftright()) + "px";
}
#rogue {
position: relative;
top: 0px;
left: 0px;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="jumpOPP.css">
<script src="jumpOPP.js"></script>
</head>
<body>
<img id="rogue" src="http://piq.codeus.net/static/media/userpics/piq_143310_400x400.png" >
</body>
</html>
I would appreciate any help at all.
Wrap your function like this:
document.body.onkeydown = function(event){
// Your event here
};
Take the handler off the body tag too.
JSFIDDLE
Change your function as below (its just a sample)
Suggested reading:
Retrieve the position (X,Y) of an HTML element
...
updown: function (){
var y = CURRENT_Y; // Get the current Y position of the image HERE
if (k==38) {
--y;
} else if (k == 40) {
++y;
}
return y;
},
leftright: function (){
var x = CURRENT_X; // Get the current X position of the image HERE
if (k == 37) {
--x;
} else if (k == 39) {
++x;
}
return x;
}
The logic you're using to set the top and left values is a little off. Note also that you need to parse the value to an integer so that you can add/remove from its value, and also provide a default.
Try this:
document.body.onkeydown = function(event){
var rogue = document.getElementById('rogue');
var currentY = parseInt(rogue.style.top || 0, 10);
var currentX = parseInt(rogue.style.left || 0, 10);
var speed = 3;
switch (event.keyCode) {
case 38: // up;
rogue.style.top = (currentY - speed) + 'px';
break;
case 40: // down;
rogue.style.top = (currentY + speed) + 'px';
break;
case 37: // left;
rogue.style.left = (currentX - speed) + 'px';
break;
case 39: // right;
rogue.style.left = (currentX + speed) + 'px';
break;
}
}
Example fiddle
Perfectly Working Answer: Run the Code Snippet and check
//bind an event when the user presses any key
window.onkeydown = function (e) {
if (!e) {
e = window.event;
}
//The event object will either be passed
//to the function, or available through
//window.event in some browsers.
var code = e.keyCode;
//that's the code of the key that was pressed.
//http://goo.gl/PsUij might be helpful for these.
//find our rouge image
var rouge = document.getElementById("rouge");
//get the image's current top and left position.
//rouge.style.top will find the top position out of our
//style attribute; parseInt will turn it from for example '10px'
//to '10'.
var top = parseInt (rouge.style.top, 10);
var left = parseInt (rouge.style.left, 10);
//We'll now compare the code that we found above with
//the code of the keys that we want. You can use a chart
//like the one in http://goo.gl/PsUij to find the right codes,
//or just press buttons and console.log it yourself.
if ( code == 37 ) { //LEFT
//time to actually move the image around. We will just modify
//its style.top and style.left accordingly. If the user has pressed the
//left button, we want our player to move closer to the beginning of the page,
//so we'll reduce the 'left' value (which of course is the distance from '0' left)
//by 10. You could use a different amount to make the image move less or more.
//we're also doing some very basic boundary check to prevent
//the image from getting out of the page.
if ( left > 0 ) {
rouge.style.left = left - 10 + 'px';
}
} else if ( code == 38 ) { //UP
//if we pressed the up button, move the image up.
if ( top > 0 ) {
rouge.style.top = top - 10 + 'px';
}
} else if ( code == 39 ) { //RIGHT
//move the image right. This time we're moving further away
//from the screen, so we need to 'increase' the 'left' value.
//the boundary check is also a little different, because we're
//trying to figure out if the rightmost end of the image
//will have gone
//further from our window width if we move it 10 pixels.
if ( left+rouge.width+10 < window.innerWidth ) {
rouge.style.left = left + 10 + 'px';
}
} else if ( code == 40 ) { //DOWN
if ( top+rouge.height+10 < window.innerHeight ) {
rouge.style.top = top + 10 +'px';
}
}
}
<img src="http://piq.codeus.net/static/media/userpics/piq_143310_400x400.png" id="rouge" style="position:absolute;top:0px;left:0px" />
Try this :
Create an array to hold key states : window.keyStates[];
Update the keyStates var with onkeyup / onkeydown events.
document.body.onkeydown = function (event) {
window.keyStates[event.keyCode] = true;
}
document.body.onkeyup = function (event) {
window.keyStates[event.keyCode] = false;
}
Create a loop to loop game :
var mainLoop = function () {
if (window.keyStates[38]) dostuff ();
if (window.keyStates[40]) dootherstuff ();
// etc....
}
window.setInterval(function() {mainLoop()}, 100);
The code is glitchy but you get the idea ? This way you can move your toon 2 directions at the same time too. Or manage virtually any key pressed at the same time.
Related
var depth = 0;
var moving = false;
var answers = new Array();
var qNo = 0;
var rangeCarousel;
var productCarousel;
var ih, iw, orient;
var sidebarOpen = false;
var focused = "range";
var currentRange = 0;
$(document).ready(function () {
document.getElementById('intro').addEventListener('click', clickHandler);
document.getElementById('q1').addEventListener('click', clickHandler);
document.getElementById('q2').addEventListener('click', clickHandler);
document.getElementById('q3').addEventListener('click', clickHandler);
document.getElementById('q4').addEventListener('click', clickHandler);
document.getElementById('intro').addEventListener('webkitTransitionEnd', transitionEnd);
document.getElementById('intro').addEventListener('transitionend', transitionEnd);
document.getElementById('intro').addEventListener('transition', transitionEnd);
});
function clickHandler(e) {
if ((qNo < 4) && (e.target.id != 'intro')) {
qNo++;
if (!moving) {
depth -= 100;
document.getElementById('intro').style.top = (depth + '%');
document.getElementById('q1').style.top = (depth + '%');
document.getElementById('q2').style.top = (depth + '%');
document.getElementById('q3').style.top = (depth + '%');
document.getElementById('q4').style.top = (depth + '%');
moving = true;
}
} else if (qNo == 4) {
var c = e.target.parentNode.classList[0];
switch (c) {
case 'one':
window.open("test.html","_self");
break;
case 'two':
window.open("test.html","_self");
break;
case 'three':
window.open("test.html","_self");
break;
case 'four':
window.open("test.html","_self");
break;
}
}
}
function transitionEnd() {
moving = false;
}
i m trying to create a quiz where users clicks on the images then loads the answer. It works fine on ie11 but i also need to make it work on ie10. I cant see any errors or anything to show me whats wrong
Any help or suggestion will be great
Some old IE does not support target property. You can use e.srcElement which is an alias of target as an alias of target
((e.target || e.srcElement).id) === "intro"
& also use it to find the parentNode
Side Note :As mentioned in comment section you can use jquery as which will also reduce the number of lines in your code beside efficiently handling events
You can also use jquery multiple selector instead of writing same lines of code for attaching event to every selector.
$('sel1 ,selector2 , selector 3 ...').click(function(event){.. rest of code})
I want to make a basic Space Invaders clone in ECMAScript/HTML5/CSS3 with the shortest and simplest code possible. I have begun implementing the controls, but they won't work. Here is the code:
<!DOCTYPE html>
<html>
<body onkeydown="javascript:move()" onkeyup=""></body>
<canvas id="myCanvas" width=800 height=800></canvas>
<script>
var context = document.getElementById('myCanvas').getContext("2d");
var img = new Image();
img.onload = function () {
context.drawImage(img, 0, 0, 40, 40);
}
img.src = "run0.png";
function leftArrowPressed() {
img.style.left = parseInt(element.style.left) - 5 + 'px';
}
function rightArrowPressed() {
img.style.left = parseInt(element.style.left) + 5 + 'px';
}
function move(evt) {
var code = window.event.keyCode;
switch (code) {
case 37:
leftArrowPressed();
break;
case 39:
rightArrowPressed();
break;
}
};
</script>
</body>
</html>
You're not handling your keydown event in the markdown of your <body> tag. You can listen to events programatically with JavaScript, or continue as you were doing by adding the move() method to your onkeydown attribute like so:
function leftArrowPressed() {
console.log('move left');
}
function rightArrowPressed() {
console.log('move right');
}
function move(evt) {
var code = window.event.keyCode;
switch (code) {
case 37:
leftArrowPressed();
break;
case 39:
rightArrowPressed();
break;
}
};
<body onkeydown="javascript:move()" onkeyup=""></body>
In order for the above to work (inside an iframe), it must first be focused. So click the white space where the demo opens up before testing.
It should be noted that interfacing the keyboard in browsers has been historically a bit of a headache. Your best bet is to delegate the task to a good library.
I have found the Mousetrap library to be pretty extensive.
You will have a mainloop so just set some flags and attach your key events to the document, no need to worry about focus. Ship will move as long as the key is held down. Fire button will need to have a reload flag and a timer to control the repeat rate. Fire reloads at key up or if reloadTime === 0. When firing set reload to true and reloadTime to repeat rate (in frames). In the key event reload on key up by setting reload = false .
That is about as simple as you can make it.
var framesPerSecond = 30;
var shipX = 0; // ship pos
var leftKeyDown = false; // key down flags
var rightKeyDown = false;
var fireKeyDown = false;
var reloadTime = 0; // fire key needs a timer a timer/counter inbuilt keyboard repeat will take over and mess with your repeat rate.
var reload = false; // dont want the keyboard repeat to trigger shots at the wrong time so
// flag that you need to reload when the next key up
// arrives.
function mainLoop(){
if(leftKeyDown){ // move left if left key down
shipX -= 1;
}
if(rightKeyDown){ // move right if right key down
shipX += 1;
}
if(fireKeyDown && !reload){ //fire is not needing to reload and fire key down
//log("FIRE"); // sends a bullet
reload = true; // need to reload
reloadTime = 10; // number of frames till reload.
}
if(reload && reloadTime > 0){ // if needing to reload
reloadTime -= 1; // count down frames
if(reloadTime === 0){ // until time to reload.
reload = false; // then reload.
}
}
....
// game stuff.
...
// can use requestAnimationFrame if you use canvas
// requestAnimationFrame(mainLoop); // 60 frames a second
// or because you are doing it in HTML
setTimeout(mainLoop,1000 / framesPerSecond);
}
function keyEvent(event){ // handle ky up and downs.
var state = false; // assume up
if(event.type === "keydown"){ // if down
state = true; // set as down
}
if(event.keyCode === 37){ // left key
leftKeyDown = state; // set key state
}else
if(event.keyCode === 39){ // right key
rightKeyDown = state; // set key sate
}else
if(event.keyCode === 32){ // space
fireKeyDown = state;
if(!state && reload){ // reload if needed and key up
reload = false;
}
}
}
document.addEventListener('keydown', keyEvent);
document.addEventListener('keyup', keyEvent);
I was looking for a function that would scroll a given element into view with some smart behavior:
if an element is descendant of a scrollable element - that ancestor is scrolled rather than body.
if an element is descendant of a positioned element - body won't be scrolled.
I didn't find any suitable function, so I made one and wanted some expert opinion on it. Please check the plunkr http://plnkr.co/edit/DNGWLh5cH1Cr1coZbwpa?p=preview . There are problems with animated scroll in FF, so please use Chrome to check the logic.
To illustrate, what I'm looking for - here is the first update that came to mind - if we reached an element that can scroll, lets call it SC (Scroll Parent), we should not only scroll SC to make the target visible inside it, but also recursively scroll SC itself into view, since it may outside of the currently visible are of the page. Here is the update plunkr http://plnkr.co/edit/DNGWLh5cH1Cr1coZbwpa?p=preview (also applied fix for FF scrolling problem).
And here is the code of the function
function scrollTo(target){
//Position delta is used for scrollable elements other than BODY
var combinedPositionDelta = 0;
var previousParent = $(target);
var parent = $(target).parent();
while(parent){
combinedPositionDelta += previousParent.position().top - parent.position().top;
//If we reached body
if(parent.prop("tagName").toUpperCase() == "BODY"){
scrollBody(target.offset().top);
break;
}
//if we reached an element that can scroll
if(parent[0].scrollHeight > parent.outerHeight()){
scrollElementByDelta(parent,combinedPositionDelta);
//Recursively scroll parent into view, since it itself might not be visible
scrollTo(parent);
break;
}
//if we reached a apositioned element - break
if(parent.css('position').toUpperCase() != 'STATIC'){
console.log("Stopping due to positioned parent " + parent[0].outerHTML);
break;
}
previousParent = parent;
parent = parent.parent();
}
}
var offsetSkin = 20;
function scrollElementByDelta(element,offsetDelta){
$(element).animate({
scrollTop: element.scrollTop() + (offsetDelta - offsetSkin)
}, 1000);
}
function scrollBody(offset){
$('body,html').animate({
scrollTop: offset - offsetSkin
}, 1000);
}
Well I'm Using this one which works very well for me:
function scrollIntoView (element, alignTop) {
var document = element.ownerDocument;
var origin = element, originRect = origin.getBoundingClientRect();
var hasScroll = false;
var documentScroll = this.getDocumentScrollElement(document);
while (element) {
if (element == document.body) {
element = documentScroll;
} else {
element = element.parentNode;
}
if (element) {
var hasScrollbar = (!element.clientHeight) ? false : element.scrollHeight > element.clientHeight;
if (!hasScrollbar) {
if (element == documentScroll) {
element = null;
}
continue;
}
var rects;
if (element == documentScroll) {
rects = {
left : 0,
top : 0
};
} else {
rects = element.getBoundingClientRect();
}
// check that elementRect is in rects
var deltaLeft = originRect.left - (rects.left + (parseInt(element.style.borderLeftWidth, 10) | 0));
var deltaRight = originRect.right
- (rects.left + element.clientWidth + (parseInt(element.style.borderLeftWidth, 10) | 0));
var deltaTop = originRect.top - (rects.top + (parseInt(element.style.borderTopWidth, 10) | 0));
var deltaBottom = originRect.bottom
- (rects.top + element.clientHeight + (parseInt(element.style.borderTopWidth, 10) | 0));
// adjust display depending on deltas
if (deltaLeft < 0) {
element.scrollLeft += deltaLeft;
} else if (deltaRight > 0) {
element.scrollLeft += deltaRight;
}
if (alignTop === true && !hasScroll) {
element.scrollTop += deltaTop;
} else if (alignTop === false && !hasScroll) {
element.scrollTop += deltaBottom;
} else {
if (deltaTop < 0) {
element.scrollTop += deltaTop;
} else if (deltaBottom > 0) {
element.scrollTop += deltaBottom;
}
}
if (element == documentScroll) {
element = null;
} else {
// readjust element position after scrolls, and check if vertical scroll has changed.
// this is required to perform only one alignment
var nextRect = origin.getBoundingClientRect();
if (nextRect.top != originRect.top) {
hasScroll = true;
}
originRect = nextRect;
}
}
}
}
I hope this helps.
If you do not mind venturing into jQuery, the scrollTo plugin is the best bet. It handles most needs and gives a very refined smooth trasition.
Hope it helps.
I'm using this javascript and the slide show slides right to left with the images in this order and positon:
start postion > 1 | 2 | 3 | 4 | 5 | 6 etc etc
but I want to swap them so they run in this position
6 | 5 | 4 | 3 | 2 | 1 < start position
Kind of like reading a book back to front, but keeping it in the right order
I've been told I need to modify the lines labelled below: //MODIFY ME
I hope someone can help! Thank you
Here's my code
(function($) {
$.fn.slideshow = function(method) {
if ( this[0][method] ) {
return this[0][ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return this.each(function() {
var ANIMATION_DURATION = .6; // The duration to flick the content. In seconds.
var MOVE_THRESHOLD = 10; // Since touch points can move slightly when initiating a click this is the
// amount to move before allowing the element to dispatch a click event.
var itemWidth;
var horizontalGap;
var $this = $(this);
var collection;
var viewItems = [];
var touchStartTransformX; // The start transformX when the user taps.
var touchStartX; // The start x coord when the user taps.
var interval; // Interval used for measuring the drag speed.
var wasContentDragged; // Flag for whether or not the content was dragged. Takes into account MOVE_THRESHOLD.
var targetTransformX; // The target transform X when a user flicks the content.
var touchDragCoords = []; // Used to keep track of the touch coordinates when dragging to measure speed.
var touchstartTarget; // The element which triggered the touchstart.
var selectedIndex = 0; // The current visible page.
var viewPortWidth; // The width of the div that holds the horizontal content.
var isAnimating;
var pageChangedLeft;
// The x coord when the items are reset.
var resetX;
var delayTimeout;
init(method);
function init(options) {
collection = options.data;
renderer = options.renderer;
itemWidth = options.itemWidth;
horizontalGap = options.horizontalGap;
initLayout();
$this[0].addEventListener("touchstart", touchstartHandler);
$this[0].addEventListener("mousedown", touchstartHandler);
viewPortWidth = $this.width();
$this.on("webkitTransitionEnd", transitionEndHandler);
collection.on("add", addItem);
}
// MODIFY ME
function initLayout() {
// Layout five items. The one in the middle is always the selected one.
for (var i = 0; i < 5; i++) {
var viewItem;
if (i > 1 && collection.at(i - 2)) // Start at the one in the middle. Subtract 2 so data index starts at 0.
viewItem = new renderer({model: collection.at(i - 2)});
else
viewItem = new renderer();
viewItem.render().$el.appendTo($this);
viewItem.$el.css("left", itemWidth * i + horizontalGap * i);
viewItem.setState(i != 2 ? "off" : "on");
viewItems.push(viewItem);
}
// Center the first viewItem
resetX = itemWidth * 2 - ($this.width() - itemWidth - horizontalGap * 4) / 2;
setTransformX(-resetX);
}
function getCssLeft($el) {
var left = $el.css("left");
return Number(left.split("px")[0]);
}
// MODIFY ME
function transitionEndHandler() {
if (pageChangedLeft != undefined) {
var viewItem;
if (pageChangedLeft) {
// Move the first item to the end.
viewItem = viewItems.shift();
viewItems.push(viewItem);
viewItem.model = collection.at(selectedIndex + 2);
viewItem.$el.css("left", getCssLeft(viewItems[3].$el) + itemWidth + horizontalGap);
} else {
// Move the last item to the beginning.
viewItem = viewItems.pop();
viewItems.splice(0, 0, viewItem);
viewItem.model = collection.at(selectedIndex - 2);
viewItem.$el.css("left", getCssLeft(viewItems[1].$el) - itemWidth - horizontalGap);
}
viewItem.render();
// Reset the layout of the items.
for (var i = 0; i < 5; i++) {
var viewItem = viewItems[i];
viewItem.$el.css("left", itemWidth * i + horizontalGap * i);
viewItem.setState(i != 2 ? "off" : "on");
}
// Reset the transformX so we don't run into any rendering limits. Can't find a definitive answer for what the limits are.
$this.css("-webkit-transition", "none");
setTransformX(-resetX);
pageChangedLeft = undefined;
}
}
function touchstartHandler(e) {
clearInterval(interval);
wasContentDragged = false;
transitionEndHandler();
// Prevent the default so the window doesn't scroll and links don't open immediately.
e.preventDefault();
// Get a reference to the element which triggered the touchstart.
touchstartTarget = e.target;
// Check for device. If not then testing on desktop.
touchStartX = window.Touch ? e.touches[0].clientX : e.clientX;
// Get the current transformX before the transition is removed.
touchStartTransformX = getTransformX();
// Set the transformX before the animation is stopped otherwise the animation will go to the end coord
// instead of stopping at its current location which is where the drag should begin from.
setTransformX(touchStartTransformX);
// Remove the transition so the content doesn't tween to the spot being dragged. This also moves the animation to the end.
$this.css("-webkit-transition", "none");
// Create an interval to monitor how fast the user is dragging.
interval = setInterval(measureDragSpeed, 20);
document.addEventListener("touchmove", touchmoveHandler);
document.addEventListener("touchend", touchendHandler);
document.addEventListener("mousemove", touchmoveHandler);
document.addEventListener("mouseup", touchendHandler);
}
function measureDragSpeed() {
touchDragCoords.push(getTransformX());
}
function touchmoveHandler(e) {
var deltaX = (window.Touch ? e.touches[0].clientX : e.clientX) - touchStartX;
if (wasContentDragged || Math.abs(deltaX) > MOVE_THRESHOLD) { // Keep track of whether or not the user dragged.
wasContentDragged = true;
setTransformX(touchStartTransformX + deltaX);
}
}
function touchendHandler(e) {
document.removeEventListener("touchmove", touchmoveHandler);
document.removeEventListener("touchend", touchendHandler);
document.removeEventListener("mousemove", touchmoveHandler);
document.removeEventListener("mouseup", touchendHandler);
clearInterval(interval);
e.preventDefault();
if (wasContentDragged) { // User dragged more than MOVE_THRESHOLD so transition the content.
var previousX = getTransformX();
var bSwitchPages;
// Compare the last 5 coordinates
for (var i = touchDragCoords.length - 1; i > Math.max(touchDragCoords.length - 5, 0); i--) {
if (touchDragCoords[i] != previousX) {
bSwitchPages = true;
break;
}
}
// User dragged more than halfway across the screen.
if (!bSwitchPages && Math.abs(touchStartTransformX - getTransformX()) > (viewPortWidth / 2))
bSwitchPages = true;
if (bSwitchPages) {
if (previousX > touchStartTransformX) { // User dragged to the right. go to previous page.
if (selectedIndex > 0) { // Make sure user is not on the first page otherwise stay on the same page.
selectedIndex--;
tweenTo(touchStartTransformX + itemWidth + horizontalGap);
pageChangedLeft = false;
} else {
tweenTo(touchStartTransformX);
pageChangedLeft = undefined;
}
} else { // User dragged to the left. go to next page.
if (selectedIndex + 1 < collection.length) {// Make sure user is not on the last page otherwise stay on the same page.
selectedIndex++;
tweenTo(touchStartTransformX - itemWidth - horizontalGap);
pageChangedLeft = true;
} else {
tweenTo(touchStartTransformX);
pageChangedLeft = undefined;
}
}
} else {
tweenTo(touchStartTransformX);
pageChangedLeft = undefined;
}
} else { // User dragged less than MOVE_THRESHOLD trigger a click event.
var event = document.createEvent("MouseEvents");
event.initEvent("click", true, true);
touchstartTarget.dispatchEvent(event);
}
}
// Returns the x of the transform matrix.
function getTransformX() {
var transformArray = $this.css("-webkit-transform").split(","); // matrix(1, 0, 0, 1, 0, 0)
var transformElement = $.trim(transformArray[4]); // remove the leading whitespace.
return transformX = Number(transformElement); // Remove the ).
}
// Sets the x of the transform matrix.
function setTransformX(value) {
$this.css("-webkit-transform", "translateX("+ Math.round(value) + "px)");
}
function tweenTo(value) {
isAnimating = true;
targetTransformX = value;
// Set the style for the transition.
$this.css("-webkit-transition", "-webkit-transform " + ANIMATION_DURATION + "s");
// Need to set the timing function each time -webkit-transition is set.
// The transition is set to ease-out.
$this.css("-webkit-transition-timing-function", "cubic-bezier(0, 0, 0, 1)");
setTransformX(targetTransformX);
}
// MODIFY ME
function addItem(folio) {
clearTimeout(delayTimeout);
// Create a timeout in case multiple items are added in the same frame.
// When the timeout completes all of the view items will have their model
// updated. The renderer should check to make sure the model is different
// before making any changes.
delayTimeout = setTimeout(function(folio) {
var index = collection.models.indexOf(folio);
var dataIndex = index;
var firstIndex = selectedIndex - 2;
var dataIndex = firstIndex;
var viewItem;
for (var i = 0; i < viewItems.length; i++) {
viewItem = viewItems[i];
if (dataIndex >= 0 && dataIndex < collection.length) {
viewItem.model = collection.at(dataIndex);
viewItem.render();
}
viewItem.setState(i != 2 ? "off" : "on");
dataIndex += 1;
}
}, 200);
}
// Called when the data source has changed. Resets the view with the new data source.
this.setData = function(data) {
$this.empty();
viewItems = [];
collection = data;
selectedIndex = 0;
initLayout();
}
});
} else {
$.error( 'Method ' + method + ' does not exist on Slideshow' );
}
}
})(jQuery);
From what I can make out, you need to simply "flip" the loops that create the sides in the slideshow so that it makes the last slide where it was making the first. It seems to do this in two places.
Then, you will need to amend the code which adds a slide to make it add it before the other slides instead of after.
This sounds an awful lot like homework - it's always best to attempt an answer before asking on here. An example on a site like JSFiddle is also generally appreciated.
I am trying to make images that move around the screen that do something when they are clicked. I am using setInterval to call a function to move the images. Each image has the onclick attribute set. The problem is that the clicks are not registering.
If I take out the setInterval and just keep the images still, then the clicks do register.
My code is here (html, css, JavaScript): https://jsfiddle.net/contini/nLc404x7/4/
The JavaScript is copied here:
var smiley_screen_params = {
smiley_size : 100, // needs to agree with width/height from css file
num_smilies: 20
}
var smiley = {
top_position : 0,
left_position : 0,
jump_speed : 2,
h_direction : 1,
v_direction : 1,
intvl_speed : 10, // advance smiley every x milliseconds
id : "smiley"
}
function randomise_direction(s) {
var hd = parseInt(Math.random()*2);
var vd = parseInt(Math.random()*2);
if (hd === 0)
s.h_direction = -1;
if (vd === 0)
s.v_direction = -1;
}
function plotSmiley(sp /* sp = smiley params */) {
var existing_smiley = document.getElementById(sp.id);
if (existing_smiley !== null)
// delete existing smiley so we can move it
document.getElementById("smileybox").removeChild(existing_smiley);
var smiley_to_plot = document.createElement('img');
smiley_to_plot.setAttribute('src', "http://i.imgur.com/C0BiXJx.png");
smiley_to_plot.setAttribute('id', sp.id);
smiley_to_plot.setAttribute('onclick', "my_click_count()");
smiley_to_plot.style.position = 'absolute';
smiley_to_plot.style.top = sp.top_position + "px";
smiley_to_plot.style.left = sp.left_position + "px";
document.getElementById("smileybox").appendChild(smiley_to_plot);
}
function random_direction_change() {
var r = parseInt(Math.random()*200);
if (r===0)
return true;
else
return false;
}
function moveFace(sp_array /* sp_array = smiley params array */) {
var i;
var sp;
for (i=0; i < sp_array.length; ++i) {
// move ith element
sp = sp_array[i];
if (
(sp.h_direction > 0 && sp.left_position >= smiley_screen_params.width - smiley_screen_params.smiley_size) ||
(sp.h_direction < 0 && sp.left_position <= 0) ||
(random_direction_change())
) {
sp.h_direction = -sp.h_direction; // hit left/right, bounce off (or random direction change)
}
if (
(sp.v_direction > 0 && sp.top_position >= smiley_screen_params.height - smiley_screen_params.smiley_size) ||
(sp.v_direction < 0 && sp.top_position <= 0) ||
(random_direction_change())
) {
sp.v_direction = -sp.v_direction; // hit top/bottom, bounce off (or random direction change)
}
sp.top_position += sp.v_direction * sp.jump_speed;
sp.left_position += sp.h_direction * sp.jump_speed;
plotSmiley(sp);
}
}
if (typeof Object.create !== 'function') {
Object.create = function(o) {
var F = function () {};
F.prototype = o;
return new F();
};
}
function generateFaces() {
var smilies = new Array();
var s;
var i;
var css_smileybox=document.getElementById("smileybox");
var sb_style = getComputedStyle(css_smileybox, null);
// add info to the screen params
smiley_screen_params.width = parseInt(sb_style.width);
smiley_screen_params.height = parseInt(sb_style.height);
// create the smileys
for (i=0; i < smiley_screen_params.num_smilies; ++i) {
s = Object.create(smiley);
s.id = "smiley" + i;
s.top_position = parseInt(Math.random() * (smiley_screen_params.height - smiley_screen_params.smiley_size)),
s.left_position = parseInt(Math.random() * (smiley_screen_params.width - smiley_screen_params.smiley_size)),
randomise_direction(s);
smilies.push(s);
}
setInterval( function(){ moveFace(smilies) }, smiley.intvl_speed );
}
var click_count=0;
function my_click_count() {
++click_count;
document.getElementById("mg").innerHTML = "Number of clicks: " + click_count;
}
generateFaces();
The generateFaces() will generate parameters (for example, coordinates of where they are placed) for a bunch of smiley face images. The setInterval is within this function, and calls the moveFace function to make the smiley faces move at a fixed interval of time. moveFace computes the new coordinates of each smiley face image and then calls plotSmiley to plot each one on the screen in its new location (removing it from the old location). The plotSmiley sets the onclick attribute of each image to call a dummy function just to see if the clicks are registering.
Thanks in advance.
This is not a complete answer but it could give you some perspective to improve your code.
First of all, your idea of deleting the existing img so wrong. If it does exist, all you need is to just change its position so instead of this
if (existing_smiley !== null)
// delete existing smiley so we can move it
document.getElementById("smileybox").removeChild(existing_smiley);
you should do something like this:
if (existing_smiley !== null)
var smiley_to_plot = existing_smiley;
else {
var smiley_to_plot = document.createElement('img');
smiley_to_plot.setAttribute('src', "http://i.imgur.com/C0BiXJx.png");
smiley_to_plot.setAttribute('id', sp.id);
smiley_to_plot.style.position = 'absolute';
document.getElementById("smileybox").appendChild(smiley_to_plot);
smiley_to_plot.addEventListener('click', my_click_count);
}
smiley_to_plot.style.top = sp.top_position + "px";
smiley_to_plot.style.left = sp.left_position + "px";
As you can see new image is only being added if it's not already there. Also notice that adding events by using .setAttribute('onclick', "my_click_count()"); is not a good way to do. You should use .addEventListener('click', my_click_count); like I did.
Like I said this is not a complete answer but at least this way they response to the click events now.
FIDDLE UPDATE
Good luck!